Please note:The SCons wiki is now restored from the attack in March 2013. All old passwords have been invalidated. Please reset your password if you have an account. If you note missing pages, please report them to webmaster@scons.org. Also, new account creation is currently disabled due to an ongoing spam flood (2013/08/27).
Differences between revisions 16 and 17
Revision 16 as of 2010-02-28 09:22:14
Size: 21188
Editor: RusselWinder
Comment:
Revision 17 as of 2012-09-05 18:18:25
Size: 21183
Editor: RusselWinder
Comment:
Deletions are marked like this. Additions are marked like this.
Line 6: Line 6:
Russel Winder has started a Bazaar branch of a SCons C# tool based on the code from this page. See [[https://code.launchpad.net/~russel/sconsaddons/csharp]] 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]]

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:

  • CSC: the name of the compiler (in this case mcs)
  • CSCFLAGS: extra compiler flags
  • CILLIBS: libraries to link against
  • CILLIBPATH: library paths

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)