Please note:The SCons wiki is in read-only mode due to ongoing spam/DoS issues. Also, new account creation is currently disabled. We are looking into alternative wiki hosts.

SCons and C#

It would be great to roll this into a generic CLI builder that can take sources from any supported CLI language and compile them to EXE or DLL.

Russel Winder has started a Mercurial repository of a SCons C# tool based on the code from this page. See https://bitbucket.org/russel/scons_csharp

Mono

Here is a simple mcs builder. It takes one or more C# files and creates and EXE or a DLL from them. The user variables that effect the build are:

Example Usage

   1 env.Tool('mcs', toolpath = [''])
   2 env.CLILibrary('Foo.dll', 'Foo.dll')
   3 env.CLIProgram('Bar.exe', 'Bar.exe')

Builder

   1 import os.path
   2 import SCons.Builder
   3 import SCons.Node.FS
   4 import SCons.Util
   5 
   6 csccom = "$CSC $CSCFLAGS -out:${TARGET.abspath} $SOURCES"
   7 csclibcom = "$CSC -t:library $CSCLIBFLAGS $_CSCLIBPATH $_CSCLIBS -out:${TARGET.abspath} $SOURCES"
   8 
   9 
  10 McsBuilder = SCons.Builder.Builder(action = '$CSCCOM',
  11                                    source_factory = SCons.Node.FS.default_fs.Entry,
  12                                    suffix = '.exe')
  13 
  14 McsLibBuilder = SCons.Builder.Builder(action = '$CSCLIBCOM',
  15                                    source_factory = SCons.Node.FS.default_fs.Entry,
  16                                    suffix = '.dll')
  17 
  18 def generate(env):
  19     env['BUILDERS']['CLIProgram'] = McsBuilder
  20     env['BUILDERS']['CLILibrary'] = McsLibBuilder
  21 
  22     env['CSC']        = 'mcs'
  23     env['_CSCLIBS']    = "${_stripixes('-r:', CILLIBS, '', '-r', '', __env__)}"
  24     env['_CSCLIBPATH'] = "${_stripixes('-lib:', CILLIBPATH, '', '-r', '', __env__)}"
  25     env['CSCFLAGS']   = SCons.Util.CLVar('')
  26     env['CSCCOM']     = SCons.Action.Action(csccom)
  27     env['CSCLIBCOM']  = SCons.Action.Action(csclibcom)
  28 
  29 def exists(env):
  30     return internal_zip or env.Detect('mcs')

Microsoft C# compiler

Example Usage (Library)

   1 refpaths = []
   2 
   3 refs = Split("""
   4   System
   5   System.Data
   6   System.Xml
   7   """)
   8 
   9 sources = Split("""
  10   DataHelper.cs
  11   Keyfile.snk
  12         """)
  13 
  14 r = env.CLIRefs(refpaths, refs)
  15 
  16 prog = env.CLILibrary('MyAssembly.Common', sources, ASSEMBLYREFS=r)
  17 # use the following call to allow programs built after this library to find it
  18 # without having to add to the refpaths (see next example)
  19 env.AddToRefPaths(prog)

Example Usage (Program)

   1 refpaths = Split("""
   2   #/thirdparty/EncryptionLib
   3   """)
   4 
   5 # note we don't have to add MyAssembly.Common's location to refpaths
   6 # it will be stored with the call to AddToRefPaths() in the above example
   7 refs = Split("""
   8   MyAssembly.Common
   9   System
  10   System.Data
  11   """)
  12 
  13 sources = Split("""
  14   Main.cs
  15   gui/App.cs
  16   gui/MyForm.cs
  17   Keyfile.snk
  18   """)
  19 
  20 resx = Split("""
  21   gui/App.resx
  22   gui/MyForm.AddServerModelForm.resx
  23   """)
  24 sources.append([env.CLIRES(r, NAMESPACE='MyCompany') for r in resx])
  25 
  26 r = env.CLIRefs(refpaths, refs)
  27 prog = env.CLIProgram('myapp', sources, ASSEMBLYREFS=r, WINEXE=1)

A Small, Complete Example

   1 import os
   2 
   3 env_vars = {}
   4 for ev in ['PATH', 'LIB', 'SYSTEMROOT', 'PYTHONPATH']:
   5   env_vars[ev] = os.environ[ev]
   6 
   7 env = Environment(
   8   platform='win32',
   9   tools=['mscs', 'msvs'],
  10   toolpath = ['.'],
  11   ENV=env_vars,
  12   MSVS_IGNORE_IDE_PATHS=1
  13   )
  14 
  15 mod = env.CLIModule('mymod', 'MyMod.cs')
  16 
  17 refs = ['System', 'System.Reflection', 'System.Runtime.CompilerServices', 'System.Runtime.InteropServices']
  18 pathrefs = env.CLIRefs(refs)
  19 
  20 mod2 = env.CLIModule('common', 'AsmInfo.cs', ASSEMBLYREFS=pathrefs) #, NETMODULES=mod)
  21 
  22 # Note that CLILink actually uses the VS 2005 C++ linker, since it can handle linking .netmodules
  23 asm = env.CLILink('Common', [mod, mod2])
  24 env.AddToRefPaths(asm)
  25 
  26 # WINEXE=1 needed if this is a windows app, rather than a console app
  27 prog = env.CLIProgram('MyApp', 'MyApp.cs', ASSEMBLYREFS=asm, VERSION="1.0.1.0")
  28 
  29 # Resolve location of Common assembly, this was registered with AddToRefPaths, above.
  30 # added_paths included simply to show how to add assembly paths to the lookup besides
  31 # the ones in the PATH environment variable.  Leave this argument out if there are none.
  32 added_paths = ['#/path']
  33 rr = env.CLIRefs(['Common'], added_paths)
  34 
  35 # VERSION can also be passed by tuple, rather than string.
  36 # "asm" variable could have been passed directly into ASSEMBLYREFS if we wanted.
  37 asm2 = env.CLILibrary('MyAsm', 'MyClass.cs', ASSEMBLYREFS=rr, VERSION=(1,0,1,0))
  38 
  39 # Create a publisher policy to redirect anything with major minor 
  40 # version of assembly to the MyAsm assembly above.
  41 policy = env.PublisherPolicy(asm2)

Builder

   1 import os.path
   2 import SCons.Builder
   3 import SCons.Node.FS
   4 import SCons.Util
   5 from SCons.Node.Python import Value
   6 
   7 # needed for adding methods to environment
   8 from SCons.Script.SConscript import SConsEnvironment
   9 
  10 # parses env['VERSION'] for major, minor, build, and revision
  11 def parseVersion(env):
  12   if type(env['VERSION']) is tuple or type(env['VERSION']) is list:
  13     major, minor, build, revision = env['VERSION']
  14   elif type(env['VERSION']) is str:
  15     major, minor, build, revision = env['VERSION'].split('.')
  16     major = int(major)
  17     minor = int(minor)
  18     build = int(build)
  19     revision = int(revision)
  20   return (major, minor, build, revision)
  21 
  22 def getVersionAsmDirective(major, minor, build, revision):
  23   return '[assembly: AssemblyVersion("%d.%d.%d.%d")]' % (major, minor, build, revision)
  24 
  25 def generateVersionId(env, target, source):
  26   out = open(target[0].path, 'w')
  27   out.write('using System;using System.Reflection;using System.Runtime.CompilerServices;using System.Runtime.InteropServices;\n')
  28   out.write(source[0].get_contents())
  29   out.close()
  30 
  31 # used so that we can capture the return value of an executed command
  32 def subprocess(cmdline):
  33   import subprocess
  34   startupinfo = subprocess.STARTUPINFO()
  35   startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
  36   proc = subprocess.Popen(cmdline, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
  37     stderr=subprocess.PIPE, startupinfo=startupinfo, shell=False)
  38   data, err = proc.communicate()
  39   return proc.wait(), data, err
  40 
  41 # this method assumes that source list corresponds to [0]=version, [1]=assembly base name, [2]=assembly file node
  42 def generatePublisherPolicyConfig(env, target, source):
  43   # call strong name tool against compiled assembly and parse output for public token
  44   outputFolder = os.path.split(target[0].tpath)[0]
  45   pubpolicy = os.path.join(outputFolder, source[2].name)
  46   rv, data, err = subprocess('sn -T ' + pubpolicy)
  47   import re
  48   tok_re = re.compile(r"([a-z0-9]{16})[\r\n ]{0,3}$")
  49   match = tok_re.search(data)
  50   tok = match.group(1)
  51     
  52   # calculate version range to redirect from
  53   version = source[0].value
  54   oldVersionStartRange = '%s.%s.0.0' % (version[0], version[1])
  55   newVersion = '%s.%s.%s.%s' % (version[0], version[1], version[2], version[3])    
  56   build = int(version[2])
  57   rev = int(version[3])
  58 
  59   # on build 0 and rev 0 or 1, no range is needed. otherwise calculate range    
  60   if build == 0 and (rev == 0 or rev == 1):
  61     oldVersionRange = oldVersionStartRange
  62   else:
  63     if rev - 1 < 0:
  64       endRevisionRange = '99'
  65       endBuildRange = str(build-1)
  66     else:
  67       endRevisionRange = str(rev - 1)
  68       endBuildRange = str(build)  
  69     oldVersionEndRange = '%s.%s.%s.%s' % (version[0], version[1], endBuildRange, endRevisionRange)
  70     oldVersionRange = '%s-%s' % (oldVersionStartRange, oldVersionEndRange)
  71   
  72   # write .net config xml out to file
  73   out = open(target[0].path, 'w')
  74   out.write('''\
  75 <configuration><runtime><assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
  76   <dependentAssembly>
  77     <assemblyIdentity name="%s" publicKeyToken="%s"/>
  78     <bindingRedirect oldVersion="%s" newVersion="%s"/>
  79   </dependentAssembly>
  80 </assemblyBinding></runtime></configuration>
  81 ''' % (source[1].value, tok, oldVersionRange, newVersion))
  82   out.close()
  83 
  84 # search for key file
  85 def getKeyFile(node, sources):
  86   for file in node.children():
  87     if file.name.endswith('.snk'):
  88       sources.append(file)
  89       return
  90   
  91   # if not found look in included netmodules (first found is used)
  92   for file in node.children():
  93     if file.name.endswith('.netmodule'):
  94       for file2 in file.children():
  95         if file2.name.endswith('.snk'):
  96           sources.append(file2)
  97           return
  98 
  99 # creates the publisher policy dll, mapping the major.minor.0.0 calls to the 
 100 # major, minor, build, and revision passed in through the dictionary VERSION key
 101 def PublisherPolicy(env, target, **kw):
 102   sources = []
 103   # get version and generate .config file
 104   version = parseVersion(kw)
 105   asm = os.path.splitext(target[0].name)[0]
 106   configName = 'policy.%d.%d.%s.%s' % (version[0], version[1], asm, 'config')
 107   targ = 'policy.%d.%d.%s' % (version[0], version[1], target[0].name)
 108   config = env.Command(configName, [Value(version), Value(asm), target[0]], generatePublisherPolicyConfig)
 109   sources.append(config[0])
 110   
 111   # find .snk key
 112   getKeyFile(target[0], sources)
 113 
 114   return env.CLIAsmLink(targ, sources, **kw)
 115 
 116 def CLIRefs(env, refs, paths = [], **kw):
 117   listRefs = []
 118   normpaths = [env.Dir(p).abspath for p in paths]
 119   normpaths += env['CLIREFPATHS']
 120   
 121   for ref in refs:
 122     if not ref.endswith(env['SHLIBSUFFIX']):
 123       ref += env['SHLIBSUFFIX']
 124     if not ref.startswith(env['SHLIBPREFIX']):
 125       ref = env['SHLIBPREFIX'] + ref
 126     pathref = detectRef(ref, normpaths, env)
 127     if pathref:
 128       listRefs.append(pathref)
 129   
 130   return listRefs
 131 
 132 def CLIMods(env, refs, paths = [], **kw):
 133   listMods = []
 134   normpaths = [env.Dir(p).abspath for p in paths]
 135   normpaths += env['CLIMODPATHS']
 136 
 137   for ref in refs:
 138     if not ref.endswith(env['CLIMODSUFFIX']):
 139       ref += env['CLIMODSUFFIX']
 140     pathref = detectRef(ref, normpaths, env)
 141     if pathref:
 142       listMods.append(pathref)
 143   
 144   return listMods
 145 
 146 # look for existance of file (ref) at one of the paths
 147 def detectRef(ref, paths, env):  
 148   for path in paths:
 149     if path.endswith(ref):
 150       return path
 151     pathref = os.path.join(path, ref)
 152     if os.path.isfile(pathref):
 153       return pathref
 154 
 155   return ''
 156 
 157 # the file name is included in path reference because otherwise checks for that output file
 158 # by CLIRefs/CLIMods would fail until after it has been built.  Since SCons makes a pass
 159 # before building anything, that file won't be there.  Only after the second pass will it be built
 160 def AddToRefPaths(env, files, **kw):
 161   ref = env.FindIxes(files, 'SHLIBPREFIX', 'SHLIBSUFFIX').abspath
 162   env['CLIREFPATHS'] = [ref] + env['CLIREFPATHS']
 163   return 0
 164 
 165 def AddToModPaths(env, files, **kw):
 166   mod = env.FindIxes(files, 'CLIMODPREFIX', 'CLIMODSUFFIX').abspath
 167   env['CLIMODPATHS'] = [mod] + env['CLIMODPATHS']
 168   return 0
 169 
 170 def cscFlags(target, source, env, for_signature):
 171   listCmd = []
 172   if 'WINEXE' in env:
 173     if env['WINEXE'] == 1:
 174       listCmd.append('-t:winexe')
 175   return listCmd
 176 
 177 def cscSources(target, source, env, for_signature):
 178   listCmd = []
 179   
 180   for s in source:
 181     if str(s).endswith('.cs'):  # do this first since most will be source files
 182       listCmd.append(s)
 183     elif str(s).endswith('.resources'):
 184       listCmd.append('-resource:%s' % s.get_string(for_signature))
 185     elif str(s).endswith('.snk'):
 186       listCmd.append('-keyfile:%s' % s.get_string(for_signature))
 187     else:
 188       # just treat this as a generic unidentified source file
 189       listCmd.append(s)
 190 
 191   return listCmd
 192 
 193 def cscRefs(target, source, env, for_signature):
 194   listCmd = []
 195   
 196   if 'ASSEMBLYREFS' in env:
 197     refs = SCons.Util.flatten(env['ASSEMBLYREFS'])
 198     for ref in refs:          
 199       if SCons.Util.is_String(ref):
 200         listCmd.append('-reference:%s' % ref)
 201       else:
 202         listCmd.append('-reference:%s' % ref.abspath)
 203         
 204   return listCmd
 205 
 206 def cscMods(target, source, env, for_signature):
 207   listCmd = []
 208   
 209   if 'NETMODULES' in env:
 210     mods = SCons.Util.flatten(env['NETMODULES'])
 211     for mod in mods:
 212       listCmd.append('-addmodule:%s' % mod)
 213       
 214   return listCmd     
 215 
 216 # TODO: this currently does not allow sources to be embedded (-embed flag)
 217 def alLinkSources(target, source, env, for_signature):
 218   listCmd = []
 219   
 220   for s in source:
 221     if str(s).endswith('.snk'):
 222       listCmd.append('-keyfile:%s' % s.get_string(for_signature))
 223     else:
 224       # just treat this as a generic unidentified source file
 225       listCmd.append('-link:%s' % s.get_string(for_signature))
 226 
 227   if 'VERSION' in env:
 228     version = parseVersion(env)
 229     listCmd.append('-version:%d.%d.%d.%d' % version)
 230     
 231   return listCmd
 232 
 233 def add_version(target, source, env):
 234   if 'VERSION' in env:
 235     if SCons.Util.is_String(target[0]):
 236       versionfile = target[0] + '_VersionInfo.cs'
 237     else:
 238       versionfile = target[0].name + '_VersionInfo.cs'
 239     source.append(env.Command(versionfile, [Value(getVersionAsmDirective(*parseVersion(env)))], generateVersionId))
 240   return (target, source)
 241 
 242 MsCliBuilder = SCons.Builder.Builder(action = '$CSCCOM',
 243                                    source_factory = SCons.Node.FS.default_fs.Entry,
 244                                    emitter = add_version,
 245                                    suffix = '.exe')
 246 
 247 # this check is needed because .NET assemblies like to have '.' in the name.
 248 # scons interprets that as an extension and doesn't append the suffix as a result
 249 def lib_emitter(target, source, env):
 250   newtargets = []
 251   for tnode in target:
 252     t = tnode.name
 253     if not t.endswith(env['SHLIBSUFFIX']):
 254       t += env['SHLIBSUFFIX']
 255     newtargets.append(t)
 256     
 257   return (newtargets, source)
 258 
 259 def add_depends(target, source, env):
 260   """Add dependency information before the build order is established"""
 261     
 262   if 'NETMODULES' in env:
 263     mods = SCons.Util.flatten(env['NETMODULES'])
 264     for mod in mods:
 265       # add as dependency if it is something we build
 266       dir = env.File(mod).dir.srcdir
 267       if dir is not None and dir is not type(None):
 268         for t in target:
 269           env.Depends(t, mod)
 270 
 271   if 'ASSEMBLYREFS' in env:
 272     refs = SCons.Util.flatten(env['ASSEMBLYREFS'])
 273     for ref in refs:            
 274       # add as dependency if it is something we build
 275       dir = env.File(ref).dir.srcdir
 276       if dir is not None and dir is not type(None):
 277         for t in target:
 278           env.Depends(t, ref)
 279 
 280   return (target, source)
 281 
 282 MsCliLibBuilder = SCons.Builder.Builder(action = '$CSCLIBCOM',
 283                                    source_factory = SCons.Node.FS.default_fs.Entry,
 284                                    emitter = [lib_emitter, add_version, add_depends],
 285                                    suffix = '$SHLIBSUFFIX')
 286 
 287 MsCliModBuilder = SCons.Builder.Builder(action = '$CSCMODCOM',
 288                                    source_factory = SCons.Node.FS.default_fs.Entry,
 289                                    emitter = [add_version, add_depends],
 290                                    suffix = '$CLIMODSUFFIX')
 291 
 292 def module_deps(target, source, env):
 293   for s in source:
 294     dir = s.dir.srcdir
 295     if dir is not None and dir is not type(None):
 296       for t in target:
 297         env.Depends(t,s)
 298   return (target, source)
 299 
 300 MsCliLinkBuilder = SCons.Builder.Builder(action = '$CLILINKCOM',
 301                                    source_factory = SCons.Node.FS.default_fs.Entry,
 302                                    emitter = [lib_emitter, add_version, module_deps], # don't know the best way yet to get module dependencies added
 303                                    suffix = '.dll') #'$SHLIBSUFFIX')
 304 
 305 # This probably needs some more work... it hasn't been used since 
 306 # finding the abilities of the VS 2005 C++ linker for .NET.
 307 MsCliAsmLinkBuilder = SCons.Builder.Builder(action = '$CLIASMLINKCOM',
 308                                    source_factory = SCons.Node.FS.default_fs.Entry,
 309                                    suffix = '.dll')
 310 
 311 typelib_prefix = 'Interop.'
 312 
 313 def typelib_emitter(target, source, env):
 314   newtargets = []
 315   for tnode in target:
 316     t = tnode.name
 317     if not t.startswith(typelib_prefix):
 318       t = typelib_prefix + t
 319     newtargets.append(t)
 320     
 321   return (newtargets, source)
 322 
 323 def tlbimpFlags(target, source, env, for_signature):
 324   listCmd = []
 325   
 326   basename = os.path.splitext(target[0].name)[0]  
 327   # strip off typelib_prefix (such as 'Interop.') so it isn't in the namespace
 328   if basename.startswith(typelib_prefix):
 329     basename = basename[len(typelib_prefix):]
 330   listCmd.append('-namespace:%s' % basename)
 331 
 332   listCmd.append('-out:%s' % target[0].tpath)
 333 
 334   for s in source:
 335     if str(s).endswith('.snk'):
 336       listCmd.append('-keyfile:%s' % s.get_string(for_signature))
 337 
 338   return listCmd     
 339 
 340 MsCliTypeLibBuilder = SCons.Builder.Builder(action = '$TYPELIBIMPCOM',
 341                                     source_factory = SCons.Node.FS.default_fs.Entry,
 342                                     emitter = [typelib_emitter, add_depends],
 343                                     suffix = '.dll')
 344 
 345 res_action = SCons.Action.Action('$CLIRCCOM', '$CLIRCCOMSTR')
 346 
 347 # prepend NAMESPACE if provided
 348 def res_emitter(target, source, env):
 349   if 'NAMESPACE' in env:
 350     newtargets = []
 351     for t in target:
 352       tname = t.name
 353       
 354       # this is a cheesy way to get rid of '.aspx' in .resx file names
 355       idx = tname.find('.aspx.')
 356       if idx >= 0:
 357         tname = tname[:idx] + tname[idx+5:]
 358 
 359       newtargets.append('%s.%s' % (env['NAMESPACE'], tname))
 360     return (newtargets, source)
 361   else:
 362     return (targets, source)
 363 
 364 res_builder = SCons.Builder.Builder(action=res_action,
 365                                    emitter=res_emitter,
 366                                    src_suffix='.resx',
 367                                    suffix='.resources',
 368                                    src_builder=[],
 369                                    source_scanner=SCons.Tool.SourceFileScanner)
 370 
 371 SCons.Tool.SourceFileScanner.add_scanner('.resx', SCons.Defaults.CScan)
 372 
 373 def generate(env):
 374   envpaths = env['ENV']['PATH']
 375   env['CLIREFPATHS']  = envpaths.split(os.pathsep)
 376   env['CLIMODPATHS']  = []
 377   env['ASSEMBLYREFS'] = []
 378   env['NETMODULES']   = []
 379 
 380   env['BUILDERS']['CLIProgram'] = MsCliBuilder
 381   env['BUILDERS']['CLIAssembly'] = MsCliLibBuilder
 382   env['BUILDERS']['CLILibrary'] = MsCliLibBuilder
 383   env['BUILDERS']['CLIModule']  = MsCliModBuilder
 384   env['BUILDERS']['CLILink']    = MsCliLinkBuilder
 385   env['BUILDERS']['CLIAsmLink'] = MsCliAsmLinkBuilder
 386   env['BUILDERS']['CLITypeLib'] = MsCliTypeLibBuilder
 387   
 388   env['CSC']          = 'csc'
 389   env['_CSCLIBS']     = "${_stripixes('-r:', CILLIBS, '', '-r', '', __env__)}"
 390   env['_CSCLIBPATH']  = "${_stripixes('-lib:', CILLIBPATH, '', '-r', '', __env__)}"
 391   env['CSCFLAGS']     = SCons.Util.CLVar('-nologo -noconfig')
 392   env['_CSCFLAGS']    = cscFlags
 393   env['_CSC_SOURCES'] = cscSources
 394   env['_CSC_REFS']    = cscRefs
 395   env['_CSC_MODS']    = cscMods
 396   env['CSCCOM']       = SCons.Action.Action('$CSC $CSCFLAGS $_CSCFLAGS -out:${TARGET.abspath} $_CSC_REFS $_CSC_MODS $_CSC_SOURCES', '$CSCCOMSTR')
 397   env['CSCLIBCOM']    = SCons.Action.Action('$CSC -t:library $CSCFLAGS $_CSCFLAGS $_CSCLIBPATH $_CSCLIBS -out:${TARGET.abspath} $_CSC_REFS $_CSC_MODS $_CSC_SOURCES', '$CSCLIBCOMSTR')
 398   env['CSCMODCOM']    = SCons.Action.Action('$CSC -t:module $CSCFLAGS $_CSCFLAGS -out:${TARGET.abspath} $_CSC_REFS $_CSC_MODS $_CSC_SOURCES', '$CSCMODCOMSTR')
 399   env['CLIMODPREFIX'] = ''
 400   env['CLIMODSUFFIX'] = '.netmodule'
 401   env['CSSUFFIX']     = '.cs'
 402 
 403   # this lets us link .netmodules together into a single assembly
 404   env['CLILINK']      = 'link'
 405   env['CLILINKFLAGS'] = SCons.Util.CLVar('-nologo -ltcg -dll -noentry')
 406   env['CLILINKCOM']   = SCons.Action.Action('$CLILINK $CLILINKFLAGS -out:${TARGET.abspath} $SOURCES', '$CLILINKCOMSTR')
 407 
 408   env['CLIASMLINK']   = 'al'
 409   env['CLIASMLINKFLAGS'] = SCons.Util.CLVar('')
 410   env['_ASMLINK_SOURCES'] = alLinkSources
 411   env['CLIASMLINKCOM'] = SCons.Action.Action('$CLIASMLINK $CLIASMLINKFLAGS -out:${TARGET.abspath} $_ASMLINK_SOURCES', '$CLIASMLINKCOMSTR')
 412 
 413   env['CLIRC']        = 'resgen'
 414   env['CLIRCFLAGS']   = ''
 415   env['CLIRCCOM']     = '$CLIRC $CLIRCFLAGS $SOURCES $TARGETS'
 416   env['BUILDERS']['CLIRES'] = res_builder
 417 
 418   env['TYPELIBIMP']       = 'tlbimp'
 419   env['TYPELIBIMPFLAGS'] = SCons.Util.CLVar('-sysarray')
 420   env['_TYPELIBIMPFLAGS'] = tlbimpFlags
 421   env['TYPELIBIMPCOM']    = SCons.Action.Action('$TYPELIBIMP $SOURCES $TYPELIBIMPFLAGS $_TYPELIBIMPFLAGS', '$TYPELIBIMPCOMSTR')
 422 
 423   SConsEnvironment.CLIRefs = CLIRefs
 424   SConsEnvironment.CLIMods = CLIMods
 425   SConsEnvironment.AddToRefPaths = AddToRefPaths
 426   SConsEnvironment.AddToModPaths = AddToModPaths
 427   SConsEnvironment.PublisherPolicy = PublisherPolicy
 428   
 429 def exists(env):
 430   return env.Detect('csc')

CsharpBuilder (last edited 2012-09-05 18:18:25 by RusselWinder)