Created
October 16, 2012 15:34
-
-
Save sjb-gist/3900013 to your computer and use it in GitHub Desktop.
waf: extra support for csharp builds
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# encoding: utf-8 | |
# Copyright © 2012 SjB <[email protected]>. All Rights Reserved. | |
import os, shutil | |
from waflib.TaskGen import feature, extension, after, before | |
from waflib.Task import Task | |
from waflib.Configure import conf | |
from waflib.Tools import ccroot | |
from waflib import Utils, Options, Context | |
# | |
# waf tools to extend the build-in cs tool provided with the default waf build system. | |
# | |
def options(ctx): | |
ctx.load('cs') | |
ctx.add_option('--sdk', type='string', dest='sdk_version') | |
ctx.add_option('--with-resgen-binary', type='string', dest='resgenbinary') | |
def configure(ctx): | |
csc = getattr(Options.options, 'cscbinary', None) | |
if csc: | |
conf.env.MCS = csc | |
else: | |
# Added the dmcs mono compile to the default list. | |
# Users can define their own list by assigning an list of compiler | |
# to the ctx.cscbinary variable | |
cscbinary = getattr(ctx, 'cscbinary', ['csc', 'dmcs', 'gmcs', 'mcs']) | |
ctx.find_program(cscbinary, var='MCS') | |
resgen = getattr(Options.options, 'resgenbinary', None) | |
if resgen: | |
conf.env.RESGEN = resgen | |
else: | |
ctx.find_program(['resgen'], var='RESGEN') | |
ctx.load('cs') | |
# new variable that allow the sdk version to be specified at the command line. | |
sdk_version = getattr(Options.options, 'sdk_version', None) | |
if sdk_version: | |
self.env.append_value('CSFLAGS', '/sdk:%s' % sdk_version) | |
# converts the *.cs.in source files into *.cs files replacing all @var@ with | |
# the appropriate values in the related variable in the ctx.Define array | |
@extension('.cs.in') | |
def process_in(self, node): | |
for x in self.env['DEFINES']: | |
(k, v) = x.split('=') | |
setattr(self.cs_task.generator, k, v) | |
tgt = node.change_ext('.cs', ext_in='.cs.in').path_from(self.bld.bldnode) | |
print repr(tgt) | |
tsk = self.create_task('subst', node, tgt) | |
class resources(Task): | |
inst_to = None | |
run_str = '${RESGEN} ${SRC} ${TGT}' | |
@extension('.resx') | |
def process_resx(self, node): | |
tsk = self.create_task('resources', node, node.change_ext('.resources', ext_in='.resx')) | |
# Make sure we assign a value to name. (this should be included in the original tool) | |
@feature('cs') | |
@before('apply_cs') | |
def fix_assign_gen_to_name(self): | |
name = getattr(self, 'name', None) or self.gen | |
setattr(self, 'name', name) | |
# Simple Coype file Task | |
class copy_file(Task): | |
chmod = Utils.O644 | |
inst_to = None | |
def run(self): | |
infile = self.inputs[0].abspath() | |
outfile = self.outputs[0].abspath() | |
try: | |
shutil.copy2(infile, outfile) | |
except (OSError, IOError): | |
return 1 | |
else: | |
if self.chmod: os.chmod(outfile, self.chmod) | |
return 0 | |
# Copy all external (USE) library in the the build directory. This will allow use to | |
# run the codes from within that build directory. | |
@feature('cs') | |
@after('use_cs') | |
def copy_dep_nodes_to_builddir(self): | |
if getattr(self, 'copy_dependent_files', True): | |
tsk = getattr(self, 'cs_task', None) | |
if not tsk: | |
self.bld.fatal('not a cs task : %r' % self) | |
bld_path = tsk.outputs[0].parent | |
for src in tsk.dep_nodes: | |
out = bld_path.find_or_declare(src.name) | |
cp_tsk = self.create_task('copy_file', src, out) | |
cp_tsk.set_run_after(tsk) | |
#tsk.outputs.append(out) | |
try: | |
self.install_task.source.append(out) | |
except AttributeError: | |
pass | |
@feature('cs') | |
@after('apply_cs') | |
@before('use_cs') | |
def pkg_cs(self): | |
names = self.to_list(getattr(self, 'use', [])) | |
for x in names: | |
pkg = 'PKG_%s' % Utils.quote_define_name(x) | |
if pkg in getattr(self.env, 'packages', []): | |
self.env.append_value('CSFLAGS', '/pkg:%s' % x) | |
names.remove(x) | |
self.use = ' '.join(names) | |
@feature('cs') | |
@after('apply_cs') | |
@before('use_cs') | |
def use_extlib(self): | |
names = self.to_list(getattr(self, 'use', [])) | |
for x in names: | |
lib_name = Utils.quote_define_name(x) | |
for lib_type in ccroot.lib_patterns.keys(): | |
if not 'csshlib' == lib_type: | |
if lib_name in getattr(self.env, 'ext_%s' % lib_type, []): | |
names.remove(x) | |
self.use = ' '.join(names) | |
# Add define params to the compile command line | |
@conf | |
def set_define(self, *k, **kw): | |
if k[0]: | |
kw['defines'] = k[0] | |
kw['defines'] = Utils.to_list(kw['defines']) | |
if len(kw['defines']): | |
self.env.append_value('CSFLAGS', '/define:%s' % ';'.join(kw['defines'])) | |
# Set the sdk version | |
@conf | |
def set_sdk_version(self, *k, **kw): | |
if k: | |
kw['sdk_version'] = k[0] | |
if 'sdk_version' in kw: | |
v = kw['sdk_version'] | |
self.msg("Setting .Net SDK version", v) | |
self.env.append_value('CSFLAGS', '/sdk:%s' % v) | |
# check if a pkg-config package in install on the system | |
@conf | |
def check_pkg(self, *k, **kw): | |
self.check_cfg(**kw) | |
if self.get_define(self.have_define(kw['package'])): | |
self.env.append_value('packages', 'PKG_%s' % Utils.quote_define_name(kw['package'])) | |
# check if an external lib is available to the compiler. | |
@conf | |
def check_extlib(self, *k, **kw): | |
if not 'package' in kw: | |
kw['package'] = k[0] | |
if not 'msg' in kw: | |
kw['msg'] = 'Checking for %s' % kw['package'] | |
paths = ['.'] | |
if "path_list" in kw: | |
for p in Utils.to_list(kw['path_list']): | |
if p: | |
paths.append(p) | |
if not 'lib_type' in kw: | |
kw['lib_type'] = 'shlib' | |
if 'csshlib' == kw['lib_type']: | |
if not 'csshlib' in ccroot.lib_patterns: | |
ccroot.lib_patterns['csshlib'] = [] | |
ccroot.lib_patterns['csshlib'].append('%s.dll') | |
names = [x % kw['package'] for x in ccroot.lib_patterns[kw['lib_type']]] | |
ret = self.find_file(names, path_list=paths) | |
if ret: | |
uselib = Utils.quote_define_name(kw['package']) | |
self.env.append_value('ext_%s' % kw['lib_type'], uselib) | |
self.env.append_value('%s_LIBPATH' % uselib, os.path.dirname(ret)) | |
self.define(self.have_define(kw.get('uselib_store', kw['package'])), 1, 0) | |
self.msg(kw['msg'], ret, "GREEN") | |
#check if an external assembly is available to the compiler | |
@conf | |
def check_assembly(self, *k, **kw): | |
kw['lib_type'] = 'csshlib' | |
check_extlib(self, *k, **kw) | |
from waflib.Build import BuildContext | |
class NUnitContext(BuildContext): | |
cmd = 'nunit' | |
fun = 'build' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment