diff options
author | Luca Falavigna <dktrkranz@debian.org> | 2010-01-02 20:56:35 +0100 |
---|---|---|
committer | Luca Falavigna <dktrkranz@debian.org> | 2010-01-02 20:56:35 +0100 |
commit | 64c458487151933ee0ba093cf4ac69e177d9be37 (patch) | |
tree | f6e3755704f53406eea85532e4ffe5d5ef50b7f0 /src/engine/SCons/Tool | |
parent | 2aec9cc58398cac1376509a7d75edb83b41f984e (diff) | |
parent | 72c578fd4b0b4a5a43e18594339ac4ff26c376dc (diff) |
Merge commit 'upstream/1.2.0.d20091224'
Diffstat (limited to 'src/engine/SCons/Tool')
209 files changed, 25755 insertions, 0 deletions
diff --git a/src/engine/SCons/Tool/386asm.py b/src/engine/SCons/Tool/386asm.py new file mode 100644 index 0000000..7b026e4 --- /dev/null +++ b/src/engine/SCons/Tool/386asm.py @@ -0,0 +1,61 @@ +"""SCons.Tool.386asm + +Tool specification for the 386ASM assembler for the Phar Lap ETS embedded +operating system. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/386asm.py 4577 2009/12/27 19:44:43 scons" + +from SCons.Tool.PharLapCommon import addPharLapPaths +import SCons.Util + +as_module = __import__('as', globals(), locals(), []) + +def generate(env): + """Add Builders and construction variables for ar to an Environment.""" + as_module.generate(env) + + env['AS'] = '386asm' + env['ASFLAGS'] = SCons.Util.CLVar('') + env['ASPPFLAGS'] = '$ASFLAGS' + env['ASCOM'] = '$AS $ASFLAGS $SOURCES -o $TARGET' + env['ASPPCOM'] = '$CC $ASPPFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS $SOURCES -o $TARGET' + + addPharLapPaths(env) + +def exists(env): + return env.Detect('386asm') + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/386asm.xml b/src/engine/SCons/Tool/386asm.xml new file mode 100644 index 0000000..ed48820 --- /dev/null +++ b/src/engine/SCons/Tool/386asm.xml @@ -0,0 +1,25 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="386asm"> +<summary> +Sets construction variables for the 386ASM assembler +for the Phar Lap ETS embedded operating system. +</summary> +<sets> +AS +ASFLAGS +ASPPFLAGS +ASCOM +ASPPCOM +</sets> +<uses> +CC +CPPFLAGS +_CPPDEFFLAGS +_CPPINCFLAGS +</uses> +</tool> diff --git a/src/engine/SCons/Tool/BitKeeper.py b/src/engine/SCons/Tool/BitKeeper.py new file mode 100644 index 0000000..6830ca9 --- /dev/null +++ b/src/engine/SCons/Tool/BitKeeper.py @@ -0,0 +1,65 @@ +"""SCons.Tool.BitKeeper.py + +Tool-specific initialization for the BitKeeper source code control +system. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/BitKeeper.py 4577 2009/12/27 19:44:43 scons" + +import SCons.Action +import SCons.Builder +import SCons.Util + +def generate(env): + """Add a Builder factory function and construction variables for + BitKeeper to an Environment.""" + + def BitKeeperFactory(env=env): + """ """ + act = SCons.Action.Action("$BITKEEPERCOM", "$BITKEEPERCOMSTR") + return SCons.Builder.Builder(action = act, env = env) + + #setattr(env, 'BitKeeper', BitKeeperFactory) + env.BitKeeper = BitKeeperFactory + + env['BITKEEPER'] = 'bk' + env['BITKEEPERGET'] = '$BITKEEPER get' + env['BITKEEPERGETFLAGS'] = SCons.Util.CLVar('') + env['BITKEEPERCOM'] = '$BITKEEPERGET $BITKEEPERGETFLAGS $TARGET' + +def exists(env): + return env.Detect('bk') + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/BitKeeper.xml b/src/engine/SCons/Tool/BitKeeper.xml new file mode 100644 index 0000000..4eb7a32 --- /dev/null +++ b/src/engine/SCons/Tool/BitKeeper.xml @@ -0,0 +1,58 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="BitKeeper"> +<summary> +Sets construction variables for the BitKeeper +source code control system. +</summary> +<sets> +BITKEEPER +BITKEEPERGET +BITKEEPERGETFLAGS +BITKEEPERCOM +</sets> +<uses> +BITKEEPERCOMSTR +</uses> +</tool> + +<cvar name="BITKEEPER"> +<summary> +The BitKeeper executable. +</summary> +</cvar> + +<cvar name="BITKEEPERCOM"> +<summary> +The command line for +fetching source files using BitKeeper. +</summary> +</cvar> + +<cvar name="BITKEEPERCOMSTR"> +<summary> +The string displayed when fetching +a source file using BitKeeper. +If this is not set, then &cv-link-BITKEEPERCOM; +(the command line) is displayed. +</summary> +</cvar> + +<cvar name="BITKEEPERGET"> +<summary> +The command (&cv-link-BITKEEPER;) and subcommand +for fetching source files using BitKeeper. +</summary> +</cvar> + +<cvar name="BITKEEPERGETFLAGS"> +<summary> +Options that are passed to the BitKeeper +<command>get</command> +subcommand. +</summary> +</cvar> diff --git a/src/engine/SCons/Tool/CVS.py b/src/engine/SCons/Tool/CVS.py new file mode 100644 index 0000000..f2334c8 --- /dev/null +++ b/src/engine/SCons/Tool/CVS.py @@ -0,0 +1,73 @@ +"""SCons.Tool.CVS.py + +Tool-specific initialization for CVS. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/CVS.py 4577 2009/12/27 19:44:43 scons" + +import SCons.Action +import SCons.Builder +import SCons.Util + +def generate(env): + """Add a Builder factory function and construction variables for + CVS to an Environment.""" + + def CVSFactory(repos, module='', env=env): + """ """ + # fail if repos is not an absolute path name? + if module != '': + # Don't use os.path.join() because the name we fetch might + # be across a network and must use POSIX slashes as separators. + module = module + '/' + env['CVSCOM'] = '$CVS $CVSFLAGS co $CVSCOFLAGS -d ${TARGET.dir} $CVSMODULE${TARGET.posix}' + act = SCons.Action.Action('$CVSCOM', '$CVSCOMSTR') + return SCons.Builder.Builder(action = act, + env = env, + CVSREPOSITORY = repos, + CVSMODULE = module) + + #setattr(env, 'CVS', CVSFactory) + env.CVS = CVSFactory + + env['CVS'] = 'cvs' + env['CVSFLAGS'] = SCons.Util.CLVar('-d $CVSREPOSITORY') + env['CVSCOFLAGS'] = SCons.Util.CLVar('') + env['CVSCOM'] = '$CVS $CVSFLAGS co $CVSCOFLAGS ${TARGET.posix}' + +def exists(env): + return env.Detect('cvs') + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/CVS.xml b/src/engine/SCons/Tool/CVS.xml new file mode 100644 index 0000000..fdb5360 --- /dev/null +++ b/src/engine/SCons/Tool/CVS.xml @@ -0,0 +1,66 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="CVS"> +<summary> +Sets construction variables for the CVS source code +management system. +</summary> +<sets> +CVS +CVSCOM +CVSFLAGS +CVSCOFLAGS +</sets> +<uses> +CVSCOMSTR +</uses> +</tool> + +<cvar name="CVS"> +<summary> +The CVS executable. +</summary> +</cvar> + +<cvar name="CVSCOFLAGS"> +<summary> +Options that are passed to the CVS checkout subcommand. +</summary> +</cvar> + +<cvar name="CVSCOM"> +<summary> +The command line used to +fetch source files from a CVS repository. +</summary> +</cvar> + +<cvar name="CVSCOMSTR"> +<summary> +The string displayed when fetching +a source file from a CVS repository. +If this is not set, then &cv-link-CVSCOM; +(the command line) is displayed. +</summary> +</cvar> + +<cvar name="CVSFLAGS"> +<summary> +General options that are passed to CVS. +By default, this is set to +<literal>-d $CVSREPOSITORY</literal> +to specify from where the files must be fetched. +</summary> +</cvar> + +<cvar name="CVSREPOSITORY"> +<summary> +The path to the CVS repository. +This is referenced in the default +&cv-link-CVSFLAGS; value. +</summary> +</cvar> diff --git a/src/engine/SCons/Tool/FortranCommon.py b/src/engine/SCons/Tool/FortranCommon.py new file mode 100644 index 0000000..784b3fa --- /dev/null +++ b/src/engine/SCons/Tool/FortranCommon.py @@ -0,0 +1,247 @@ +"""SCons.Tool.FortranCommon + +Stuff for processing Fortran, common to all fortran dialects. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/FortranCommon.py 4577 2009/12/27 19:44:43 scons" + +import re +import string +import os.path + +import SCons.Action +import SCons.Defaults +import SCons.Scanner.Fortran +import SCons.Tool +import SCons.Util + +def isfortran(env, source): + """Return 1 if any of code in source has fortran files in it, 0 + otherwise.""" + try: + fsuffixes = env['FORTRANSUFFIXES'] + except KeyError: + # If no FORTRANSUFFIXES, no fortran tool, so there is no need to look + # for fortran sources. + return 0 + + if not source: + # Source might be None for unusual cases like SConf. + return 0 + for s in source: + if s.sources: + ext = os.path.splitext(str(s.sources[0]))[1] + if ext in fsuffixes: + return 1 + return 0 + +def _fortranEmitter(target, source, env): + node = source[0].rfile() + if not node.exists() and not node.is_derived(): + print "Could not locate " + str(node.name) + return ([], []) + mod_regex = """(?i)^\s*MODULE\s+(?!PROCEDURE)(\w+)""" + cre = re.compile(mod_regex,re.M) + # Retrieve all USE'd module names + modules = cre.findall(node.get_text_contents()) + # Remove unique items from the list + modules = SCons.Util.unique(modules) + # Convert module name to a .mod filename + suffix = env.subst('$FORTRANMODSUFFIX', target=target, source=source) + moddir = env.subst('$FORTRANMODDIR', target=target, source=source) + modules = map(lambda x, s=suffix: string.lower(x) + s, modules) + for m in modules: + target.append(env.fs.File(m, moddir)) + return (target, source) + +def FortranEmitter(target, source, env): + target, source = _fortranEmitter(target, source, env) + return SCons.Defaults.StaticObjectEmitter(target, source, env) + +def ShFortranEmitter(target, source, env): + target, source = _fortranEmitter(target, source, env) + return SCons.Defaults.SharedObjectEmitter(target, source, env) + +def ComputeFortranSuffixes(suffixes, ppsuffixes): + """suffixes are fortran source files, and ppsuffixes the ones to be + pre-processed. Both should be sequences, not strings.""" + assert len(suffixes) > 0 + s = suffixes[0] + sup = string.upper(s) + upper_suffixes = map(string.upper, suffixes) + if SCons.Util.case_sensitive_suffixes(s, sup): + ppsuffixes.extend(upper_suffixes) + else: + suffixes.extend(upper_suffixes) + +def CreateDialectActions(dialect): + """Create dialect specific actions.""" + CompAction = SCons.Action.Action('$%sCOM ' % dialect, '$%sCOMSTR' % dialect) + CompPPAction = SCons.Action.Action('$%sPPCOM ' % dialect, '$%sPPCOMSTR' % dialect) + ShCompAction = SCons.Action.Action('$SH%sCOM ' % dialect, '$SH%sCOMSTR' % dialect) + ShCompPPAction = SCons.Action.Action('$SH%sPPCOM ' % dialect, '$SH%sPPCOMSTR' % dialect) + + return CompAction, CompPPAction, ShCompAction, ShCompPPAction + +def DialectAddToEnv(env, dialect, suffixes, ppsuffixes, support_module = 0): + """Add dialect specific construction variables.""" + ComputeFortranSuffixes(suffixes, ppsuffixes) + + fscan = SCons.Scanner.Fortran.FortranScan("%sPATH" % dialect) + + for suffix in suffixes + ppsuffixes: + SCons.Tool.SourceFileScanner.add_scanner(suffix, fscan) + + env.AppendUnique(FORTRANSUFFIXES = suffixes + ppsuffixes) + + compaction, compppaction, shcompaction, shcompppaction = \ + CreateDialectActions(dialect) + + static_obj, shared_obj = SCons.Tool.createObjBuilders(env) + + for suffix in suffixes: + static_obj.add_action(suffix, compaction) + shared_obj.add_action(suffix, shcompaction) + static_obj.add_emitter(suffix, FortranEmitter) + shared_obj.add_emitter(suffix, ShFortranEmitter) + + for suffix in ppsuffixes: + static_obj.add_action(suffix, compppaction) + shared_obj.add_action(suffix, shcompppaction) + static_obj.add_emitter(suffix, FortranEmitter) + shared_obj.add_emitter(suffix, ShFortranEmitter) + + if not env.has_key('%sFLAGS' % dialect): + env['%sFLAGS' % dialect] = SCons.Util.CLVar('') + + if not env.has_key('SH%sFLAGS' % dialect): + env['SH%sFLAGS' % dialect] = SCons.Util.CLVar('$%sFLAGS' % dialect) + + # If a tool does not define fortran prefix/suffix for include path, use C ones + if not env.has_key('INC%sPREFIX' % dialect): + env['INC%sPREFIX' % dialect] = '$INCPREFIX' + + if not env.has_key('INC%sSUFFIX' % dialect): + env['INC%sSUFFIX' % dialect] = '$INCSUFFIX' + + env['_%sINCFLAGS' % dialect] = '$( ${_concat(INC%sPREFIX, %sPATH, INC%sSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)' % (dialect, dialect, dialect) + + if support_module == 1: + env['%sCOM' % dialect] = '$%s -o $TARGET -c $%sFLAGS $_%sINCFLAGS $_FORTRANMODFLAG $SOURCES' % (dialect, dialect, dialect) + env['%sPPCOM' % dialect] = '$%s -o $TARGET -c $%sFLAGS $CPPFLAGS $_CPPDEFFLAGS $_%sINCFLAGS $_FORTRANMODFLAG $SOURCES' % (dialect, dialect, dialect) + env['SH%sCOM' % dialect] = '$SH%s -o $TARGET -c $SH%sFLAGS $_%sINCFLAGS $_FORTRANMODFLAG $SOURCES' % (dialect, dialect, dialect) + env['SH%sPPCOM' % dialect] = '$SH%s -o $TARGET -c $SH%sFLAGS $CPPFLAGS $_CPPDEFFLAGS $_%sINCFLAGS $_FORTRANMODFLAG $SOURCES' % (dialect, dialect, dialect) + else: + env['%sCOM' % dialect] = '$%s -o $TARGET -c $%sFLAGS $_%sINCFLAGS $SOURCES' % (dialect, dialect, dialect) + env['%sPPCOM' % dialect] = '$%s -o $TARGET -c $%sFLAGS $CPPFLAGS $_CPPDEFFLAGS $_%sINCFLAGS $SOURCES' % (dialect, dialect, dialect) + env['SH%sCOM' % dialect] = '$SH%s -o $TARGET -c $SH%sFLAGS $_%sINCFLAGS $SOURCES' % (dialect, dialect, dialect) + env['SH%sPPCOM' % dialect] = '$SH%s -o $TARGET -c $SH%sFLAGS $CPPFLAGS $_CPPDEFFLAGS $_%sINCFLAGS $SOURCES' % (dialect, dialect, dialect) + +def add_fortran_to_env(env): + """Add Builders and construction variables for Fortran to an Environment.""" + try: + FortranSuffixes = env['FORTRANFILESUFFIXES'] + except KeyError: + FortranSuffixes = ['.f', '.for', '.ftn'] + + #print "Adding %s to fortran suffixes" % FortranSuffixes + try: + FortranPPSuffixes = env['FORTRANPPFILESUFFIXES'] + except KeyError: + FortranPPSuffixes = ['.fpp', '.FPP'] + + DialectAddToEnv(env, "FORTRAN", FortranSuffixes, + FortranPPSuffixes, support_module = 1) + + env['FORTRANMODPREFIX'] = '' # like $LIBPREFIX + env['FORTRANMODSUFFIX'] = '.mod' # like $LIBSUFFIX + + env['FORTRANMODDIR'] = '' # where the compiler should place .mod files + env['FORTRANMODDIRPREFIX'] = '' # some prefix to $FORTRANMODDIR - similar to $INCPREFIX + env['FORTRANMODDIRSUFFIX'] = '' # some suffix to $FORTRANMODDIR - similar to $INCSUFFIX + env['_FORTRANMODFLAG'] = '$( ${_concat(FORTRANMODDIRPREFIX, FORTRANMODDIR, FORTRANMODDIRSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)' + +def add_f77_to_env(env): + """Add Builders and construction variables for f77 to an Environment.""" + try: + F77Suffixes = env['F77FILESUFFIXES'] + except KeyError: + F77Suffixes = ['.f77'] + + #print "Adding %s to f77 suffixes" % F77Suffixes + try: + F77PPSuffixes = env['F77PPFILESUFFIXES'] + except KeyError: + F77PPSuffixes = [] + + DialectAddToEnv(env, "F77", F77Suffixes, F77PPSuffixes) + +def add_f90_to_env(env): + """Add Builders and construction variables for f90 to an Environment.""" + try: + F90Suffixes = env['F90FILESUFFIXES'] + except KeyError: + F90Suffixes = ['.f90'] + + #print "Adding %s to f90 suffixes" % F90Suffixes + try: + F90PPSuffixes = env['F90PPFILESUFFIXES'] + except KeyError: + F90PPSuffixes = [] + + DialectAddToEnv(env, "F90", F90Suffixes, F90PPSuffixes, + support_module = 1) + +def add_f95_to_env(env): + """Add Builders and construction variables for f95 to an Environment.""" + try: + F95Suffixes = env['F95FILESUFFIXES'] + except KeyError: + F95Suffixes = ['.f95'] + + #print "Adding %s to f95 suffixes" % F95Suffixes + try: + F95PPSuffixes = env['F95PPFILESUFFIXES'] + except KeyError: + F95PPSuffixes = [] + + DialectAddToEnv(env, "F95", F95Suffixes, F95PPSuffixes, + support_module = 1) + +def add_all_to_env(env): + """Add builders and construction variables for all supported fortran + dialects.""" + add_fortran_to_env(env) + add_f77_to_env(env) + add_f90_to_env(env) + add_f95_to_env(env) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/JavaCommon.py b/src/engine/SCons/Tool/JavaCommon.py new file mode 100644 index 0000000..44a6091 --- /dev/null +++ b/src/engine/SCons/Tool/JavaCommon.py @@ -0,0 +1,324 @@ +"""SCons.Tool.JavaCommon + +Stuff for processing Java. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/JavaCommon.py 4577 2009/12/27 19:44:43 scons" + +import os +import os.path +import re +import string + +java_parsing = 1 + +default_java_version = '1.4' + +if java_parsing: + # Parse Java files for class names. + # + # This is a really cool parser from Charles Crain + # that finds appropriate class names in Java source. + + # A regular expression that will find, in a java file: + # newlines; + # double-backslashes; + # a single-line comment "//"; + # single or double quotes preceeded by a backslash; + # single quotes, double quotes, open or close braces, semi-colons, + # periods, open or close parentheses; + # floating-point numbers; + # any alphanumeric token (keyword, class name, specifier); + # any alphanumeric token surrounded by angle brackets (generics); + # the multi-line comment begin and end tokens /* and */; + # array declarations "[]". + _reToken = re.compile(r'(\n|\\\\|//|\\[\'"]|[\'"\{\}\;\.\(\)]|' + + r'\d*\.\d*|[A-Za-z_][\w\$\.]*|<[A-Za-z_]\w+>|' + + r'/\*|\*/|\[\])') + + class OuterState: + """The initial state for parsing a Java file for classes, + interfaces, and anonymous inner classes.""" + def __init__(self, version=default_java_version): + + if not version in ('1.1', '1.2', '1.3','1.4', '1.5', '1.6', + '5', '6'): + msg = "Java version %s not supported" % version + raise NotImplementedError, msg + + self.version = version + self.listClasses = [] + self.listOutputs = [] + self.stackBrackets = [] + self.brackets = 0 + self.nextAnon = 1 + self.localClasses = [] + self.stackAnonClassBrackets = [] + self.anonStacksStack = [[0]] + self.package = None + + def trace(self): + pass + + def __getClassState(self): + try: + return self.classState + except AttributeError: + ret = ClassState(self) + self.classState = ret + return ret + + def __getPackageState(self): + try: + return self.packageState + except AttributeError: + ret = PackageState(self) + self.packageState = ret + return ret + + def __getAnonClassState(self): + try: + return self.anonState + except AttributeError: + self.outer_state = self + ret = SkipState(1, AnonClassState(self)) + self.anonState = ret + return ret + + def __getSkipState(self): + try: + return self.skipState + except AttributeError: + ret = SkipState(1, self) + self.skipState = ret + return ret + + def __getAnonStack(self): + return self.anonStacksStack[-1] + + def openBracket(self): + self.brackets = self.brackets + 1 + + def closeBracket(self): + self.brackets = self.brackets - 1 + if len(self.stackBrackets) and \ + self.brackets == self.stackBrackets[-1]: + self.listOutputs.append(string.join(self.listClasses, '$')) + self.localClasses.pop() + self.listClasses.pop() + self.anonStacksStack.pop() + self.stackBrackets.pop() + if len(self.stackAnonClassBrackets) and \ + self.brackets == self.stackAnonClassBrackets[-1]: + self.__getAnonStack().pop() + self.stackAnonClassBrackets.pop() + + def parseToken(self, token): + if token[:2] == '//': + return IgnoreState('\n', self) + elif token == '/*': + return IgnoreState('*/', self) + elif token == '{': + self.openBracket() + elif token == '}': + self.closeBracket() + elif token in [ '"', "'" ]: + return IgnoreState(token, self) + elif token == "new": + # anonymous inner class + if len(self.listClasses) > 0: + return self.__getAnonClassState() + return self.__getSkipState() # Skip the class name + elif token in ['class', 'interface', 'enum']: + if len(self.listClasses) == 0: + self.nextAnon = 1 + self.stackBrackets.append(self.brackets) + return self.__getClassState() + elif token == 'package': + return self.__getPackageState() + elif token == '.': + # Skip the attribute, it might be named "class", in which + # case we don't want to treat the following token as + # an inner class name... + return self.__getSkipState() + return self + + def addAnonClass(self): + """Add an anonymous inner class""" + if self.version in ('1.1', '1.2', '1.3', '1.4'): + clazz = self.listClasses[0] + self.listOutputs.append('%s$%d' % (clazz, self.nextAnon)) + elif self.version in ('1.5', '1.6', '5', '6'): + self.stackAnonClassBrackets.append(self.brackets) + className = [] + className.extend(self.listClasses) + self.__getAnonStack()[-1] = self.__getAnonStack()[-1] + 1 + for anon in self.__getAnonStack(): + className.append(str(anon)) + self.listOutputs.append(string.join(className, '$')) + + self.nextAnon = self.nextAnon + 1 + self.__getAnonStack().append(0) + + def setPackage(self, package): + self.package = package + + class AnonClassState: + """A state that looks for anonymous inner classes.""" + def __init__(self, old_state): + # outer_state is always an instance of OuterState + self.outer_state = old_state.outer_state + self.old_state = old_state + self.brace_level = 0 + def parseToken(self, token): + # This is an anonymous class if and only if the next + # non-whitespace token is a bracket. Everything between + # braces should be parsed as normal java code. + if token[:2] == '//': + return IgnoreState('\n', self) + elif token == '/*': + return IgnoreState('*/', self) + elif token == '\n': + return self + elif token[0] == '<' and token[-1] == '>': + return self + elif token == '(': + self.brace_level = self.brace_level + 1 + return self + if self.brace_level > 0: + if token == 'new': + # look further for anonymous inner class + return SkipState(1, AnonClassState(self)) + elif token in [ '"', "'" ]: + return IgnoreState(token, self) + elif token == ')': + self.brace_level = self.brace_level - 1 + return self + if token == '{': + self.outer_state.addAnonClass() + return self.old_state.parseToken(token) + + class SkipState: + """A state that will skip a specified number of tokens before + reverting to the previous state.""" + def __init__(self, tokens_to_skip, old_state): + self.tokens_to_skip = tokens_to_skip + self.old_state = old_state + def parseToken(self, token): + self.tokens_to_skip = self.tokens_to_skip - 1 + if self.tokens_to_skip < 1: + return self.old_state + return self + + class ClassState: + """A state we go into when we hit a class or interface keyword.""" + def __init__(self, outer_state): + # outer_state is always an instance of OuterState + self.outer_state = outer_state + def parseToken(self, token): + # the next non-whitespace token should be the name of the class + if token == '\n': + return self + # If that's an inner class which is declared in a method, it + # requires an index prepended to the class-name, e.g. + # 'Foo$1Inner' (Tigris Issue 2087) + if self.outer_state.localClasses and \ + self.outer_state.stackBrackets[-1] > \ + self.outer_state.stackBrackets[-2]+1: + locals = self.outer_state.localClasses[-1] + try: + idx = locals[token] + locals[token] = locals[token]+1 + except KeyError: + locals[token] = 1 + token = str(locals[token]) + token + self.outer_state.localClasses.append({}) + self.outer_state.listClasses.append(token) + self.outer_state.anonStacksStack.append([0]) + return self.outer_state + + class IgnoreState: + """A state that will ignore all tokens until it gets to a + specified token.""" + def __init__(self, ignore_until, old_state): + self.ignore_until = ignore_until + self.old_state = old_state + def parseToken(self, token): + if self.ignore_until == token: + return self.old_state + return self + + class PackageState: + """The state we enter when we encounter the package keyword. + We assume the next token will be the package name.""" + def __init__(self, outer_state): + # outer_state is always an instance of OuterState + self.outer_state = outer_state + def parseToken(self, token): + self.outer_state.setPackage(token) + return self.outer_state + + def parse_java_file(fn, version=default_java_version): + return parse_java(open(fn, 'r').read(), version) + + def parse_java(contents, version=default_java_version, trace=None): + """Parse a .java file and return a double of package directory, + plus a list of .class files that compiling that .java file will + produce""" + package = None + initial = OuterState(version) + currstate = initial + for token in _reToken.findall(contents): + # The regex produces a bunch of groups, but only one will + # have anything in it. + currstate = currstate.parseToken(token) + if trace: trace(token, currstate) + if initial.package: + package = string.replace(initial.package, '.', os.sep) + return (package, initial.listOutputs) + +else: + # Don't actually parse Java files for class names. + # + # We might make this a configurable option in the future if + # Java-file parsing takes too long (although it shouldn't relative + # to how long the Java compiler itself seems to take...). + + def parse_java_file(fn): + """ "Parse" a .java file. + + This actually just splits the file name, so the assumption here + is that the file name matches the public class name, and that + the path to the file is the same as the package name. + """ + return os.path.split(file) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/JavaCommonTests.py b/src/engine/SCons/Tool/JavaCommonTests.py new file mode 100644 index 0000000..da44639 --- /dev/null +++ b/src/engine/SCons/Tool/JavaCommonTests.py @@ -0,0 +1,580 @@ +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/JavaCommonTests.py 4577 2009/12/27 19:44:43 scons" + +import os.path +import sys +import unittest + +import SCons.Tool.JavaCommon + + +# Adding trace=trace to any of the parse_jave() calls below will cause +# the parser to spit out trace messages of the tokens it sees and the +# attendant transitions. + +def trace(token, newstate): + from SCons.Debug import Trace + statename = newstate.__class__.__name__ + Trace('token = %s, state = %s\n' % (repr(token), statename)) + +class parse_javaTestCase(unittest.TestCase): + + def test_bare_bones(self): + """Test a bare-bones class""" + + input = """\ +package com.sub.bar; + +public class Foo +{ + + public static void main(String[] args) + { + + /* This tests a former bug where strings would eat later code. */ + String hello1 = new String("Hello, world!"); + + } + +} +""" + pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input) + assert pkg_dir == os.path.join('com', 'sub', 'bar'), pkg_dir + assert classes == ['Foo'], classes + + + + def test_dollar_sign(self): + """Test class names with $ in them""" + + input = """\ +public class BadDep { + public void new$rand () {} +} +""" + pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input) + assert pkg_dir is None, pkg_dir + assert classes == ['BadDep'], classes + + + + def test_inner_classes(self): + """Test parsing various forms of inner classes""" + + input = """\ +class Empty { +} + +interface Listener { + public void execute(); +} + +public +class +Test implements Listener { + class Inner { + void go() { + use(new Listener() { + public void execute() { + System.out.println("In Inner"); + } + }); + } + String s1 = "class A"; + String s2 = "new Listener() { }"; + /* class B */ + /* new Listener() { } */ + } + + class Inner2 { + Inner2() { Listener l = new Listener(); } + } + + /* Make sure this class doesn't get interpreted as an inner class of the previous one, when "new" is used in the previous class. */ + class Inner3 { + + } + + public static void main(String[] args) { + new Test().run(); + } + + void run() { + use(new Listener() { + public void execute() { + use(new Listener( ) { + public void execute() { + System.out.println("Inside execute()"); + } + }); + } + }); + + new Inner().go(); + } + + void use(Listener l) { + l.execute(); + } +} + +class Private { + void run() { + new Listener() { + public void execute() { + } + }; + } +} +""" + + pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '1.4') + assert pkg_dir is None, pkg_dir + expect = [ + 'Empty', + 'Listener', + 'Test$1', + 'Test$Inner', + 'Test$Inner2', + 'Test$Inner3', + 'Test$2', + 'Test$3', + 'Test', + 'Private$1', + 'Private', + ] + assert classes == expect, classes + + pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '1.5') + assert pkg_dir is None, pkg_dir + expect = [ + 'Empty', + 'Listener', + 'Test$Inner$1', + 'Test$Inner', + 'Test$Inner2', + 'Test$Inner3', + 'Test$1', + 'Test$1$1', + 'Test', + 'Private$1', + 'Private', + ] + assert classes == expect, (expect, classes) + + pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '5') + assert pkg_dir is None, pkg_dir + expect = [ + 'Empty', + 'Listener', + 'Test$Inner$1', + 'Test$Inner', + 'Test$Inner2', + 'Test$Inner3', + 'Test$1', + 'Test$1$1', + 'Test', + 'Private$1', + 'Private', + ] + assert classes == expect, (expect, classes) + + + + def test_comments(self): + """Test a class with comments""" + + input = """\ +package com.sub.foo; + +import java.rmi.Naming; +import java.rmi.RemoteException; +import java.rmi.RMISecurityManager; +import java.rmi.server.UnicastRemoteObject; + +public class Example1 extends UnicastRemoteObject implements Hello { + + public Example1() throws RemoteException { + super(); + } + + public String sayHello() { + return "Hello World!"; + } + + public static void main(String args[]) { + if (System.getSecurityManager() == null) { + System.setSecurityManager(new RMISecurityManager()); + } + // a comment + try { + Example1 obj = new Example1(); + + Naming.rebind("//myhost/HelloServer", obj); + + System.out.println("HelloServer bound in registry"); + } catch (Exception e) { + System.out.println("Example1 err: " + e.getMessage()); + e.printStackTrace(); + } + } +} +""" + + pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input) + assert pkg_dir == os.path.join('com', 'sub', 'foo'), pkg_dir + assert classes == ['Example1'], classes + + + def test_arrays(self): + """Test arrays of class instances""" + + input = """\ +public class Test { + MyClass abc = new MyClass(); + MyClass xyz = new MyClass(); + MyClass _array[] = new MyClass[] { + abc, + xyz + } +} +""" + + pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input) + assert pkg_dir is None, pkg_dir + assert classes == ['Test'], classes + + + + def test_backslash(self): + """Test backslash handling""" + + input = """\ +public class MyTabs +{ + private class MyInternal + { + } + private final static String PATH = "images\\\\"; +} +""" + + pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input) + assert pkg_dir is None, pkg_dir + assert classes == ['MyTabs$MyInternal', 'MyTabs'], classes + + + def test_enum(self): + """Test the Java 1.5 enum keyword""" + + input = """\ +package p; +public enum a {} +""" + + pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input) + assert pkg_dir == 'p', pkg_dir + assert classes == ['a'], classes + + + def test_anon_classes(self): + """Test anonymous classes""" + + input = """\ +public abstract class TestClass +{ + public void completed() + { + new Thread() + { + }.start(); + + new Thread() + { + }.start(); + } +} +""" + + pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input) + assert pkg_dir is None, pkg_dir + assert classes == ['TestClass$1', 'TestClass$2', 'TestClass'], classes + + + def test_closing_bracket(self): + """Test finding a closing bracket instead of an anonymous class""" + + input = """\ +class TestSCons { + public static void main(String[] args) { + Foo[] fooArray = new Foo[] { new Foo() }; + } +} + +class Foo { } +""" + + pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input) + assert pkg_dir is None, pkg_dir + assert classes == ['TestSCons', 'Foo'], classes + + + def test_dot_class_attributes(self): + """Test handling ".class" attributes""" + + input = """\ +public class Test extends Object +{ + static { + Class c = Object[].class; + Object[] s = new Object[] {}; + } +} +""" + + pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input) + assert classes == ['Test'], classes + + input = """\ +public class A { + public class B { + public void F(Object[] o) { + F(new Object[] {Object[].class}); + } + public void G(Object[] o) { + F(new Object[] {}); + } + } +} +""" + + pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input) + assert pkg_dir is None, pkg_dir + assert classes == ['A$B', 'A'], classes + + def test_anonymous_classes_with_parentheses(self): + """Test finding anonymous classes marked by parentheses""" + + input = """\ +import java.io.File; + +public class Foo { + public static void main(String[] args) { + File f = new File( + new File("a") { + public String toString() { + return "b"; + } + } to String() + ) { + public String toString() { + return "c"; + } + }; + } +} +""" + + pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '1.4') + assert classes == ['Foo$1', 'Foo$2', 'Foo'], classes + + pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '1.5') + assert classes == ['Foo$1', 'Foo$1$1', 'Foo'], classes + + pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '6') + assert classes == ['Foo$1', 'Foo$1$1', 'Foo'], classes + + + + def test_nested_anonymous_inner_classes(self): + """Test finding nested anonymous inner classes""" + + input = """\ +// import java.util.*; + +public class NestedExample +{ + public NestedExample() + { + Thread t = new Thread() { + public void start() + { + Thread t = new Thread() { + public void start() + { + try {Thread.sleep(200);} + catch (Exception e) {} + } + }; + while (true) + { + try {Thread.sleep(200);} + catch (Exception e) {} + } + } + }; + } + + + public static void main(String argv[]) + { + NestedExample e = new NestedExample(); + } +} +""" + + pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '1.4') + expect = [ 'NestedExample$1', 'NestedExample$2', 'NestedExample' ] + assert expect == classes, (expect, classes) + + pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '1.5') + expect = [ 'NestedExample$1', 'NestedExample$1$1', 'NestedExample' ] + assert expect == classes, (expect, classes) + + pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '6') + expect = [ 'NestedExample$1', 'NestedExample$1$1', 'NestedExample' ] + assert expect == classes, (expect, classes) + + def test_private_inner_class_instantiation(self): + """Test anonymous inner class generated by private instantiation""" + + input = """\ +class test +{ + test() + { + super(); + new inner(); + } + + static class inner + { + private inner() {} + } +} +""" + + # This is what we *should* generate, apparently due to the + # private instantiation of the inner class, but don't today. + #expect = [ 'test$1', 'test$inner', 'test' ] + + # What our parser currently generates, which doesn't match + # what the Java compiler actually generates. + expect = [ 'test$inner', 'test' ] + + pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '1.4') + assert expect == classes, (expect, classes) + + pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '1.5') + assert expect == classes, (expect, classes) + + def test_floating_point_numbers(self): + """Test floating-point numbers in the input stream""" + input = """ +// Broken.java +class Broken +{ + /** + * Detected. + */ + Object anonymousInnerOK = new Runnable() { public void run () {} }; + + /** + * Detected. + */ + class InnerOK { InnerOK () { } } + + { + System.out.println("a number: " + 1000.0 + ""); + } + + /** + * Not detected. + */ + Object anonymousInnerBAD = new Runnable() { public void run () {} }; + + /** + * Not detected. + */ + class InnerBAD { InnerBAD () { } } +} +""" + + expect = ['Broken$1', 'Broken$InnerOK', 'Broken$2', 'Broken$InnerBAD', 'Broken'] + + pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '1.4') + assert expect == classes, (expect, classes) + + pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '1.5') + assert expect == classes, (expect, classes) + + + def test_genercis(self): + """Test that generics don't interfere with detecting anonymous classes""" + + input = """\ +import java.util.Date; +import java.util.Comparator; + +public class Foo +{ + public void foo() + { + Comparator<Date> comp = new Comparator<Date>() + { + static final long serialVersionUID = 1L; + public int compare(Date lhs, Date rhs) + { + return 0; + } + }; + } +} +""" + + expect = [ 'Foo$1', 'Foo' ] + + pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '1.6') + assert expect == classes, (expect, classes) + + pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '6') + assert expect == classes, (expect, classes) + + + +if __name__ == "__main__": + suite = unittest.TestSuite() + tclasses = [ parse_javaTestCase ] + for tclass in tclasses: + names = unittest.getTestCaseNames(tclass, 'test_') + suite.addTests(map(tclass, names)) + if not unittest.TextTestRunner().run(suite).wasSuccessful(): + sys.exit(1) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/MSCommon/__init__.py b/src/engine/SCons/Tool/MSCommon/__init__.py new file mode 100644 index 0000000..78a6030 --- /dev/null +++ b/src/engine/SCons/Tool/MSCommon/__init__.py @@ -0,0 +1,56 @@ +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/MSCommon/__init__.py 4577 2009/12/27 19:44:43 scons" + +__doc__ = """ +Common functions for Microsoft Visual Studio and Visual C/C++. +""" + +import copy +import os +import re +import subprocess + +import SCons.Errors +import SCons.Platform.win32 +import SCons.Util + +from SCons.Tool.MSCommon.sdk import mssdk_exists, \ + mssdk_setup_env + +from SCons.Tool.MSCommon.vc import msvc_exists, \ + msvc_setup_env, \ + msvc_setup_env_once + +from SCons.Tool.MSCommon.vs import get_default_version, \ + get_vs_by_version, \ + merge_default_version, \ + msvs_exists, \ + query_versions + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/MSCommon/arch.py b/src/engine/SCons/Tool/MSCommon/arch.py new file mode 100644 index 0000000..3cf2fa0 --- /dev/null +++ b/src/engine/SCons/Tool/MSCommon/arch.py @@ -0,0 +1,61 @@ +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/MSCommon/arch.py 4577 2009/12/27 19:44:43 scons" + +__doc__ = """Module to define supported Windows chip architectures. +""" + +import os + +class ArchDefinition: + """ + A class for defining architecture-specific settings and logic. + """ + def __init__(self, arch, synonyms=[]): + self.arch = arch + self.synonyms = synonyms + +SupportedArchitectureList = [ + ArchitectureDefinition( + 'x86', + ['i386', 'i486', 'i586', 'i686'], + ), + + ArchitectureDefinition( + 'x86_64', + ['AMD64', 'amd64', 'em64t', 'EM64T', 'x86_64'], + ), + + ArchitectureDefinition( + 'ia64', + ['IA64'], + ), +] + +SupportedArchitectureMap = {} +for a in SupportedArchitectureList: + SupportedArchitectureMap[a.arch] = a + for s in a.synonyms: + SupportedArchitectureMap[s] = a + diff --git a/src/engine/SCons/Tool/MSCommon/common.py b/src/engine/SCons/Tool/MSCommon/common.py new file mode 100644 index 0000000..8fc49cc --- /dev/null +++ b/src/engine/SCons/Tool/MSCommon/common.py @@ -0,0 +1,195 @@ +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/MSCommon/common.py 4577 2009/12/27 19:44:43 scons" + +__doc__ = """ +Common helper functions for working with the Microsoft tool chain. +""" + +import copy +import os +import subprocess +import re + +import SCons.Util + + +logfile = os.environ.get('SCONS_MSCOMMON_DEBUG') +if logfile == '-': + def debug(x): + print x +elif logfile: + try: + import logging + except ImportError: + debug = lambda x: open(logfile, 'a').write(x + '\n') + else: + logging.basicConfig(filename=logfile, level=logging.DEBUG) + debug = logging.debug +else: + debug = lambda x: None + + +_is_win64 = None + +def is_win64(): + """Return true if running on windows 64 bits. + + Works whether python itself runs in 64 bits or 32 bits.""" + # Unfortunately, python does not provide a useful way to determine + # if the underlying Windows OS is 32-bit or 64-bit. Worse, whether + # the Python itself is 32-bit or 64-bit affects what it returns, + # so nothing in sys.* or os.* help. So we go to the registry to + # look directly for a clue from Windows, caching the result to + # avoid repeated registry calls. + global _is_win64 + if _is_win64 is None: + _is_win64 = has_reg(r"Software\Wow6432Node") + return _is_win64 + + +def read_reg(value): + return SCons.Util.RegGetValue(SCons.Util.HKEY_LOCAL_MACHINE, value)[0] + +def has_reg(value): + """Return True if the given key exists in HKEY_LOCAL_MACHINE, False + otherwise.""" + try: + SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_LOCAL_MACHINE, value) + ret = True + except WindowsError: + ret = False + return ret + +# Functions for fetching environment variable settings from batch files. + +def normalize_env(env, keys): + """Given a dictionary representing a shell environment, add the variables + from os.environ needed for the processing of .bat files; the keys are + controlled by the keys argument. + + It also makes sure the environment values are correctly encoded. + + Note: the environment is copied""" + normenv = {} + if env: + for k in env.keys(): + normenv[k] = copy.deepcopy(env[k]).encode('mbcs') + + for k in keys: + if os.environ.has_key(k): + normenv[k] = os.environ[k].encode('mbcs') + + return normenv + +def get_output(vcbat, args = None, env = None): + """Parse the output of given bat file, with given args.""" + if args: + debug("Calling '%s %s'" % (vcbat, args)) + popen = subprocess.Popen('"%s" %s & set' % (vcbat, args), + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + env=env) + else: + debug("Calling '%s'" % vcbat) + popen = subprocess.Popen('"%s" & set' % vcbat, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + env=env) + + # Use the .stdout and .stderr attributes directly because the + # .communicate() method uses the threading module on Windows + # and won't work under Pythons not built with threading. + stdout = popen.stdout.read() + if popen.wait() != 0: + raise IOError(popen.stderr.read().decode("mbcs")) + + output = stdout.decode("mbcs") + return output + +def parse_output(output, keep = ("INCLUDE", "LIB", "LIBPATH", "PATH")): + # dkeep is a dict associating key: path_list, where key is one item from + # keep, and pat_list the associated list of paths + + # TODO(1.5): replace with the following list comprehension: + #dkeep = dict([(i, []) for i in keep]) + dkeep = dict(map(lambda i: (i, []), keep)) + + # rdk will keep the regex to match the .bat file output line starts + rdk = {} + for i in keep: + rdk[i] = re.compile('%s=(.*)' % i, re.I) + + def add_env(rmatch, key, dkeep=dkeep): + plist = rmatch.group(1).split(os.pathsep) + for p in plist: + # Do not add empty paths (when a var ends with ;) + if p: + p = p.encode('mbcs') + # XXX: For some reason, VC98 .bat file adds "" around the PATH + # values, and it screws up the environment later, so we strip + # it. + p = p.strip('"') + dkeep[key].append(p) + + for line in output.splitlines(): + for k,v in rdk.items(): + m = v.match(line) + if m: + add_env(m, k) + + return dkeep + +# TODO(sgk): unused +def output_to_dict(output): + """Given an output string, parse it to find env variables. + + Return a dict where keys are variables names, and values their content""" + envlinem = re.compile(r'^([a-zA-z0-9]+)=([\S\s]*)$') + parsedenv = {} + for line in output.splitlines(): + m = envlinem.match(line) + if m: + parsedenv[m.group(1)] = m.group(2) + return parsedenv + +# TODO(sgk): unused +def get_new(l1, l2): + """Given two list l1 and l2, return the items in l2 which are not in l1. + Order is maintained.""" + + # We don't try to be smart: lists are small, and this is not the bottleneck + # is any case + new = [] + for i in l2: + if i not in l1: + new.append(i) + + return new + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/MSCommon/netframework.py b/src/engine/SCons/Tool/MSCommon/netframework.py new file mode 100644 index 0000000..3a38abd --- /dev/null +++ b/src/engine/SCons/Tool/MSCommon/netframework.py @@ -0,0 +1,84 @@ +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/MSCommon/netframework.py 4577 2009/12/27 19:44:43 scons" + +__doc__ = """ +""" + +import os +import re +import string + +from common import read_reg, debug + +# Original value recorded by dcournapeau +_FRAMEWORKDIR_HKEY_ROOT = r'Software\Microsoft\.NETFramework\InstallRoot' +# On SGK's system +_FRAMEWORKDIR_HKEY_ROOT = r'Software\Microsoft\Microsoft SDKs\.NETFramework\v2.0\InstallationFolder' + +def find_framework_root(): + # XXX: find it from environment (FrameworkDir) + try: + froot = read_reg(_FRAMEWORKDIR_HKEY_ROOT) + debug("Found framework install root in registry: %s" % froot) + except WindowsError, e: + debug("Could not read reg key %s" % _FRAMEWORKDIR_HKEY_ROOT) + return None + + if not os.path.exists(froot): + debug("%s not found on fs" % froot) + return None + + return froot + +def query_versions(): + froot = find_framework_root() + if froot: + contents = os.listdir(froot) + + l = re.compile('v[0-9]+.*') + versions = filter(lambda e, l=l: l.match(e), contents) + + def versrt(a,b): + # since version numbers aren't really floats... + aa = a[1:] + bb = b[1:] + aal = string.split(aa, '.') + bbl = string.split(bb, '.') + # sequence comparison in python is lexicographical + # which is exactly what we want. + # Note we sort backwards so the highest version is first. + return cmp(bbl,aal) + + versions.sort(versrt) + else: + versions = [] + + return versions + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/MSCommon/sdk.py b/src/engine/SCons/Tool/MSCommon/sdk.py new file mode 100644 index 0000000..88af6aa --- /dev/null +++ b/src/engine/SCons/Tool/MSCommon/sdk.py @@ -0,0 +1,321 @@ +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/MSCommon/sdk.py 4577 2009/12/27 19:44:43 scons" + +__doc__ = """Module to detect the Platform/Windows SDK + +PSDK 2003 R1 is the earliest version detected. +""" + +import os + +import SCons.Errors +import SCons.Util + +import common + +debug = common.debug + +# SDK Checks. This is of course a mess as everything else on MS platforms. Here +# is what we do to detect the SDK: +# +# For Windows SDK >= 6.0: just look into the registry entries: +# HKLM\Software\Microsoft\Microsoft SDKs\Windows +# All the keys in there are the available versions. +# +# For Platform SDK before 6.0 (2003 server R1 and R2, etc...), there does not +# seem to be any sane registry key, so the precise location is hardcoded. +# +# For versions below 2003R1, it seems the PSDK is included with Visual Studio? +# +# Also, per the following: +# http://benjamin.smedbergs.us/blog/tag/atl/ +# VC++ Professional comes with the SDK, VC++ Express does not. + +# Location of the SDK (checked for 6.1 only) +_CURINSTALLED_SDK_HKEY_ROOT = \ + r"Software\Microsoft\Microsoft SDKs\Windows\CurrentInstallFolder" + + +class SDKDefinition: + """ + An abstract base class for trying to find installed SDK directories. + """ + def __init__(self, version, **kw): + self.version = version + self.__dict__.update(kw) + + def find_sdk_dir(self): + """Try to find the MS SDK from the registry. + + Return None if failed or the directory does not exist. + """ + if not SCons.Util.can_read_reg: + debug('find_sdk_dir(): can not read registry') + return None + + hkey = self.HKEY_FMT % self.hkey_data + + try: + sdk_dir = common.read_reg(hkey) + except WindowsError, e: + debug('find_sdk_dir(): no SDK registry key %s' % repr(hkey)) + return None + + if not os.path.exists(sdk_dir): + debug('find_sdk_dir(): %s not on file system' % sdk_dir) + return None + + ftc = os.path.join(sdk_dir, self.sanity_check_file) + if not os.path.exists(ftc): + debug("find_sdk_dir(): sanity check %s not found" % ftc) + return None + + return sdk_dir + + def get_sdk_dir(self): + """Return the MSSSDK given the version string.""" + try: + return self._sdk_dir + except AttributeError: + sdk_dir = self.find_sdk_dir() + self._sdk_dir = sdk_dir + return sdk_dir + +class WindowsSDK(SDKDefinition): + """ + A subclass for trying to find installed Windows SDK directories. + """ + HKEY_FMT = r'Software\Microsoft\Microsoft SDKs\Windows\v%s\InstallationFolder' + def __init__(self, *args, **kw): + apply(SDKDefinition.__init__, (self,)+args, kw) + self.hkey_data = self.version + +class PlatformSDK(SDKDefinition): + """ + A subclass for trying to find installed Platform SDK directories. + """ + HKEY_FMT = r'Software\Microsoft\MicrosoftSDK\InstalledSDKS\%s\Install Dir' + def __init__(self, *args, **kw): + apply(SDKDefinition.__init__, (self,)+args, kw) + self.hkey_data = self.uuid + +# The list of support SDKs which we know how to detect. +# +# The first SDK found in the list is the one used by default if there +# are multiple SDKs installed. Barring good reasons to the contrary, +# this means we should list SDKs with from most recent to oldest. +# +# If you update this list, update the documentation in Tool/mssdk.xml. +SupportedSDKList = [ + WindowsSDK('6.1', + sanity_check_file=r'bin\SetEnv.Cmd', + include_subdir='include', + lib_subdir={ + 'x86' : ['lib'], + 'x86_64' : [r'lib\x64'], + 'ia64' : [r'lib\ia64'], + }, + ), + + WindowsSDK('6.0A', + sanity_check_file=r'include\windows.h', + include_subdir='include', + lib_subdir={ + 'x86' : ['lib'], + 'x86_64' : [r'lib\x64'], + 'ia64' : [r'lib\ia64'], + }, + ), + + WindowsSDK('6.0', + sanity_check_file=r'bin\gacutil.exe', + include_subdir='include', + lib_subdir='lib', + ), + + PlatformSDK('2003R2', + sanity_check_file=r'SetEnv.Cmd', + uuid="D2FF9F89-8AA2-4373-8A31-C838BF4DBBE1" + ), + + PlatformSDK('2003R1', + sanity_check_file=r'SetEnv.Cmd', + uuid="8F9E5EF3-A9A5-491B-A889-C58EFFECE8B3", + ), +] + +SupportedSDKMap = {} +for sdk in SupportedSDKList: + SupportedSDKMap[sdk.version] = sdk + + +# Finding installed SDKs isn't cheap, because it goes not only to the +# registry but also to the disk to sanity-check that there is, in fact, +# an SDK installed there and that the registry entry isn't just stale. +# Find this information once, when requested, and cache it. + +InstalledSDKList = None +InstalledSDKMap = None + +def get_installed_sdks(): + global InstalledSDKList + global InstalledSDKMap + if InstalledSDKList is None: + InstalledSDKList = [] + InstalledSDKMap = {} + for sdk in SupportedSDKList: + debug('trying to find SDK %s' % sdk.version) + if sdk.get_sdk_dir(): + debug('found SDK %s' % sdk.version) + InstalledSDKList.append(sdk) + InstalledSDKMap[sdk.version] = sdk + return InstalledSDKList + + +# We may be asked to update multiple construction environments with +# SDK information. When doing this, we check on-disk for whether +# the SDK has 'mfc' and 'atl' subdirectories. Since going to disk +# is expensive, cache results by directory. + +SDKEnvironmentUpdates = {} + +def set_sdk_by_directory(env, sdk_dir): + global SDKEnvironmentUpdates + try: + env_tuple_list = SDKEnvironmentUpdates[sdk_dir] + except KeyError: + env_tuple_list = [] + SDKEnvironmentUpdates[sdk_dir] = env_tuple_list + + include_path = os.path.join(sdk_dir, 'include') + mfc_path = os.path.join(include_path, 'mfc') + atl_path = os.path.join(include_path, 'atl') + + if os.path.exists(mfc_path): + env_tuple_list.append(('INCLUDE', mfc_path)) + if os.path.exists(atl_path): + env_tuple_list.append(('INCLUDE', atl_path)) + env_tuple_list.append(('INCLUDE', include_path)) + + env_tuple_list.append(('LIB', os.path.join(sdk_dir, 'lib'))) + env_tuple_list.append(('LIBPATH', os.path.join(sdk_dir, 'lib'))) + env_tuple_list.append(('PATH', os.path.join(sdk_dir, 'bin'))) + + for variable, directory in env_tuple_list: + env.PrependENVPath(variable, directory) + + +# TODO(sgk): currently unused; remove? +def get_cur_sdk_dir_from_reg(): + """Try to find the platform sdk directory from the registry. + + Return None if failed or the directory does not exist""" + if not SCons.Util.can_read_reg: + debug('SCons cannot read registry') + return None + + try: + val = common.read_reg(_CURINSTALLED_SDK_HKEY_ROOT) + debug("Found current sdk dir in registry: %s" % val) + except WindowsError, e: + debug("Did not find current sdk in registry") + return None + + if not os.path.exists(val): + debug("Current sdk dir %s not on fs" % val) + return None + + return val + +def get_sdk_by_version(mssdk): + if not SupportedSDKMap.has_key(mssdk): + msg = "SDK version %s is not supported" % repr(mssdk) + raise SCons.Errors.UserError, msg + get_installed_sdks() + return InstalledSDKMap.get(mssdk) + +def get_default_sdk(): + """Set up the default Platform/Windows SDK.""" + get_installed_sdks() + if not InstalledSDKList: + return None + return InstalledSDKList[0] + +def mssdk_setup_env(env): + debug('msvs_setup_env()') + if env.has_key('MSSDK_DIR'): + sdk_dir = env['MSSDK_DIR'] + if sdk_dir is None: + return + sdk_dir = env.subst(sdk_dir) + elif env.has_key('MSSDK_VERSION'): + sdk_version = env['MSSDK_VERSION'] + if sdk_version is None: + msg = "SDK version %s is not installed" % repr(mssdk) + raise SCons.Errors.UserError, msg + sdk_version = env.subst(sdk_version) + mssdk = get_sdk_by_version(sdk_version) + sdk_dir = mssdk.get_sdk_dir() + elif env.has_key('MSVS_VERSION'): + msvs_version = env['MSVS_VERSION'] + debug('Getting MSVS_VERSION from env:%s'%msvs_version) + if msvs_version is None: + return + msvs_version = env.subst(msvs_version) + import vs + msvs = vs.get_vs_by_version(msvs_version) + debug('msvs is :%s'%msvs) + if not msvs: + return + sdk_version = msvs.sdk_version + if not sdk_version: + return + mssdk = get_sdk_by_version(sdk_version) + if not mssdk: + mssdk = get_default_sdk() + if not mssdk: + return + sdk_dir = mssdk.get_sdk_dir() + else: + mssdk = get_default_sdk() + if not mssdk: + return + sdk_dir = mssdk.get_sdk_dir() + + set_sdk_by_directory(env, sdk_dir) + + #print "No MSVS_VERSION: this is likely to be a bug" + +def mssdk_exists(version=None): + sdks = get_installed_sdks() + if version is None: + return len(sdks) > 0 + return sdks.has_key(version) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/MSCommon/vc.py b/src/engine/SCons/Tool/MSCommon/vc.py new file mode 100644 index 0000000..7d34374 --- /dev/null +++ b/src/engine/SCons/Tool/MSCommon/vc.py @@ -0,0 +1,367 @@ +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +# TODO: +# * supported arch for versions: for old versions of batch file without +# argument, giving bogus argument cannot be detected, so we have to hardcode +# this here +# * print warning when msvc version specified but not found +# * find out why warning do not print +# * test on 64 bits XP + VS 2005 (and VS 6 if possible) +# * SDK +# * Assembly +__revision__ = "src/engine/SCons/Tool/MSCommon/vc.py 4577 2009/12/27 19:44:43 scons" + +__doc__ = """Module for Visual C/C++ detection and configuration. +""" +import SCons.compat + +import os +import platform + +import SCons.Warnings + +import common + +debug = common.debug + +class VisualCException(Exception): + pass + +class UnsupportedVersion(VisualCException): + pass + +class UnsupportedArch(VisualCException): + pass + +class MissingConfiguration(VisualCException): + pass + +class NoVersionFound(VisualCException): + pass + +class BatchFileExecutionError(VisualCException): + pass + +# Dict to 'canonalize' the arch +_ARCH_TO_CANONICAL = { + "x86": "x86", + "amd64": "amd64", + "i386": "x86", + "emt64": "amd64", + "x86_64": "amd64", + "itanium": "ia64", + "ia64": "ia64", +} + +# Given a (host, target) tuple, return the argument for the bat file. Both host +# and targets should be canonalized. +_HOST_TARGET_ARCH_TO_BAT_ARCH = { + ("x86", "x86"): "x86", + ("x86", "amd64"): "x86_amd64", + ("amd64", "amd64"): "amd64", + ("amd64", "x86"): "x86", + ("x86", "ia64"): "x86_ia64" +} + +def get_host_target(env): + host_platform = env.get('HOST_ARCH') + if not host_platform: + host_platform = platform.machine() + # TODO(2.5): the native Python platform.machine() function returns + # '' on all Python versions before 2.6, after which it also uses + # PROCESSOR_ARCHITECTURE. + if not host_platform: + host_platform = os.environ.get('PROCESSOR_ARCHITECTURE', '') + target_platform = env.get('TARGET_ARCH') + if not target_platform: + target_platform = host_platform + + try: + host = _ARCH_TO_CANONICAL[host_platform] + except KeyError, e: + msg = "Unrecognized host architecture %s" + raise ValueError(msg % repr(host_platform)) + + try: + target = _ARCH_TO_CANONICAL[target_platform] + except KeyError, e: + raise ValueError("Unrecognized target architecture %s" % target_platform) + + return (host, target) + +_VCVER = ["10.0", "9.0", "8.0", "7.1", "7.0", "6.0"] + +_VCVER_TO_PRODUCT_DIR = { + '10.0': [ + r'Microsoft\VisualStudio\10.0\Setup\VC\ProductDir'], + '9.0': [ + r'Microsoft\VisualStudio\9.0\Setup\VC\ProductDir', + r'Microsoft\VCExpress\9.0\Setup\VC\ProductDir'], + '8.0': [ + r'Microsoft\VisualStudio\8.0\Setup\VC\ProductDir', + r'Microsoft\VCExpress\8.0\Setup\VC\ProductDir'], + '7.1': [ + r'Microsoft\VisualStudio\7.1\Setup\VC\ProductDir'], + '7.0': [ + r'Microsoft\VisualStudio\7.0\Setup\VC\ProductDir'], + '6.0': [ + r'Microsoft\VisualStudio\6.0\Setup\Microsoft Visual C++\ProductDir'] +} + +def msvc_version_to_maj_min(msvc_version): + t = msvc_version.split(".") + if not len(t) == 2: + raise ValueError("Unrecognized version %s" % msvc_version) + try: + maj = int(t[0]) + min = int(t[1]) + return maj, min + except ValueError, e: + raise ValueError("Unrecognized version %s" % msvc_version) + +def is_host_target_supported(host_target, msvc_version): + """Return True if the given (host, target) tuple is supported given the + msvc version. + + Parameters + ---------- + host_target: tuple + tuple of (canonalized) host-target, e.g. ("x86", "amd64") for cross + compilation from 32 bits windows to 64 bits. + msvc_version: str + msvc version (major.minor, e.g. 10.0) + + Note + ---- + This only check whether a given version *may* support the given (host, + target), not that the toolchain is actually present on the machine. + """ + # We assume that any Visual Studio version supports x86 as a target + if host_target[1] != "x86": + maj, min = msvc_version_to_maj_min(msvc_version) + if maj < 8: + return False + + return True + +def find_vc_pdir(msvc_version): + """Try to find the product directory for the given + version. + + Note + ---- + If for some reason the requested version could not be found, an + exception which inherits from VisualCException will be raised.""" + root = 'Software\\' + if common.is_win64(): + root = root + 'Wow6432Node\\' + try: + hkeys = _VCVER_TO_PRODUCT_DIR[msvc_version] + except KeyError: + debug("Unknown version of MSVC: %s" % msvc_version) + raise UnsupportedVersion("Unknown version %s" % msvc_version) + + for key in hkeys: + key = root + key + try: + comps = common.read_reg(key) + except WindowsError, e: + debug('find_vc_dir(): no VC registry key %s' % repr(key)) + else: + debug('find_vc_dir(): found VC in registry: %s' % comps) + if os.path.exists(comps): + return comps + else: + debug('find_vc_dir(): reg says dir is %s, but it does not exist. (ignoring)'\ + % comps) + raise MissingConfiguration("registry dir %s not found on the filesystem" % comps) + return None + +def find_batch_file(msvc_version): + pdir = find_vc_pdir(msvc_version) + if pdir is None: + raise NoVersionFound("No version of Visual Studio found") + + vernum = float(msvc_version) + if 7 <= vernum < 8: + pdir = os.path.join(pdir, os.pardir, "Common7", "Tools") + batfilename = os.path.join(pdir, "vsvars32.bat") + elif vernum < 7: + pdir = os.path.join(pdir, "Bin") + batfilename = os.path.join(pdir, "vcvars32.bat") + else: # >= 8 + batfilename = os.path.join(pdir, "vcvarsall.bat") + + if os.path.exists(batfilename): + return batfilename + else: + debug("Not found: %s" % batfilename) + return None + +__INSTALLED_VCS_RUN = None + +def cached_get_installed_vcs(): + global __INSTALLED_VCS_RUN + + if __INSTALLED_VCS_RUN is None: + ret = get_installed_vcs() + __INSTALLED_VCS_RUN = ret + + return __INSTALLED_VCS_RUN + +def get_installed_vcs(): + installed_versions = [] + for ver in _VCVER: + debug('trying to find VC %s' % ver) + try: + if find_vc_pdir(ver): + debug('found VC %s' % ver) + installed_versions.append(ver) + else: + debug('find_vc_pdir return None for ver %s' % ver) + except VisualCException, e: + debug('did not find VC %s: caught exception %s' % (ver, str(e))) + return installed_versions + +def reset_installed_vcs(): + """Make it try again to find VC. This is just for the tests.""" + __INSTALLED_VCS_RUN = None + +def script_env(script, args=None): + stdout = common.get_output(script, args) + # Stupid batch files do not set return code: we take a look at the + # beginning of the output for an error message instead + olines = stdout.splitlines() + if olines[0].startswith("The specified configuration type is missing"): + raise BatchFileExecutionError("\n".join(olines[:2])) + + return common.parse_output(stdout) + +def get_default_version(env): + debug('get_default_version()') + + msvc_version = env.get('MSVC_VERSION') + msvs_version = env.get('MSVS_VERSION') + + if msvs_version and not msvc_version: + SCons.Warnings.warn( + SCons.Warnings.DeprecatedWarning, + "MSVS_VERSION is deprecated: please use MSVC_VERSION instead ") + return msvs_version + elif msvc_version and msvs_version: + if not msvc_version == msvs_version: + SCons.Warnings.warn( + SCons.Warnings.VisualVersionMismatch, + "Requested msvc version (%s) and msvs version (%s) do " \ + "not match: please use MSVC_VERSION only to request a " \ + "visual studio version, MSVS_VERSION is deprecated" \ + % (msvc_version, msvs_version)) + return msvs_version + if not msvc_version: + installed_vcs = cached_get_installed_vcs() + debug('installed_vcs:%s' % installed_vcs) + if not installed_vcs: + msg = 'No installed VCs' + debug('msv %s\n' % repr(msg)) + SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, msg) + return None + msvc_version = installed_vcs[0] + debug('msvc_setup_env: using default installed MSVC version %s\n' % repr(msvc_version)) + + return msvc_version + +def msvc_setup_env_once(env): + try: + has_run = env["MSVC_SETUP_RUN"] + except KeyError: + has_run = False + + if not has_run: + msvc_setup_env(env) + env["MSVC_SETUP_RUN"] = True + +def msvc_setup_env(env): + debug('msvc_setup_env()') + + version = get_default_version(env) + if version is None: + warn_msg = "No version of Visual Studio compiler found - C/C++ " \ + "compilers most likely not set correctly" + SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, warn_msg) + return None + debug('msvc_setup_env: using specified MSVC version %s\n' % repr(version)) + + # XXX: we set-up both MSVS version for backward + # compatibility with the msvs tool + env['MSVC_VERSION'] = version + env['MSVS_VERSION'] = version + env['MSVS'] = {} + + try: + script = find_batch_file(version) + except VisualCException, e: + msg = str(e) + debug('Caught exception while looking for batch file (%s)' % msg) + warn_msg = "VC version %s not installed. " + \ + "C/C++ compilers are most likely not set correctly.\n" + \ + " Installed versions are: %s" + warn_msg = warn_msg % (version, cached_get_installed_vcs()) + SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, warn_msg) + return None + + use_script = env.get('MSVC_USE_SCRIPT', True) + if SCons.Util.is_String(use_script): + debug('use_script 1 %s\n' % repr(use_script)) + d = script_env(use_script) + elif use_script: + host_platform, target_platform = get_host_target(env) + host_target = (host_platform, target_platform) + if not is_host_target_supported(host_target, version): + warn_msg = "host, target = %s not supported for MSVC version %s" % \ + (host_target, version) + SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, warn_msg) + arg = _HOST_TARGET_ARCH_TO_BAT_ARCH[host_target] + debug('use_script 2 %s, args:%s\n' % (repr(script), arg)) + try: + d = script_env(script, args=arg) + except BatchFileExecutionError, e: + msg = "MSVC error while executing %s with args %s (error was %s)" % \ + (script, arg, str(e)) + raise SCons.Errors.UserError(msg) + else: + debug('MSVC_USE_SCRIPT set to False') + warn_msg = "MSVC_USE_SCRIPT set to False, assuming environment " \ + "set correctly." + SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, warn_msg) + return None + + for k, v in d.items(): + env.PrependENVPath(k, v, delete_existing=True) + +def msvc_exists(version=None): + vcs = cached_get_installed_vcs() + if version is None: + return len(vcs) > 0 + return version in vcs + diff --git a/src/engine/SCons/Tool/MSCommon/vc.py.bak b/src/engine/SCons/Tool/MSCommon/vc.py.bak new file mode 100644 index 0000000..e59092f --- /dev/null +++ b/src/engine/SCons/Tool/MSCommon/vc.py.bak @@ -0,0 +1,394 @@ +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/MSCommon/vc.py.bak 4577 2009/12/27 19:44:43 scons" + +__doc__ = """Module for Visual C/C++ detection and configuration. +""" + +import os +import platform + +import SCons.Warnings + +import common + +debug = common.debug + +class VisualC: + """ + An base class for finding installed versions of Visual C/C++. + """ + def __init__(self, version, **kw): + self.version = version + self.__dict__.update(kw) + self._cache = {} + + def vcbin_arch(self): + if common.is_win64(): + result = { + 'x86_64' : ['amd64', r'BIN\x86_amd64'], + 'ia64' : [r'BIN\ia64'], + }.get(target_arch, []) + else: + result = { + 'x86_64' : ['x86_amd64'], + 'ia64' : ['x86_ia64'], + }.get(target_arch, []) + # TODO(1.5) + #return ';'.join(result) + return string.join(result, ';') + + # Support for searching for an appropriate .bat file. + # The map is indexed by (target_architecture, host_architecture). + # Entries where the host_architecture is None specify the + # cross-platform "default" .bat file if there isn't sn entry + # specific to the current host architecture. + + batch_file_map = { + ('x86_64', 'x86_64') : [ + r'bin\amd64\vcvarsamd64.bat', + r'bin\x86_amd64\vcvarsx86_amd64.bat', + r'bin\vcvarsx86_amd64.bat', + ], + ('x86_64', 'x86') : [ + r'bin\x86_amd64\vcvarsx86_amd64.bat', + ], + ('ia64', 'ia64') : [ + r'bin\ia64\vcvarsia64.bat', + r'bin\x86_ia64\vcvarsx86_ia64.bat', + ], + ('ia64', None) : [ + r'bin\x86_ia64\vcvarsx86_ia64.bat', + ], + ('x86', None) : [ + r'bin\vcvars32.bat', + ], + } + + def find_batch_file(self, target_architecture, host_architecture): + key = (target_architecture, host_architecture) + potential_batch_files = self.batch_file_map.get(key) + if not potential_batch_files: + key = (target_architecture, None) + potential_batch_files = self.batch_file_map.get(key) + if potential_batch_files: + product_dir = self.get_vc_dir() + for batch_file in potential_batch_files: + bf = os.path.join(product_dir, batch_file) + if os.path.isfile(bf): + return bf + return None + + def find_vc_dir(self): + root = 'Software\\' + if common.is_win64(): + root = root + 'Wow6432Node\\' + for key in self.hkeys: + key = root + key + try: + comps = common.read_reg(key) + except WindowsError, e: + debug('find_vc_dir(): no VC registry key %s' % repr(key)) + else: + debug('find_vc_dir(): found VC in registry: %s' % comps) + if os.path.exists(comps): + return comps + else: + debug('find_vc_dir(): reg says dir is %s, but it does not exist. (ignoring)'\ + % comps) + return None + return None + + # + + def get_batch_file(self, target_architecture, host_architecture): + try: + return self._cache['batch_file'] + except KeyError: + batch_file = self.find_batch_file(target_architecture, host_architecture) + self._cache['batch_file'] = batch_file + return batch_file + + def get_vc_dir(self): + try: + return self._cache['vc_dir'] + except KeyError: + vc_dir = self.find_vc_dir() + self._cache['vc_dir'] = vc_dir + return vc_dir + + def reset(self): + self._cache={} + + +# The list of supported Visual C/C++ versions we know how to detect. +# +# The first VC found in the list is the one used by default if there +# are multiple VC installed. Barring good reasons to the contrary, +# this means we should list VC with from most recent to oldest. +# +# If you update this list, update the documentation in Tool/vc.xml. +SupportedVCList = [ + VisualC('9.0', + hkeys=[ + r'Microsoft\VisualStudio\9.0\Setup\VC\ProductDir', + r'Microsoft\VCExpress\9.0\Setup\VC\ProductDir', + ], + default_install=r'Microsoft Visual Studio 9.0\VC', + common_tools_var='VS90COMNTOOLS', + vc_subdir=r'\VC', + batch_file_base='vcvars', + supported_arch=['x86', 'x86_64', 'ia64'], + atlmc_include_subdir = [r'ATLMFC\INCLUDE'], + atlmfc_lib_subdir = { + 'x86' : r'ATLMFC\LIB', + 'x86_64' : r'ATLMFC\LIB\amd64', + 'ia64' : r'ATLMFC\LIB\ia64', + }, + crt_lib_subdir = { + 'x86_64' : r'LIB\amd64', + 'ia64' : r'LIB\ia64', + }, + ), + VisualC('8.0', + hkeys=[ + r'Microsoft\VisualStudio\8.0\Setup\VC\ProductDir', + r'Microsoft\VCExpress\8.0\Setup\VC\ProductDir', + ], + default_install=r'%s\Microsoft Visual Studio 8\VC', + common_tools_var='VS80COMNTOOLS', + vc_subdir=r'\VC', + batch_file_base='vcvars', + supported_arch=['x86', 'x86_64', 'ia64'], + atlmc_include_subdir = [r'ATLMFC\INCLUDE'], + atlmfc_lib_subdir = { + 'x86' : r'ATLMFC\LIB', + 'x86_64' : r'ATLMFC\LIB\amd64', + 'ia64' : r'ATLMFC\LIB\ia64', + }, + crt_lib_subdir = { + 'x86_64' : r'LIB\amd64', + 'ia64' : r'LIB\ia64', + }, + ), + VisualC('7.1', + hkeys=[ + r'Microsoft\VisualStudio\7.1\Setup\VC\ProductDir', + ], + default_install=r'%s\Microsoft Visual Studio 7.1.NET 2003\VC7', + common_tools_var='VS71COMNTOOLS', + vc_subdir=r'\VC7', + batch_file_base='vcvars', + supported_arch=['x86'], + atlmc_include_subdir = [r'ATLMFC\INCLUDE'], + atlmfc_lib_subdir = { + 'x86' : r'ATLMFC\LIB', + }, + ), + VisualC('7.0', + hkeys=[ + r'Microsoft\VisualStudio\7.0\Setup\VC\ProductDir', + ], + default_install=r'%s\Microsoft Visual Studio .NET\VC7', + common_tools_var='VS70COMNTOOLS', + vc_subdir=r'\VC7', + batch_file_base='vcvars', + supported_arch=['x86'], + atlmc_include_subdir = [r'ATLMFC\INCLUDE'], + atlmfc_lib_subdir = { + 'x86' : r'ATLMFC\LIB', + }, + ), + VisualC('6.0', + hkeys=[ + r'Microsoft\VisualStudio\6.0\Setup\Microsoft Visual C++\ProductDir', + ], + default_install=r'%s\Microsoft Visual Studio\VC98', + common_tools_var='VS60COMNTOOLS', + vc_subdir=r'\VC98', + batch_file_base='vcvars', + supported_arch=['x86'], + atlmc_include_subdir = [r'ATL\INCLUDE', r'MFC\INCLUDE'], + atlmfc_lib_subdir = { + 'x86' : r'MFC\LIB', + }, + ), +] + +SupportedVCMap = {} +for vc in SupportedVCList: + SupportedVCMap[vc.version] = vc + + +# Finding installed versions of Visual C/C++ isn't cheap, because it goes +# not only to the registry but also to the disk to sanity-check that there +# is, in fact, something installed there and that the registry entry isn't +# just stale. Find this information once, when requested, and cache it. + +InstalledVCList = None +InstalledVCMap = None + +def get_installed_vcs(): + global InstalledVCList + global InstalledVCMap + if InstalledVCList is None: + InstalledVCList = [] + InstalledVCMap = {} + for vc in SupportedVCList: + debug('trying to find VC %s' % vc.version) + if vc.get_vc_dir(): + debug('found VC %s' % vc.version) + InstalledVCList.append(vc) + InstalledVCMap[vc.version] = vc + return InstalledVCList + + +def set_vc_by_version(env, msvc): + if not SupportedVCMap.has_key(msvc): + msg = "VC version %s is not supported" % repr(msvc) + raise SCons.Errors.UserError, msg + get_installed_vcs() + vc = InstalledVCMap.get(msvc) + if not vc: + msg = "VC version %s is not installed" % repr(msvc) + raise SCons.Errors.UserError, msg + set_vc_by_directory(env, vc.get_vc_dir()) + +# New stuff + +def script_env(script, args=None): + stdout = common.get_output(script, args) + return common.parse_output(stdout) + +def get_default_version(env): + debug('get_default_version()') + + msvc_version = env.get('MSVC_VERSION') + if not msvc_version: + installed_vcs = get_installed_vcs() + debug('InstalledVCMap:%s'%InstalledVCMap) + if not installed_vcs: + msg = 'No installed VCs' + debug('msv %s\n' % repr(msg)) + SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, msg) + return None + msvc = installed_vcs[0] + msvc_version = msvc.version + debug('msvc_setup_env: using default installed MSVC version %s\n' % repr(msvc_version)) + + return msvc_version + +# Dict to 'canonalize' the arch +_ARCH_TO_CANONICAL = { + "x86": "x86", + "amd64": "amd64", + "i386": "x86", + "emt64": "amd64", + "x86_64": "amd64" +} + +# Given a (host, target) tuple, return the argument for the bat file. Both host +# and targets should be canonalized. +_HOST_TARGET_ARCH_TO_BAT_ARCH = { + ("x86", "x86"): "x86", + ("x86", "amd64"): "x86_amd64", + ("amd64", "amd64"): "amd64", + ("amd64", "x86"): "x86" +} + +def get_host_target(env): + host_platform = env.get('HOST_ARCH') + if not host_platform: + #host_platform = get_default_host_platform() + host_platform = platform.machine() + target_platform = env.get('TARGET_ARCH') + if not target_platform: + target_platform = host_platform + + return (_ARCH_TO_CANONICAL[host_platform], + _ARCH_TO_CANONICAL[target_platform]) + +def msvc_setup_env_once(env): + try: + has_run = env["MSVC_SETUP_RUN"] + except KeyError: + has_run = False + + if not has_run: + msvc_setup_env(env) + env["MSVC_SETUP_RUN"] = False + +def msvc_setup_env(env): + debug('msvc_setup_env()') + + version = get_default_version(env) + host_platform, target_platform = get_host_target(env) + debug('msvc_setup_env: using specified MSVC version %s\n' % repr(version)) + env['MSVC_VERSION'] = version + + msvc = InstalledVCMap.get(version) + if not msvc: + msg = 'VC version %s not installed' % version + debug('msv %s\n' % repr(msg)) + SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, msg) + return None + + use_script = env.get('MSVC_USE_SCRIPT', True) + if SCons.Util.is_String(use_script): + debug('use_script 1 %s\n' % repr(use_script)) + d = script_env(use_script) + elif use_script: + # XXX: this is VS 2008 specific, fix this + script = os.path.join(msvc.find_vc_dir(), "vcvarsall.bat") + + arg = _HOST_TARGET_ARCH_TO_BAT_ARCH[(host_platform, target_platform)] + debug('use_script 2 %s, args:%s\n' % (repr(script), arg)) + d = script_env(script, args=arg) + else: + debug('msvc.get_default_env()\n') + d = msvc.get_default_env() + + for k, v in d.items(): + env.PrependENVPath(k, v, delete_existing=True) + +def msvc_exists(version=None): + vcs = get_installed_vcs() + if version is None: + return len(vcs) > 0 + return InstalledVCMap.has_key(version) + + +def reset_installed_vcs(): + global InstalledVCList + global InstalledVCMap + InstalledVCList = None + InstalledVCMap = None + for vc in SupportedVCList: + vc.reset() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/MSCommon/vs.py b/src/engine/SCons/Tool/MSCommon/vs.py new file mode 100644 index 0000000..69003ef --- /dev/null +++ b/src/engine/SCons/Tool/MSCommon/vs.py @@ -0,0 +1,497 @@ +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/MSCommon/vs.py 4577 2009/12/27 19:44:43 scons" + +__doc__ = """Module to detect Visual Studio and/or Visual C/C++ +""" + +import os + +import SCons.Errors +import SCons.Util + +from common import debug, \ + get_output, \ + is_win64, \ + normalize_env, \ + parse_output, \ + read_reg + +import SCons.Tool.MSCommon.vc + +class VisualStudio: + """ + An abstract base class for trying to find installed versions of + Visual Studio. + """ + def __init__(self, version, **kw): + self.version = version + kw['vc_version'] = kw.get('vc_version', version) + kw['sdk_version'] = kw.get('sdk_version', version) + self.__dict__.update(kw) + self._cache = {} + + # + + def find_batch_file(self): + vs_dir = self.get_vs_dir() + if not vs_dir: + debug('find_executable(): no vs_dir') + return None + batch_file = os.path.join(vs_dir, self.batch_file_path) + batch_file = os.path.normpath(batch_file) + if not os.path.isfile(batch_file): + debug('find_batch_file(): %s not on file system' % batch_file) + return None + return batch_file + + def find_vs_dir_by_vc(self): + SCons.Tool.MSCommon.vc.get_installed_vcs() + dir = SCons.Tool.MSCommon.vc.find_vc_pdir(self.vc_version) + if not dir: + debug('find_vs_dir(): no installed VC %s' % self.vc_version) + return None + return dir + + def find_vs_dir_by_reg(self): + root = 'Software\\' + + if is_win64(): + root = root + 'Wow6432Node\\' + for key in self.hkeys: + if key=='use_dir': + return self.find_vs_dir_by_vc() + key = root + key + try: + comps = read_reg(key) + except WindowsError, e: + debug('find_vs_dir_by_reg(): no VS registry key %s' % repr(key)) + else: + debug('find_vs_dir_by_reg(): found VS in registry: %s' % comps) + return comps + return None + + def find_vs_dir(self): + """ Can use registry or location of VC to find vs dir + First try to find by registry, and if that fails find via VC dir + """ + + + if True: + vs_dir=self.find_vs_dir_by_reg() + return vs_dir + else: + return self.find_vs_dir_by_vc() + + def find_executable(self): + vs_dir = self.get_vs_dir() + if not vs_dir: + debug('find_executable(): no vs_dir (%s)'%vs_dir) + return None + executable = os.path.join(vs_dir, self.executable_path) + executable = os.path.normpath(executable) + if not os.path.isfile(executable): + debug('find_executable(): %s not on file system' % executable) + return None + return executable + + # + + def get_batch_file(self): + try: + return self._cache['batch_file'] + except KeyError: + batch_file = self.find_batch_file() + self._cache['batch_file'] = batch_file + return batch_file + + def get_executable(self): + try: + debug('get_executable using cache:%s'%self._cache['executable']) + return self._cache['executable'] + except KeyError: + executable = self.find_executable() + self._cache['executable'] = executable + debug('get_executable not in cache:%s'%executable) + return executable + + def get_vs_dir(self): + try: + return self._cache['vs_dir'] + except KeyError: + vs_dir = self.find_vs_dir() + self._cache['vs_dir'] = vs_dir + return vs_dir + + def get_supported_arch(self): + try: + return self._cache['supported_arch'] + except KeyError: + # RDEVE: for the time being use hardcoded lists + # supported_arch = self.find_supported_arch() + self._cache['supported_arch'] = self.supported_arch + return self.supported_arch + + def reset(self): + self._cache = {} + +# The list of supported Visual Studio versions we know how to detect. +# +# How to look for .bat file ? +# - VS 2008 Express (x86): +# * from registry key productdir, gives the full path to vsvarsall.bat. In +# HKEY_LOCAL_MACHINE): +# Software\Microsoft\VCEpress\9.0\Setup\VC\productdir +# * from environmnent variable VS90COMNTOOLS: the path is then ..\..\VC +# relatively to the path given by the variable. +# +# - VS 2008 Express (WoW6432: 32 bits on windows x64): +# Software\Wow6432Node\Microsoft\VCEpress\9.0\Setup\VC\productdir +# +# - VS 2005 Express (x86): +# * from registry key productdir, gives the full path to vsvarsall.bat. In +# HKEY_LOCAL_MACHINE): +# Software\Microsoft\VCEpress\8.0\Setup\VC\productdir +# * from environmnent variable VS80COMNTOOLS: the path is then ..\..\VC +# relatively to the path given by the variable. +# +# - VS 2005 Express (WoW6432: 32 bits on windows x64): does not seem to have a +# productdir ? +# +# - VS 2003 .Net (pro edition ? x86): +# * from registry key productdir. The path is then ..\Common7\Tools\ +# relatively to the key. The key is in HKEY_LOCAL_MACHINE): +# Software\Microsoft\VisualStudio\7.1\Setup\VC\productdir +# * from environmnent variable VS71COMNTOOLS: the path is the full path to +# vsvars32.bat +# +# - VS 98 (VS 6): +# * from registry key productdir. The path is then Bin +# relatively to the key. The key is in HKEY_LOCAL_MACHINE): +# Software\Microsoft\VisualStudio\6.0\Setup\VC98\productdir +# +# The first version found in the list is the one used by default if +# there are multiple versions installed. Barring good reasons to +# the contrary, this means we should list versions from most recent +# to oldest. Pro versions get listed before Express versions on the +# assumption that, by default, you'd rather use the version you paid +# good money for in preference to whatever Microsoft makes available +# for free. +# +# If you update this list, update the documentation in Tool/msvs.xml. + +SupportedVSList = [ + # Visual Studio 2010 + # TODO: find the settings, perhaps from someone with a CTP copy? + #VisualStudio('TBD', + # hkey_root=r'TBD', + # common_tools_var='TBD', + # executable_path=r'TBD', + # default_dirname='TBD', + #), + + # Visual Studio 2008 + # The batch file we look for is in the VC directory, + # so the devenv.com executable is up in ..\..\Common7\IDE. + VisualStudio('9.0', + sdk_version='6.1', + hkeys=[r'Microsoft\VisualStudio\9.0\Setup\VS\ProductDir'], + common_tools_var='VS90COMNTOOLS', + executable_path=r'Common7\IDE\devenv.com', + batch_file_path=r'Common7\Tools\vsvars32.bat', + default_dirname='Microsoft Visual Studio 9', + supported_arch=['x86', 'amd64'], + ), + + # Visual C++ 2008 Express Edition + # The batch file we look for is in the VC directory, + # so the VCExpress.exe executable is up in ..\..\Common7\IDE. + VisualStudio('9.0Exp', + vc_version='9.0', + sdk_version='6.1', + hkeys=[r'Microsoft\VCExpress\9.0\Setup\VS\ProductDir'], + common_tools_var='VS90COMNTOOLS', + executable_path=r'Common7\IDE\VCExpress.exe', + batch_file_path=r'Common7\Tools\vsvars32.bat', + default_dirname='Microsoft Visual Studio 9', + supported_arch=['x86'], + ), + + # Visual Studio 2005 + # The batch file we look for is in the VC directory, + # so the devenv.com executable is up in ..\..\Common7\IDE. + VisualStudio('8.0', + sdk_version='6.0A', + hkeys=[r'Microsoft\VisualStudio\8.0\Setup\VS\ProductDir'], + common_tools_var='VS80COMNTOOLS', + executable_path=r'Common7\IDE\devenv.com', + batch_file_path=r'Common7\Tools\vsvars32.bat', + default_dirname='Microsoft Visual Studio 8', + supported_arch=['x86', 'amd64'], + ), + + # Visual C++ 2005 Express Edition + # The batch file we look for is in the VC directory, + # so the VCExpress.exe executable is up in ..\..\Common7\IDE. + VisualStudio('8.0Exp', + vc_version='8.0', + sdk_version='6.0A', + hkeys=[r'Microsoft\VCExpress\8.0\Setup\VS\ProductDir'], + common_tools_var='VS80COMNTOOLS', + executable_path=r'Common7\IDE\VCExpress.exe', + batch_file_path=r'Common7\Tools\vsvars32.bat', + default_dirname='Microsoft Visual Studio 8', + supported_arch=['x86'], + ), + + # Visual Studio .NET 2003 + # The batch file we look for is in the Common7\Tools directory, + # so the devenv.com executable is next door in ..\IDE. + VisualStudio('7.1', + sdk_version='6.0', + hkeys=[r'Microsoft\VisualStudio\7.1\Setup\VS\ProductDir'], + common_tools_var='VS71COMNTOOLS', + executable_path=r'Common7\IDE\devenv.com', + batch_file_path=r'Common7\Tools\vsvars32.bat', + default_dirname='Microsoft Visual Studio .NET 2003', + supported_arch=['x86'], + ), + + # Visual Studio .NET + # The batch file we look for is in the Common7\Tools directory, + # so the devenv.com executable is next door in ..\IDE. + VisualStudio('7.0', + sdk_version='2003R2', + hkeys=[r'Microsoft\VisualStudio\7.0\Setup\VS\ProductDir'], + common_tools_var='VS70COMNTOOLS', + executable_path=r'IDE\devenv.com', + batch_file_path=r'Common7\Tools\vsvars32.bat', + default_dirname='Microsoft Visual Studio .NET', + supported_arch=['x86'], + ), + + # Visual Studio 6.0 + VisualStudio('6.0', + sdk_version='2003R1', + hkeys=[r'Microsoft\VisualStudio\6.0\Setup\Microsoft Visual Studio\ProductDir', + 'use_dir'], + common_tools_var='VS60COMNTOOLS', + executable_path=r'Common\MSDev98\Bin\MSDEV.COM', + batch_file_path=r'Common7\Tools\vsvars32.bat', + default_dirname='Microsoft Visual Studio', + supported_arch=['x86'], + ), +] + +SupportedVSMap = {} +for vs in SupportedVSList: + SupportedVSMap[vs.version] = vs + + +# Finding installed versions of Visual Studio isn't cheap, because it +# goes not only to the registry but also to the disk to sanity-check +# that there is, in fact, a Visual Studio directory there and that the +# registry entry isn't just stale. Find this information once, when +# requested, and cache it. + +InstalledVSList = None +InstalledVSMap = None + +def get_installed_visual_studios(): + global InstalledVSList + global InstalledVSMap + if InstalledVSList is None: + InstalledVSList = [] + InstalledVSMap = {} + for vs in SupportedVSList: + debug('trying to find VS %s' % vs.version) + if vs.get_executable(): + debug('found VS %s' % vs.version) + InstalledVSList.append(vs) + InstalledVSMap[vs.version] = vs + return InstalledVSList + +def reset_installed_visual_studios(): + global InstalledVSList + global InstalledVSMap + InstalledVSList = None + InstalledVSMap = None + for vs in SupportedVSList: + vs.reset() + + # Need to clear installed VC's as well as they are used in finding + # installed VS's + SCons.Tool.MSCommon.vc.reset_installed_vcs() + + +# We may be asked to update multiple construction environments with +# SDK information. When doing this, we check on-disk for whether +# the SDK has 'mfc' and 'atl' subdirectories. Since going to disk +# is expensive, cache results by directory. + +#SDKEnvironmentUpdates = {} +# +#def set_sdk_by_directory(env, sdk_dir): +# global SDKEnvironmentUpdates +# try: +# env_tuple_list = SDKEnvironmentUpdates[sdk_dir] +# except KeyError: +# env_tuple_list = [] +# SDKEnvironmentUpdates[sdk_dir] = env_tuple_list +# +# include_path = os.path.join(sdk_dir, 'include') +# mfc_path = os.path.join(include_path, 'mfc') +# atl_path = os.path.join(include_path, 'atl') +# +# if os.path.exists(mfc_path): +# env_tuple_list.append(('INCLUDE', mfc_path)) +# if os.path.exists(atl_path): +# env_tuple_list.append(('INCLUDE', atl_path)) +# env_tuple_list.append(('INCLUDE', include_path)) +# +# env_tuple_list.append(('LIB', os.path.join(sdk_dir, 'lib'))) +# env_tuple_list.append(('LIBPATH', os.path.join(sdk_dir, 'lib'))) +# env_tuple_list.append(('PATH', os.path.join(sdk_dir, 'bin'))) +# +# for variable, directory in env_tuple_list: +# env.PrependENVPath(variable, directory) + +def msvs_exists(): + return (len(get_installed_visual_studios()) > 0) + +def get_vs_by_version(msvs): + global InstalledVSMap + global SupportedVSMap + + if not SupportedVSMap.has_key(msvs): + msg = "Visual Studio version %s is not supported" % repr(msvs) + raise SCons.Errors.UserError, msg + get_installed_visual_studios() + vs = InstalledVSMap.get(msvs) + debug('InstalledVSMap:%s'%InstalledVSMap) + # Some check like this would let us provide a useful error message + # if they try to set a Visual Studio version that's not installed. + # However, we also want to be able to run tests (like the unit + # tests) on systems that don't, or won't ever, have it installed. + # It might be worth resurrecting this, with some configurable + # setting that the tests can use to bypass the check. + #if not vs: + # msg = "Visual Studio version %s is not installed" % repr(msvs) + # raise SCons.Errors.UserError, msg + return vs + +def get_default_version(env): + """Returns the default version string to use for MSVS. + + If no version was requested by the user through the MSVS environment + variable, query all the available the visual studios through + query_versions, and take the highest one. + + Return + ------ + version: str + the default version. + """ + if not env.has_key('MSVS') or not SCons.Util.is_Dict(env['MSVS']): + # TODO(1.5): + #versions = [vs.version for vs in get_installed_visual_studios()] + versions = map(lambda vs: vs.version, get_installed_visual_studios()) + env['MSVS'] = {'VERSIONS' : versions} + else: + versions = env['MSVS'].get('VERSIONS', []) + + if not env.has_key('MSVS_VERSION'): + if versions: + env['MSVS_VERSION'] = versions[0] #use highest version by default + else: + env['MSVS_VERSION'] = SupportedVSList[0].version + + env['MSVS']['VERSION'] = env['MSVS_VERSION'] + + return env['MSVS_VERSION'] + +def get_default_arch(env): + """Return the default arch to use for MSVS + + if no version was requested by the user through the MSVS_ARCH environment + variable, select x86 + + Return + ------ + arch: str + """ + arch = env.get('MSVS_ARCH', 'x86') + + msvs = InstalledVSMap.get(env['MSVS_VERSION']) + + if not msvs: + arch = 'x86' + elif not arch in msvs.get_supported_arch(): + fmt = "Visual Studio version %s does not support architecture %s" + raise SCons.Errors.UserError, fmt % (env['MSVS_VERSION'], arch) + + return arch + +def merge_default_version(env): + version = get_default_version(env) + arch = get_default_arch(env) + +def msvs_setup_env(env): + batfilename = msvs.get_batch_file() + msvs = get_vs_by_version(version) + if msvs is None: + return + + # XXX: I think this is broken. This will silently set a bogus tool instead + # of failing, but there is no other way with the current scons tool + # framework + if batfilename is not None: + + vars = ('LIB', 'LIBPATH', 'PATH', 'INCLUDE') + + msvs_list = get_installed_visual_studios() + # TODO(1.5): + #vscommonvarnames = [ vs.common_tools_var for vs in msvs_list ] + vscommonvarnames = map(lambda vs: vs.common_tools_var, msvs_list) + nenv = normalize_env(env['ENV'], vscommonvarnames + ['COMSPEC']) + output = get_output(batfilename, arch, env=nenv) + vars = parse_output(output, vars) + + for k, v in vars.items(): + env.PrependENVPath(k, v, delete_existing=1) + +def query_versions(): + """Query the system to get available versions of VS. A version is + considered when a batfile is found.""" + msvs_list = get_installed_visual_studios() + # TODO(1.5) + #versions = [ msvs.version for msvs in msvs_list ] + versions = map(lambda msvs: msvs.version, msvs_list) + return versions + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/Perforce.py b/src/engine/SCons/Tool/Perforce.py new file mode 100644 index 0000000..441b2cb --- /dev/null +++ b/src/engine/SCons/Tool/Perforce.py @@ -0,0 +1,104 @@ +"""SCons.Tool.Perforce.py + +Tool-specific initialization for Perforce Source Code Management system. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/Perforce.py 4577 2009/12/27 19:44:43 scons" + +import os + +import SCons.Action +import SCons.Builder +import SCons.Node.FS +import SCons.Util + +# This function should maybe be moved to SCons.Util? +from SCons.Tool.PharLapCommon import addPathIfNotExists + + + +# Variables that we want to import from the base OS environment. +_import_env = [ 'P4PORT', 'P4CLIENT', 'P4USER', 'USER', 'USERNAME', 'P4PASSWD', + 'P4CHARSET', 'P4LANGUAGE', 'SystemRoot' ] + +PerforceAction = SCons.Action.Action('$P4COM', '$P4COMSTR') + +def generate(env): + """Add a Builder factory function and construction variables for + Perforce to an Environment.""" + + def PerforceFactory(env=env): + """ """ + return SCons.Builder.Builder(action = PerforceAction, env = env) + + #setattr(env, 'Perforce', PerforceFactory) + env.Perforce = PerforceFactory + + env['P4'] = 'p4' + env['P4FLAGS'] = SCons.Util.CLVar('') + env['P4COM'] = '$P4 $P4FLAGS sync $TARGET' + try: + environ = env['ENV'] + except KeyError: + environ = {} + env['ENV'] = environ + + # Perforce seems to use the PWD environment variable rather than + # calling getcwd() for itself, which is odd. If no PWD variable + # is present, p4 WILL call getcwd, but this seems to cause problems + # with good ol' Windows's tilde-mangling for long file names. + environ['PWD'] = env.Dir('#').get_abspath() + + for var in _import_env: + v = os.environ.get(var) + if v: + environ[var] = v + + if SCons.Util.can_read_reg: + # If we can read the registry, add the path to Perforce to our environment. + try: + k=SCons.Util.RegOpenKeyEx(SCons.Util.hkey_mod.HKEY_LOCAL_MACHINE, + 'Software\\Perforce\\environment') + val, tok = SCons.Util.RegQueryValueEx(k, 'P4INSTROOT') + addPathIfNotExists(environ, 'PATH', val) + except SCons.Util.RegError: + # Can't detect where Perforce is, hope the user has it set in the + # PATH. + pass + +def exists(env): + return env.Detect('p4') + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/Perforce.xml b/src/engine/SCons/Tool/Perforce.xml new file mode 100644 index 0000000..7bfcdc0 --- /dev/null +++ b/src/engine/SCons/Tool/Perforce.xml @@ -0,0 +1,47 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="Perforce"> +<summary> +Sets construction variables for interacting with the +Perforce source code management system. +</summary> +<sets> +P4 +P4FLAGS +P4COM +</sets> +<uses> +P4COMSTR +</uses> +</tool> + +<cvar name="P4"> +<summary> +The Perforce executable. +</summary> +</cvar> + +<cvar name="P4COM"> +<summary> +The command line used to +fetch source files from Perforce. +</summary> +</cvar> + +<cvar name="P4COMSTR"> +<summary> +The string displayed when +fetching a source file from Perforce. +If this is not set, then &cv-link-P4COM; (the command line) is displayed. +</summary> +</cvar> + +<cvar name="P4FLAGS"> +<summary> +General options that are passed to Perforce. +</summary> +</cvar> diff --git a/src/engine/SCons/Tool/PharLapCommon.py b/src/engine/SCons/Tool/PharLapCommon.py new file mode 100644 index 0000000..dd5ddd1 --- /dev/null +++ b/src/engine/SCons/Tool/PharLapCommon.py @@ -0,0 +1,138 @@ +"""SCons.Tool.PharLapCommon + +This module contains common code used by all Tools for the +Phar Lap ETS tool chain. Right now, this is linkloc and +386asm. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/PharLapCommon.py 4577 2009/12/27 19:44:43 scons" + +import os +import os.path +import SCons.Errors +import SCons.Util +import re +import string + +def getPharLapPath(): + """Reads the registry to find the installed path of the Phar Lap ETS + development kit. + + Raises UserError if no installed version of Phar Lap can + be found.""" + + if not SCons.Util.can_read_reg: + raise SCons.Errors.InternalError, "No Windows registry module was found" + try: + k=SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_LOCAL_MACHINE, + 'SOFTWARE\\Pharlap\\ETS') + val, type = SCons.Util.RegQueryValueEx(k, 'BaseDir') + + # The following is a hack...there is (not surprisingly) + # an odd issue in the Phar Lap plug in that inserts + # a bunch of junk data after the phar lap path in the + # registry. We must trim it. + idx=val.find('\0') + if idx >= 0: + val = val[:idx] + + return os.path.normpath(val) + except SCons.Util.RegError: + raise SCons.Errors.UserError, "Cannot find Phar Lap ETS path in the registry. Is it installed properly?" + +REGEX_ETS_VER = re.compile(r'#define\s+ETS_VER\s+([0-9]+)') + +def getPharLapVersion(): + """Returns the version of the installed ETS Tool Suite as a + decimal number. This version comes from the ETS_VER #define in + the embkern.h header. For example, '#define ETS_VER 1010' (which + is what Phar Lap 10.1 defines) would cause this method to return + 1010. Phar Lap 9.1 does not have such a #define, but this method + will return 910 as a default. + + Raises UserError if no installed version of Phar Lap can + be found.""" + + include_path = os.path.join(getPharLapPath(), os.path.normpath("include/embkern.h")) + if not os.path.exists(include_path): + raise SCons.Errors.UserError, "Cannot find embkern.h in ETS include directory.\nIs Phar Lap ETS installed properly?" + mo = REGEX_ETS_VER.search(open(include_path, 'r').read()) + if mo: + return int(mo.group(1)) + # Default return for Phar Lap 9.1 + return 910 + +def addPathIfNotExists(env_dict, key, path, sep=os.pathsep): + """This function will take 'key' out of the dictionary + 'env_dict', then add the path 'path' to that key if it is not + already there. This treats the value of env_dict[key] as if it + has a similar format to the PATH variable...a list of paths + separated by tokens. The 'path' will get added to the list if it + is not already there.""" + try: + is_list = 1 + paths = env_dict[key] + if not SCons.Util.is_List(env_dict[key]): + paths = string.split(paths, sep) + is_list = 0 + if not os.path.normcase(path) in map(os.path.normcase, paths): + paths = [ path ] + paths + if is_list: + env_dict[key] = paths + else: + env_dict[key] = string.join(paths, sep) + except KeyError: + env_dict[key] = path + +def addPharLapPaths(env): + """This function adds the path to the Phar Lap binaries, includes, + and libraries, if they are not already there.""" + ph_path = getPharLapPath() + + try: + env_dict = env['ENV'] + except KeyError: + env_dict = {} + env['ENV'] = env_dict + addPathIfNotExists(env_dict, 'PATH', + os.path.join(ph_path, 'bin')) + addPathIfNotExists(env_dict, 'INCLUDE', + os.path.join(ph_path, 'include')) + addPathIfNotExists(env_dict, 'LIB', + os.path.join(ph_path, 'lib')) + addPathIfNotExists(env_dict, 'LIB', + os.path.join(ph_path, os.path.normpath('lib/vclib'))) + + env['PHARLAP_PATH'] = getPharLapPath() + env['PHARLAP_VERSION'] = str(getPharLapVersion()) + + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/PharLapCommonTests.py b/src/engine/SCons/Tool/PharLapCommonTests.py new file mode 100644 index 0000000..99e7524 --- /dev/null +++ b/src/engine/SCons/Tool/PharLapCommonTests.py @@ -0,0 +1,68 @@ +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/PharLapCommonTests.py 4577 2009/12/27 19:44:43 scons" + +import unittest +import os.path +import os +import sys + +import SCons.Errors +from SCons.Tool.PharLapCommon import * + +class PharLapCommonTestCase(unittest.TestCase): + def test_addPathIfNotExists(self): + """Test the addPathIfNotExists() function""" + env_dict = { 'FOO' : os.path.normpath('/foo/bar') + os.pathsep + \ + os.path.normpath('/baz/blat'), + 'BAR' : os.path.normpath('/foo/bar') + os.pathsep + \ + os.path.normpath('/baz/blat'), + 'BLAT' : [ os.path.normpath('/foo/bar'), + os.path.normpath('/baz/blat') ] } + addPathIfNotExists(env_dict, 'FOO', os.path.normpath('/foo/bar')) + addPathIfNotExists(env_dict, 'BAR', os.path.normpath('/bar/foo')) + addPathIfNotExists(env_dict, 'BAZ', os.path.normpath('/foo/baz')) + addPathIfNotExists(env_dict, 'BLAT', os.path.normpath('/baz/blat')) + addPathIfNotExists(env_dict, 'BLAT', os.path.normpath('/baz/foo')) + + assert env_dict['FOO'] == os.path.normpath('/foo/bar') + os.pathsep + \ + os.path.normpath('/baz/blat'), env_dict['FOO'] + assert env_dict['BAR'] == os.path.normpath('/bar/foo') + os.pathsep + \ + os.path.normpath('/foo/bar') + os.pathsep + \ + os.path.normpath('/baz/blat'), env_dict['BAR'] + assert env_dict['BAZ'] == os.path.normpath('/foo/baz'), env_dict['BAZ'] + assert env_dict['BLAT'] == [ os.path.normpath('/baz/foo'), + os.path.normpath('/foo/bar'), + os.path.normpath('/baz/blat') ], env_dict['BLAT' ] + +if __name__ == "__main__": + suite = unittest.makeSuite(PharLapCommonTestCase, 'test_') + if not unittest.TextTestRunner().run(suite).wasSuccessful(): + sys.exit(1) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/RCS.py b/src/engine/SCons/Tool/RCS.py new file mode 100644 index 0000000..7605f73 --- /dev/null +++ b/src/engine/SCons/Tool/RCS.py @@ -0,0 +1,64 @@ +"""SCons.Tool.RCS.py + +Tool-specific initialization for RCS. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/RCS.py 4577 2009/12/27 19:44:43 scons" + +import SCons.Action +import SCons.Builder +import SCons.Util + +def generate(env): + """Add a Builder factory function and construction variables for + RCS to an Environment.""" + + def RCSFactory(env=env): + """ """ + act = SCons.Action.Action('$RCS_COCOM', '$RCS_COCOMSTR') + return SCons.Builder.Builder(action = act, env = env) + + #setattr(env, 'RCS', RCSFactory) + env.RCS = RCSFactory + + env['RCS'] = 'rcs' + env['RCS_CO'] = 'co' + env['RCS_COFLAGS'] = SCons.Util.CLVar('') + env['RCS_COCOM'] = '$RCS_CO $RCS_COFLAGS $TARGET' + +def exists(env): + return env.Detect('rcs') + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/RCS.xml b/src/engine/SCons/Tool/RCS.xml new file mode 100644 index 0000000..52d8165 --- /dev/null +++ b/src/engine/SCons/Tool/RCS.xml @@ -0,0 +1,61 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="RCS"> +<summary> +Sets construction variables for the interaction +with the Revision Control System. +</summary> +<sets> +RCS +RCS_CO +RCS_COFLAGS +RCS_COCOM +</sets> +<uses> +RCS_COCOMSTR +</uses> +</tool> + +<cvar name="RCS"> +<summary> +The RCS executable. +Note that this variable is not actually used +for the command to fetch source files from RCS; +see the +&cv-link-RCS_CO; +construction variable, below. +</summary> +</cvar> + +<cvar name="RCS_CO"> +<summary> +The RCS "checkout" executable, +used to fetch source files from RCS. +</summary> +</cvar> + +<cvar name="RCS_COCOM"> +<summary> +The command line used to +fetch (checkout) source files from RCS. +</summary> +</cvar> + +<cvar name="RCS_COCOMSTR"> +<summary> +The string displayed when fetching +a source file from RCS. +If this is not set, then &cv-link-RCS_COCOM; +(the command line) is displayed. +</summary> +</cvar> + +<cvar name="RCS_COFLAGS"> +<summary> +Options that are passed to the &cv-link-RCS_CO; command. +</summary> +</cvar> diff --git a/src/engine/SCons/Tool/SCCS.py b/src/engine/SCons/Tool/SCCS.py new file mode 100644 index 0000000..acbd9aa --- /dev/null +++ b/src/engine/SCons/Tool/SCCS.py @@ -0,0 +1,64 @@ +"""SCons.Tool.SCCS.py + +Tool-specific initialization for SCCS. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/SCCS.py 4577 2009/12/27 19:44:43 scons" + +import SCons.Action +import SCons.Builder +import SCons.Util + +def generate(env): + """Add a Builder factory function and construction variables for + SCCS to an Environment.""" + + def SCCSFactory(env=env): + """ """ + act = SCons.Action.Action('$SCCSCOM', '$SCCSCOMSTR') + return SCons.Builder.Builder(action = act, env = env) + + #setattr(env, 'SCCS', SCCSFactory) + env.SCCS = SCCSFactory + + env['SCCS'] = 'sccs' + env['SCCSFLAGS'] = SCons.Util.CLVar('') + env['SCCSGETFLAGS'] = SCons.Util.CLVar('') + env['SCCSCOM'] = '$SCCS $SCCSFLAGS get $SCCSGETFLAGS $TARGET' + +def exists(env): + return env.Detect('sccs') + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/SCCS.xml b/src/engine/SCons/Tool/SCCS.xml new file mode 100644 index 0000000..83ccec7 --- /dev/null +++ b/src/engine/SCons/Tool/SCCS.xml @@ -0,0 +1,58 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="SCCS"> +<summary> +Sets construction variables for interacting with the +Source Code Control System. +</summary> +<sets> +SCCS +SCCSFLAGS +SCCSGETFLAGS +SCCSCOM +</sets> +<uses> +SCCSCOMSTR +</uses> +</tool> + +<cvar name="SCCS"> +<summary> +The SCCS executable. +</summary> +</cvar> + +<cvar name="SCCSCOM"> +<summary> +The command line used to +fetch source files from SCCS. +</summary> +</cvar> + +<cvar name="SCCSCOMSTR"> +<summary> +The string displayed when fetching +a source file from a CVS repository. +If this is not set, then &cv-link-SCCSCOM; +(the command line) is displayed. +</summary> +</cvar> + +<cvar name="SCCSFLAGS"> +<summary> +General options that are passed to SCCS. +</summary> +</cvar> + +<cvar name="SCCSGETFLAGS"> +<summary> +Options that are passed specifically to the SCCS "get" subcommand. +This can be set, for example, to +<option>-e</option> +to check out editable files from SCCS. +</summary> +</cvar> diff --git a/src/engine/SCons/Tool/Subversion.py b/src/engine/SCons/Tool/Subversion.py new file mode 100644 index 0000000..55906bb --- /dev/null +++ b/src/engine/SCons/Tool/Subversion.py @@ -0,0 +1,71 @@ +"""SCons.Tool.Subversion.py + +Tool-specific initialization for Subversion. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/Subversion.py 4577 2009/12/27 19:44:43 scons" + +import os.path + +import SCons.Action +import SCons.Builder +import SCons.Util + +def generate(env): + """Add a Builder factory function and construction variables for + Subversion to an Environment.""" + + def SubversionFactory(repos, module='', env=env): + """ """ + # fail if repos is not an absolute path name? + if module != '': + module = os.path.join(module, '') + act = SCons.Action.Action('$SVNCOM', '$SVNCOMSTR') + return SCons.Builder.Builder(action = act, + env = env, + SVNREPOSITORY = repos, + SVNMODULE = module) + + #setattr(env, 'Subversion', SubversionFactory) + env.Subversion = SubversionFactory + + env['SVN'] = 'svn' + env['SVNFLAGS'] = SCons.Util.CLVar('') + env['SVNCOM'] = '$SVN $SVNFLAGS cat $SVNREPOSITORY/$SVNMODULE$TARGET > $TARGET' + +def exists(env): + return env.Detect('svn') + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/Subversion.xml b/src/engine/SCons/Tool/Subversion.xml new file mode 100644 index 0000000..40ca399 --- /dev/null +++ b/src/engine/SCons/Tool/Subversion.xml @@ -0,0 +1,47 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<!-- +<tool name="Subversion"> +<summary> +Sets construction variables for interacting with Subversion. +</summary> +<sets> +SVN +SVNFLAGS +SVNCOM +</sets> +<uses> +SVNCOMSTR +</uses> +</tool> +--> + +<!-- +<cvar name="SVN"> +<summary> +The Subversion executable (usually named +<command>svn</command>). +</summary> +</cvar> +--> + +<!-- +<cvar name="SVNCOM"> +<summary> +The command line used to +fetch source files from a Subversion repository. +</summary> +</cvar> +--> + +<!-- +<cvar name="SVNFLAGS"> +<summary> +General options that are passed to Subversion. +</summary> +</cvar> +--> diff --git a/src/engine/SCons/Tool/ToolTests.py b/src/engine/SCons/Tool/ToolTests.py new file mode 100644 index 0000000..0b6463e --- /dev/null +++ b/src/engine/SCons/Tool/ToolTests.py @@ -0,0 +1,84 @@ +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/ToolTests.py 4577 2009/12/27 19:44:43 scons" + +import sys +import unittest + +import SCons.Errors +import SCons.Tool + +class ToolTestCase(unittest.TestCase): + def test_Tool(self): + """Test the Tool() function""" + class Environment: + def __init__(self): + self.dict = {} + def Detect(self, progs): + if not SCons.Util.is_List(progs): + progs = [ progs ] + return progs[0] + def Append(self, **kw): + self.dict.update(kw) + def __getitem__(self, key): + return self.dict[key] + def __setitem__(self, key, val): + self.dict[key] = val + def has_key(self, key): + return self.dict.has_key(key) + env = Environment() + env['BUILDERS'] = {} + env['ENV'] = {} + env['PLATFORM'] = 'test' + t = SCons.Tool.Tool('g++') + t(env) + assert (env['CXX'] == 'c++' or env['CXX'] == 'g++'), env['CXX'] + assert env['INCPREFIX'] == '-I', env['INCPREFIX'] + assert env['TOOLS'] == ['g++'], env['TOOLS'] + + try: + SCons.Tool.Tool() + except TypeError: + pass + else: + raise + + try: + p = SCons.Tool.Tool('_does_not_exist_') + except SCons.Errors.EnvironmentError: + pass + else: + raise + + +if __name__ == "__main__": + suite = unittest.makeSuite(ToolTestCase, 'test_') + if not unittest.TextTestRunner().run(suite).wasSuccessful(): + sys.exit(1) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py new file mode 100644 index 0000000..a0eb2e8 --- /dev/null +++ b/src/engine/SCons/Tool/__init__.py @@ -0,0 +1,675 @@ +"""SCons.Tool + +SCons tool selection. + +This looks for modules that define a callable object that can modify +a construction environment as appropriate for a given tool (or tool +chain). + +Note that because this subsystem just *selects* a callable that can +modify a construction environment, it's possible for people to define +their own "tool specification" in an arbitrary callable function. No +one needs to use or tie in to this subsystem in order to roll their own +tool definition. +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/__init__.py 4577 2009/12/27 19:44:43 scons" + +import imp +import sys + +import SCons.Builder +import SCons.Errors +import SCons.Node.FS +import SCons.Scanner +import SCons.Scanner.C +import SCons.Scanner.D +import SCons.Scanner.LaTeX +import SCons.Scanner.Prog + +DefaultToolpath=[] + +CScanner = SCons.Scanner.C.CScanner() +DScanner = SCons.Scanner.D.DScanner() +LaTeXScanner = SCons.Scanner.LaTeX.LaTeXScanner() +PDFLaTeXScanner = SCons.Scanner.LaTeX.PDFLaTeXScanner() +ProgramScanner = SCons.Scanner.Prog.ProgramScanner() +SourceFileScanner = SCons.Scanner.Base({}, name='SourceFileScanner') + +CSuffixes = [".c", ".C", ".cxx", ".cpp", ".c++", ".cc", + ".h", ".H", ".hxx", ".hpp", ".hh", + ".F", ".fpp", ".FPP", + ".m", ".mm", + ".S", ".spp", ".SPP"] + +DSuffixes = ['.d'] + +IDLSuffixes = [".idl", ".IDL"] + +LaTeXSuffixes = [".tex", ".ltx", ".latex"] + +for suffix in CSuffixes: + SourceFileScanner.add_scanner(suffix, CScanner) + +for suffix in DSuffixes: + SourceFileScanner.add_scanner(suffix, DScanner) + +# FIXME: what should be done here? Two scanners scan the same extensions, +# but look for different files, e.g., "picture.eps" vs. "picture.pdf". +# The builders for DVI and PDF explicitly reference their scanners +# I think that means this is not needed??? +for suffix in LaTeXSuffixes: + SourceFileScanner.add_scanner(suffix, LaTeXScanner) + SourceFileScanner.add_scanner(suffix, PDFLaTeXScanner) + +class Tool: + def __init__(self, name, toolpath=[], **kw): + self.name = name + self.toolpath = toolpath + DefaultToolpath + # remember these so we can merge them into the call + self.init_kw = kw + + module = self._tool_module() + self.generate = module.generate + self.exists = module.exists + if hasattr(module, 'options'): + self.options = module.options + + def _tool_module(self): + # TODO: Interchange zipimport with normal initilization for better error reporting + oldpythonpath = sys.path + sys.path = self.toolpath + sys.path + + try: + try: + file, path, desc = imp.find_module(self.name, self.toolpath) + try: + return imp.load_module(self.name, file, path, desc) + finally: + if file: + file.close() + except ImportError, e: + if str(e)!="No module named %s"%self.name: + raise SCons.Errors.EnvironmentError, e + try: + import zipimport + except ImportError: + pass + else: + for aPath in self.toolpath: + try: + importer = zipimport.zipimporter(aPath) + return importer.load_module(self.name) + except ImportError, e: + pass + finally: + sys.path = oldpythonpath + + full_name = 'SCons.Tool.' + self.name + try: + return sys.modules[full_name] + except KeyError: + try: + smpath = sys.modules['SCons.Tool'].__path__ + try: + file, path, desc = imp.find_module(self.name, smpath) + module = imp.load_module(full_name, file, path, desc) + setattr(SCons.Tool, self.name, module) + if file: + file.close() + return module + except ImportError, e: + if str(e)!="No module named %s"%self.name: + raise SCons.Errors.EnvironmentError, e + try: + import zipimport + importer = zipimport.zipimporter( sys.modules['SCons.Tool'].__path__[0] ) + module = importer.load_module(full_name) + setattr(SCons.Tool, self.name, module) + return module + except ImportError, e: + m = "No tool named '%s': %s" % (self.name, e) + raise SCons.Errors.EnvironmentError, m + except ImportError, e: + m = "No tool named '%s': %s" % (self.name, e) + raise SCons.Errors.EnvironmentError, m + + def __call__(self, env, *args, **kw): + if self.init_kw is not None: + # Merge call kws into init kws; + # but don't bash self.init_kw. + if kw is not None: + call_kw = kw + kw = self.init_kw.copy() + kw.update(call_kw) + else: + kw = self.init_kw + env.Append(TOOLS = [ self.name ]) + if hasattr(self, 'options'): + import SCons.Variables + if not env.has_key('options'): + from SCons.Script import ARGUMENTS + env['options']=SCons.Variables.Variables(args=ARGUMENTS) + opts=env['options'] + + self.options(opts) + opts.Update(env) + + apply(self.generate, ( env, ) + args, kw) + + def __str__(self): + return self.name + +########################################################################## +# Create common executable program / library / object builders + +def createProgBuilder(env): + """This is a utility function that creates the Program + Builder in an Environment if it is not there already. + + If it is already there, we return the existing one. + """ + + try: + program = env['BUILDERS']['Program'] + except KeyError: + import SCons.Defaults + program = SCons.Builder.Builder(action = SCons.Defaults.LinkAction, + emitter = '$PROGEMITTER', + prefix = '$PROGPREFIX', + suffix = '$PROGSUFFIX', + src_suffix = '$OBJSUFFIX', + src_builder = 'Object', + target_scanner = ProgramScanner) + env['BUILDERS']['Program'] = program + + return program + +def createStaticLibBuilder(env): + """This is a utility function that creates the StaticLibrary + Builder in an Environment if it is not there already. + + If it is already there, we return the existing one. + """ + + try: + static_lib = env['BUILDERS']['StaticLibrary'] + except KeyError: + action_list = [ SCons.Action.Action("$ARCOM", "$ARCOMSTR") ] + if env.Detect('ranlib'): + ranlib_action = SCons.Action.Action("$RANLIBCOM", "$RANLIBCOMSTR") + action_list.append(ranlib_action) + + static_lib = SCons.Builder.Builder(action = action_list, + emitter = '$LIBEMITTER', + prefix = '$LIBPREFIX', + suffix = '$LIBSUFFIX', + src_suffix = '$OBJSUFFIX', + src_builder = 'StaticObject') + env['BUILDERS']['StaticLibrary'] = static_lib + env['BUILDERS']['Library'] = static_lib + + return static_lib + +def createSharedLibBuilder(env): + """This is a utility function that creates the SharedLibrary + Builder in an Environment if it is not there already. + + If it is already there, we return the existing one. + """ + + try: + shared_lib = env['BUILDERS']['SharedLibrary'] + except KeyError: + import SCons.Defaults + action_list = [ SCons.Defaults.SharedCheck, + SCons.Defaults.ShLinkAction ] + shared_lib = SCons.Builder.Builder(action = action_list, + emitter = "$SHLIBEMITTER", + prefix = '$SHLIBPREFIX', + suffix = '$SHLIBSUFFIX', + target_scanner = ProgramScanner, + src_suffix = '$SHOBJSUFFIX', + src_builder = 'SharedObject') + env['BUILDERS']['SharedLibrary'] = shared_lib + + return shared_lib + +def createLoadableModuleBuilder(env): + """This is a utility function that creates the LoadableModule + Builder in an Environment if it is not there already. + + If it is already there, we return the existing one. + """ + + try: + ld_module = env['BUILDERS']['LoadableModule'] + except KeyError: + import SCons.Defaults + action_list = [ SCons.Defaults.SharedCheck, + SCons.Defaults.LdModuleLinkAction ] + ld_module = SCons.Builder.Builder(action = action_list, + emitter = "$LDMODULEEMITTER", + prefix = '$LDMODULEPREFIX', + suffix = '$LDMODULESUFFIX', + target_scanner = ProgramScanner, + src_suffix = '$SHOBJSUFFIX', + src_builder = 'SharedObject') + env['BUILDERS']['LoadableModule'] = ld_module + + return ld_module + +def createObjBuilders(env): + """This is a utility function that creates the StaticObject + and SharedObject Builders in an Environment if they + are not there already. + + If they are there already, we return the existing ones. + + This is a separate function because soooo many Tools + use this functionality. + + The return is a 2-tuple of (StaticObject, SharedObject) + """ + + + try: + static_obj = env['BUILDERS']['StaticObject'] + except KeyError: + static_obj = SCons.Builder.Builder(action = {}, + emitter = {}, + prefix = '$OBJPREFIX', + suffix = '$OBJSUFFIX', + src_builder = ['CFile', 'CXXFile'], + source_scanner = SourceFileScanner, + single_source = 1) + env['BUILDERS']['StaticObject'] = static_obj + env['BUILDERS']['Object'] = static_obj + + try: + shared_obj = env['BUILDERS']['SharedObject'] + except KeyError: + shared_obj = SCons.Builder.Builder(action = {}, + emitter = {}, + prefix = '$SHOBJPREFIX', + suffix = '$SHOBJSUFFIX', + src_builder = ['CFile', 'CXXFile'], + source_scanner = SourceFileScanner, + single_source = 1) + env['BUILDERS']['SharedObject'] = shared_obj + + return (static_obj, shared_obj) + +def createCFileBuilders(env): + """This is a utility function that creates the CFile/CXXFile + Builders in an Environment if they + are not there already. + + If they are there already, we return the existing ones. + + This is a separate function because soooo many Tools + use this functionality. + + The return is a 2-tuple of (CFile, CXXFile) + """ + + try: + c_file = env['BUILDERS']['CFile'] + except KeyError: + c_file = SCons.Builder.Builder(action = {}, + emitter = {}, + suffix = {None:'$CFILESUFFIX'}) + env['BUILDERS']['CFile'] = c_file + + env.SetDefault(CFILESUFFIX = '.c') + + try: + cxx_file = env['BUILDERS']['CXXFile'] + except KeyError: + cxx_file = SCons.Builder.Builder(action = {}, + emitter = {}, + suffix = {None:'$CXXFILESUFFIX'}) + env['BUILDERS']['CXXFile'] = cxx_file + env.SetDefault(CXXFILESUFFIX = '.cc') + + return (c_file, cxx_file) + +########################################################################## +# Create common Java builders + +def CreateJarBuilder(env): + try: + java_jar = env['BUILDERS']['Jar'] + except KeyError: + fs = SCons.Node.FS.get_default_fs() + jar_com = SCons.Action.Action('$JARCOM', '$JARCOMSTR') + java_jar = SCons.Builder.Builder(action = jar_com, + suffix = '$JARSUFFIX', + src_suffix = '$JAVACLASSSUFIX', + src_builder = 'JavaClassFile', + source_factory = fs.Entry) + env['BUILDERS']['Jar'] = java_jar + return java_jar + +def CreateJavaHBuilder(env): + try: + java_javah = env['BUILDERS']['JavaH'] + except KeyError: + fs = SCons.Node.FS.get_default_fs() + java_javah_com = SCons.Action.Action('$JAVAHCOM', '$JAVAHCOMSTR') + java_javah = SCons.Builder.Builder(action = java_javah_com, + src_suffix = '$JAVACLASSSUFFIX', + target_factory = fs.Entry, + source_factory = fs.File, + src_builder = 'JavaClassFile') + env['BUILDERS']['JavaH'] = java_javah + return java_javah + +def CreateJavaClassFileBuilder(env): + try: + java_class_file = env['BUILDERS']['JavaClassFile'] + except KeyError: + fs = SCons.Node.FS.get_default_fs() + javac_com = SCons.Action.Action('$JAVACCOM', '$JAVACCOMSTR') + java_class_file = SCons.Builder.Builder(action = javac_com, + emitter = {}, + #suffix = '$JAVACLASSSUFFIX', + src_suffix = '$JAVASUFFIX', + src_builder = ['JavaFile'], + target_factory = fs.Entry, + source_factory = fs.File) + env['BUILDERS']['JavaClassFile'] = java_class_file + return java_class_file + +def CreateJavaClassDirBuilder(env): + try: + java_class_dir = env['BUILDERS']['JavaClassDir'] + except KeyError: + fs = SCons.Node.FS.get_default_fs() + javac_com = SCons.Action.Action('$JAVACCOM', '$JAVACCOMSTR') + java_class_dir = SCons.Builder.Builder(action = javac_com, + emitter = {}, + target_factory = fs.Dir, + source_factory = fs.Dir) + env['BUILDERS']['JavaClassDir'] = java_class_dir + return java_class_dir + +def CreateJavaFileBuilder(env): + try: + java_file = env['BUILDERS']['JavaFile'] + except KeyError: + java_file = SCons.Builder.Builder(action = {}, + emitter = {}, + suffix = {None:'$JAVASUFFIX'}) + env['BUILDERS']['JavaFile'] = java_file + env['JAVASUFFIX'] = '.java' + return java_file + +class ToolInitializerMethod: + """ + This is added to a construction environment in place of a + method(s) normally called for a Builder (env.Object, env.StaticObject, + etc.). When called, it has its associated ToolInitializer + object search the specified list of tools and apply the first + one that exists to the construction environment. It then calls + whatever builder was (presumably) added to the construction + environment in place of this particular instance. + """ + def __init__(self, name, initializer): + """ + Note: we store the tool name as __name__ so it can be used by + the class that attaches this to a construction environment. + """ + self.__name__ = name + self.initializer = initializer + + def get_builder(self, env): + """ + Returns the appropriate real Builder for this method name + after having the associated ToolInitializer object apply + the appropriate Tool module. + """ + builder = getattr(env, self.__name__) + + self.initializer.apply_tools(env) + + builder = getattr(env, self.__name__) + if builder is self: + # There was no Builder added, which means no valid Tool + # for this name was found (or possibly there's a mismatch + # between the name we were called by and the Builder name + # added by the Tool module). + return None + + self.initializer.remove_methods(env) + + return builder + + def __call__(self, env, *args, **kw): + """ + """ + builder = self.get_builder(env) + if builder is None: + return [], [] + return apply(builder, args, kw) + +class ToolInitializer: + """ + A class for delayed initialization of Tools modules. + + Instances of this class associate a list of Tool modules with + a list of Builder method names that will be added by those Tool + modules. As part of instantiating this object for a particular + construction environment, we also add the appropriate + ToolInitializerMethod objects for the various Builder methods + that we want to use to delay Tool searches until necessary. + """ + def __init__(self, env, tools, names): + if not SCons.Util.is_List(tools): + tools = [tools] + if not SCons.Util.is_List(names): + names = [names] + self.env = env + self.tools = tools + self.names = names + self.methods = {} + for name in names: + method = ToolInitializerMethod(name, self) + self.methods[name] = method + env.AddMethod(method) + + def remove_methods(self, env): + """ + Removes the methods that were added by the tool initialization + so we no longer copy and re-bind them when the construction + environment gets cloned. + """ + for method in self.methods.values(): + env.RemoveMethod(method) + + def apply_tools(self, env): + """ + Searches the list of associated Tool modules for one that + exists, and applies that to the construction environment. + """ + for t in self.tools: + tool = SCons.Tool.Tool(t) + if tool.exists(env): + env.Tool(tool) + return + + # If we fall through here, there was no tool module found. + # This is where we can put an informative error message + # about the inability to find the tool. We'll start doing + # this as we cut over more pre-defined Builder+Tools to use + # the ToolInitializer class. + +def Initializers(env): + ToolInitializer(env, ['install'], ['_InternalInstall', '_InternalInstallAs']) + def Install(self, *args, **kw): + return apply(self._InternalInstall, args, kw) + def InstallAs(self, *args, **kw): + return apply(self._InternalInstallAs, args, kw) + env.AddMethod(Install) + env.AddMethod(InstallAs) + +def FindTool(tools, env): + for tool in tools: + t = Tool(tool) + if t.exists(env): + return tool + return None + +def FindAllTools(tools, env): + def ToolExists(tool, env=env): + return Tool(tool).exists(env) + return filter (ToolExists, tools) + +def tool_list(platform, env): + + other_plat_tools=[] + # XXX this logic about what tool to prefer on which platform + # should be moved into either the platform files or + # the tool files themselves. + # The search orders here are described in the man page. If you + # change these search orders, update the man page as well. + if str(platform) == 'win32': + "prefer Microsoft tools on Windows" + linkers = ['mslink', 'gnulink', 'ilink', 'linkloc', 'ilink32' ] + c_compilers = ['msvc', 'mingw', 'gcc', 'intelc', 'icl', 'icc', 'cc', 'bcc32' ] + cxx_compilers = ['msvc', 'intelc', 'icc', 'g++', 'c++', 'bcc32' ] + assemblers = ['masm', 'nasm', 'gas', '386asm' ] + fortran_compilers = ['gfortran', 'g77', 'ifl', 'cvf', 'f95', 'f90', 'fortran'] + ars = ['mslib', 'ar', 'tlib'] + other_plat_tools=['msvs','midl'] + elif str(platform) == 'os2': + "prefer IBM tools on OS/2" + linkers = ['ilink', 'gnulink', ]#'mslink'] + c_compilers = ['icc', 'gcc',]# 'msvc', 'cc'] + cxx_compilers = ['icc', 'g++',]# 'msvc', 'c++'] + assemblers = ['nasm',]# 'masm', 'gas'] + fortran_compilers = ['ifl', 'g77'] + ars = ['ar',]# 'mslib'] + elif str(platform) == 'irix': + "prefer MIPSPro on IRIX" + linkers = ['sgilink', 'gnulink'] + c_compilers = ['sgicc', 'gcc', 'cc'] + cxx_compilers = ['sgic++', 'g++', 'c++'] + assemblers = ['as', 'gas'] + fortran_compilers = ['f95', 'f90', 'f77', 'g77', 'fortran'] + ars = ['sgiar'] + elif str(platform) == 'sunos': + "prefer Forte tools on SunOS" + linkers = ['sunlink', 'gnulink'] + c_compilers = ['suncc', 'gcc', 'cc'] + cxx_compilers = ['sunc++', 'g++', 'c++'] + assemblers = ['as', 'gas'] + fortran_compilers = ['sunf95', 'sunf90', 'sunf77', 'f95', 'f90', 'f77', + 'gfortran', 'g77', 'fortran'] + ars = ['sunar'] + elif str(platform) == 'hpux': + "prefer aCC tools on HP-UX" + linkers = ['hplink', 'gnulink'] + c_compilers = ['hpcc', 'gcc', 'cc'] + cxx_compilers = ['hpc++', 'g++', 'c++'] + assemblers = ['as', 'gas'] + fortran_compilers = ['f95', 'f90', 'f77', 'g77', 'fortran'] + ars = ['ar'] + elif str(platform) == 'aix': + "prefer AIX Visual Age tools on AIX" + linkers = ['aixlink', 'gnulink'] + c_compilers = ['aixcc', 'gcc', 'cc'] + cxx_compilers = ['aixc++', 'g++', 'c++'] + assemblers = ['as', 'gas'] + fortran_compilers = ['f95', 'f90', 'aixf77', 'g77', 'fortran'] + ars = ['ar'] + elif str(platform) == 'darwin': + "prefer GNU tools on Mac OS X, except for some linkers and IBM tools" + linkers = ['applelink', 'gnulink'] + c_compilers = ['gcc', 'cc'] + cxx_compilers = ['g++', 'c++'] + assemblers = ['as'] + fortran_compilers = ['gfortran', 'f95', 'f90', 'g77'] + ars = ['ar'] + else: + "prefer GNU tools on all other platforms" + linkers = ['gnulink', 'mslink', 'ilink'] + c_compilers = ['gcc', 'msvc', 'intelc', 'icc', 'cc'] + cxx_compilers = ['g++', 'msvc', 'intelc', 'icc', 'c++'] + assemblers = ['gas', 'nasm', 'masm'] + fortran_compilers = ['gfortran', 'g77', 'ifort', 'ifl', 'f95', 'f90', 'f77'] + ars = ['ar', 'mslib'] + + c_compiler = FindTool(c_compilers, env) or c_compilers[0] + + # XXX this logic about what tool provides what should somehow be + # moved into the tool files themselves. + if c_compiler and c_compiler == 'mingw': + # MinGW contains a linker, C compiler, C++ compiler, + # Fortran compiler, archiver and assembler: + cxx_compiler = None + linker = None + assembler = None + fortran_compiler = None + ar = None + else: + # Don't use g++ if the C compiler has built-in C++ support: + if c_compiler in ('msvc', 'intelc', 'icc'): + cxx_compiler = None + else: + cxx_compiler = FindTool(cxx_compilers, env) or cxx_compilers[0] + linker = FindTool(linkers, env) or linkers[0] + assembler = FindTool(assemblers, env) or assemblers[0] + fortran_compiler = FindTool(fortran_compilers, env) or fortran_compilers[0] + ar = FindTool(ars, env) or ars[0] + + other_tools = FindAllTools(['BitKeeper', 'CVS', + 'dmd', + 'filesystem', + 'dvipdf', 'dvips', 'gs', + 'jar', 'javac', 'javah', + 'latex', 'lex', + 'm4', #'midl', 'msvs', + 'pdflatex', 'pdftex', 'Perforce', + 'RCS', 'rmic', 'rpcgen', + 'SCCS', + # 'Subversion', + 'swig', + 'tar', 'tex', + 'yacc', 'zip', 'rpm', 'wix']+other_plat_tools, + env) + + tools = ([linker, c_compiler, cxx_compiler, + fortran_compiler, assembler, ar] + + other_tools) + + return filter(lambda x: x, tools) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/__init__.xml b/src/engine/SCons/Tool/__init__.xml new file mode 100644 index 0000000..fa3e37a --- /dev/null +++ b/src/engine/SCons/Tool/__init__.xml @@ -0,0 +1,367 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<builder name="CFile"> +<summary> +Builds a C source file given a lex (<filename>.l</filename>) +or yacc (<filename>.y</filename>) input file. +The suffix specified by the &cv-link-CFILESUFFIX; construction variable +(<filename>.c</filename> by default) +is automatically added to the target +if it is not already present. +Example: + +<example> +# builds foo.c +env.CFile(target = 'foo.c', source = 'foo.l') +# builds bar.c +env.CFile(target = 'bar', source = 'bar.y') +</example> +</summary> +</builder> + +<builder name="CXXFile"> +<summary> +Builds a C++ source file given a lex (<filename>.ll</filename>) +or yacc (<filename>.yy</filename>) +input file. +The suffix specified by the &cv-link-CXXFILESUFFIX; construction variable +(<filename>.cc</filename> by default) +is automatically added to the target +if it is not already present. +Example: + +<example> +# builds foo.cc +env.CXXFile(target = 'foo.cc', source = 'foo.ll') +# builds bar.cc +env.CXXFile(target = 'bar', source = 'bar.yy') +</example> +</summary> +</builder> + +<builder name="Library"> +<summary> +A synonym for the +&b-StaticLibrary; +builder method. +</summary> +</builder> + +<builder name="LoadableModule"> +<summary> +On most systems, +this is the same as +&b-SharedLibrary;. +On Mac OS X (Darwin) platforms, +this creates a loadable module bundle. +</summary> +</builder> + +<builder name="Object"> +<summary> +A synonym for the +&b-StaticObject; +builder method. +</summary> +</builder> + +<builder name="Program"> +<summary> +Builds an executable given one or more object files +or C, C++, D, or Fortran source files. +If any C, C++, D or Fortran source files are specified, +then they will be automatically +compiled to object files using the +&b-Object; +builder method; +see that builder method's description for +a list of legal source file suffixes +and how they are interpreted. +The target executable file prefix +(specified by the &cv-link-PROGPREFIX; construction variable; nothing by default) +and suffix +(specified by the &cv-link-PROGSUFFIX; construction variable; +by default, <filename>.exe</filename> on Windows systems, +nothing on POSIX systems) +are automatically added to the target if not already present. +Example: + +<example> +env.Program(target = 'foo', source = ['foo.o', 'bar.c', 'baz.f']) +</example> +</summary> +</builder> + +<builder name="SharedLibrary"> +<summary> +Builds a shared library +(<filename>.so</filename> on a POSIX system, +<filename>.dll</filename> on Windows) +given one or more object files +or C, C++, D or Fortran source files. +If any source files are given, +then they will be automatically +compiled to object files. +The static library prefix and suffix (if any) +are automatically added to the target. +The target library file prefix +(specified by the &cv-link-SHLIBPREFIX; construction variable; +by default, <filename>lib</filename> on POSIX systems, +nothing on Windows systems) +and suffix +(specified by the &cv-link-SHLIBSUFFIX; construction variable; +by default, <filename>.dll</filename> on Windows systems, +<filename>.so</filename> on POSIX systems) +are automatically added to the target if not already present. +Example: + +<example> +env.SharedLibrary(target = 'bar', source = ['bar.c', 'foo.o']) +</example> + +On Windows systems, the +&b-SharedLibrary; +builder method will always build an import +(<filename>.lib</filename>) library +in addition to the shared (<filename>.dll</filename>) library, +adding a <filename>.lib</filename> library with the same basename +if there is not already a <filename>.lib</filename> file explicitly +listed in the targets. + +Any object files listed in the +<literal>source</literal> +must have been built for a shared library +(that is, using the +&b-SharedObject; +builder method). +&scons; +will raise an error if there is any mismatch. + +On some platforms, there is a distinction between a shared library +(loaded automatically by the system to resolve external references) +and a loadable module (explicitly loaded by user action). +For maximum portability, use the &b-LoadableModule; builder for the latter. + +On Windows systems, specifying +<literal>register=1</literal> +will cause the <filename>.dll</filename> to be +registered after it is built using REGSVR32. +The command that is run +("regsvr32" by default) is determined by &cv-link-REGSVR; construction +variable, and the flags passed are determined by &cv-link-REGSVRFLAGS;. By +default, &cv-link-REGSVRFLAGS; includes the <option>/s</option> option, +to prevent dialogs from popping +up and requiring user attention when it is run. If you change +&cv-link-REGSVRFLAGS;, be sure to include the <option>/s</option> option. +For example, + +<example> +env.SharedLibrary(target = 'bar', + source = ['bar.cxx', 'foo.obj'], + register=1) +</example> + +will register <filename>bar.dll</filename> as a COM object +when it is done linking it. +</summary> +</builder> + +<builder name="SharedObject"> +<summary> +Builds an object file for +inclusion in a shared library. +Source files must have one of the same set of extensions +specified above for the +&b-StaticObject; +builder method. +On some platforms building a shared object requires additional +compiler option +(e.g. <option>-fPIC</option> for gcc) +in addition to those needed to build a +normal (static) object, but on some platforms there is no difference between a +shared object and a normal (static) one. When there is a difference, SCons +will only allow shared objects to be linked into a shared library, and will +use a different suffix for shared objects. On platforms where there is no +difference, SCons will allow both normal (static) +and shared objects to be linked into a +shared library, and will use the same suffix for shared and normal +(static) objects. +The target object file prefix +(specified by the &cv-link-SHOBJPREFIX; construction variable; +by default, the same as &cv-link-OBJPREFIX;) +and suffix +(specified by the &cv-link-SHOBJSUFFIX; construction variable) +are automatically added to the target if not already present. +Examples: + +<example> +env.SharedObject(target = 'ddd', source = 'ddd.c') +env.SharedObject(target = 'eee.o', source = 'eee.cpp') +env.SharedObject(target = 'fff.obj', source = 'fff.for') +</example> + +Note that the source files will be scanned +according to the suffix mappings in the +<literal>SourceFileScanner</literal> +object. +See the section "Scanner Objects," +below, for a more information. +</summary> +</builder> + +<builder name="StaticLibrary"> +<summary> +Builds a static library given one or more object files +or C, C++, D or Fortran source files. +If any source files are given, +then they will be automatically +compiled to object files. +The static library prefix and suffix (if any) +are automatically added to the target. +The target library file prefix +(specified by the &cv-link-LIBPREFIX; construction variable; +by default, <filename>lib</filename> on POSIX systems, +nothing on Windows systems) +and suffix +(specified by the &cv-link-LIBSUFFIX; construction variable; +by default, <filename>.lib</filename> on Windows systems, +<filename>.a</filename> on POSIX systems) +are automatically added to the target if not already present. +Example: + +<example> +env.StaticLibrary(target = 'bar', source = ['bar.c', 'foo.o']) +</example> + +Any object files listed in the +<literal>source</literal> +must have been built for a static library +(that is, using the +&b-StaticObject; +builder method). +&scons; +will raise an error if there is any mismatch. +</summary> +</builder> + +<builder name="StaticObject"> +<summary> +Builds a static object file +from one or more C, C++, D, or Fortran source files. +Source files must have one of the following extensions: + +<example> + .asm assembly language file + .ASM assembly language file + .c C file + .C Windows: C file + POSIX: C++ file + .cc C++ file + .cpp C++ file + .cxx C++ file + .cxx C++ file + .c++ C++ file + .C++ C++ file + .d D file + .f Fortran file + .F Windows: Fortran file + POSIX: Fortran file + C pre-processor + .for Fortran file + .FOR Fortran file + .fpp Fortran file + C pre-processor + .FPP Fortran file + C pre-processor + .m Object C file + .mm Object C++ file + .s assembly language file + .S Windows: assembly language file + ARM: CodeSourcery Sourcery Lite + .sx assembly language file + C pre-processor + POSIX: assembly language file + C pre-processor + .spp assembly language file + C pre-processor + .SPP assembly language file + C pre-processor +</example> + +The target object file prefix +(specified by the &cv-link-OBJPREFIX; construction variable; nothing by default) +and suffix +(specified by the &cv-link-OBJSUFFIX; construction variable; +<filename>.obj</filename> on Windows systems, +<filename>.o</filename> on POSIX systems) +are automatically added to the target if not already present. +Examples: + +<example> +env.StaticObject(target = 'aaa', source = 'aaa.c') +env.StaticObject(target = 'bbb.o', source = 'bbb.c++') +env.StaticObject(target = 'ccc.obj', source = 'ccc.f') +</example> + +Note that the source files will be scanned +according to the suffix mappings in +<literal>SourceFileScanner</literal> +object. +See the section "Scanner Objects," +below, for a more information. +</summary> +</builder> + +<cvar name="CCVERSION"> +<summary> +The version number of the C compiler. +This may or may not be set, +depending on the specific C compiler being used. +</summary> +</cvar> + +<cvar name="CFILESUFFIX"> +<summary> +The suffix for C source files. +This is used by the internal CFile builder +when generating C files from Lex (.l) or YACC (.y) input files. +The default suffix, of course, is +<filename>.c</filename> +(lower case). +On case-insensitive systems (like Windows), +SCons also treats +<filename>.C</filename> +(upper case) files +as C files. +</summary> +</cvar> + +<cvar name="CXXVERSION"> +<summary> +The version number of the C++ compiler. +This may or may not be set, +depending on the specific C++ compiler being used. +</summary> +</cvar> + +<cvar name="CXXFILESUFFIX"> +<summary> +The suffix for C++ source files. +This is used by the internal CXXFile builder +when generating C++ files from Lex (.ll) or YACC (.yy) input files. +The default suffix is +<filename>.cc</filename>. +SCons also treats files with the suffixes +<filename>.cpp</filename>, +<filename>.cxx</filename>, +<filename>.c++</filename>, +and +<filename>.C++</filename> +as C++ files, +and files with +<filename>.mm</filename> +suffixes as Objective C++ files. +On case-sensitive systems (Linux, UNIX, and other POSIX-alikes), +SCons also treats +<filename>.C</filename> +(upper case) files +as C++ files. +</summary> +</cvar> diff --git a/src/engine/SCons/Tool/aixc++.py b/src/engine/SCons/Tool/aixc++.py new file mode 100644 index 0000000..c141cec --- /dev/null +++ b/src/engine/SCons/Tool/aixc++.py @@ -0,0 +1,82 @@ +"""SCons.Tool.aixc++ + +Tool-specific initialization for IBM xlC / Visual Age C++ compiler. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/aixc++.py 4577 2009/12/27 19:44:43 scons" + +import os.path + +import SCons.Platform.aix + +cplusplus = __import__('c++', globals(), locals(), []) + +packages = ['vacpp.cmp.core', 'vacpp.cmp.batch', 'vacpp.cmp.C', 'ibmcxx.cmp'] + +def get_xlc(env): + xlc = env.get('CXX', 'xlC') + xlc_r = env.get('SHCXX', 'xlC_r') + return SCons.Platform.aix.get_xlc(env, xlc, xlc_r, packages) + +def smart_cxxflags(source, target, env, for_signature): + build_dir = env.GetBuildPath() + if build_dir: + return '-qtempinc=' + os.path.join(build_dir, 'tempinc') + return '' + +def generate(env): + """Add Builders and construction variables for xlC / Visual Age + suite to an Environment.""" + path, _cxx, _shcxx, version = get_xlc(env) + if path: + _cxx = os.path.join(path, _cxx) + _shcxx = os.path.join(path, _shcxx) + + cplusplus.generate(env) + + env['CXX'] = _cxx + env['SHCXX'] = _shcxx + env['CXXVERSION'] = version + env['SHOBJSUFFIX'] = '.pic.o' + +def exists(env): + path, _cxx, _shcxx, version = get_xlc(env) + if path and _cxx: + xlc = os.path.join(path, _cxx) + if os.path.exists(xlc): + return xlc + return None + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/aixc++.xml b/src/engine/SCons/Tool/aixc++.xml new file mode 100644 index 0000000..d4fcdaf --- /dev/null +++ b/src/engine/SCons/Tool/aixc++.xml @@ -0,0 +1,19 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="aixc++"> +<summary> +Sets construction variables for the IMB xlc / Visual Age C++ compiler. +</summary> +<sets> +CXX +SHCXX +CXXVERSION +SHOBJSUFFIX +</sets> +<uses> +</uses> +</tool> diff --git a/src/engine/SCons/Tool/aixcc.py b/src/engine/SCons/Tool/aixcc.py new file mode 100644 index 0000000..23ef705 --- /dev/null +++ b/src/engine/SCons/Tool/aixcc.py @@ -0,0 +1,74 @@ +"""SCons.Tool.aixcc + +Tool-specific initialization for IBM xlc / Visual Age C compiler. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/aixcc.py 4577 2009/12/27 19:44:43 scons" + +import os.path + +import SCons.Platform.aix + +import cc + +packages = ['vac.C', 'ibmcxx.cmp'] + +def get_xlc(env): + xlc = env.get('CC', 'xlc') + xlc_r = env.get('SHCC', 'xlc_r') + return SCons.Platform.aix.get_xlc(env, xlc, xlc_r, packages) + +def generate(env): + """Add Builders and construction variables for xlc / Visual Age + suite to an Environment.""" + path, _cc, _shcc, version = get_xlc(env) + if path: + _cc = os.path.join(path, _cc) + _shcc = os.path.join(path, _shcc) + + cc.generate(env) + + env['CC'] = _cc + env['SHCC'] = _shcc + env['CCVERSION'] = version + +def exists(env): + path, _cc, _shcc, version = get_xlc(env) + if path and _cc: + xlc = os.path.join(path, _cc) + if os.path.exists(xlc): + return xlc + return None + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/aixcc.xml b/src/engine/SCons/Tool/aixcc.xml new file mode 100644 index 0000000..df1c4f3 --- /dev/null +++ b/src/engine/SCons/Tool/aixcc.xml @@ -0,0 +1,18 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="aixcc"> +<summary> +Sets construction variables for the IBM xlc / Visual Age C compiler. +</summary> +<sets> +CC +SHCC +CCVERSION +</sets> +<uses> +</uses> +</tool> diff --git a/src/engine/SCons/Tool/aixf77.py b/src/engine/SCons/Tool/aixf77.py new file mode 100644 index 0000000..5c0a3a7 --- /dev/null +++ b/src/engine/SCons/Tool/aixf77.py @@ -0,0 +1,80 @@ +"""engine.SCons.Tool.aixf77 + +Tool-specific initialization for IBM Visual Age f77 Fortran compiler. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/aixf77.py 4577 2009/12/27 19:44:43 scons" + +import os.path + +#import SCons.Platform.aix + +import f77 + +# It would be good to look for the AIX F77 package the same way we're now +# looking for the C and C++ packages. This should be as easy as supplying +# the correct package names in the following list and uncommenting the +# SCons.Platform.aix_get_xlc() call the in the function below. +packages = [] + +def get_xlf77(env): + xlf77 = env.get('F77', 'xlf77') + xlf77_r = env.get('SHF77', 'xlf77_r') + #return SCons.Platform.aix.get_xlc(env, xlf77, xlf77_r, packages) + return (None, xlf77, xlf77_r, None) + +def generate(env): + """ + Add Builders and construction variables for the Visual Age FORTRAN + compiler to an Environment. + """ + path, _f77, _shf77, version = get_xlf77(env) + if path: + _f77 = os.path.join(path, _f77) + _shf77 = os.path.join(path, _shf77) + + f77.generate(env) + + env['F77'] = _f77 + env['SHF77'] = _shf77 + +def exists(env): + path, _f77, _shf77, version = get_xlf77(env) + if path and _f77: + xlf77 = os.path.join(path, _f77) + if os.path.exists(xlf77): + return xlf77 + return None + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/aixf77.xml b/src/engine/SCons/Tool/aixf77.xml new file mode 100644 index 0000000..aa428c4 --- /dev/null +++ b/src/engine/SCons/Tool/aixf77.xml @@ -0,0 +1,17 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="aixf77"> +<summary> +Sets construction variables for the IBM Visual Age f77 Fortran compiler. +</summary> +<sets> +F77 +SHF77 +</sets> +<uses> +</uses> +</tool> diff --git a/src/engine/SCons/Tool/aixlink.py b/src/engine/SCons/Tool/aixlink.py new file mode 100644 index 0000000..2c036ff --- /dev/null +++ b/src/engine/SCons/Tool/aixlink.py @@ -0,0 +1,76 @@ +"""SCons.Tool.aixlink + +Tool-specific initialization for the IBM Visual Age linker. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/aixlink.py 4577 2009/12/27 19:44:43 scons" + +import os +import os.path + +import SCons.Util + +import aixcc +import link + +cplusplus = __import__('c++', globals(), locals(), []) + +def smart_linkflags(source, target, env, for_signature): + if cplusplus.iscplusplus(source): + build_dir = env.subst('$BUILDDIR', target=target, source=source) + if build_dir: + return '-qtempinc=' + os.path.join(build_dir, 'tempinc') + return '' + +def generate(env): + """ + Add Builders and construction variables for Visual Age linker to + an Environment. + """ + link.generate(env) + + env['SMARTLINKFLAGS'] = smart_linkflags + env['LINKFLAGS'] = SCons.Util.CLVar('$SMARTLINKFLAGS') + env['SHLINKFLAGS'] = SCons.Util.CLVar('$LINKFLAGS -qmkshrobj -qsuppress=1501-218') + env['SHLIBSUFFIX'] = '.a' + +def exists(env): + path, _cc, _shcc, version = aixcc.get_xlc(env) + if path and _cc: + xlc = os.path.join(path, _cc) + if os.path.exists(xlc): + return xlc + return None + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/aixlink.xml b/src/engine/SCons/Tool/aixlink.xml new file mode 100644 index 0000000..b2ef46e --- /dev/null +++ b/src/engine/SCons/Tool/aixlink.xml @@ -0,0 +1,19 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="aixlink"> +<summary> +Sets construction variables for the IBM Visual Age linker. +</summary> +<sets> +<!--SMARTLINKFLAGS--> +LINKFLAGS +SHLINKFLAGS +SHLIBSUFFIX +</sets> +<uses> +</uses> +</tool> diff --git a/src/engine/SCons/Tool/applelink.py b/src/engine/SCons/Tool/applelink.py new file mode 100644 index 0000000..4e3b802 --- /dev/null +++ b/src/engine/SCons/Tool/applelink.py @@ -0,0 +1,71 @@ +"""SCons.Tool.applelink + +Tool-specific initialization for the Apple gnu-like linker. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/applelink.py 4577 2009/12/27 19:44:43 scons" + +import SCons.Util + +# Even though the Mac is based on the GNU toolchain, it doesn't understand +# the -rpath option, so we use the "link" tool instead of "gnulink". +import link + +def generate(env): + """Add Builders and construction variables for applelink to an + Environment.""" + link.generate(env) + + env['FRAMEWORKPATHPREFIX'] = '-F' + env['_FRAMEWORKPATH'] = '${_concat(FRAMEWORKPATHPREFIX, FRAMEWORKPATH, "", __env__)}' + env['_FRAMEWORKS'] = '${_concat("-framework ", FRAMEWORKS, "", __env__)}' + env['LINKCOM'] = env['LINKCOM'] + ' $_FRAMEWORKPATH $_FRAMEWORKS $FRAMEWORKSFLAGS' + env['SHLINKFLAGS'] = SCons.Util.CLVar('$LINKFLAGS -dynamiclib') + env['SHLINKCOM'] = env['SHLINKCOM'] + ' $_FRAMEWORKPATH $_FRAMEWORKS $FRAMEWORKSFLAGS' + + # override the default for loadable modules, which are different + # on OS X than dynamic shared libs. echoing what XCode does for + # pre/suffixes: + env['LDMODULEPREFIX'] = '' + env['LDMODULESUFFIX'] = '' + env['LDMODULEFLAGS'] = SCons.Util.CLVar('$LINKFLAGS -bundle') + env['LDMODULECOM'] = '$LDMODULE -o ${TARGET} $LDMODULEFLAGS $SOURCES $_LIBDIRFLAGS $_LIBFLAGS $_FRAMEWORKPATH $_FRAMEWORKS $FRAMEWORKSFLAGS' + + + +def exists(env): + return env['PLATFORM'] == 'darwin' + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/applelink.xml b/src/engine/SCons/Tool/applelink.xml new file mode 100644 index 0000000..29c8183 --- /dev/null +++ b/src/engine/SCons/Tool/applelink.xml @@ -0,0 +1,114 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="applelink"> +<summary> +Sets construction variables for the Apple linker +(similar to the GNU linker). +</summary> +<sets> +FRAMEWORKPATHPREFIX +_FRAMEWORKPATH +_FRAMEWORKS +LINKCOM +SHLINKFLAGS +SHLINKCOM +LDMODULEPREFIX +LDMODULESUFFIX +LDMODULEFLAGS +LDMODULECOM +</sets> +<uses> +FRAMEWORKSFLAGS +</uses> +</tool> + +<cvar name="FRAMEWORKSFLAGS">"> +<summary> +On Mac OS X with gcc, +general user-supplied frameworks options to be added at +the end of a command +line building a loadable module. +(This has been largely superceded by +the &cv-link-FRAMEWORKPATH;, &cv-link-FRAMEWORKPATHPREFIX;, +&cv-link-FRAMEWORKPREFIX; and &cv-link-FRAMEWORKS; variables +described above.) +</summary> +</cvar> + +<cvar name="FRAMEWORKS"> +<summary> +On Mac OS X with gcc, a list of the framework names to be linked into a +program or shared library or bundle. +The default value is the empty list. +For example: + +<example> + env.AppendUnique(FRAMEWORKS=Split('System Cocoa SystemConfiguration')) +</example> + +</summary> +</cvar> + +<cvar name="FRAMEWORKPREFIX"> +<summary> +On Mac OS X with gcc, +the prefix to be used for linking in frameworks +(see &cv-link-FRAMEWORKS;). +The default value is +<option>-framework</option>. +</summary> +</cvar> + +<cvar name="_FRAMEWORKS"> +<summary> +On Mac OS X with gcc, +an automatically-generated construction variable +containing the linker command-line options +for linking with FRAMEWORKS. +</summary> +</cvar> + +<cvar name="FRAMEWORKPATH"> +<summary> +On Mac OS X with gcc, +a list containing the paths to search for frameworks. +Used by the compiler to find framework-style includes like +#include <Fmwk/Header.h>. +Used by the linker to find user-specified frameworks when linking (see +&cv-link-FRAMEWORKS;). +For example: + +<example> + env.AppendUnique(FRAMEWORKPATH='#myframeworkdir') +</example> + +will add + +<example> + ... -Fmyframeworkdir +</example> + +to the compiler and linker command lines. +</summary> +</cvar> + +<cvar name="FRAMEWORKPATHPREFIX"> +<summary> +On Mac OS X with gcc, the prefix to be used for the FRAMEWORKPATH entries. +(see &cv-link-FRAMEWORKPATH;). +The default value is +<option>-F</option>. +</summary> +</cvar> + +<cvar name="_FRAMEWORKPATH"> +<summary> +On Mac OS X with gcc, an automatically-generated construction variable +containing the linker command-line options corresponding to +&cv-link-FRAMEWORKPATH;. +</summary> +</cvar> diff --git a/src/engine/SCons/Tool/ar.py b/src/engine/SCons/Tool/ar.py new file mode 100644 index 0000000..cdffcdf --- /dev/null +++ b/src/engine/SCons/Tool/ar.py @@ -0,0 +1,63 @@ +"""SCons.Tool.ar + +Tool-specific initialization for ar (library archive). + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/ar.py 4577 2009/12/27 19:44:43 scons" + +import SCons.Defaults +import SCons.Tool +import SCons.Util + + +def generate(env): + """Add Builders and construction variables for ar to an Environment.""" + SCons.Tool.createStaticLibBuilder(env) + + env['AR'] = 'ar' + env['ARFLAGS'] = SCons.Util.CLVar('rc') + env['ARCOM'] = '$AR $ARFLAGS $TARGET $SOURCES' + env['LIBPREFIX'] = 'lib' + env['LIBSUFFIX'] = '.a' + + if env.Detect('ranlib'): + env['RANLIB'] = 'ranlib' + env['RANLIBFLAGS'] = SCons.Util.CLVar('') + env['RANLIBCOM'] = '$RANLIB $RANLIBFLAGS $TARGET' + +def exists(env): + return env.Detect('ar') + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/ar.xml b/src/engine/SCons/Tool/ar.xml new file mode 100644 index 0000000..a359823 --- /dev/null +++ b/src/engine/SCons/Tool/ar.xml @@ -0,0 +1,82 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="ar"> +<summary> +Sets construction variables for the &ar; library archiver. +</summary> +<sets> +AR +ARFLAGS +ARCOM +LIBPREFIX +LIBSUFFIX +RANLIB +RANLIBFLAGS +RANLIBCOM +</sets> +<uses> +</uses> +</tool> + +<cvar name="AR"> +<summary> +The static library archiver. +</summary> +</cvar> + +<cvar name="ARCOM"> +<summary> +The command line used to generate a static library from object files. +</summary> +</cvar> + +<cvar name="ARCOMSTR"> +<summary> +The string displayed when an object file +is generated from an assembly-language source file. +If this is not set, then &cv-link-ARCOM; (the command line) is displayed. + +<example> +env = Environment(ARCOMSTR = "Archiving $TARGET") +</example> +</summary> +</cvar> + +<cvar name="ARFLAGS"> +<summary> +General options passed to the static library archiver. +</summary> +</cvar> + +<cvar name="RANLIB"> +<summary> +The archive indexer. +</summary> +</cvar> + +<cvar name="RANLIBCOM"> +<summary> +The command line used to index a static library archive. +</summary> +</cvar> + +<cvar name="RANLIBCOMSTR"> +<summary> +The string displayed when a static library archive is indexed. +If this is not set, then &cv-link-RANLIBCOM; (the command line) is displayed. + +<example> +env = Environment(RANLIBCOMSTR = "Indexing $TARGET") +</example> +</summary> +</cvar> + +<cvar name="RANLIBFLAGS"> +<summary> +General options passed to the archive indexer. +</summary> +</cvar> diff --git a/src/engine/SCons/Tool/as.py b/src/engine/SCons/Tool/as.py new file mode 100644 index 0000000..2e180ce --- /dev/null +++ b/src/engine/SCons/Tool/as.py @@ -0,0 +1,78 @@ +"""SCons.Tool.as + +Tool-specific initialization for as, the generic Posix assembler. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/as.py 4577 2009/12/27 19:44:43 scons" + +import SCons.Defaults +import SCons.Tool +import SCons.Util + +assemblers = ['as'] + +ASSuffixes = ['.s', '.asm', '.ASM'] +ASPPSuffixes = ['.spp', '.SPP', '.sx'] +if SCons.Util.case_sensitive_suffixes('.s', '.S'): + ASPPSuffixes.extend(['.S']) +else: + ASSuffixes.extend(['.S']) + +def generate(env): + """Add Builders and construction variables for as to an Environment.""" + static_obj, shared_obj = SCons.Tool.createObjBuilders(env) + + for suffix in ASSuffixes: + static_obj.add_action(suffix, SCons.Defaults.ASAction) + shared_obj.add_action(suffix, SCons.Defaults.ASAction) + static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter) + shared_obj.add_emitter(suffix, SCons.Defaults.SharedObjectEmitter) + + for suffix in ASPPSuffixes: + static_obj.add_action(suffix, SCons.Defaults.ASPPAction) + shared_obj.add_action(suffix, SCons.Defaults.ASPPAction) + static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter) + shared_obj.add_emitter(suffix, SCons.Defaults.SharedObjectEmitter) + + env['AS'] = env.Detect(assemblers) or 'as' + env['ASFLAGS'] = SCons.Util.CLVar('') + env['ASCOM'] = '$AS $ASFLAGS -o $TARGET $SOURCES' + env['ASPPFLAGS'] = '$ASFLAGS' + env['ASPPCOM'] = '$CC $ASPPFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES' + +def exists(env): + return env.Detect(assemblers) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/as.xml b/src/engine/SCons/Tool/as.xml new file mode 100644 index 0000000..94af6b6 --- /dev/null +++ b/src/engine/SCons/Tool/as.xml @@ -0,0 +1,88 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="as"> +<summary> +Sets construction variables for the &as; assembler. +</summary> +<sets> +AS +ASFLAGS +ASCOM +ASPPFLAGS +ASPPCOM +</sets> +<uses> +CC +CPPFLAGS +_CPPDEFFLAGS +_CPPINCFLAGS +</uses> +</tool> + +<cvar name="AS"> +<summary> +The assembler. +</summary> +</cvar> + +<cvar name="ASCOM"> +<summary> +The command line used to generate an object file +from an assembly-language source file. +</summary> +</cvar> + +<cvar name="ASCOMSTR"> +<summary> +The string displayed when an object file +is generated from an assembly-language source file. +If this is not set, then &cv-link-ASCOM; (the command line) is displayed. + +<example> +env = Environment(ASCOMSTR = "Assembling $TARGET") +</example> +</summary> +</cvar> + +<cvar name="ASFLAGS"> +<summary> +General options passed to the assembler. +</summary> +</cvar> + +<cvar name="ASPPCOM"> +<summary> +The command line used to assemble an assembly-language +source file into an object file +after first running the file through the C preprocessor. +Any options specified +in the &cv-link-ASFLAGS; and &cv-link-CPPFLAGS; construction variables +are included on this command line. +</summary> +</cvar> + +<cvar name="ASPPCOMSTR"> +<summary> +The string displayed when an object file +is generated from an assembly-language source file +after first running the file through the C preprocessor. +If this is not set, then &cv-link-ASPPCOM; (the command line) is displayed. + +<example> +env = Environment(ASPPCOMSTR = "Assembling $TARGET") +</example> +</summary> +</cvar> + +<cvar name="ASPPFLAGS"> +<summary> +General options when an assembling an assembly-language +source file into an object file +after first running the file through the C preprocessor. +The default is to use the value of &cv-link-ASFLAGS;. +</summary> +</cvar> diff --git a/src/engine/SCons/Tool/bcc32.py b/src/engine/SCons/Tool/bcc32.py new file mode 100644 index 0000000..71daa2c --- /dev/null +++ b/src/engine/SCons/Tool/bcc32.py @@ -0,0 +1,82 @@ +"""SCons.Tool.bcc32 + +XXX + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/bcc32.py 4577 2009/12/27 19:44:43 scons" + +import os +import os.path +import string + +import SCons.Defaults +import SCons.Tool +import SCons.Util + +def findIt(program, env): + # First search in the SCons path and then the OS path: + borwin = env.WhereIs(program) or SCons.Util.WhereIs(program) + if borwin: + dir = os.path.dirname(borwin) + env.PrependENVPath('PATH', dir) + return borwin + +def generate(env): + findIt('bcc32', env) + """Add Builders and construction variables for bcc to an + Environment.""" + static_obj, shared_obj = SCons.Tool.createObjBuilders(env) + for suffix in ['.c', '.cpp']: + static_obj.add_action(suffix, SCons.Defaults.CAction) + shared_obj.add_action(suffix, SCons.Defaults.ShCAction) + static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter) + shared_obj.add_emitter(suffix, SCons.Defaults.SharedObjectEmitter) + + env['CC'] = 'bcc32' + env['CCFLAGS'] = SCons.Util.CLVar('') + env['CFLAGS'] = SCons.Util.CLVar('') + env['CCCOM'] = '$CC -q $CFLAGS $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -c -o$TARGET $SOURCES' + env['SHCC'] = '$CC' + env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS') + env['SHCFLAGS'] = SCons.Util.CLVar('$CFLAGS') + env['SHCCCOM'] = '$SHCC -WD $SHCFLAGS $SHCCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -c -o$TARGET $SOURCES' + env['CPPDEFPREFIX'] = '-D' + env['CPPDEFSUFFIX'] = '' + env['INCPREFIX'] = '-I' + env['INCSUFFIX'] = '' + env['SHOBJSUFFIX'] = '.dll' + env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 0 + env['CFILESUFFIX'] = '.cpp' + +def exists(env): + return findIt('bcc32', env) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/bcc32.xml b/src/engine/SCons/Tool/bcc32.xml new file mode 100644 index 0000000..c7f3155 --- /dev/null +++ b/src/engine/SCons/Tool/bcc32.xml @@ -0,0 +1,32 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="bcc32"> +<summary> +Sets construction variables for the bcc32 compiler. +</summary> +<sets> +CC +CCFLAGS +CFLAGS +CCCOM +SHCC +SHCCFLAGS +SHCFLAGS +SHCCCOM +CPPDEFPREFIX +CPPDEFSUFFIX +INCPREFIX +INCSUFFIX +SHOBJSUFFIX +<!--STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME--> +CFILESUFFIX +</sets> +<uses> +_CPPDEFFLAGS +_CPPINCFLAGS +</uses> +</tool> diff --git a/src/engine/SCons/Tool/c++.py b/src/engine/SCons/Tool/c++.py new file mode 100644 index 0000000..ad7fa13 --- /dev/null +++ b/src/engine/SCons/Tool/c++.py @@ -0,0 +1,99 @@ +"""SCons.Tool.c++ + +Tool-specific initialization for generic Posix C++ compilers. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/c++.py 4577 2009/12/27 19:44:43 scons" + +import os.path + +import SCons.Tool +import SCons.Defaults +import SCons.Util + +compilers = ['CC', 'c++'] + +CXXSuffixes = ['.cpp', '.cc', '.cxx', '.c++', '.C++', '.mm'] +if SCons.Util.case_sensitive_suffixes('.c', '.C'): + CXXSuffixes.append('.C') + +def iscplusplus(source): + if not source: + # Source might be None for unusual cases like SConf. + return 0 + for s in source: + if s.sources: + ext = os.path.splitext(str(s.sources[0]))[1] + if ext in CXXSuffixes: + return 1 + return 0 + +def generate(env): + """ + Add Builders and construction variables for Visual Age C++ compilers + to an Environment. + """ + import SCons.Tool + import SCons.Tool.cc + static_obj, shared_obj = SCons.Tool.createObjBuilders(env) + + for suffix in CXXSuffixes: + static_obj.add_action(suffix, SCons.Defaults.CXXAction) + shared_obj.add_action(suffix, SCons.Defaults.ShCXXAction) + static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter) + shared_obj.add_emitter(suffix, SCons.Defaults.SharedObjectEmitter) + + SCons.Tool.cc.add_common_cc_variables(env) + + env['CXX'] = 'c++' + env['CXXFLAGS'] = SCons.Util.CLVar('') + env['CXXCOM'] = '$CXX -o $TARGET -c $CXXFLAGS $CCFLAGS $_CCCOMCOM $SOURCES' + env['SHCXX'] = '$CXX' + env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS') + env['SHCXXCOM'] = '$SHCXX -o $TARGET -c $SHCXXFLAGS $SHCCFLAGS $_CCCOMCOM $SOURCES' + + env['CPPDEFPREFIX'] = '-D' + env['CPPDEFSUFFIX'] = '' + env['INCPREFIX'] = '-I' + env['INCSUFFIX'] = '' + env['SHOBJSUFFIX'] = '.os' + env['OBJSUFFIX'] = '.o' + env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 0 + + env['CXXFILESUFFIX'] = '.cc' + +def exists(env): + return env.Detect(compilers) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/c++.xml b/src/engine/SCons/Tool/c++.xml new file mode 100644 index 0000000..d9dfd57 --- /dev/null +++ b/src/engine/SCons/Tool/c++.xml @@ -0,0 +1,102 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="cXX"> +<summary> +Sets construction variables for generic POSIX C++ compilers. +</summary> +<sets> +CXX +CXXFLAGS +CXXCOM +SHCXX +SHCXXFLAGS +SHCXXCOM +CPPDEFPREFIX +CPPDEFSUFFIX +INCPREFIX +INCSUFFIX +SHOBJSUFFIX +OBJSUFFIX +<!--STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME--> +CXXFILESUFFIX +</sets> +<uses> +CXXCOMSTR +</uses> +</tool> + +<cvar name="CXX"> +<summary> +The C++ compiler. +</summary> +</cvar> + +<cvar name="CXXCOM"> +<summary> +The command line used to compile a C++ source file to an object file. +Any options specified in the &cv-link-CXXFLAGS; and +&cv-link-CPPFLAGS; construction variables +are included on this command line. +</summary> +</cvar> + +<cvar name="CXXCOMSTR"> +<summary> +The string displayed when a C++ source file +is compiled to a (static) object file. +If this is not set, then &cv-link-CXXCOM; (the command line) is displayed. + +<example> +env = Environment(CXXCOMSTR = "Compiling static object $TARGET") +</example> +</summary> +</cvar> + +<cvar name="CXXFLAGS"> +<summary> +General options that are passed to the C++ compiler. +By default, this includes the value of &cv-link-CCFLAGS;, +so that setting &cv-CCFLAGS; affects both C and C++ compilation. +If you want to add C++-specific flags, +you must set or override the value of &cv-link-CXXFLAGS;. +</summary> +</cvar> + +<cvar name="SHCXX"> +<summary> +The C++ compiler used for generating shared-library objects. +</summary> +</cvar> + +<cvar name="SHCXXCOM"> +<summary> +The command line used to compile a C++ source file +to a shared-library object file. +Any options specified in the &cv-link-SHCXXFLAGS; and +&cv-link-CPPFLAGS; construction variables +are included on this command line. +</summary> +</cvar> + +<cvar name="SHCXXCOMSTR"> +<summary> +The string displayed when a C++ source file +is compiled to a shared object file. +If this is not set, then &cv-link-SHCXXCOM; (the command line) is displayed. + +<example> +env = Environment(SHCXXCOMSTR = "Compiling shared object $TARGET") +</example> +</summary> +</cvar> + +<cvar name="SHCXXFLAGS"> +<summary> +Options that are passed to the C++ compiler +to generate shared-library objects. +</summary> +</cvar> diff --git a/src/engine/SCons/Tool/cc.py b/src/engine/SCons/Tool/cc.py new file mode 100644 index 0000000..0ba3856 --- /dev/null +++ b/src/engine/SCons/Tool/cc.py @@ -0,0 +1,114 @@ +"""SCons.Tool.cc + +Tool-specific initialization for generic Posix C compilers. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/cc.py 4577 2009/12/27 19:44:43 scons" + +import SCons.Tool +import SCons.Defaults +import SCons.Util + +CSuffixes = ['.c', '.m'] +if not SCons.Util.case_sensitive_suffixes('.c', '.C'): + CSuffixes.append('.C') + +def add_common_cc_variables(env): + """ + Add underlying common "C compiler" variables that + are used by multiple tools (specifically, c++). + """ + if not env.has_key('_CCCOMCOM'): + env['_CCCOMCOM'] = '$CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS' + # It's a hack to test for darwin here, but the alternative + # of creating an applecc.py to contain this seems overkill. + # Maybe someday the Apple platform will require more setup and + # this logic will be moved. + env['FRAMEWORKS'] = SCons.Util.CLVar('') + env['FRAMEWORKPATH'] = SCons.Util.CLVar('') + if env['PLATFORM'] == 'darwin': + env['_CCCOMCOM'] = env['_CCCOMCOM'] + ' $_FRAMEWORKPATH' + + if not env.has_key('CCFLAGS'): + env['CCFLAGS'] = SCons.Util.CLVar('') + + if not env.has_key('SHCCFLAGS'): + env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS') + +def generate(env): + """ + Add Builders and construction variables for C compilers to an Environment. + """ + static_obj, shared_obj = SCons.Tool.createObjBuilders(env) + + for suffix in CSuffixes: + static_obj.add_action(suffix, SCons.Defaults.CAction) + shared_obj.add_action(suffix, SCons.Defaults.ShCAction) + static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter) + shared_obj.add_emitter(suffix, SCons.Defaults.SharedObjectEmitter) +#<<<<<<< .working +# +# env['_CCCOMCOM'] = '$CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS' +# # It's a hack to test for darwin here, but the alternative of creating +# # an applecc.py to contain this seems overkill. Maybe someday the Apple +# # platform will require more setup and this logic will be moved. +# env['FRAMEWORKS'] = SCons.Util.CLVar('') +# env['FRAMEWORKPATH'] = SCons.Util.CLVar('') +# if env['PLATFORM'] == 'darwin': +# env['_CCCOMCOM'] = env['_CCCOMCOM'] + ' $_FRAMEWORKPATH' +#======= +#>>>>>>> .merge-right.r1907 + + add_common_cc_variables(env) + + env['CC'] = 'cc' + env['CFLAGS'] = SCons.Util.CLVar('') + env['CCCOM'] = '$CC -o $TARGET -c $CFLAGS $CCFLAGS $_CCCOMCOM $SOURCES' + env['SHCC'] = '$CC' + env['SHCFLAGS'] = SCons.Util.CLVar('$CFLAGS') + env['SHCCCOM'] = '$SHCC -o $TARGET -c $SHCFLAGS $SHCCFLAGS $_CCCOMCOM $SOURCES' + + env['CPPDEFPREFIX'] = '-D' + env['CPPDEFSUFFIX'] = '' + env['INCPREFIX'] = '-I' + env['INCSUFFIX'] = '' + env['SHOBJSUFFIX'] = '.os' + env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 0 + + env['CFILESUFFIX'] = '.c' + +def exists(env): + return env.Detect('cc') + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/cc.xml b/src/engine/SCons/Tool/cc.xml new file mode 100644 index 0000000..fbfcb06 --- /dev/null +++ b/src/engine/SCons/Tool/cc.xml @@ -0,0 +1,161 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="cc"> +<summary> +Sets construction variables for generic POSIX C copmilers. +</summary> +<sets> +<!--_CCCOMCOM--> +FRAMEWORKS +FRAMEWORKPATH +CC +CFLAGS +CCFLAGS +CCCOM +SHCC +SHCFLAGS +SHCCFLAGS +SHCCCOM +CPPDEFPREFIX +CPPDEFSUFFIX +INCPREFIX +INCSUFFIX +SHOBJSUFFIX +<!--STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME--> +CFILESUFFIX +</sets> +<uses> +PLATFORM +</uses> +</tool> + +<cvar name="CC"> +<summary> +The C compiler. +</summary> +</cvar> + +<cvar name="CCCOM"> +<summary> +The command line used to compile a C source file to a (static) object +file. Any options specified in the &cv-link-CFLAGS;, &cv-link-CCFLAGS; and +&cv-link-CPPFLAGS; construction variables are included on this command +line. +</summary> +</cvar> + +<cvar name="CCCOMSTR"> +<summary> +The string displayed when a C source file +is compiled to a (static) object file. +If this is not set, then &cv-link-CCCOM; (the command line) is displayed. + +<example> +env = Environment(CCCOMSTR = "Compiling static object $TARGET") +</example> +</summary> +</cvar> + +<cvar name="CCFLAGS"> +<summary> +General options that are passed to the C and C++ compilers. +</summary> +</cvar> + +<cvar name="CFLAGS"> +<summary> +General options that are passed to the C compiler (C only; not C++). +</summary> +</cvar> + +<cvar name="CPPFLAGS"> +<summary> +User-specified C preprocessor options. +These will be included in any command that uses the C preprocessor, +including not just compilation of C and C++ source files +via the &cv-link-CCCOM;, +&cv-link-SHCCCOM;, +&cv-link-CXXCOM; and +&cv-link-SHCXXCOM; command lines, +but also the &cv-link-FORTRANPPCOM;, +&cv-link-SHFORTRANPPCOM;, +&cv-link-F77PPCOM; and +&cv-link-SHF77PPCOM; command lines +used to compile a Fortran source file, +and the &cv-link-ASPPCOM; command line +used to assemble an assembly language source file, +after first running each file through the C preprocessor. +Note that this variable does +<emphasis>not</emphasis> +contain +<option>-I</option> +(or similar) include search path options +that scons generates automatically from &cv-link-CPPPATH;. +See &cv-link-_CPPINCFLAGS;, below, +for the variable that expands to those options. +</summary> +</cvar> + +<cvar name="CPPSUFFIXES"> +<summary> +The list of suffixes of files that will be scanned +for C preprocessor implicit dependencies +(#include lines). +The default list is: + +<example> +[".c", ".C", ".cxx", ".cpp", ".c++", ".cc", + ".h", ".H", ".hxx", ".hpp", ".hh", + ".F", ".fpp", ".FPP", + ".m", ".mm", + ".S", ".spp", ".SPP"] +</example> +</summary> +</cvar> + +<cvar name="SHCC"> +<summary> +The C compiler used for generating shared-library objects. +</summary> +</cvar> + +<cvar name="SHCCCOM"> +<summary> +The command line used to compile a C source file +to a shared-library object file. +Any options specified in the &cv-link-SHCFLAGS;, +&cv-link-SHCCFLAGS; and +&cv-link-CPPFLAGS; construction variables +are included on this command line. +</summary> +</cvar> + +<cvar name="SHCCCOMSTR"> +<summary> +The string displayed when a C source file +is compiled to a shared object file. +If this is not set, then &cv-link-SHCCCOM; (the command line) is displayed. + +<example> +env = Environment(SHCCCOMSTR = "Compiling shared object $TARGET") +</example> +</summary> +</cvar> + +<cvar name="SHCCFLAGS"> +<summary> +Options that are passed to the C and C++ compilers +to generate shared-library objects. +</summary> +</cvar> + +<cvar name="SHCFLAGS"> +<summary> +Options that are passed to the C compiler (only; not C++) +to generate shared-library objects. +</summary> +</cvar> diff --git a/src/engine/SCons/Tool/cvf.py b/src/engine/SCons/Tool/cvf.py new file mode 100644 index 0000000..1d7332b --- /dev/null +++ b/src/engine/SCons/Tool/cvf.py @@ -0,0 +1,58 @@ +"""engine.SCons.Tool.cvf + +Tool-specific initialization for the Compaq Visual Fortran compiler. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/cvf.py 4577 2009/12/27 19:44:43 scons" + +import fortran + +compilers = ['f90'] + +def generate(env): + """Add Builders and construction variables for compaq visual fortran to an Environment.""" + + fortran.generate(env) + + env['FORTRAN'] = 'f90' + env['FORTRANCOM'] = '$FORTRAN $FORTRANFLAGS $_FORTRANMODFLAG $_FORTRANINCFLAGS /compile_only ${SOURCES.windows} /object:${TARGET.windows}' + env['FORTRANPPCOM'] = '$FORTRAN $FORTRANFLAGS $CPPFLAGS $_CPPDEFFLAGS $_FORTRANMODFLAG $_FORTRANINCFLAGS /compile_only ${SOURCES.windows} /object:${TARGET.windows}' + env['SHFORTRANCOM'] = '$SHFORTRAN $SHFORTRANFLAGS $_FORTRANMODFLAG $_FORTRANINCFLAGS /compile_only ${SOURCES.windows} /object:${TARGET.windows}' + env['SHFORTRANPPCOM'] = '$SHFORTRAN $SHFORTRANFLAGS $CPPFLAGS $_CPPDEFFLAGS $_FORTRANMODFLAG $_FORTRANINCFLAGS /compile_only ${SOURCES.windows} /object:${TARGET.windows}' + env['OBJSUFFIX'] = '.obj' + env['FORTRANMODDIR'] = '${TARGET.dir}' + env['FORTRANMODDIRPREFIX'] = '/module:' + env['FORTRANMODDIRSUFFIX'] = '' + +def exists(env): + return env.Detect(compilers) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/cvf.xml b/src/engine/SCons/Tool/cvf.xml new file mode 100644 index 0000000..6c27e6b --- /dev/null +++ b/src/engine/SCons/Tool/cvf.xml @@ -0,0 +1,30 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="cvf"> +<summary> +Sets construction variables for the Compaq Visual Fortran compiler. +</summary> +<sets> +FORTRAN +FORTRANCOM +FORTRANPPCOM +SHFORTRANCOM +SHFORTRANPPCOM +OBJSUFFIX +FORTRANMODDIR +FORTRANMODDIRPREFIX +FORTRANMODDIRSUFFIX +</sets> +<uses> +FORTRANFLAGS +SHFORTRANFLAGS +_FORTRANMODFLAG +_FORTRANINCFLAGS +CPPFLAGS +_CPPDEFFLAGS +</uses> +</tool> diff --git a/src/engine/SCons/Tool/default.py b/src/engine/SCons/Tool/default.py new file mode 100644 index 0000000..0640d8c --- /dev/null +++ b/src/engine/SCons/Tool/default.py @@ -0,0 +1,50 @@ +"""SCons.Tool.default + +Initialization with a default tool list. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/default.py 4577 2009/12/27 19:44:43 scons" + +import SCons.Tool + +def generate(env): + """Add default tools.""" + for t in SCons.Tool.tool_list(env['PLATFORM'], env): + SCons.Tool.Tool(t)(env) + +def exists(env): + return 1 + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/default.xml b/src/engine/SCons/Tool/default.xml new file mode 100644 index 0000000..5c36b41 --- /dev/null +++ b/src/engine/SCons/Tool/default.xml @@ -0,0 +1,12 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="default"> +<summary> +Sets variables by calling a default list of Tool modules +for the platform on which SCons is running. +</summary> +</tool> diff --git a/src/engine/SCons/Tool/dmd.py b/src/engine/SCons/Tool/dmd.py new file mode 100644 index 0000000..0c74877 --- /dev/null +++ b/src/engine/SCons/Tool/dmd.py @@ -0,0 +1,224 @@ +"""SCons.Tool.dmd + +Tool-specific initialization for the Digital Mars D compiler. +(http://digitalmars.com/d) + +Coded by Andy Friesen (andy@ikagames.com) +15 November 2003 + +There are a number of problems with this script at this point in time. +The one that irritates me the most is the Windows linker setup. The D +linker doesn't have a way to add lib paths on the commandline, as far +as I can see. You have to specify paths relative to the SConscript or +use absolute paths. To hack around it, add '#/blah'. This will link +blah.lib from the directory where SConstruct resides. + +Compiler variables: + DC - The name of the D compiler to use. Defaults to dmd or gdmd, + whichever is found. + DPATH - List of paths to search for import modules. + DVERSIONS - List of version tags to enable when compiling. + DDEBUG - List of debug tags to enable when compiling. + +Linker related variables: + LIBS - List of library files to link in. + DLINK - Name of the linker to use. Defaults to dmd or gdmd. + DLINKFLAGS - List of linker flags. + +Lib tool variables: + DLIB - Name of the lib tool to use. Defaults to lib. + DLIBFLAGS - List of flags to pass to the lib tool. + LIBS - Same as for the linker. (libraries to pull into the .lib) +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/dmd.py 4577 2009/12/27 19:44:43 scons" + +import os +import string + +import SCons.Action +import SCons.Builder +import SCons.Defaults +import SCons.Scanner.D +import SCons.Tool + +# Adapted from c++.py +def isD(source): + if not source: + return 0 + + for s in source: + if s.sources: + ext = os.path.splitext(str(s.sources[0]))[1] + if ext == '.d': + return 1 + return 0 + +smart_link = {} + +smart_lib = {} + +def generate(env): + global smart_link + global smart_lib + + static_obj, shared_obj = SCons.Tool.createObjBuilders(env) + + DAction = SCons.Action.Action('$DCOM', '$DCOMSTR') + + static_obj.add_action('.d', DAction) + shared_obj.add_action('.d', DAction) + static_obj.add_emitter('.d', SCons.Defaults.StaticObjectEmitter) + shared_obj.add_emitter('.d', SCons.Defaults.SharedObjectEmitter) + + dc = env.Detect(['dmd', 'gdmd']) + env['DC'] = dc + env['DCOM'] = '$DC $_DINCFLAGS $_DVERFLAGS $_DDEBUGFLAGS $_DFLAGS -c -of$TARGET $SOURCES' + env['_DINCFLAGS'] = '$( ${_concat(DINCPREFIX, DPATH, DINCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)' + env['_DVERFLAGS'] = '$( ${_concat(DVERPREFIX, DVERSIONS, DVERSUFFIX, __env__)} $)' + env['_DDEBUGFLAGS'] = '$( ${_concat(DDEBUGPREFIX, DDEBUG, DDEBUGSUFFIX, __env__)} $)' + env['_DFLAGS'] = '$( ${_concat(DFLAGPREFIX, DFLAGS, DFLAGSUFFIX, __env__)} $)' + + env['DPATH'] = ['#/'] + env['DFLAGS'] = [] + env['DVERSIONS'] = [] + env['DDEBUG'] = [] + + if dc: + # Add the path to the standard library. + # This is merely for the convenience of the dependency scanner. + dmd_path = env.WhereIs(dc) + if dmd_path: + x = string.rindex(dmd_path, dc) + phobosDir = dmd_path[:x] + '/../src/phobos' + if os.path.isdir(phobosDir): + env.Append(DPATH = [phobosDir]) + + env['DINCPREFIX'] = '-I' + env['DINCSUFFIX'] = '' + env['DVERPREFIX'] = '-version=' + env['DVERSUFFIX'] = '' + env['DDEBUGPREFIX'] = '-debug=' + env['DDEBUGSUFFIX'] = '' + env['DFLAGPREFIX'] = '-' + env['DFLAGSUFFIX'] = '' + env['DFILESUFFIX'] = '.d' + + # Need to use the Digital Mars linker/lib on windows. + # *nix can just use GNU link. + if env['PLATFORM'] == 'win32': + env['DLINK'] = '$DC' + env['DLINKCOM'] = '$DLINK -of$TARGET $SOURCES $DFLAGS $DLINKFLAGS $_DLINKLIBFLAGS' + env['DLIB'] = 'lib' + env['DLIBCOM'] = '$DLIB $_DLIBFLAGS -c $TARGET $SOURCES $_DLINKLIBFLAGS' + + env['_DLINKLIBFLAGS'] = '$( ${_concat(DLIBLINKPREFIX, LIBS, DLIBLINKSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)' + env['_DLIBFLAGS'] = '$( ${_concat(DLIBFLAGPREFIX, DLIBFLAGS, DLIBFLAGSUFFIX, __env__)} $)' + env['DLINKFLAGS'] = [] + env['DLIBLINKPREFIX'] = '' + env['DLIBLINKSUFFIX'] = '.lib' + env['DLIBFLAGPREFIX'] = '-' + env['DLIBFLAGSUFFIX'] = '' + env['DLINKFLAGPREFIX'] = '-' + env['DLINKFLAGSUFFIX'] = '' + + SCons.Tool.createStaticLibBuilder(env) + + # Basically, we hijack the link and ar builders with our own. + # these builders check for the presence of D source, and swap out + # the system's defaults for the Digital Mars tools. If there's no D + # source, then we silently return the previous settings. + linkcom = env.get('LINKCOM') + try: + env['SMART_LINKCOM'] = smart_link[linkcom] + except KeyError: + def _smartLink(source, target, env, for_signature, + defaultLinker=linkcom): + if isD(source): + # XXX I'm not sure how to add a $DLINKCOMSTR variable + # so that it works with this _smartLink() logic, + # and I don't have a D compiler/linker to try it out, + # so we'll leave it alone for now. + return '$DLINKCOM' + else: + return defaultLinker + env['SMART_LINKCOM'] = smart_link[linkcom] = _smartLink + + arcom = env.get('ARCOM') + try: + env['SMART_ARCOM'] = smart_lib[arcom] + except KeyError: + def _smartLib(source, target, env, for_signature, + defaultLib=arcom): + if isD(source): + # XXX I'm not sure how to add a $DLIBCOMSTR variable + # so that it works with this _smartLib() logic, and + # I don't have a D compiler/archiver to try it out, + # so we'll leave it alone for now. + return '$DLIBCOM' + else: + return defaultLib + env['SMART_ARCOM'] = smart_lib[arcom] = _smartLib + + # It is worth noting that the final space in these strings is + # absolutely pivotal. SCons sees these as actions and not generators + # if it is not there. (very bad) + env['ARCOM'] = '$SMART_ARCOM ' + env['LINKCOM'] = '$SMART_LINKCOM ' + else: # assuming linux + linkcom = env.get('LINKCOM') + try: + env['SMART_LINKCOM'] = smart_link[linkcom] + except KeyError: + def _smartLink(source, target, env, for_signature, + defaultLinker=linkcom, dc=dc): + if isD(source): + try: + libs = env['LIBS'] + except KeyError: + libs = [] + if 'phobos' not in libs and 'gphobos' not in libs: + if dc is 'dmd': + env.Append(LIBS = ['phobos']) + elif dc is 'gdmd': + env.Append(LIBS = ['gphobos']) + if 'pthread' not in libs: + env.Append(LIBS = ['pthread']) + if 'm' not in libs: + env.Append(LIBS = ['m']) + return defaultLinker + env['SMART_LINKCOM'] = smart_link[linkcom] = _smartLink + + env['LINKCOM'] = '$SMART_LINKCOM ' + +def exists(env): + return env.Detect(['dmd', 'gdmd']) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/dmd.xml b/src/engine/SCons/Tool/dmd.xml new file mode 100644 index 0000000..a12b25c --- /dev/null +++ b/src/engine/SCons/Tool/dmd.xml @@ -0,0 +1,53 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="dmd"> +<summary> +Sets construction variables for D language compilers +(the Digital Mars D compiler, or GDC). +</summary> +<sets> +<!-- +DC +DCOM +_DINCFLAGS +_DVERFLAGS +_DDEBUGFLAGS +_DFLAGS +DPATH +DFLAGS +DVERSIONS +DDEBUG +DINCPREFIX +DINCSUFFIX +DVERPREFIX +DVERSUFFIX +DDEBUGPREFIX +DDEBUGSUFFIX +DFLAGPREFIX +DFLAGSUFFIX +DFLESUFFIX +DLINK +DLINKCOM +DLIB +DLIBCOM +_DLINKLIBFLAGS +_DLIBFLAGS +DLINKFLAGS +DLIBLINKPREFIX +DLIBLINKSUFFIX +DLIBFLAGPREFIX +DLIBFLAGSUFFIX +DLINKFLAGPREFIX +DLINKFLAGSUFFIX +LINKCOM +ARCOM +LIBS +--> +</sets> +<uses> +</uses> +</tool> diff --git a/src/engine/SCons/Tool/dvi.py b/src/engine/SCons/Tool/dvi.py new file mode 100644 index 0000000..5c859c7 --- /dev/null +++ b/src/engine/SCons/Tool/dvi.py @@ -0,0 +1,64 @@ +"""SCons.Tool.dvi + +Common DVI Builder definition for various other Tool modules that use it. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/dvi.py 4577 2009/12/27 19:44:43 scons" + +import SCons.Builder +import SCons.Tool + +DVIBuilder = None + +def generate(env): + try: + env['BUILDERS']['DVI'] + except KeyError: + global DVIBuilder + + if DVIBuilder is None: + # The suffix is hard-coded to '.dvi', not configurable via a + # construction variable like $DVISUFFIX, because the output + # file name is hard-coded within TeX. + DVIBuilder = SCons.Builder.Builder(action = {}, + source_scanner = SCons.Tool.LaTeXScanner, + suffix = '.dvi', + emitter = {}, + source_ext_match = None) + + env['BUILDERS']['DVI'] = DVIBuilder + +def exists(env): + # This only puts a skeleton Builder in place, so if someone + # references this Tool directly, it's always "available." + return 1 + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/dvi.xml b/src/engine/SCons/Tool/dvi.xml new file mode 100644 index 0000000..b0a871f --- /dev/null +++ b/src/engine/SCons/Tool/dvi.xml @@ -0,0 +1,67 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="dvi"> +<summary> +Attaches the &b-DVI; builder to the +construction environment. +</summary> +<sets> +</sets> +<uses> +</uses> +</tool> + +<builder name="DVI"> +<summary> +Builds a <filename>.dvi</filename> file +from a <filename>.tex</filename>, +<filename>.ltx</filename> or <filename>.latex</filename> input file. +If the source file suffix is <filename>.tex</filename>, +&scons; +will examine the contents of the file; +if the string +<literal>\documentclass</literal> +or +<literal>\documentstyle</literal> +is found, the file is assumed to be a LaTeX file and +the target is built by invoking the &cv-link-LATEXCOM; command line; +otherwise, the &cv-link-TEXCOM; command line is used. +If the file is a LaTeX file, +the +&b-DVI; +builder method will also examine the contents +of the +<filename>.aux</filename> +file and invoke the &cv-link-BIBTEX; command line +if the string +<literal>bibdata</literal> +is found, +start &cv-link-MAKEINDEX; to generate an index if a +<filename>.ind</filename> +file is found +and will examine the contents +<filename>.log</filename> +file and re-run the &cv-link-LATEXCOM; command +if the log file says it is necessary. + +The suffix <filename>.dvi</filename> +(hard-coded within TeX itself) +is automatically added to the target +if it is not already present. +Examples: + +<example> +# builds from aaa.tex +env.DVI(target = 'aaa.dvi', source = 'aaa.tex') +# builds bbb.dvi +env.DVI(target = 'bbb', source = 'bbb.ltx') +# builds from ccc.latex +env.DVI(target = 'ccc.dvi', source = 'ccc.latex') +</example> +</summary> +</builder> + diff --git a/src/engine/SCons/Tool/dvipdf.py b/src/engine/SCons/Tool/dvipdf.py new file mode 100644 index 0000000..67137a8 --- /dev/null +++ b/src/engine/SCons/Tool/dvipdf.py @@ -0,0 +1,125 @@ +"""SCons.Tool.dvipdf + +Tool-specific initialization for dvipdf. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/dvipdf.py 4577 2009/12/27 19:44:43 scons" + +import SCons.Action +import SCons.Defaults +import SCons.Tool.pdf +import SCons.Tool.tex +import SCons.Util + +_null = SCons.Scanner.LaTeX._null + +def DviPdfPsFunction(XXXDviAction, target = None, source= None, env=None): + """A builder for DVI files that sets the TEXPICTS environment + variable before running dvi2ps or dvipdf.""" + + try: + abspath = source[0].attributes.path + except AttributeError : + abspath = '' + + saved_env = SCons.Scanner.LaTeX.modify_env_var(env, 'TEXPICTS', abspath) + + result = XXXDviAction(target, source, env) + + if saved_env is _null: + try: + del env['ENV']['TEXPICTS'] + except KeyError: + pass # was never set + else: + env['ENV']['TEXPICTS'] = saved_env + + return result + +def DviPdfFunction(target = None, source= None, env=None): + result = DviPdfPsFunction(PDFAction,target,source,env) + return result + +def DviPdfStrFunction(target = None, source= None, env=None): + """A strfunction for dvipdf that returns the appropriate + command string for the no_exec options.""" + if env.GetOption("no_exec"): + result = env.subst('$DVIPDFCOM',0,target,source) + else: + result = '' + return result + +PDFAction = None +DVIPDFAction = None + +def PDFEmitter(target, source, env): + """Strips any .aux or .log files from the input source list. + These are created by the TeX Builder that in all likelihood was + used to generate the .dvi file we're using as input, and we only + care about the .dvi file. + """ + def strip_suffixes(n): + return not SCons.Util.splitext(str(n))[1] in ['.aux', '.log'] + source = filter(strip_suffixes, source) + return (target, source) + +def generate(env): + """Add Builders and construction variables for dvipdf to an Environment.""" + global PDFAction + if PDFAction is None: + PDFAction = SCons.Action.Action('$DVIPDFCOM', '$DVIPDFCOMSTR') + + global DVIPDFAction + if DVIPDFAction is None: + DVIPDFAction = SCons.Action.Action(DviPdfFunction, strfunction = DviPdfStrFunction) + + import pdf + pdf.generate(env) + + bld = env['BUILDERS']['PDF'] + bld.add_action('.dvi', DVIPDFAction) + bld.add_emitter('.dvi', PDFEmitter) + + env['DVIPDF'] = 'dvipdf' + env['DVIPDFFLAGS'] = SCons.Util.CLVar('') + env['DVIPDFCOM'] = 'cd ${TARGET.dir} && $DVIPDF $DVIPDFFLAGS ${SOURCE.file} ${TARGET.file}' + + # Deprecated synonym. + env['PDFCOM'] = ['$DVIPDFCOM'] + +def exists(env): + return env.Detect('dvipdf') + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/dvipdf.xml b/src/engine/SCons/Tool/dvipdf.xml new file mode 100644 index 0000000..c3c2a36 --- /dev/null +++ b/src/engine/SCons/Tool/dvipdf.xml @@ -0,0 +1,51 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="dvipdf"> +<summary> +Sets construction variables for the dvipdf utility. +</summary> +<sets> +DVIPDF +DVIPDFFLAGS +DVIPDFCOM +</sets> +<uses> +DVIPDFCOMSTR +</uses> +</tool> + +<cvar name="DVIPDF"> +<summary> +The TeX DVI file to PDF file converter. +</summary> +</cvar> + +<cvar name="DVIPDFFLAGS"> +<summary> +General options passed to the TeX DVI file to PDF file converter. +</summary> +</cvar> + +<cvar name="DVIPDFCOM"> +<summary> +The command line used to convert TeX DVI files into a PDF file. +</summary> +</cvar> + +<cvar name="DVIPDFCOMSTR"> +<summary> +The string displayed when a TeX DVI file +is converted into a PDF file. +If this is not set, then &cv-link-DVIPDFCOM; (the command line) is displayed. +</summary> +</cvar> + +<cvar name="PDFCOM"> +<summary> +A deprecated synonym for &cv-link-DVIPDFCOM;. +</summary> +</cvar> diff --git a/src/engine/SCons/Tool/dvips.py b/src/engine/SCons/Tool/dvips.py new file mode 100644 index 0000000..da61891 --- /dev/null +++ b/src/engine/SCons/Tool/dvips.py @@ -0,0 +1,94 @@ +"""SCons.Tool.dvips + +Tool-specific initialization for dvips. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/dvips.py 4577 2009/12/27 19:44:43 scons" + +import SCons.Action +import SCons.Builder +import SCons.Tool.dvipdf +import SCons.Util + +def DviPsFunction(target = None, source= None, env=None): + result = SCons.Tool.dvipdf.DviPdfPsFunction(PSAction,target,source,env) + return result + +def DviPsStrFunction(target = None, source= None, env=None): + """A strfunction for dvipdf that returns the appropriate + command string for the no_exec options.""" + if env.GetOption("no_exec"): + result = env.subst('$PSCOM',0,target,source) + else: + result = '' + return result + +PSAction = None +DVIPSAction = None +PSBuilder = None + +def generate(env): + """Add Builders and construction variables for dvips to an Environment.""" + global PSAction + if PSAction is None: + PSAction = SCons.Action.Action('$PSCOM', '$PSCOMSTR') + + global DVIPSAction + if DVIPSAction is None: + DVIPSAction = SCons.Action.Action(DviPsFunction, strfunction = DviPsStrFunction) + + global PSBuilder + if PSBuilder is None: + PSBuilder = SCons.Builder.Builder(action = PSAction, + prefix = '$PSPREFIX', + suffix = '$PSSUFFIX', + src_suffix = '.dvi', + src_builder = 'DVI', + single_source=True) + + env['BUILDERS']['PostScript'] = PSBuilder + + env['DVIPS'] = 'dvips' + env['DVIPSFLAGS'] = SCons.Util.CLVar('') + # I'm not quite sure I got the directories and filenames right for variant_dir + # We need to be in the correct directory for the sake of latex \includegraphics eps included files. + env['PSCOM'] = 'cd ${TARGET.dir} && $DVIPS $DVIPSFLAGS -o ${TARGET.file} ${SOURCE.file}' + env['PSPREFIX'] = '' + env['PSSUFFIX'] = '.ps' + +def exists(env): + return env.Detect('dvips') + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/dvips.xml b/src/engine/SCons/Tool/dvips.xml new file mode 100644 index 0000000..b7ead77 --- /dev/null +++ b/src/engine/SCons/Tool/dvips.xml @@ -0,0 +1,81 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="dvips"> +<summary> +Sets construction variables for the dvips utility. +</summary> +<sets> +DVIPS +DVIPSFLAGS +PSCOM +PSPREFIX +PSSUFFIX +</sets> +<uses> +PSCOMSTR +</uses> +</tool> + +<builder name="PostScript"> +<summary> +Builds a <filename>.ps</filename> file +from a <filename>.dvi</filename> input file +(or, by extension, a <filename>.tex</filename>, +<filename>.ltx</filename>, +or +<filename>.latex</filename> input file). +The suffix specified by the &cv-link-PSSUFFIX; construction variable +(<filename>.ps</filename> by default) +is added automatically to the target +if it is not already present. Example: + +<example> +# builds from aaa.tex +env.PostScript(target = 'aaa.ps', source = 'aaa.tex') +# builds bbb.ps from bbb.dvi +env.PostScript(target = 'bbb', source = 'bbb.dvi') +</example> +</summary> +</builder> + +<cvar name="DVIPS"> +<summary> +The TeX DVI file to PostScript converter. +</summary> +</cvar> + +<cvar name="DVIPSFLAGS"> +<summary> +General options passed to the TeX DVI file to PostScript converter. +</summary> +</cvar> + +<cvar name="PSCOM"> +<summary> +The command line used to convert TeX DVI files into a PostScript file. +</summary> +</cvar> + +<cvar name="PSCOMSTR"> +<summary> +The string displayed when a TeX DVI file +is converted into a PostScript file. +If this is not set, then &cv-link-PSCOM; (the command line) is displayed. +</summary> +</cvar> + +<cvar name="PSPREFIX"> +<summary> +The prefix used for PostScript file names. +</summary> +</cvar> + +<cvar name="PSSUFFIX"> +<summary> +The prefix used for PostScript file names. +</summary> +</cvar> diff --git a/src/engine/SCons/Tool/f77.py b/src/engine/SCons/Tool/f77.py new file mode 100644 index 0000000..3fe3c3f --- /dev/null +++ b/src/engine/SCons/Tool/f77.py @@ -0,0 +1,62 @@ +"""engine.SCons.Tool.f77 + +Tool-specific initialization for the generic Posix f77 Fortran compiler. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/f77.py 4577 2009/12/27 19:44:43 scons" + +import SCons.Defaults +import SCons.Scanner.Fortran +import SCons.Tool +import SCons.Util +from SCons.Tool.FortranCommon import add_all_to_env, add_f77_to_env + +compilers = ['f77'] + +def generate(env): + add_all_to_env(env) + add_f77_to_env(env) + + fcomp = env.Detect(compilers) or 'f77' + env['F77'] = fcomp + env['SHF77'] = fcomp + + env['FORTRAN'] = fcomp + env['SHFORTRAN'] = fcomp + +def exists(env): + return env.Detect(compilers) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/f77.xml b/src/engine/SCons/Tool/f77.xml new file mode 100644 index 0000000..c947905 --- /dev/null +++ b/src/engine/SCons/Tool/f77.xml @@ -0,0 +1,265 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="f77"> +<summary> +Set construction variables for generic POSIX Fortran 77 compilers. +</summary> +<sets> +F77 +F77FLAGS +F77COM +F77PPCOM +F77FILESUFFIXES +F77PPFILESUFFIXES +FORTRAN +FORTRANFLAGS +FORTRANCOM +SHF77 +SHF77FLAGS +SHF77COM +SHF77PPCOM +SHFORTRAN +SHFORTRANFLAGS +SHFORTRANCOM +SHFORTRANPPCOM +_F77INCFLAGS +</sets> +<uses> +F77COMSTR +F77PPCOMSTR +FORTRANCOMSTR +FORTRANPPCOMSTR +SHF77COMSTR +SHF77PPCOMSTR +SHFORTRANCOMSTR +SHFORTRANPPCOMSTR +</uses> +</tool> + +<cvar name="F77"> +<summary> +The Fortran 77 compiler. +You should normally set the &cv-link-FORTRAN; variable, +which specifies the default Fortran compiler +for all Fortran versions. +You only need to set &cv-link-F77; if you need to use a specific compiler +or compiler version for Fortran 77 files. +</summary> +</cvar> + +<cvar name="F77COM"> +<summary> +The command line used to compile a Fortran 77 source file to an object file. +You only need to set &cv-link-F77COM; if you need to use a specific +command line for Fortran 77 files. +You should normally set the &cv-link-FORTRANCOM; variable, +which specifies the default command line +for all Fortran versions. +</summary> +</cvar> + +<cvar name="F77FILESUFFIXES"> +<summary> +The list of file extensions for which the F77 dialect will be used. By +default, this is ['.f77'] +</summary> +</cvar> + +<cvar name="F77PPFILESUFFIXES"> +<summary> +The list of file extensions for which the compilation + preprocessor pass for +F77 dialect will be used. By default, this is empty +</summary> +</cvar> + +<cvar name="F77COMSTR"> +<summary> +The string displayed when a Fortran 77 source file +is compiled to an object file. +If this is not set, then &cv-link-F77COM; or &cv-link-FORTRANCOM; +(the command line) is displayed. +</summary> +</cvar> + +<cvar name="F77FLAGS"> +<summary> +General user-specified options that are passed to the Fortran 77 compiler. +Note that this variable does +<emphasis>not</emphasis> +contain +<option>-I</option> +(or similar) include search path options +that scons generates automatically from &cv-link-F77PATH;. +See +&cv-link-_F77INCFLAGS; +below, +for the variable that expands to those options. +You only need to set &cv-link-F77FLAGS; if you need to define specific +user options for Fortran 77 files. +You should normally set the &cv-link-FORTRANFLAGS; variable, +which specifies the user-specified options +passed to the default Fortran compiler +for all Fortran versions. +</summary> +</cvar> + +<cvar name="_F77INCFLAGS"> +<summary> +An automatically-generated construction variable +containing the Fortran 77 compiler command-line options +for specifying directories to be searched for include files. +The value of &cv-link-_F77INCFLAGS; is created +by appending &cv-link-INCPREFIX; and &cv-link-INCSUFFIX; +to the beginning and end +of each directory in &cv-link-F77PATH;. +</summary> +</cvar> + +<cvar name="F77PATH"> +<summary> +The list of directories that the Fortran 77 compiler will search for include +directories. The implicit dependency scanner will search these +directories for include files. Don't explicitly put include directory +arguments in &cv-link-F77FLAGS; because the result will be non-portable +and the directories will not be searched by the dependency scanner. Note: +directory names in &cv-link-F77PATH; will be looked-up relative to the SConscript +directory when they are used in a command. To force +&scons; +to look-up a directory relative to the root of the source tree use #: +You only need to set &cv-link-F77PATH; if you need to define a specific +include path for Fortran 77 files. +You should normally set the &cv-link-FORTRANPATH; variable, +which specifies the include path +for the default Fortran compiler +for all Fortran versions. + +<example> +env = Environment(F77PATH='#/include') +</example> + +The directory look-up can also be forced using the +&Dir;() +function: + +<example> +include = Dir('include') +env = Environment(F77PATH=include) +</example> + +The directory list will be added to command lines +through the automatically-generated +&cv-link-_F77INCFLAGS; +construction variable, +which is constructed by +appending the values of the +&cv-link-INCPREFIX; and &cv-link-INCSUFFIX; +construction variables +to the beginning and end +of each directory in &cv-link-F77PATH;. +Any command lines you define that need +the F77PATH directory list should +include &cv-link-_F77INCFLAGS;: + +<example> +env = Environment(F77COM="my_compiler $_F77INCFLAGS -c -o $TARGET $SOURCE") +</example> +</summary> +</cvar> + +<cvar name="F77PPCOM"> +<summary> +The command line used to compile a Fortran 77 source file to an object file +after first running the file through the C preprocessor. +Any options specified in the &cv-link-F77FLAGS; and &cv-link-CPPFLAGS; construction variables +are included on this command line. +You only need to set &cv-link-F77PPCOM; if you need to use a specific +C-preprocessor command line for Fortran 77 files. +You should normally set the &cv-link-FORTRANPPCOM; variable, +which specifies the default C-preprocessor command line +for all Fortran versions. +</summary> +</cvar> + +<cvar name="F77PPCOMSTR"> +<summary> +The string displayed when a Fortran 77 source file +is compiled to an object file +after first running the file through the C preprocessor. +If this is not set, then &cv-link-F77PPCOM; or &cv-link-FORTRANPPCOM; +(the command line) is displayed. +</summary> +</cvar> + +<cvar name="SHF77"> +<summary> +The Fortran 77 compiler used for generating shared-library objects. +You should normally set the &cv-link-SHFORTRAN; variable, +which specifies the default Fortran compiler +for all Fortran versions. +You only need to set &cv-link-SHF77; if you need to use a specific compiler +or compiler version for Fortran 77 files. +</summary> +</cvar> + +<cvar name="SHF77COM"> +<summary> +The command line used to compile a Fortran 77 source file +to a shared-library object file. +You only need to set &cv-link-SHF77COM; if you need to use a specific +command line for Fortran 77 files. +You should normally set the &cv-link-SHFORTRANCOM; variable, +which specifies the default command line +for all Fortran versions. +</summary> +</cvar> + +<cvar name="SHF77COMSTR"> +<summary> +The string displayed when a Fortran 77 source file +is compiled to a shared-library object file. +If this is not set, then &cv-link-SHF77COM; or &cv-link-SHFORTRANCOM; +(the command line) is displayed. +</summary> +</cvar> + +<cvar name="SHF77FLAGS"> +<summary> +Options that are passed to the Fortran 77 compiler +to generated shared-library objects. +You only need to set &cv-link-SHF77FLAGS; if you need to define specific +user options for Fortran 77 files. +You should normally set the &cv-link-SHFORTRANFLAGS; variable, +which specifies the user-specified options +passed to the default Fortran compiler +for all Fortran versions. +</summary> +</cvar> + +<cvar name="SHF77PPCOM"> +<summary> +The command line used to compile a Fortran 77 source file to a +shared-library object file +after first running the file through the C preprocessor. +Any options specified in the &cv-link-SHF77FLAGS; and &cv-link-CPPFLAGS; construction variables +are included on this command line. +You only need to set &cv-link-SHF77PPCOM; if you need to use a specific +C-preprocessor command line for Fortran 77 files. +You should normally set the &cv-link-SHFORTRANPPCOM; variable, +which specifies the default C-preprocessor command line +for all Fortran versions. +</summary> +</cvar> + +<cvar name="SHF77PPCOMSTR"> +<summary> +The string displayed when a Fortran 77 source file +is compiled to a shared-library object file +after first running the file through the C preprocessor. +If this is not set, then &cv-link-SHF77PPCOM; or &cv-link-SHFORTRANPPCOM; +(the command line) is displayed. +</summary> +</cvar> diff --git a/src/engine/SCons/Tool/f90.py b/src/engine/SCons/Tool/f90.py new file mode 100644 index 0000000..b53014e --- /dev/null +++ b/src/engine/SCons/Tool/f90.py @@ -0,0 +1,62 @@ +"""engine.SCons.Tool.f90 + +Tool-specific initialization for the generic Posix f90 Fortran compiler. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/f90.py 4577 2009/12/27 19:44:43 scons" + +import SCons.Defaults +import SCons.Scanner.Fortran +import SCons.Tool +import SCons.Util +from SCons.Tool.FortranCommon import add_all_to_env, add_f90_to_env + +compilers = ['f90'] + +def generate(env): + add_all_to_env(env) + add_f90_to_env(env) + + fc = env.Detect(compilers) or 'f90' + env['F90'] = fc + env['SHF90'] = fc + + env['FORTRAN'] = fc + env['SHFORTRAN'] = fc + +def exists(env): + return env.Detect(compilers) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/f90.xml b/src/engine/SCons/Tool/f90.xml new file mode 100644 index 0000000..665333d --- /dev/null +++ b/src/engine/SCons/Tool/f90.xml @@ -0,0 +1,251 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="f90"> +<summary> +Set construction variables for generic POSIX Fortran 90 compilers. +</summary> +<sets> +F90 +F90FLAGS +F90COM +F90PPCOM +SHF90 +SHF90FLAGS +SHF90COM +SHF90PPCOM +_F90INCFLAGS +</sets> +<uses> +F90COMSTR +F90PPCOMSTR +SHF90COMSTR +SHF90PPCOMSTR +</uses> +</tool> + +<cvar name="F90"> +<summary> +The Fortran 90 compiler. +You should normally set the &cv-link-FORTRAN; variable, +which specifies the default Fortran compiler +for all Fortran versions. +You only need to set &cv-link-F90; if you need to use a specific compiler +or compiler version for Fortran 90 files. +</summary> +</cvar> + +<cvar name="F90COM"> +<summary> +The command line used to compile a Fortran 90 source file to an object file. +You only need to set &cv-link-F90COM; if you need to use a specific +command line for Fortran 90 files. +You should normally set the &cv-link-FORTRANCOM; variable, +which specifies the default command line +for all Fortran versions. +</summary> +</cvar> + +<cvar name="F90COMSTR"> +<summary> +The string displayed when a Fortran 90 source file +is compiled to an object file. +If this is not set, then &cv-link-F90COM; or &cv-link-FORTRANCOM; +(the command line) is displayed. +</summary> +</cvar> + +<cvar name="F90FILESUFFIXES"> +<summary> +The list of file extensions for which the F90 dialect will be used. By +default, this is ['.f90'] +</summary> +</cvar> + +<cvar name="F90PPFILESUFFIXES"> +<summary> +The list of file extensions for which the compilation + preprocessor pass for +F90 dialect will be used. By default, this is empty +</summary> +</cvar> + +<cvar name="F90FLAGS"> +<summary> +General user-specified options that are passed to the Fortran 90 compiler. +Note that this variable does +<emphasis>not</emphasis> +contain +<option>-I</option> +(or similar) include search path options +that scons generates automatically from &cv-link-F90PATH;. +See +&cv-link-_F90INCFLAGS; +below, +for the variable that expands to those options. +You only need to set &cv-link-F90FLAGS; if you need to define specific +user options for Fortran 90 files. +You should normally set the &cv-link-FORTRANFLAGS; variable, +which specifies the user-specified options +passed to the default Fortran compiler +for all Fortran versions. +</summary> +</cvar> + +<cvar name="_F90INCFLAGS"> +<summary> +An automatically-generated construction variable +containing the Fortran 90 compiler command-line options +for specifying directories to be searched for include files. +The value of &cv-link-_F90INCFLAGS; is created +by appending &cv-link-INCPREFIX; and &cv-link-INCSUFFIX; +to the beginning and end +of each directory in &cv-link-F90PATH;. +</summary> +</cvar> + +<cvar name="F90PATH"> +<summary> +The list of directories that the Fortran 90 compiler will search for include +directories. The implicit dependency scanner will search these +directories for include files. Don't explicitly put include directory +arguments in &cv-link-F90FLAGS; because the result will be non-portable +and the directories will not be searched by the dependency scanner. Note: +directory names in &cv-link-F90PATH; will be looked-up relative to the SConscript +directory when they are used in a command. To force +&scons; +to look-up a directory relative to the root of the source tree use #: +You only need to set &cv-link-F90PATH; if you need to define a specific +include path for Fortran 90 files. +You should normally set the &cv-link-FORTRANPATH; variable, +which specifies the include path +for the default Fortran compiler +for all Fortran versions. + +<example> +env = Environment(F90PATH='#/include') +</example> + +The directory look-up can also be forced using the +&Dir;() +function: + +<example> +include = Dir('include') +env = Environment(F90PATH=include) +</example> + +The directory list will be added to command lines +through the automatically-generated +&cv-link-_F90INCFLAGS; +construction variable, +which is constructed by +appending the values of the +&cv-link-INCPREFIX; and &cv-link-INCSUFFIX; +construction variables +to the beginning and end +of each directory in &cv-link-F90PATH;. +Any command lines you define that need +the F90PATH directory list should +include &cv-link-_F90INCFLAGS;: + +<example> +env = Environment(F90COM="my_compiler $_F90INCFLAGS -c -o $TARGET $SOURCE") +</example> +</summary> +</cvar> + +<cvar name="F90PPCOM"> +<summary> +The command line used to compile a Fortran 90 source file to an object file +after first running the file through the C preprocessor. +Any options specified in the &cv-link-F90FLAGS; and &cv-link-CPPFLAGS; construction variables +are included on this command line. +You only need to set &cv-link-F90PPCOM; if you need to use a specific +C-preprocessor command line for Fortran 90 files. +You should normally set the &cv-link-FORTRANPPCOM; variable, +which specifies the default C-preprocessor command line +for all Fortran versions. +</summary> +</cvar> + +<cvar name="F90PPCOMSTR"> +<summary> +The string displayed when a Fortran 90 source file +is compiled after first running the file through the C preprocessor. +If this is not set, then &cv-link-F90PPCOM; or &cv-link-FORTRANPPCOM; +(the command line) is displayed. +</summary> +</cvar> + +<cvar name="SHF90"> +<summary> +The Fortran 90 compiler used for generating shared-library objects. +You should normally set the &cv-link-SHFORTRAN; variable, +which specifies the default Fortran compiler +for all Fortran versions. +You only need to set &cv-link-SHF90; if you need to use a specific compiler +or compiler version for Fortran 90 files. +</summary> +</cvar> + +<cvar name="SHF90COM"> +<summary> +The command line used to compile a Fortran 90 source file +to a shared-library object file. +You only need to set &cv-link-SHF90COM; if you need to use a specific +command line for Fortran 90 files. +You should normally set the &cv-link-SHFORTRANCOM; variable, +which specifies the default command line +for all Fortran versions. +</summary> +</cvar> + +<cvar name="SHF90COMSTR"> +<summary> +The string displayed when a Fortran 90 source file +is compiled to a shared-library object file. +If this is not set, then &cv-link-SHF90COM; or &cv-link-SHFORTRANCOM; +(the command line) is displayed. +</summary> +</cvar> + +<cvar name="SHF90FLAGS"> +<summary> +Options that are passed to the Fortran 90 compiler +to generated shared-library objects. +You only need to set &cv-link-SHF90FLAGS; if you need to define specific +user options for Fortran 90 files. +You should normally set the &cv-link-SHFORTRANFLAGS; variable, +which specifies the user-specified options +passed to the default Fortran compiler +for all Fortran versions. +</summary> +</cvar> + +<cvar name="SHF90PPCOM"> +<summary> +The command line used to compile a Fortran 90 source file to a +shared-library object file +after first running the file through the C preprocessor. +Any options specified in the &cv-link-SHF90FLAGS; and &cv-link-CPPFLAGS; construction variables +are included on this command line. +You only need to set &cv-link-SHF90PPCOM; if you need to use a specific +C-preprocessor command line for Fortran 90 files. +You should normally set the &cv-link-SHFORTRANPPCOM; variable, +which specifies the default C-preprocessor command line +for all Fortran versions. +</summary> +</cvar> + +<cvar name="SHF90PPCOMSTR"> +<summary> +The string displayed when a Fortran 90 source file +is compiled to a shared-library object file +after first running the file through the C preprocessor. +If this is not set, then &cv-link-SHF90PPCOM; or &cv-link-SHFORTRANPPCOM; +(the command line) is displayed. +</summary> +</cvar> diff --git a/src/engine/SCons/Tool/f95.py b/src/engine/SCons/Tool/f95.py new file mode 100644 index 0000000..72e8443 --- /dev/null +++ b/src/engine/SCons/Tool/f95.py @@ -0,0 +1,63 @@ +"""engine.SCons.Tool.f95 + +Tool-specific initialization for the generic Posix f95 Fortran compiler. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/f95.py 4577 2009/12/27 19:44:43 scons" + +import SCons.Defaults +import SCons.Tool +import SCons.Util +import fortran +from SCons.Tool.FortranCommon import add_all_to_env, add_f95_to_env + +compilers = ['f95'] + +def generate(env): + add_all_to_env(env) + add_f95_to_env(env) + + fcomp = env.Detect(compilers) or 'f95' + env['F95'] = fcomp + env['SHF95'] = fcomp + + env['FORTRAN'] = fcomp + env['SHFORTRAN'] = fcomp + + +def exists(env): + return env.Detect(compilers) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/f95.xml b/src/engine/SCons/Tool/f95.xml new file mode 100644 index 0000000..2418cb9 --- /dev/null +++ b/src/engine/SCons/Tool/f95.xml @@ -0,0 +1,252 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="f95"> +<summary> +Set construction variables for generic POSIX Fortran 95 compilers. +</summary> +<sets> +F95 +F95FLAGS +F95COM +F95PPCOM +SHF95 +SHF95FLAGS +SHF95COM +SHF95PPCOM +_F95INCFLAGS +</sets> +<uses> +F95COMSTR +F95PPCOMSTR +SHF95COMSTR +SHF95PPCOMSTR +</uses> +</tool> + +<cvar name="F95"> +<summary> +The Fortran 95 compiler. +You should normally set the &cv-link-FORTRAN; variable, +which specifies the default Fortran compiler +for all Fortran versions. +You only need to set &cv-link-F95; if you need to use a specific compiler +or compiler version for Fortran 95 files. +</summary> +</cvar> + +<cvar name="F95COM"> +<summary> +The command line used to compile a Fortran 95 source file to an object file. +You only need to set &cv-link-F95COM; if you need to use a specific +command line for Fortran 95 files. +You should normally set the &cv-link-FORTRANCOM; variable, +which specifies the default command line +for all Fortran versions. +</summary> +</cvar> + +<cvar name="F95COMSTR"> +<summary> +The string displayed when a Fortran 95 source file +is compiled to an object file. +If this is not set, then &cv-link-F95COM; or &cv-link-FORTRANCOM; +(the command line) is displayed. +</summary> +</cvar> + +<cvar name="F95FILESUFFIXES"> +<summary> +The list of file extensions for which the F95 dialect will be used. By +default, this is ['.f95'] +</summary> +</cvar> + +<cvar name="F95PPFILESUFFIXES"> +<summary> +The list of file extensions for which the compilation + preprocessor pass for +F95 dialect will be used. By default, this is empty +</summary> +</cvar> + +<cvar name="F95FLAGS"> +<summary> +General user-specified options that are passed to the Fortran 95 compiler. +Note that this variable does +<emphasis>not</emphasis> +contain +<option>-I</option> +(or similar) include search path options +that scons generates automatically from &cv-link-F95PATH;. +See +&cv-link-_F95INCFLAGS; +below, +for the variable that expands to those options. +You only need to set &cv-link-F95FLAGS; if you need to define specific +user options for Fortran 95 files. +You should normally set the &cv-link-FORTRANFLAGS; variable, +which specifies the user-specified options +passed to the default Fortran compiler +for all Fortran versions. +</summary> +</cvar> + +<cvar name="_F95INCFLAGS"> +<summary> +An automatically-generated construction variable +containing the Fortran 95 compiler command-line options +for specifying directories to be searched for include files. +The value of &cv-link-_F95INCFLAGS; is created +by appending &cv-link-INCPREFIX; and &cv-link-INCSUFFIX; +to the beginning and end +of each directory in &cv-link-F95PATH;. +</summary> +</cvar> + +<cvar name="F95PATH"> +<summary> +The list of directories that the Fortran 95 compiler will search for include +directories. The implicit dependency scanner will search these +directories for include files. Don't explicitly put include directory +arguments in &cv-link-F95FLAGS; because the result will be non-portable +and the directories will not be searched by the dependency scanner. Note: +directory names in &cv-link-F95PATH; will be looked-up relative to the SConscript +directory when they are used in a command. To force +&scons; +to look-up a directory relative to the root of the source tree use #: +You only need to set &cv-link-F95PATH; if you need to define a specific +include path for Fortran 95 files. +You should normally set the &cv-link-FORTRANPATH; variable, +which specifies the include path +for the default Fortran compiler +for all Fortran versions. + +<example> +env = Environment(F95PATH='#/include') +</example> + +The directory look-up can also be forced using the +&Dir;() +function: + +<example> +include = Dir('include') +env = Environment(F95PATH=include) +</example> + +The directory list will be added to command lines +through the automatically-generated +&cv-link-_F95INCFLAGS; +construction variable, +which is constructed by +appending the values of the +&cv-link-INCPREFIX; and &cv-link-INCSUFFIX; +construction variables +to the beginning and end +of each directory in &cv-link-F95PATH;. +Any command lines you define that need +the F95PATH directory list should +include &cv-link-_F95INCFLAGS;: + +<example> +env = Environment(F95COM="my_compiler $_F95INCFLAGS -c -o $TARGET $SOURCE") +</example> +</summary> +</cvar> + +<cvar name="F95PPCOM"> +<summary> +The command line used to compile a Fortran 95 source file to an object file +after first running the file through the C preprocessor. +Any options specified in the &cv-link-F95FLAGS; and &cv-link-CPPFLAGS; construction variables +are included on this command line. +You only need to set &cv-link-F95PPCOM; if you need to use a specific +C-preprocessor command line for Fortran 95 files. +You should normally set the &cv-link-FORTRANPPCOM; variable, +which specifies the default C-preprocessor command line +for all Fortran versions. +</summary> +</cvar> + +<cvar name="F95PPCOMSTR"> +<summary> +The string displayed when a Fortran 95 source file +is compiled to an object file +after first running the file through the C preprocessor. +If this is not set, then &cv-link-F95PPCOM; or &cv-link-FORTRANPPCOM; +(the command line) is displayed. +</summary> +</cvar> + +<cvar name="SHF95"> +<summary> +The Fortran 95 compiler used for generating shared-library objects. +You should normally set the &cv-link-SHFORTRAN; variable, +which specifies the default Fortran compiler +for all Fortran versions. +You only need to set &cv-link-SHF95; if you need to use a specific compiler +or compiler version for Fortran 95 files. +</summary> +</cvar> + +<cvar name="SHF95COM"> +<summary> +The command line used to compile a Fortran 95 source file +to a shared-library object file. +You only need to set &cv-link-SHF95COM; if you need to use a specific +command line for Fortran 95 files. +You should normally set the &cv-link-SHFORTRANCOM; variable, +which specifies the default command line +for all Fortran versions. +</summary> +</cvar> + +<cvar name="SHF95COMSTR"> +<summary> +The string displayed when a Fortran 95 source file +is compiled to a shared-library object file. +If this is not set, then &cv-link-SHF95COM; or &cv-link-SHFORTRANCOM; +(the command line) is displayed. +</summary> +</cvar> + +<cvar name="SHF95FLAGS"> +<summary> +Options that are passed to the Fortran 95 compiler +to generated shared-library objects. +You only need to set &cv-link-SHF95FLAGS; if you need to define specific +user options for Fortran 95 files. +You should normally set the &cv-link-SHFORTRANFLAGS; variable, +which specifies the user-specified options +passed to the default Fortran compiler +for all Fortran versions. +</summary> +</cvar> + +<cvar name="SHF95PPCOM"> +<summary> +The command line used to compile a Fortran 95 source file to a +shared-library object file +after first running the file through the C preprocessor. +Any options specified in the &cv-link-SHF95FLAGS; and &cv-link-CPPFLAGS; construction variables +are included on this command line. +You only need to set &cv-link-SHF95PPCOM; if you need to use a specific +C-preprocessor command line for Fortran 95 files. +You should normally set the &cv-link-SHFORTRANPPCOM; variable, +which specifies the default C-preprocessor command line +for all Fortran versions. +</summary> +</cvar> + +<cvar name="SHF95PPCOMSTR"> +<summary> +The string displayed when a Fortran 95 source file +is compiled to a shared-library object file +after first running the file through the C preprocessor. +If this is not set, then &cv-link-SHF95PPCOM; or &cv-link-SHFORTRANPPCOM; +(the command line) is displayed. +</summary> +</cvar> diff --git a/src/engine/SCons/Tool/filesystem.py b/src/engine/SCons/Tool/filesystem.py new file mode 100644 index 0000000..bd4c803 --- /dev/null +++ b/src/engine/SCons/Tool/filesystem.py @@ -0,0 +1,98 @@ +"""SCons.Tool.filesystem + +Tool-specific initialization for the filesystem tools. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/filesystem.py 4577 2009/12/27 19:44:43 scons" + +import SCons +from SCons.Tool.install import copyFunc + +copyToBuilder, copyAsBuilder = None, None + +def copyto_emitter(target, source, env): + """ changes the path of the source to be under the target (which + are assumed to be directories. + """ + n_target = [] + + for t in target: + n_target = n_target + map( lambda s, t=t: t.File( str( s ) ), source ) + + return (n_target, source) + +def copy_action_func(target, source, env): + assert( len(target) == len(source) ), "\ntarget: %s\nsource: %s" %(map(str, target),map(str, source)) + + for t, s in zip(target, source): + if copyFunc(t.get_path(), s.get_path(), env): + return 1 + + return 0 + +def copy_action_str(target, source, env): + return env.subst_target_source(env['COPYSTR'], 0, target, source) + +copy_action = SCons.Action.Action( copy_action_func, copy_action_str ) + +def generate(env): + try: + env['BUILDERS']['CopyTo'] + env['BUILDERS']['CopyAs'] + except KeyError, e: + global copyToBuilder + if copyToBuilder is None: + copyToBuilder = SCons.Builder.Builder( + action = copy_action, + target_factory = env.fs.Dir, + source_factory = env.fs.Entry, + multi = 1, + emitter = [ copyto_emitter, ] ) + + global copyAsBuilder + if copyAsBuilder is None: + copyAsBuilder = SCons.Builder.Builder( + action = copy_action, + target_factory = env.fs.Entry, + source_factory = env.fs.Entry ) + + env['BUILDERS']['CopyTo'] = copyToBuilder + env['BUILDERS']['CopyAs'] = copyAsBuilder + + env['COPYSTR'] = 'Copy file(s): "$SOURCES" to "$TARGETS"' + +def exists(env): + return 1 + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/fortran.py b/src/engine/SCons/Tool/fortran.py new file mode 100644 index 0000000..b88c1a9 --- /dev/null +++ b/src/engine/SCons/Tool/fortran.py @@ -0,0 +1,63 @@ +"""SCons.Tool.fortran + +Tool-specific initialization for a generic Posix f77/f90 Fortran compiler. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/fortran.py 4577 2009/12/27 19:44:43 scons" + +import re +import string + +import SCons.Action +import SCons.Defaults +import SCons.Scanner.Fortran +import SCons.Tool +import SCons.Util +from SCons.Tool.FortranCommon import add_all_to_env, add_fortran_to_env + +compilers = ['f95', 'f90', 'f77'] + +def generate(env): + add_all_to_env(env) + add_fortran_to_env(env) + + fc = env.Detect(compilers) or 'f77' + env['SHFORTRAN'] = fc + env['FORTRAN'] = fc + +def exists(env): + return env.Detect(compilers) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/fortran.xml b/src/engine/SCons/Tool/fortran.xml new file mode 100644 index 0000000..1800559 --- /dev/null +++ b/src/engine/SCons/Tool/fortran.xml @@ -0,0 +1,302 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="fortran"> +<summary> +Set construction variables for generic POSIX Fortran compilers. +</summary> +<sets> +FORTRAN +FORTRANFLAGS +FORTRANCOM +SHFORTRAN +SHFORTRANFLAGS +SHFORTRANCOM +SHFORTRANPPCOM +</sets> +<uses> +FORTRANCOMSTR +FORTRANPPCOMSTR +SHFORTRANCOMSTR +SHFORTRANPPCOMSTR +</uses> +</tool> + +<cvar name="FORTRAN"> +<summary> +The default Fortran compiler +for all versions of Fortran. +</summary> +</cvar> + +<cvar name="FORTRANCOM"> +<summary> +The command line used to compile a Fortran source file to an object file. +By default, any options specified +in the &cv-link-FORTRANFLAGS;, +&cv-link-CPPFLAGS;, +&cv-link-_CPPDEFFLAGS;, +&cv-link-_FORTRANMODFLAG;, and +&cv-link-_FORTRANINCFLAGS; construction variables +are included on this command line. +</summary> +</cvar> + +<cvar name="FORTRANCOMSTR"> +<summary> +The string displayed when a Fortran source file +is compiled to an object file. +If this is not set, then &cv-link-FORTRANCOM; +(the command line) is displayed. +</summary> +</cvar> + +<cvar name="FORTRANFILESUFFIXES"> +<summary> +The list of file extensions for which the FORTRAN dialect will be used. By +default, this is ['.f', '.for', '.ftn'] +</summary> +</cvar> + +<cvar name="FORTRANPPFILESUFFIXES"> +<summary> +The list of file extensions for which the compilation + preprocessor pass for +FORTRAN dialect will be used. By default, this is ['.fpp', '.FPP'] +</summary> +</cvar> + +<cvar name="FORTRANFLAGS"> +<summary> +General user-specified options that are passed to the Fortran compiler. +Note that this variable does +<emphasis>not</emphasis> +contain +<option>-I</option> +(or similar) include or module search path options +that scons generates automatically from &cv-link-FORTRANPATH;. +See +&cv-link-_FORTRANINCFLAGS; and &cv-link-_FORTRANMODFLAG;, +below, +for the variables that expand those options. +</summary> +</cvar> + +<cvar name="_FORTRANINCFLAGS"> +<summary> +An automatically-generated construction variable +containing the Fortran compiler command-line options +for specifying directories to be searched for include +files and module files. +The value of &cv-link-_FORTRANINCFLAGS; is created +by prepending/appending &cv-link-INCPREFIX; and &cv-link-INCSUFFIX; +to the beginning and end +of each directory in &cv-link-FORTRANPATH;. +</summary> +</cvar> + +<cvar name="FORTRANMODDIR"> +<summary> +Directory location where the Fortran compiler should place +any module files it generates. This variable is empty, by default. Some +Fortran compilers will internally append this directory in the search path +for module files, as well. +</summary> +</cvar> + +<cvar name="FORTRANMODDIRPREFIX"> +<summary> +The prefix used to specify a module directory on the Fortran compiler command +line. +This will be appended to the beginning of the directory +in the &cv-link-FORTRANMODDIR; construction variables +when the &cv-link-_FORTRANMODFLAG; variables is automatically generated. +</summary> +</cvar> + +<cvar name="FORTRANMODDIRSUFFIX"> +<summary> +The suffix used to specify a module directory on the Fortran compiler command +line. +This will be appended to the beginning of the directory +in the &cv-link-FORTRANMODDIR; construction variables +when the &cv-link-_FORTRANMODFLAG; variables is automatically generated. +</summary> +</cvar> + +<cvar name="_FORTRANMODFLAG"> +<summary> +An automatically-generated construction variable +containing the Fortran compiler command-line option +for specifying the directory location where the Fortran +compiler should place any module files that happen to get +generated during compilation. +The value of &cv-link-_FORTRANMODFLAG; is created +by prepending/appending &cv-link-FORTRANMODDIRPREFIX; and +&cv-link-FORTRANMODDIRSUFFIX; +to the beginning and end of the directory in &cv-link-FORTRANMODDIR;. +</summary> +</cvar> + +<cvar name="FORTRANMODPREFIX"> +<summary> +The module file prefix used by the Fortran compiler. SCons assumes that +the Fortran compiler follows the quasi-standard naming convention for +module files of +<filename>module_name.mod</filename>. +As a result, this variable is left empty, by default. For situations in +which the compiler does not necessarily follow the normal convention, +the user may use this variable. Its value will be appended to every +module file name as scons attempts to resolve dependencies. +</summary> +</cvar> + +<cvar name="FORTRANMODSUFFIX"> +<summary> +The module file suffix used by the Fortran compiler. SCons assumes that +the Fortran compiler follows the quasi-standard naming convention for +module files of +<filename>module_name.mod</filename>. +As a result, this variable is set to ".mod", by default. For situations +in which the compiler does not necessarily follow the normal convention, +the user may use this variable. Its value will be appended to every +module file name as scons attempts to resolve dependencies. +</summary> +</cvar> + +<cvar name="FORTRANPATH"> +<summary> +The list of directories that the Fortran compiler will search for +include files and (for some compilers) module files. The Fortran implicit +dependency scanner will search these directories for include files (but +not module files since they are autogenerated and, as such, may not +actually exist at the time the scan takes place). Don't explicitly put +include directory arguments in FORTRANFLAGS because the result will be +non-portable and the directories will not be searched by the dependency +scanner. Note: directory names in FORTRANPATH will be looked-up relative +to the SConscript directory when they are used in a command. To force +&scons; +to look-up a directory relative to the root of the source tree use #: + +<example> +env = Environment(FORTRANPATH='#/include') +</example> + +The directory look-up can also be forced using the +&Dir;() +function: + +<example> +include = Dir('include') +env = Environment(FORTRANPATH=include) +</example> + +The directory list will be added to command lines +through the automatically-generated +&cv-link-_FORTRANINCFLAGS; +construction variable, +which is constructed by +appending the values of the +&cv-link-INCPREFIX; and &cv-link-INCSUFFIX; +construction variables +to the beginning and end +of each directory in &cv-link-FORTRANPATH;. +Any command lines you define that need +the FORTRANPATH directory list should +include &cv-link-_FORTRANINCFLAGS;: + +<example> +env = Environment(FORTRANCOM="my_compiler $_FORTRANINCFLAGS -c -o $TARGET $SOURCE") +</example> +</summary> +</cvar> + +<cvar name="FORTRANPPCOM"> +<summary> +The command line used to compile a Fortran source file to an object file +after first running the file through the C preprocessor. +By default, any options specified in the &cv-link-FORTRANFLAGS;, +&cv-link-CPPFLAGS;, +&cv-link-_CPPDEFFLAGS;, +&cv-link-_FORTRANMODFLAG;, and +&cv-link-_FORTRANINCFLAGS; +construction variables are included on this command line. +</summary> +</cvar> + +<cvar name="FORTRANPPCOMSTR"> +<summary> +The string displayed when a Fortran source file +is compiled to an object file +after first running the file throught the C preprocessor. +If this is not set, then &cv-link-FORTRANPPCOM; +(the command line) is displayed. +</summary> +</cvar> + +<cvar name="FORTRANSUFFIXES"> +<summary> +The list of suffixes of files that will be scanned +for Fortran implicit dependencies +(INCLUDE lines and USE statements). +The default list is: + +<example> +[".f", ".F", ".for", ".FOR", ".ftn", ".FTN", ".fpp", ".FPP", +".f77", ".F77", ".f90", ".F90", ".f95", ".F95"] +</example> +</summary> +</cvar> + +<cvar name="SHFORTRAN"> +<summary> +The default Fortran compiler used for generating shared-library objects. +</summary> +</cvar> + +<cvar name="SHFORTRANCOM"> +<summary> +The command line used to compile a Fortran source file +to a shared-library object file. +</summary> +</cvar> + +<cvar name="SHFORTRANCOMSTR"> +<summary> +The string displayed when a Fortran source file +is compiled to a shared-library object file. +If this is not set, then &cv-link-SHFORTRANCOM; +(the command line) is displayed. +</summary> +</cvar> + +<cvar name="SHFORTRANFLAGS"> +<summary> +Options that are passed to the Fortran compiler +to generate shared-library objects. +</summary> +</cvar> + +<cvar name="SHFORTRANPPCOM"> +<summary> +The command line used to compile a Fortran source file to a +shared-library object file +after first running the file through the C preprocessor. +Any options specified +in the &cv-link-SHFORTRANFLAGS; and +&cv-link-CPPFLAGS; construction variables +are included on this command line. +</summary> +</cvar> + +<cvar name="SHFORTRANPPCOMSTR"> +<summary> +The string displayed when a Fortran source file +is compiled to a shared-library object file +after first running the file throught the C preprocessor. +If this is not set, then &cv-link-SHFORTRANPPCOM; +(the command line) is displayed. +</summary> +</cvar> diff --git a/src/engine/SCons/Tool/g++.py b/src/engine/SCons/Tool/g++.py new file mode 100644 index 0000000..1ffb254 --- /dev/null +++ b/src/engine/SCons/Tool/g++.py @@ -0,0 +1,90 @@ +"""SCons.Tool.g++ + +Tool-specific initialization for g++. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/g++.py 4577 2009/12/27 19:44:43 scons" + +import os.path +import re +import subprocess + +import SCons.Tool +import SCons.Util + +cplusplus = __import__('c++', globals(), locals(), []) + +compilers = ['g++'] + +def generate(env): + """Add Builders and construction variables for g++ to an Environment.""" + static_obj, shared_obj = SCons.Tool.createObjBuilders(env) + + cplusplus.generate(env) + + env['CXX'] = env.Detect(compilers) + + # platform specific settings + if env['PLATFORM'] == 'aix': + env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS -mminimal-toc') + env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1 + env['SHOBJSUFFIX'] = '$OBJSUFFIX' + elif env['PLATFORM'] == 'hpux': + env['SHOBJSUFFIX'] = '.pic.o' + elif env['PLATFORM'] == 'sunos': + env['SHOBJSUFFIX'] = '.pic.o' + # determine compiler version + if env['CXX']: + #pipe = SCons.Action._subproc(env, [env['CXX'], '-dumpversion'], + pipe = SCons.Action._subproc(env, [env['CXX'], '--version'], + stdin = 'devnull', + stderr = 'devnull', + stdout = subprocess.PIPE) + if pipe.wait() != 0: return + # -dumpversion was added in GCC 3.0. As long as we're supporting + # GCC versions older than that, we should use --version and a + # regular expression. + #line = pipe.stdout.read().strip() + #if line: + # env['CXXVERSION'] = line + line = pipe.stdout.readline() + match = re.search(r'[0-9]+(\.[0-9]+)+', line) + if match: + env['CXXVERSION'] = match.group(0) + +def exists(env): + return env.Detect(compilers) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/g++.xml b/src/engine/SCons/Tool/g++.xml new file mode 100644 index 0000000..37bd2f8 --- /dev/null +++ b/src/engine/SCons/Tool/g++.xml @@ -0,0 +1,18 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="g++"> +<summary> +Set construction variables for the &gXX; C++ compiler. +</summary> +<sets> +CXX +SHCXXFLAGS +<!--STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME--> +SHOBJSUFFIX +CXXVERSION +</sets> +</tool> diff --git a/src/engine/SCons/Tool/g77.py b/src/engine/SCons/Tool/g77.py new file mode 100644 index 0000000..2607b76 --- /dev/null +++ b/src/engine/SCons/Tool/g77.py @@ -0,0 +1,73 @@ +"""engine.SCons.Tool.g77 + +Tool-specific initialization for g77. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/g77.py 4577 2009/12/27 19:44:43 scons" + +import SCons.Util +from SCons.Tool.FortranCommon import add_all_to_env, add_f77_to_env + +compilers = ['g77', 'f77'] + +def generate(env): + """Add Builders and construction variables for g77 to an Environment.""" + add_all_to_env(env) + add_f77_to_env(env) + + fcomp = env.Detect(compilers) or 'g77' + if env['PLATFORM'] in ['cygwin', 'win32']: + env['SHFORTRANFLAGS'] = SCons.Util.CLVar('$FORTRANFLAGS') + env['SHF77FLAGS'] = SCons.Util.CLVar('$F77FLAGS') + else: + env['SHFORTRANFLAGS'] = SCons.Util.CLVar('$FORTRANFLAGS -fPIC') + env['SHF77FLAGS'] = SCons.Util.CLVar('$F77FLAGS -fPIC') + + env['FORTRAN'] = fcomp + env['SHFORTRAN'] = '$FORTRAN' + + env['F77'] = fcomp + env['SHF77'] = '$F77' + + env['INCFORTRANPREFIX'] = "-I" + env['INCFORTRANSUFFIX'] = "" + + env['INCF77PREFIX'] = "-I" + env['INCF77SUFFIX'] = "" + +def exists(env): + return env.Detect(compilers) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/g77.xml b/src/engine/SCons/Tool/g77.xml new file mode 100644 index 0000000..b694580 --- /dev/null +++ b/src/engine/SCons/Tool/g77.xml @@ -0,0 +1,13 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="g77"> +<summary> +Set construction variables for the &g77; Fortran compiler. +Calls the &t-f77; Tool module +to set variables. +</summary> +</tool> diff --git a/src/engine/SCons/Tool/gas.py b/src/engine/SCons/Tool/gas.py new file mode 100644 index 0000000..7ac4d71 --- /dev/null +++ b/src/engine/SCons/Tool/gas.py @@ -0,0 +1,53 @@ +"""SCons.Tool.gas + +Tool-specific initialization for as, the Gnu assembler. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/gas.py 4577 2009/12/27 19:44:43 scons" + +as_module = __import__('as', globals(), locals(), []) + +assemblers = ['as', 'gas'] + +def generate(env): + """Add Builders and construction variables for as to an Environment.""" + as_module.generate(env) + + env['AS'] = env.Detect(assemblers) or 'as' + +def exists(env): + return env.Detect(assemblers) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/gas.xml b/src/engine/SCons/Tool/gas.xml new file mode 100644 index 0000000..6b60b33 --- /dev/null +++ b/src/engine/SCons/Tool/gas.xml @@ -0,0 +1,15 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="gas"> +<summary> +Sets construction variables for the &gas; assembler. +Calls the &t-as; module. +</summary> +<sets> +AS +</sets> +</tool> diff --git a/src/engine/SCons/Tool/gcc.py b/src/engine/SCons/Tool/gcc.py new file mode 100644 index 0000000..58597a6 --- /dev/null +++ b/src/engine/SCons/Tool/gcc.py @@ -0,0 +1,80 @@ +"""SCons.Tool.gcc + +Tool-specific initialization for gcc. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/gcc.py 4577 2009/12/27 19:44:43 scons" + +import cc +import os +import re +import subprocess + +import SCons.Util + +compilers = ['gcc', 'cc'] + +def generate(env): + """Add Builders and construction variables for gcc to an Environment.""" + cc.generate(env) + + env['CC'] = env.Detect(compilers) or 'gcc' + if env['PLATFORM'] in ['cygwin', 'win32']: + env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS') + else: + env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS -fPIC') + # determine compiler version + if env['CC']: + #pipe = SCons.Action._subproc(env, [env['CC'], '-dumpversion'], + pipe = SCons.Action._subproc(env, [env['CC'], '--version'], + stdin = 'devnull', + stderr = 'devnull', + stdout = subprocess.PIPE) + if pipe.wait() != 0: return + # -dumpversion was added in GCC 3.0. As long as we're supporting + # GCC versions older than that, we should use --version and a + # regular expression. + #line = pipe.stdout.read().strip() + #if line: + # env['CCVERSION'] = line + line = pipe.stdout.readline() + match = re.search(r'[0-9]+(\.[0-9]+)+', line) + if match: + env['CCVERSION'] = match.group(0) + +def exists(env): + return env.Detect(compilers) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/gcc.xml b/src/engine/SCons/Tool/gcc.xml new file mode 100644 index 0000000..ac78a98 --- /dev/null +++ b/src/engine/SCons/Tool/gcc.xml @@ -0,0 +1,16 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="gcc"> +<summary> +Set construction variables for the &gcc; C compiler. +</summary> +<sets> +CC +SHCCFLAGS +CCVERSION +</sets> +</tool> diff --git a/src/engine/SCons/Tool/gfortran.py b/src/engine/SCons/Tool/gfortran.py new file mode 100644 index 0000000..79e8817 --- /dev/null +++ b/src/engine/SCons/Tool/gfortran.py @@ -0,0 +1,64 @@ +"""SCons.Tool.gfortran + +Tool-specific initialization for gfortran, the GNU Fortran 95/Fortran +2003 compiler. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/gfortran.py 4577 2009/12/27 19:44:43 scons" + +import SCons.Util + +import fortran + +def generate(env): + """Add Builders and construction variables for gfortran to an + Environment.""" + fortran.generate(env) + + for dialect in ['F77', 'F90', 'FORTRAN', 'F95']: + env['%s' % dialect] = 'gfortran' + env['SH%s' % dialect] = '$%s' % dialect + if env['PLATFORM'] in ['cygwin', 'win32']: + env['SH%sFLAGS' % dialect] = SCons.Util.CLVar('$%sFLAGS' % dialect) + else: + env['SH%sFLAGS' % dialect] = SCons.Util.CLVar('$%sFLAGS -fPIC' % dialect) + + env['INC%sPREFIX' % dialect] = "-I" + env['INC%sSUFFIX' % dialect] = "" + +def exists(env): + return env.Detect('gfortran') + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/gfortran.xml b/src/engine/SCons/Tool/gfortran.xml new file mode 100644 index 0000000..cf6bb9a --- /dev/null +++ b/src/engine/SCons/Tool/gfortran.xml @@ -0,0 +1,25 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="gfortran"> +<summary> +Sets construction variables for the GNU F95/F2003 GNU compiler. +</summary> +<sets> +FORTRAN +F77 +F90 +F95 +SHFORTRAN +SHF77 +SHF90 +SHF95 +SHFORTRANFLAGS +SHF77FLAGS +SHF90FLAGS +SHF95FLAGS +</sets> +</tool> diff --git a/src/engine/SCons/Tool/gnulink.py b/src/engine/SCons/Tool/gnulink.py new file mode 100644 index 0000000..9a12f82 --- /dev/null +++ b/src/engine/SCons/Tool/gnulink.py @@ -0,0 +1,63 @@ +"""SCons.Tool.gnulink + +Tool-specific initialization for the gnu linker. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/gnulink.py 4577 2009/12/27 19:44:43 scons" + +import SCons.Util + +import link + +linkers = ['g++', 'gcc'] + +def generate(env): + """Add Builders and construction variables for gnulink to an Environment.""" + link.generate(env) + + if env['PLATFORM'] == 'hpux': + env['SHLINKFLAGS'] = SCons.Util.CLVar('$LINKFLAGS -shared -fPIC') + + # __RPATH is set to $_RPATH in the platform specification if that + # platform supports it. + env.Append(LINKFLAGS=['$__RPATH']) + env['RPATHPREFIX'] = '-Wl,-rpath=' + env['RPATHSUFFIX'] = '' + env['_RPATH'] = '${_concat(RPATHPREFIX, RPATH, RPATHSUFFIX, __env__)}' + +def exists(env): + return env.Detect(linkers) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/gnulink.xml b/src/engine/SCons/Tool/gnulink.xml new file mode 100644 index 0000000..0f499de --- /dev/null +++ b/src/engine/SCons/Tool/gnulink.xml @@ -0,0 +1,16 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="gnulink"> +<summary> +Set construction variables for GNU linker/loader. +</summary> +<sets> +SHLINKFLAGS +RPATHPREFIX +RPATHSUFFIX +</sets> +</tool> diff --git a/src/engine/SCons/Tool/gs.py b/src/engine/SCons/Tool/gs.py new file mode 100644 index 0000000..2c0db92 --- /dev/null +++ b/src/engine/SCons/Tool/gs.py @@ -0,0 +1,81 @@ +"""SCons.Tool.gs + +Tool-specific initialization for Ghostscript. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/gs.py 4577 2009/12/27 19:44:43 scons" + +import SCons.Action +import SCons.Platform +import SCons.Util + +# Ghostscript goes by different names on different platforms... +platform = SCons.Platform.platform_default() + +if platform == 'os2': + gs = 'gsos2' +elif platform == 'win32': + gs = 'gswin32c' +else: + gs = 'gs' + +GhostscriptAction = None + +def generate(env): + """Add Builders and construction variables for Ghostscript to an + Environment.""" + + global GhostscriptAction + if GhostscriptAction is None: + GhostscriptAction = SCons.Action.Action('$GSCOM', '$GSCOMSTR') + + import pdf + pdf.generate(env) + + bld = env['BUILDERS']['PDF'] + bld.add_action('.ps', GhostscriptAction) + + env['GS'] = gs + env['GSFLAGS'] = SCons.Util.CLVar('-dNOPAUSE -dBATCH -sDEVICE=pdfwrite') + env['GSCOM'] = '$GS $GSFLAGS -sOutputFile=$TARGET $SOURCES' + + +def exists(env): + if env.has_key('PS2PDF'): + return env.Detect(env['PS2PDF']) + else: + return env.Detect(gs) or SCons.Util.WhereIs(gs) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/gs.xml b/src/engine/SCons/Tool/gs.xml new file mode 100644 index 0000000..e1817d5 --- /dev/null +++ b/src/engine/SCons/Tool/gs.xml @@ -0,0 +1,47 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="gs"> +<summary> +Set construction variables for Ghostscript. +</summary> +<sets> +GS +GSFLAGS +GSCOM +</sets> +<uses> +GSCOMSTR +</uses> +</tool> + +<cvar name="GS"> +<summary> +The Ghostscript program used to convert PostScript to PDF files. +</summary> +</cvar> + +<cvar name="GSCOM"> +<summary> +The Ghostscript command line used to convert PostScript to PDF files. +</summary> +</cvar> + +<cvar name="GSCOMSTR"> +<summary> +The string displayed when +Ghostscript is used to convert +a PostScript file to a PDF file. +If this is not set, then &cv-link-GSCOM; (the command line) is displayed. +</summary> +</cvar> + +<cvar name="GSFLAGS"> +<summary> +General options passed to the Ghostscript program +when converting PostScript to PDF files. +</summary> +</cvar> diff --git a/src/engine/SCons/Tool/hpc++.py b/src/engine/SCons/Tool/hpc++.py new file mode 100644 index 0000000..cd7e041 --- /dev/null +++ b/src/engine/SCons/Tool/hpc++.py @@ -0,0 +1,85 @@ +"""SCons.Tool.hpc++ + +Tool-specific initialization for c++ on HP/UX. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/hpc++.py 4577 2009/12/27 19:44:43 scons" + +import os.path +import string + +import SCons.Util + +cplusplus = __import__('c++', globals(), locals(), []) + +acc = None + +# search for the acc compiler and linker front end + +try: + dirs = os.listdir('/opt') +except (IOError, OSError): + # Not being able to read the directory because it doesn't exist + # (IOError) or isn't readable (OSError) is okay. + dirs = [] + +for dir in dirs: + cc = '/opt/' + dir + '/bin/aCC' + if os.path.exists(cc): + acc = cc + break + + +def generate(env): + """Add Builders and construction variables for g++ to an Environment.""" + cplusplus.generate(env) + + if acc: + env['CXX'] = acc or 'aCC' + env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS +Z') + # determine version of aCC + line = os.popen(acc + ' -V 2>&1').readline().rstrip() + if string.find(line, 'aCC: HP ANSI C++') == 0: + env['CXXVERSION'] = string.split(line)[-1] + + if env['PLATFORM'] == 'cygwin': + env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS') + else: + env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS +Z') + +def exists(env): + return acc + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/hpc++.xml b/src/engine/SCons/Tool/hpc++.xml new file mode 100644 index 0000000..3829ae7 --- /dev/null +++ b/src/engine/SCons/Tool/hpc++.xml @@ -0,0 +1,11 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="hpc++"> +<summary> +Set construction variables for the compilers aCC on HP/UX systems. +</summary> +</tool> diff --git a/src/engine/SCons/Tool/hpcc.py b/src/engine/SCons/Tool/hpcc.py new file mode 100644 index 0000000..122e3aa --- /dev/null +++ b/src/engine/SCons/Tool/hpcc.py @@ -0,0 +1,53 @@ +"""SCons.Tool.hpcc + +Tool-specific initialization for HP aCC and cc. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/hpcc.py 4577 2009/12/27 19:44:43 scons" + +import SCons.Util + +import cc + +def generate(env): + """Add Builders and construction variables for aCC & cc to an Environment.""" + cc.generate(env) + + env['CXX'] = 'aCC' + env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS +Z') + +def exists(env): + return env.Detect('aCC') + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/hpcc.xml b/src/engine/SCons/Tool/hpcc.xml new file mode 100644 index 0000000..f103384 --- /dev/null +++ b/src/engine/SCons/Tool/hpcc.xml @@ -0,0 +1,18 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="hpcc"> +<summary> +Set construction variables for the +<application>aCC</application> on HP/UX systems. +Calls the &t-cXX; tool for additional variables. +</summary> +<sets> +CXX +SHCXXFLAGS +CXXVERSION +</sets> +</tool> diff --git a/src/engine/SCons/Tool/hplink.py b/src/engine/SCons/Tool/hplink.py new file mode 100644 index 0000000..32c59a5 --- /dev/null +++ b/src/engine/SCons/Tool/hplink.py @@ -0,0 +1,77 @@ +"""SCons.Tool.hplink + +Tool-specific initialization for the HP linker. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/hplink.py 4577 2009/12/27 19:44:43 scons" + +import os +import os.path + +import SCons.Util + +import link + +ccLinker = None + +# search for the acc compiler and linker front end + +try: + dirs = os.listdir('/opt') +except (IOError, OSError): + # Not being able to read the directory because it doesn't exist + # (IOError) or isn't readable (OSError) is okay. + dirs = [] + +for dir in dirs: + linker = '/opt/' + dir + '/bin/aCC' + if os.path.exists(linker): + ccLinker = linker + break + +def generate(env): + """ + Add Builders and construction variables for Visual Age linker to + an Environment. + """ + link.generate(env) + + env['LINKFLAGS'] = SCons.Util.CLVar('-Wl,+s -Wl,+vnocompatwarnings') + env['SHLINKFLAGS'] = SCons.Util.CLVar('$LINKFLAGS -b') + env['SHLIBSUFFIX'] = '.sl' + +def exists(env): + return ccLinker + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/hplink.xml b/src/engine/SCons/Tool/hplink.xml new file mode 100644 index 0000000..d4c29fb --- /dev/null +++ b/src/engine/SCons/Tool/hplink.xml @@ -0,0 +1,16 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="hplink"> +<summary> +Sets construction variables for the linker on HP/UX systems. +</summary> +<sets> +LINKFLAGS +SHLINKFLAGS +SHLIBSUFFIX +</sets> +</tool> diff --git a/src/engine/SCons/Tool/icc.py b/src/engine/SCons/Tool/icc.py new file mode 100644 index 0000000..78f8606 --- /dev/null +++ b/src/engine/SCons/Tool/icc.py @@ -0,0 +1,59 @@ +"""engine.SCons.Tool.icc + +Tool-specific initialization for the OS/2 icc compiler. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/icc.py 4577 2009/12/27 19:44:43 scons" + +import cc + +def generate(env): + """Add Builders and construction variables for the OS/2 to an Environment.""" + cc.generate(env) + + env['CC'] = 'icc' + env['CCCOM'] = '$CC $CFLAGS $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS /c $SOURCES /Fo$TARGET' + env['CXXCOM'] = '$CXX $CXXFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS /c $SOURCES /Fo$TARGET' + env['CPPDEFPREFIX'] = '/D' + env['CPPDEFSUFFIX'] = '' + env['INCPREFIX'] = '/I' + env['INCSUFFIX'] = '' + env['CFILESUFFIX'] = '.c' + env['CXXFILESUFFIX'] = '.cc' + +def exists(env): + return env.Detect('icc') + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/icc.xml b/src/engine/SCons/Tool/icc.xml new file mode 100644 index 0000000..6b03105 --- /dev/null +++ b/src/engine/SCons/Tool/icc.xml @@ -0,0 +1,30 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="icc"> +<summary> +Sets construction variables for the +<application>icc</application> compiler on OS/2 systems. +</summary> +<sets> +CC +CCCOM +CXXCOM +CPPDEFPREFIX +CPPDEFSUFFIX +INCPREFIX +INCSUFFIX +CFILESUFFIX +CXXFILESUFFIX +</sets> +<uses> +CFLAGS +CCFLAGS +CPPFLAGS +_CPPDEFFLAGS +_CPPINCFLAGS +</uses> +</tool> diff --git a/src/engine/SCons/Tool/icl.py b/src/engine/SCons/Tool/icl.py new file mode 100644 index 0000000..3a43da7 --- /dev/null +++ b/src/engine/SCons/Tool/icl.py @@ -0,0 +1,52 @@ +"""engine.SCons.Tool.icl + +Tool-specific initialization for the Intel C/C++ compiler. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/icl.py 4577 2009/12/27 19:44:43 scons" + +import SCons.Tool.intelc + +# This has been completely superceded by intelc.py, which can +# handle both Windows and Linux versions. + +def generate(*args, **kw): + """Add Builders and construction variables for icl to an Environment.""" + return apply(SCons.Tool.intelc.generate, args, kw) + +def exists(*args, **kw): + return apply(SCons.Tool.intelc.exists, args, kw) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/icl.xml b/src/engine/SCons/Tool/icl.xml new file mode 100644 index 0000000..06dc7af --- /dev/null +++ b/src/engine/SCons/Tool/icl.xml @@ -0,0 +1,12 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="icl"> +<summary> +Sets construction variables for the Intel C/C++ compiler. +Calls the &t-intelc; Tool module to set its variables. +</summary> +</tool> diff --git a/src/engine/SCons/Tool/ifl.py b/src/engine/SCons/Tool/ifl.py new file mode 100644 index 0000000..8fe8c3a --- /dev/null +++ b/src/engine/SCons/Tool/ifl.py @@ -0,0 +1,72 @@ +"""SCons.Tool.ifl + +Tool-specific initialization for the Intel Fortran compiler. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/ifl.py 4577 2009/12/27 19:44:43 scons" + +import SCons.Defaults +from SCons.Scanner.Fortran import FortranScan +from FortranCommon import add_all_to_env + +def generate(env): + """Add Builders and construction variables for ifl to an Environment.""" + fscan = FortranScan("FORTRANPATH") + SCons.Tool.SourceFileScanner.add_scanner('.i', fscan) + SCons.Tool.SourceFileScanner.add_scanner('.i90', fscan) + + if not env.has_key('FORTRANFILESUFFIXES'): + env['FORTRANFILESUFFIXES'] = ['.i'] + else: + env['FORTRANFILESUFFIXES'].append('.i') + + if not env.has_key('F90FILESUFFIXES'): + env['F90FILESUFFIXES'] = ['.i90'] + else: + env['F90FILESUFFIXES'].append('.i90') + + add_all_to_env(env) + + env['FORTRAN'] = 'ifl' + env['SHFORTRAN'] = '$FORTRAN' + env['FORTRANCOM'] = '$FORTRAN $FORTRANFLAGS $_FORTRANINCFLAGS /c $SOURCES /Fo$TARGET' + env['FORTRANPPCOM'] = '$FORTRAN $FORTRANFLAGS $CPPFLAGS $_CPPDEFFLAGS $_FORTRANINCFLAGS /c $SOURCES /Fo$TARGET' + env['SHFORTRANCOM'] = '$SHFORTRAN $SHFORTRANFLAGS $_FORTRANINCFLAGS /c $SOURCES /Fo$TARGET' + env['SHFORTRANPPCOM'] = '$SHFORTRAN $SHFORTRANFLAGS $CPPFLAGS $_CPPDEFFLAGS $_FORTRANINCFLAGS /c $SOURCES /Fo$TARGET' + +def exists(env): + return env.Detect('ifl') + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/ifl.xml b/src/engine/SCons/Tool/ifl.xml new file mode 100644 index 0000000..3456d36 --- /dev/null +++ b/src/engine/SCons/Tool/ifl.xml @@ -0,0 +1,24 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="ifl"> +<summary> +Sets construction variables for the Intel Fortran compiler. +</summary> +<sets> +FORTRAN +FORTRANCOM +FORTRANPPCOM +SHFORTRANCOM +SHFORTRANPPCOM +</sets> +<uses> +FORTRANFLAGS +_FORTRANINCFLAGS +CPPFLAGS +_CPPDEFFLAGS +</uses> +</tool> diff --git a/src/engine/SCons/Tool/ifort.py b/src/engine/SCons/Tool/ifort.py new file mode 100644 index 0000000..250d875 --- /dev/null +++ b/src/engine/SCons/Tool/ifort.py @@ -0,0 +1,90 @@ +"""SCons.Tool.ifort + +Tool-specific initialization for newer versions of the Intel Fortran Compiler +for Linux/Windows (and possibly Mac OS X). + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/ifort.py 4577 2009/12/27 19:44:43 scons" + +import string + +import SCons.Defaults +from SCons.Scanner.Fortran import FortranScan +from FortranCommon import add_all_to_env + +def generate(env): + """Add Builders and construction variables for ifort to an Environment.""" + # ifort supports Fortran 90 and Fortran 95 + # Additionally, ifort recognizes more file extensions. + fscan = FortranScan("FORTRANPATH") + SCons.Tool.SourceFileScanner.add_scanner('.i', fscan) + SCons.Tool.SourceFileScanner.add_scanner('.i90', fscan) + + if not env.has_key('FORTRANFILESUFFIXES'): + env['FORTRANFILESUFFIXES'] = ['.i'] + else: + env['FORTRANFILESUFFIXES'].append('.i') + + if not env.has_key('F90FILESUFFIXES'): + env['F90FILESUFFIXES'] = ['.i90'] + else: + env['F90FILESUFFIXES'].append('.i90') + + add_all_to_env(env) + + fc = 'ifort' + + for dialect in ['F77', 'F90', 'FORTRAN', 'F95']: + env['%s' % dialect] = fc + env['SH%s' % dialect] = '$%s' % dialect + if env['PLATFORM'] == 'posix': + env['SH%sFLAGS' % dialect] = SCons.Util.CLVar('$%sFLAGS -fPIC' % dialect) + + if env['PLATFORM'] == 'win32': + # On Windows, the ifort compiler specifies the object on the + # command line with -object:, not -o. Massage the necessary + # command-line construction variables. + for dialect in ['F77', 'F90', 'FORTRAN', 'F95']: + for var in ['%sCOM' % dialect, '%sPPCOM' % dialect, + 'SH%sCOM' % dialect, 'SH%sPPCOM' % dialect]: + env[var] = string.replace(env[var], '-o $TARGET', '-object:$TARGET') + env['FORTRANMODDIRPREFIX'] = "/module:" + else: + env['FORTRANMODDIRPREFIX'] = "-module " + +def exists(env): + return env.Detect('ifort') + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/ifort.xml b/src/engine/SCons/Tool/ifort.xml new file mode 100644 index 0000000..fc348ab --- /dev/null +++ b/src/engine/SCons/Tool/ifort.xml @@ -0,0 +1,26 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="ifort"> +<summary> +Sets construction variables for newer versions +of the Intel Fortran compiler for Linux. +</summary> +<sets> +FORTRAN +F77 +F90 +F95 +SHFORTRAN +SHF77 +SHF90 +SHF95 +SHFORTRANFLAGS +SHF77FLAGS +SHF90FLAGS +SHF95FLAGS +</sets> +</tool> diff --git a/src/engine/SCons/Tool/ilink.py b/src/engine/SCons/Tool/ilink.py new file mode 100644 index 0000000..c8d74f7 --- /dev/null +++ b/src/engine/SCons/Tool/ilink.py @@ -0,0 +1,59 @@ +"""SCons.Tool.ilink + +Tool-specific initialization for the OS/2 ilink linker. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/ilink.py 4577 2009/12/27 19:44:43 scons" + +import SCons.Defaults +import SCons.Tool +import SCons.Util + +def generate(env): + """Add Builders and construction variables for ilink to an Environment.""" + SCons.Tool.createProgBuilder(env) + + env['LINK'] = 'ilink' + env['LINKFLAGS'] = SCons.Util.CLVar('') + env['LINKCOM'] = '$LINK $LINKFLAGS /O:$TARGET $SOURCES $_LIBDIRFLAGS $_LIBFLAGS' + env['LIBDIRPREFIX']='/LIBPATH:' + env['LIBDIRSUFFIX']='' + env['LIBLINKPREFIX']='' + env['LIBLINKSUFFIX']='$LIBSUFFIX' + +def exists(env): + return env.Detect('ilink') + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/ilink.xml b/src/engine/SCons/Tool/ilink.xml new file mode 100644 index 0000000..a5f25a6 --- /dev/null +++ b/src/engine/SCons/Tool/ilink.xml @@ -0,0 +1,23 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="ilink"> +<summary> +Sets construction variables for the +<application>ilink</application> linker on OS/2 systems. +</summary> +<sets> +LINK +LINKFLAGS +LINKCOM +LIBDIRPREFIX +LIBDIRSUFFIX +LIBLINKPREFIX +LIBLINKSUFFIX +</sets> +<uses> +</uses> +</tool> diff --git a/src/engine/SCons/Tool/ilink32.py b/src/engine/SCons/Tool/ilink32.py new file mode 100644 index 0000000..f0fd9f8 --- /dev/null +++ b/src/engine/SCons/Tool/ilink32.py @@ -0,0 +1,60 @@ +"""SCons.Tool.ilink32 + +XXX + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/ilink32.py 4577 2009/12/27 19:44:43 scons" + +import SCons.Tool +import SCons.Tool.bcc32 +import SCons.Util + +def generate(env): + """Add Builders and construction variables for Borland ilink to an + Environment.""" + SCons.Tool.createSharedLibBuilder(env) + SCons.Tool.createProgBuilder(env) + + env['LINK'] = '$CC' + env['LINKFLAGS'] = SCons.Util.CLVar('') + env['LINKCOM'] = '$LINK -q $LINKFLAGS -e$TARGET $SOURCES $LIBS' + env['LIBDIRPREFIX']='' + env['LIBDIRSUFFIX']='' + env['LIBLINKPREFIX']='' + env['LIBLINKSUFFIX']='$LIBSUFFIX' + + +def exists(env): + # Uses bcc32 to do linking as it generally knows where the standard + # LIBS are and set up the linking correctly + return SCons.Tool.bcc32.findIt('bcc32', env) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/ilink32.xml b/src/engine/SCons/Tool/ilink32.xml new file mode 100644 index 0000000..0528487 --- /dev/null +++ b/src/engine/SCons/Tool/ilink32.xml @@ -0,0 +1,23 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="ilink32"> +<summary> +Sets construction variables for the Borland +<application>ilink32</application> linker. +</summary> +<sets> +LINK +LINKFLAGS +LINKCOM +LIBDIRPREFIX +LIBDIRSUFFIX +LIBLINKPREFIX +LIBLINKSUFFIX +</sets> +<uses> +</uses> +</tool> diff --git a/src/engine/SCons/Tool/install.py b/src/engine/SCons/Tool/install.py new file mode 100644 index 0000000..4c2ac2e --- /dev/null +++ b/src/engine/SCons/Tool/install.py @@ -0,0 +1,229 @@ +"""SCons.Tool.install + +Tool-specific initialization for the install tool. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/install.py 4577 2009/12/27 19:44:43 scons" + +import os +import shutil +import stat + +import SCons.Action +from SCons.Util import make_path_relative + +# +# We keep track of *all* installed files. +_INSTALLED_FILES = [] +_UNIQUE_INSTALLED_FILES = None + +# +# Functions doing the actual work of the Install Builder. +# +def copyFunc(dest, source, env): + """Install a source file or directory into a destination by copying, + (including copying permission/mode bits).""" + + if os.path.isdir(source): + if os.path.exists(dest): + if not os.path.isdir(dest): + raise SCons.Errors.UserError, "cannot overwrite non-directory `%s' with a directory `%s'" % (str(dest), str(source)) + else: + parent = os.path.split(dest)[0] + if not os.path.exists(parent): + os.makedirs(parent) + shutil.copytree(source, dest) + else: + shutil.copy2(source, dest) + st = os.stat(source) + os.chmod(dest, stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE) + + return 0 + +def installFunc(target, source, env): + """Install a source file into a target using the function specified + as the INSTALL construction variable.""" + try: + install = env['INSTALL'] + except KeyError: + raise SCons.Errors.UserError('Missing INSTALL construction variable.') + + assert len(target)==len(source), \ + "Installing source %s into target %s: target and source lists must have same length."%(map(str, source), map(str, target)) + for t,s in zip(target,source): + if install(t.get_path(),s.get_path(),env): + return 1 + + return 0 + +def stringFunc(target, source, env): + installstr = env.get('INSTALLSTR') + if installstr: + return env.subst_target_source(installstr, 0, target, source) + target = str(target[0]) + source = str(source[0]) + if os.path.isdir(source): + type = 'directory' + else: + type = 'file' + return 'Install %s: "%s" as "%s"' % (type, source, target) + +# +# Emitter functions +# +def add_targets_to_INSTALLED_FILES(target, source, env): + """ an emitter that adds all target files to the list stored in the + _INSTALLED_FILES global variable. This way all installed files of one + scons call will be collected. + """ + global _INSTALLED_FILES, _UNIQUE_INSTALLED_FILES + _INSTALLED_FILES.extend(target) + _UNIQUE_INSTALLED_FILES = None + return (target, source) + +class DESTDIR_factory: + """ a node factory, where all files will be relative to the dir supplied + in the constructor. + """ + def __init__(self, env, dir): + self.env = env + self.dir = env.arg2nodes( dir, env.fs.Dir )[0] + + def Entry(self, name): + name = make_path_relative(name) + return self.dir.Entry(name) + + def Dir(self, name): + name = make_path_relative(name) + return self.dir.Dir(name) + +# +# The Builder Definition +# +install_action = SCons.Action.Action(installFunc, stringFunc) +installas_action = SCons.Action.Action(installFunc, stringFunc) + +BaseInstallBuilder = None + +def InstallBuilderWrapper(env, target=None, source=None, dir=None, **kw): + if target and dir: + import SCons.Errors + raise SCons.Errors.UserError, "Both target and dir defined for Install(), only one may be defined." + if not dir: + dir=target + + import SCons.Script + install_sandbox = SCons.Script.GetOption('install_sandbox') + if install_sandbox: + target_factory = DESTDIR_factory(env, install_sandbox) + else: + target_factory = env.fs + + try: + dnodes = env.arg2nodes(dir, target_factory.Dir) + except TypeError: + raise SCons.Errors.UserError, "Target `%s' of Install() is a file, but should be a directory. Perhaps you have the Install() arguments backwards?" % str(dir) + sources = env.arg2nodes(source, env.fs.Entry) + tgt = [] + for dnode in dnodes: + for src in sources: + # Prepend './' so the lookup doesn't interpret an initial + # '#' on the file name portion as meaning the Node should + # be relative to the top-level SConstruct directory. + target = env.fs.Entry('.'+os.sep+src.name, dnode) + #tgt.extend(BaseInstallBuilder(env, target, src, **kw)) + tgt.extend(apply(BaseInstallBuilder, (env, target, src), kw)) + return tgt + +def InstallAsBuilderWrapper(env, target=None, source=None, **kw): + result = [] + for src, tgt in map(lambda x, y: (x, y), source, target): + #result.extend(BaseInstallBuilder(env, tgt, src, **kw)) + result.extend(apply(BaseInstallBuilder, (env, tgt, src), kw)) + return result + +added = None + +def generate(env): + + from SCons.Script import AddOption, GetOption + global added + if not added: + added = 1 + AddOption('--install-sandbox', + dest='install_sandbox', + type="string", + action="store", + help='A directory under which all installed files will be placed.') + + global BaseInstallBuilder + if BaseInstallBuilder is None: + install_sandbox = GetOption('install_sandbox') + if install_sandbox: + target_factory = DESTDIR_factory(env, install_sandbox) + else: + target_factory = env.fs + + BaseInstallBuilder = SCons.Builder.Builder( + action = install_action, + target_factory = target_factory.Entry, + source_factory = env.fs.Entry, + multi = 1, + emitter = [ add_targets_to_INSTALLED_FILES, ], + name = 'InstallBuilder') + + env['BUILDERS']['_InternalInstall'] = InstallBuilderWrapper + env['BUILDERS']['_InternalInstallAs'] = InstallAsBuilderWrapper + + # We'd like to initialize this doing something like the following, + # but there isn't yet support for a ${SOURCE.type} expansion that + # will print "file" or "directory" depending on what's being + # installed. For now we punt by not initializing it, and letting + # the stringFunc() that we put in the action fall back to the + # hand-crafted default string if it's not set. + # + #try: + # env['INSTALLSTR'] + #except KeyError: + # env['INSTALLSTR'] = 'Install ${SOURCE.type}: "$SOURCES" as "$TARGETS"' + + try: + env['INSTALL'] + except KeyError: + env['INSTALL'] = copyFunc + +def exists(env): + return 1 + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/install.xml b/src/engine/SCons/Tool/install.xml new file mode 100644 index 0000000..c9eea00 --- /dev/null +++ b/src/engine/SCons/Tool/install.xml @@ -0,0 +1,52 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> + +<tool name="install"> +<summary> +Sets construction variables for file +and directory installation. +</summary> +<sets> +INSTALL +INSTALLSTR +</sets> +</tool> + +<builder name="Install"> +<summary> +Installs one or more source files or directories +in the specified target, +which must be a directory. +The names of the specified source files or directories +remain the same within the destination directory. + +<example> +env.Install('/usr/local/bin', source = ['foo', 'bar']) +</example> +</summary> +</builder> + +<builder name="InstallAs"> +<summary> +Installs one or more source files or directories +to specific names, +allowing changing a file or directory name +as part of the installation. +It is an error if the +target +and +source +arguments list different numbers of files or directories. + +<example> +env.InstallAs(target = '/usr/local/bin/foo', + source = 'foo_debug') +env.InstallAs(target = ['../lib/libfoo.a', '../lib/libbar.a'], + source = ['libFOO.a', 'libBAR.a']) +</example> +</summary> +</builder> diff --git a/src/engine/SCons/Tool/intelc.py b/src/engine/SCons/Tool/intelc.py new file mode 100644 index 0000000..7add013 --- /dev/null +++ b/src/engine/SCons/Tool/intelc.py @@ -0,0 +1,490 @@ +"""SCons.Tool.icl + +Tool-specific initialization for the Intel C/C++ compiler. +Supports Linux and Windows compilers, v7 and up. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/intelc.py 4577 2009/12/27 19:44:43 scons" + +import math, sys, os.path, glob, string, re + +is_windows = sys.platform == 'win32' +is_win64 = is_windows and (os.environ['PROCESSOR_ARCHITECTURE'] == 'AMD64' or + (os.environ.has_key('PROCESSOR_ARCHITEW6432') and + os.environ['PROCESSOR_ARCHITEW6432'] == 'AMD64')) +is_linux = sys.platform == 'linux2' +is_mac = sys.platform == 'darwin' + +if is_windows: + import SCons.Tool.msvc +elif is_linux: + import SCons.Tool.gcc +elif is_mac: + import SCons.Tool.gcc +import SCons.Util +import SCons.Warnings + +# Exceptions for this tool +class IntelCError(SCons.Errors.InternalError): + pass +class MissingRegistryError(IntelCError): # missing registry entry + pass +class MissingDirError(IntelCError): # dir not found + pass +class NoRegistryModuleError(IntelCError): # can't read registry at all + pass + +def uniquify(s): + """Return a sequence containing only one copy of each unique element from input sequence s. + Does not preserve order. + Input sequence must be hashable (i.e. must be usable as a dictionary key).""" + u = {} + for x in s: + u[x] = 1 + return u.keys() + +def linux_ver_normalize(vstr): + """Normalize a Linux compiler version number. + Intel changed from "80" to "9.0" in 2005, so we assume if the number + is greater than 60 it's an old-style number and otherwise new-style. + Always returns an old-style float like 80 or 90 for compatibility with Windows. + Shades of Y2K!""" + # Check for version number like 9.1.026: return 91.026 + m = re.match(r'([0-9]+)\.([0-9]+)\.([0-9]+)', vstr) + if m: + vmaj,vmin,build = m.groups() + return float(vmaj) * 10 + float(vmin) + float(build) / 1000.; + else: + f = float(vstr) + if is_windows: + return f + else: + if f < 60: return f * 10.0 + else: return f + +def check_abi(abi): + """Check for valid ABI (application binary interface) name, + and map into canonical one""" + if not abi: + return None + abi = abi.lower() + # valid_abis maps input name to canonical name + if is_windows: + valid_abis = {'ia32' : 'ia32', + 'x86' : 'ia32', + 'ia64' : 'ia64', + 'em64t' : 'em64t', + 'amd64' : 'em64t'} + if is_linux: + valid_abis = {'ia32' : 'ia32', + 'x86' : 'ia32', + 'x86_64' : 'x86_64', + 'em64t' : 'x86_64', + 'amd64' : 'x86_64'} + if is_mac: + valid_abis = {'ia32' : 'ia32', + 'x86' : 'ia32', + 'x86_64' : 'x86_64', + 'em64t' : 'x86_64'} + try: + abi = valid_abis[abi] + except KeyError: + raise SCons.Errors.UserError, \ + "Intel compiler: Invalid ABI %s, valid values are %s"% \ + (abi, valid_abis.keys()) + return abi + +def vercmp(a, b): + """Compare strings as floats, + but Intel changed Linux naming convention at 9.0""" + return cmp(linux_ver_normalize(b), linux_ver_normalize(a)) + +def get_version_from_list(v, vlist): + """See if we can match v (string) in vlist (list of strings) + Linux has to match in a fuzzy way.""" + if is_windows: + # Simple case, just find it in the list + if v in vlist: return v + else: return None + else: + # Fuzzy match: normalize version number first, but still return + # original non-normalized form. + fuzz = 0.001 + for vi in vlist: + if math.fabs(linux_ver_normalize(vi) - linux_ver_normalize(v)) < fuzz: + return vi + # Not found + return None + +def get_intel_registry_value(valuename, version=None, abi=None): + """ + Return a value from the Intel compiler registry tree. (Windows only) + """ + # Open the key: + if is_win64: + K = 'Software\\Wow6432Node\\Intel\\Compilers\\C++\\' + version + '\\'+abi.upper() + else: + K = 'Software\\Intel\\Compilers\\C++\\' + version + '\\'+abi.upper() + try: + k = SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_LOCAL_MACHINE, K) + except SCons.Util.RegError: + raise MissingRegistryError, \ + "%s was not found in the registry, for Intel compiler version %s, abi='%s'"%(K, version,abi) + + # Get the value: + try: + v = SCons.Util.RegQueryValueEx(k, valuename)[0] + return v # or v.encode('iso-8859-1', 'replace') to remove unicode? + except SCons.Util.RegError: + raise MissingRegistryError, \ + "%s\\%s was not found in the registry."%(K, valuename) + + +def get_all_compiler_versions(): + """Returns a sorted list of strings, like "70" or "80" or "9.0" + with most recent compiler version first. + """ + versions=[] + if is_windows: + if is_win64: + keyname = 'Software\\WoW6432Node\\Intel\\Compilers\\C++' + else: + keyname = 'Software\\Intel\\Compilers\\C++' + try: + k = SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_LOCAL_MACHINE, + keyname) + except WindowsError: + return [] + i = 0 + versions = [] + try: + while i < 100: + subkey = SCons.Util.RegEnumKey(k, i) # raises EnvironmentError + # Check that this refers to an existing dir. + # This is not 100% perfect but should catch common + # installation issues like when the compiler was installed + # and then the install directory deleted or moved (rather + # than uninstalling properly), so the registry values + # are still there. + ok = False + for try_abi in ('IA32', 'IA32e', 'IA64', 'EM64T'): + try: + d = get_intel_registry_value('ProductDir', subkey, try_abi) + except MissingRegistryError: + continue # not found in reg, keep going + if os.path.exists(d): ok = True + if ok: + versions.append(subkey) + else: + try: + # Registry points to nonexistent dir. Ignore this + # version. + value = get_intel_registry_value('ProductDir', subkey, 'IA32') + except MissingRegistryError, e: + + # Registry key is left dangling (potentially + # after uninstalling). + + print \ + "scons: *** Ignoring the registry key for the Intel compiler version %s.\n" \ + "scons: *** It seems that the compiler was uninstalled and that the registry\n" \ + "scons: *** was not cleaned up properly.\n" % subkey + else: + print "scons: *** Ignoring "+str(value) + + i = i + 1 + except EnvironmentError: + # no more subkeys + pass + elif is_linux: + for d in glob.glob('/opt/intel_cc_*'): + # Typical dir here is /opt/intel_cc_80. + m = re.search(r'cc_(.*)$', d) + if m: + versions.append(m.group(1)) + for d in glob.glob('/opt/intel/cc*/*'): + # Typical dir here is /opt/intel/cc/9.0 for IA32, + # /opt/intel/cce/9.0 for EMT64 (AMD64) + m = re.search(r'([0-9.]+)$', d) + if m: + versions.append(m.group(1)) + elif is_mac: + for d in glob.glob('/opt/intel/cc*/*'): + # Typical dir here is /opt/intel/cc/9.0 for IA32, + # /opt/intel/cce/9.0 for EMT64 (AMD64) + m = re.search(r'([0-9.]+)$', d) + if m: + versions.append(m.group(1)) + versions = uniquify(versions) # remove dups + versions.sort(vercmp) + return versions + +def get_intel_compiler_top(version, abi): + """ + Return the main path to the top-level dir of the Intel compiler, + using the given version. + The compiler will be in <top>/bin/icl.exe (icc on linux), + the include dir is <top>/include, etc. + """ + + if is_windows: + if not SCons.Util.can_read_reg: + raise NoRegistryModuleError, "No Windows registry module was found" + top = get_intel_registry_value('ProductDir', version, abi) + # pre-11, icl was in Bin. 11 and later, it's in Bin/<abi> apparently. + if not os.path.exists(os.path.join(top, "Bin", "icl.exe")) \ + and not os.path.exists(os.path.join(top, "Bin", abi, "icl.exe")): + raise MissingDirError, \ + "Can't find Intel compiler in %s"%(top) + elif is_mac or is_linux: + # first dir is new (>=9.0) style, second is old (8.0) style. + dirs=('/opt/intel/cc/%s', '/opt/intel_cc_%s') + if abi == 'x86_64': + dirs=('/opt/intel/cce/%s',) # 'e' stands for 'em64t', aka x86_64 aka amd64 + top=None + for d in dirs: + if os.path.exists(os.path.join(d%version, "bin", "icc")): + top = d%version + break + if not top: + raise MissingDirError, \ + "Can't find version %s Intel compiler in %s (abi='%s')"%(version,top, abi) + return top + + +def generate(env, version=None, abi=None, topdir=None, verbose=0): + """Add Builders and construction variables for Intel C/C++ compiler + to an Environment. + args: + version: (string) compiler version to use, like "80" + abi: (string) 'win32' or whatever Itanium version wants + topdir: (string) compiler top dir, like + "c:\Program Files\Intel\Compiler70" + If topdir is used, version and abi are ignored. + verbose: (int) if >0, prints compiler version used. + """ + if not (is_mac or is_linux or is_windows): + # can't handle this platform + return + + if is_windows: + SCons.Tool.msvc.generate(env) + elif is_linux: + SCons.Tool.gcc.generate(env) + elif is_mac: + SCons.Tool.gcc.generate(env) + + # if version is unspecified, use latest + vlist = get_all_compiler_versions() + if not version: + if vlist: + version = vlist[0] + else: + # User may have specified '90' but we need to get actual dirname '9.0'. + # get_version_from_list does that mapping. + v = get_version_from_list(version, vlist) + if not v: + raise SCons.Errors.UserError, \ + "Invalid Intel compiler version %s: "%version + \ + "installed versions are %s"%(', '.join(vlist)) + version = v + + # if abi is unspecified, use ia32 + # alternatives are ia64 for Itanium, or amd64 or em64t or x86_64 (all synonyms here) + abi = check_abi(abi) + if abi is None: + if is_mac or is_linux: + # Check if we are on 64-bit linux, default to 64 then. + uname_m = os.uname()[4] + if uname_m == 'x86_64': + abi = 'x86_64' + else: + abi = 'ia32' + else: + if is_win64: + abi = 'em64t' + else: + abi = 'ia32' + + if version and not topdir: + try: + topdir = get_intel_compiler_top(version, abi) + except (SCons.Util.RegError, IntelCError): + topdir = None + + if not topdir: + # Normally this is an error, but it might not be if the compiler is + # on $PATH and the user is importing their env. + class ICLTopDirWarning(SCons.Warnings.Warning): + pass + if (is_mac or is_linux) and not env.Detect('icc') or \ + is_windows and not env.Detect('icl'): + + SCons.Warnings.enableWarningClass(ICLTopDirWarning) + SCons.Warnings.warn(ICLTopDirWarning, + "Failed to find Intel compiler for version='%s', abi='%s'"% + (str(version), str(abi))) + else: + # should be cleaned up to say what this other version is + # since in this case we have some other Intel compiler installed + SCons.Warnings.enableWarningClass(ICLTopDirWarning) + SCons.Warnings.warn(ICLTopDirWarning, + "Can't find Intel compiler top dir for version='%s', abi='%s'"% + (str(version), str(abi))) + + if topdir: + if verbose: + print "Intel C compiler: using version %s (%g), abi %s, in '%s'"%\ + (repr(version), linux_ver_normalize(version),abi,topdir) + if is_linux: + # Show the actual compiler version by running the compiler. + os.system('%s/bin/icc --version'%topdir) + if is_mac: + # Show the actual compiler version by running the compiler. + os.system('%s/bin/icc --version'%topdir) + + env['INTEL_C_COMPILER_TOP'] = topdir + if is_linux: + paths={'INCLUDE' : 'include', + 'LIB' : 'lib', + 'PATH' : 'bin', + 'LD_LIBRARY_PATH' : 'lib'} + for p in paths.keys(): + env.PrependENVPath(p, os.path.join(topdir, paths[p])) + if is_mac: + paths={'INCLUDE' : 'include', + 'LIB' : 'lib', + 'PATH' : 'bin', + 'LD_LIBRARY_PATH' : 'lib'} + for p in paths.keys(): + env.PrependENVPath(p, os.path.join(topdir, paths[p])) + if is_windows: + # env key reg valname default subdir of top + paths=(('INCLUDE', 'IncludeDir', 'Include'), + ('LIB' , 'LibDir', 'Lib'), + ('PATH' , 'BinDir', 'Bin')) + # We are supposed to ignore version if topdir is set, so set + # it to the emptry string if it's not already set. + if version is None: + version = '' + # Each path has a registry entry, use that or default to subdir + for p in paths: + try: + path=get_intel_registry_value(p[1], version, abi) + # These paths may have $(ICInstallDir) + # which needs to be substituted with the topdir. + path=path.replace('$(ICInstallDir)', topdir + os.sep) + except IntelCError: + # Couldn't get it from registry: use default subdir of topdir + env.PrependENVPath(p[0], os.path.join(topdir, p[2])) + else: + env.PrependENVPath(p[0], string.split(path, os.pathsep)) + # print "ICL %s: %s, final=%s"%(p[0], path, str(env['ENV'][p[0]])) + + if is_windows: + env['CC'] = 'icl' + env['CXX'] = 'icl' + env['LINK'] = 'xilink' + else: + env['CC'] = 'icc' + env['CXX'] = 'icpc' + # Don't reset LINK here; + # use smart_link which should already be here from link.py. + #env['LINK'] = '$CC' + env['AR'] = 'xiar' + env['LD'] = 'xild' # not used by default + + # This is not the exact (detailed) compiler version, + # just the major version as determined above or specified + # by the user. It is a float like 80 or 90, in normalized form for Linux + # (i.e. even for Linux 9.0 compiler, still returns 90 rather than 9.0) + if version: + env['INTEL_C_COMPILER_VERSION']=linux_ver_normalize(version) + + if is_windows: + # Look for license file dir + # in system environment, registry, and default location. + envlicdir = os.environ.get("INTEL_LICENSE_FILE", '') + K = ('SOFTWARE\Intel\Licenses') + try: + k = SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_LOCAL_MACHINE, K) + reglicdir = SCons.Util.RegQueryValueEx(k, "w_cpp")[0] + except (AttributeError, SCons.Util.RegError): + reglicdir = "" + defaultlicdir = r'C:\Program Files\Common Files\Intel\Licenses' + + licdir = None + for ld in [envlicdir, reglicdir]: + # If the string contains an '@', then assume it's a network + # license (port@system) and good by definition. + if ld and (string.find(ld, '@') != -1 or os.path.exists(ld)): + licdir = ld + break + if not licdir: + licdir = defaultlicdir + if not os.path.exists(licdir): + class ICLLicenseDirWarning(SCons.Warnings.Warning): + pass + SCons.Warnings.enableWarningClass(ICLLicenseDirWarning) + SCons.Warnings.warn(ICLLicenseDirWarning, + "Intel license dir was not found." + " Tried using the INTEL_LICENSE_FILE environment variable (%s), the registry (%s) and the default path (%s)." + " Using the default path as a last resort." + % (envlicdir, reglicdir, defaultlicdir)) + env['ENV']['INTEL_LICENSE_FILE'] = licdir + +def exists(env): + if not (is_mac or is_linux or is_windows): + # can't handle this platform + return 0 + + try: + versions = get_all_compiler_versions() + except (SCons.Util.RegError, IntelCError): + versions = None + detected = versions is not None and len(versions) > 0 + if not detected: + # try env.Detect, maybe that will work + if is_windows: + return env.Detect('icl') + elif is_linux: + return env.Detect('icc') + elif is_mac: + return env.Detect('icc') + return detected + +# end of file + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/intelc.xml b/src/engine/SCons/Tool/intelc.xml new file mode 100644 index 0000000..61fb8d8 --- /dev/null +++ b/src/engine/SCons/Tool/intelc.xml @@ -0,0 +1,33 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="intelc"> +<summary> +Sets construction variables for the Intel C/C++ compiler +(Linux and Windows, version 7 and later). +Calls the &t-gcc; or &t-msvc; +(on Linux and Windows, respectively) +to set underlying variables. +</summary> +<sets> +CC +CXX +LINK +AR +<!--LD--> +INTEL_C_COMPILER_VERSION +</sets> +<uses> +</uses> +</tool> + +<cvar name="INTEL_C_COMPILER_VERSION"> +<summary> +Set by the "intelc" Tool +to the major version number of the Intel C compiler +selected for use. +</summary> +</cvar> diff --git a/src/engine/SCons/Tool/ipkg.py b/src/engine/SCons/Tool/ipkg.py new file mode 100644 index 0000000..b026938 --- /dev/null +++ b/src/engine/SCons/Tool/ipkg.py @@ -0,0 +1,71 @@ +"""SCons.Tool.ipkg + +Tool-specific initialization for ipkg. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +The ipkg tool calls the ipkg-build. Its only argument should be the +packages fake_root. +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/ipkg.py 4577 2009/12/27 19:44:43 scons" + +import os +import string + +import SCons.Builder + +def generate(env): + """Add Builders and construction variables for ipkg to an Environment.""" + try: + bld = env['BUILDERS']['Ipkg'] + except KeyError: + bld = SCons.Builder.Builder( action = '$IPKGCOM', + suffix = '$IPKGSUFFIX', + source_scanner = None, + target_scanner = None) + env['BUILDERS']['Ipkg'] = bld + + env['IPKG'] = 'ipkg-build' + env['IPKGCOM'] = '$IPKG $IPKGFLAGS ${SOURCE}' + # TODO(1.5) + #env['IPKGUSER'] = os.popen('id -un').read().strip() + #env['IPKGGROUP'] = os.popen('id -gn').read().strip() + env['IPKGUSER'] = string.strip(os.popen('id -un').read()) + env['IPKGGROUP'] = string.strip(os.popen('id -gn').read()) + env['IPKGFLAGS'] = SCons.Util.CLVar('-o $IPKGUSER -g $IPKGGROUP') + env['IPKGSUFFIX'] = '.ipk' + +def exists(env): + return env.Detect('ipkg-build') + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/jar.py b/src/engine/SCons/Tool/jar.py new file mode 100644 index 0000000..1c086c2 --- /dev/null +++ b/src/engine/SCons/Tool/jar.py @@ -0,0 +1,110 @@ +"""SCons.Tool.jar + +Tool-specific initialization for jar. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/jar.py 4577 2009/12/27 19:44:43 scons" + +import SCons.Subst +import SCons.Util + +def jarSources(target, source, env, for_signature): + """Only include sources that are not a manifest file.""" + try: + env['JARCHDIR'] + except KeyError: + jarchdir_set = False + else: + jarchdir_set = True + jarchdir = env.subst('$JARCHDIR', target=target, source=source) + if jarchdir: + jarchdir = env.fs.Dir(jarchdir) + result = [] + for src in source: + contents = src.get_text_contents() + if contents[:16] != "Manifest-Version": + if jarchdir_set: + _chdir = jarchdir + else: + try: + _chdir = src.attributes.java_classdir + except AttributeError: + _chdir = None + if _chdir: + # If we are changing the dir with -C, then sources should + # be relative to that directory. + src = SCons.Subst.Literal(src.get_path(_chdir)) + result.append('-C') + result.append(_chdir) + result.append(src) + return result + +def jarManifest(target, source, env, for_signature): + """Look in sources for a manifest file, if any.""" + for src in source: + contents = src.get_text_contents() + if contents[:16] == "Manifest-Version": + return src + return '' + +def jarFlags(target, source, env, for_signature): + """If we have a manifest, make sure that the 'm' + flag is specified.""" + jarflags = env.subst('$JARFLAGS', target=target, source=source) + for src in source: + contents = src.get_text_contents() + if contents[:16] == "Manifest-Version": + if not 'm' in jarflags: + return jarflags + 'm' + break + return jarflags + +def generate(env): + """Add Builders and construction variables for jar to an Environment.""" + SCons.Tool.CreateJarBuilder(env) + + env['JAR'] = 'jar' + env['JARFLAGS'] = SCons.Util.CLVar('cf') + env['_JARFLAGS'] = jarFlags + env['_JARMANIFEST'] = jarManifest + env['_JARSOURCES'] = jarSources + env['_JARCOM'] = '$JAR $_JARFLAGS $TARGET $_JARMANIFEST $_JARSOURCES' + env['JARCOM'] = "${TEMPFILE('$_JARCOM')}" + env['JARSUFFIX'] = '.jar' + +def exists(env): + return env.Detect('jar') + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/jar.xml b/src/engine/SCons/Tool/jar.xml new file mode 100644 index 0000000..d6a986d --- /dev/null +++ b/src/engine/SCons/Tool/jar.xml @@ -0,0 +1,110 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="jar"> +<summary> +Sets construction variables for the &jar; utility. +</summary> +<sets> +JAR +JARFLAGS +JARCOM +JARSUFFIX +</sets> +<uses> +JARCOMSTR +</uses> +</tool> + +<builder name="Jar"> +<summary> +Builds a Java archive (<filename>.jar</filename>) file +from the specified list of sources. +Any directories in the source list +will be searched for <filename>.class</filename> files). +Any <filename>.java</filename> files in the source list +will be compiled to <filename>.class</filename> files +by calling the &b-link-Java; Builder. + +If the &cv-link-JARCHDIR; value is set, the +&jar; +command will change to the specified directory using the +<option>-C</option> +option. +If &cv-JARCHDIR; is not set explicitly, +&SCons; will use the top of any subdirectory tree +in which Java <filename>.class</filename> +were built by the &b-link-Java; Builder. + +If the contents any of the source files begin with the string +<literal>Manifest-Version</literal>, +the file is assumed to be a manifest +and is passed to the +&jar; +command with the +<option>m</option> +option set. + +<example> +env.Jar(target = 'foo.jar', source = 'classes') + +env.Jar(target = 'bar.jar', + source = ['bar1.java', 'bar2.java']) +</example> +</summary> +</builder> + +<cvar name="JAR"> +<summary> +The Java archive tool. +</summary> +</cvar> + +<cvar name="JARCHDIR"> +<summary> +The directory to which the Java archive tool should change +(using the +<option>-C</option> +option). +</summary> +</cvar> + +<cvar name="JARCOM"> +<summary> +The command line used to call the Java archive tool. +</summary> +</cvar> + +<cvar name="JARCOMSTR"> +<summary> +The string displayed when the Java archive tool +is called +If this is not set, then &cv-link-JARCOM; (the command line) is displayed. + +<example> +env = Environment(JARCOMSTR = "JARchiving $SOURCES into $TARGET") +</example> +</summary> +</cvar> + +<cvar name="JARFLAGS"> +<summary> +General options passed to the Java archive tool. +By default this is set to +<option>cf</option> +to create the necessary +<command>jar</command> +file. +</summary> +</cvar> + +<cvar name="JARSUFFIX"> +<summary> +The suffix for Java archives: +<filename>.jar</filename> +by default. +</summary> +</cvar> diff --git a/src/engine/SCons/Tool/javac.py b/src/engine/SCons/Tool/javac.py new file mode 100644 index 0000000..e51afe2 --- /dev/null +++ b/src/engine/SCons/Tool/javac.py @@ -0,0 +1,234 @@ +"""SCons.Tool.javac + +Tool-specific initialization for javac. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/javac.py 4577 2009/12/27 19:44:43 scons" + +import os +import os.path +import string + +import SCons.Action +import SCons.Builder +from SCons.Node.FS import _my_normcase +from SCons.Tool.JavaCommon import parse_java_file +import SCons.Util + +def classname(path): + """Turn a string (path name) into a Java class name.""" + return string.replace(os.path.normpath(path), os.sep, '.') + +def emit_java_classes(target, source, env): + """Create and return lists of source java files + and their corresponding target class files. + """ + java_suffix = env.get('JAVASUFFIX', '.java') + class_suffix = env.get('JAVACLASSSUFFIX', '.class') + + target[0].must_be_same(SCons.Node.FS.Dir) + classdir = target[0] + + s = source[0].rentry().disambiguate() + if isinstance(s, SCons.Node.FS.File): + sourcedir = s.dir.rdir() + elif isinstance(s, SCons.Node.FS.Dir): + sourcedir = s.rdir() + else: + raise SCons.Errors.UserError("Java source must be File or Dir, not '%s'" % s.__class__) + + slist = [] + js = _my_normcase(java_suffix) + find_java = lambda n, js=js, ljs=len(js): _my_normcase(n[-ljs:]) == js + for entry in source: + entry = entry.rentry().disambiguate() + if isinstance(entry, SCons.Node.FS.File): + slist.append(entry) + elif isinstance(entry, SCons.Node.FS.Dir): + result = SCons.Util.OrderedDict() + def visit(arg, dirname, names, fj=find_java, dirnode=entry.rdir()): + java_files = filter(fj, names) + # The on-disk entries come back in arbitrary order. Sort + # them so our target and source lists are determinate. + java_files.sort() + mydir = dirnode.Dir(dirname) + java_paths = map(lambda f, d=mydir: d.File(f), java_files) + for jp in java_paths: + arg[jp] = True + + os.path.walk(entry.rdir().get_abspath(), visit, result) + entry.walk(visit, result) + + slist.extend(result.keys()) + else: + raise SCons.Errors.UserError("Java source must be File or Dir, not '%s'" % entry.__class__) + + version = env.get('JAVAVERSION', '1.4') + full_tlist = [] + for f in slist: + tlist = [] + source_file_based = True + pkg_dir = None + if not f.is_derived(): + pkg_dir, classes = parse_java_file(f.rfile().get_abspath(), version) + if classes: + source_file_based = False + if pkg_dir: + d = target[0].Dir(pkg_dir) + p = pkg_dir + os.sep + else: + d = target[0] + p = '' + for c in classes: + t = d.File(c + class_suffix) + t.attributes.java_classdir = classdir + t.attributes.java_sourcedir = sourcedir + t.attributes.java_classname = classname(p + c) + tlist.append(t) + + if source_file_based: + base = f.name[:-len(java_suffix)] + if pkg_dir: + t = target[0].Dir(pkg_dir).File(base + class_suffix) + else: + t = target[0].File(base + class_suffix) + t.attributes.java_classdir = classdir + t.attributes.java_sourcedir = f.dir + t.attributes.java_classname = classname(base) + tlist.append(t) + + for t in tlist: + t.set_specific_source([f]) + + full_tlist.extend(tlist) + + return full_tlist, slist + +JavaAction = SCons.Action.Action('$JAVACCOM', '$JAVACCOMSTR') + +JavaBuilder = SCons.Builder.Builder(action = JavaAction, + emitter = emit_java_classes, + target_factory = SCons.Node.FS.Entry, + source_factory = SCons.Node.FS.Entry) + +class pathopt: + """ + Callable object for generating javac-style path options from + a construction variable (e.g. -classpath, -sourcepath). + """ + def __init__(self, opt, var, default=None): + self.opt = opt + self.var = var + self.default = default + + def __call__(self, target, source, env, for_signature): + path = env[self.var] + if path and not SCons.Util.is_List(path): + path = [path] + if self.default: + path = path + [ env[self.default] ] + if path: + return [self.opt, string.join(path, os.pathsep)] + #return self.opt + " " + string.join(path, os.pathsep) + else: + return [] + #return "" + +def Java(env, target, source, *args, **kw): + """ + A pseudo-Builder wrapper around the separate JavaClass{File,Dir} + Builders. + """ + if not SCons.Util.is_List(target): + target = [target] + if not SCons.Util.is_List(source): + source = [source] + + # Pad the target list with repetitions of the last element in the + # list so we have a target for every source element. + target = target + ([target[-1]] * (len(source) - len(target))) + + java_suffix = env.subst('$JAVASUFFIX') + result = [] + + for t, s in zip(target, source): + if isinstance(s, SCons.Node.FS.Base): + if isinstance(s, SCons.Node.FS.File): + b = env.JavaClassFile + else: + b = env.JavaClassDir + else: + if os.path.isfile(s): + b = env.JavaClassFile + elif os.path.isdir(s): + b = env.JavaClassDir + elif s[-len(java_suffix):] == java_suffix: + b = env.JavaClassFile + else: + b = env.JavaClassDir + result.extend(apply(b, (t, s) + args, kw)) + + return result + +def generate(env): + """Add Builders and construction variables for javac to an Environment.""" + java_file = SCons.Tool.CreateJavaFileBuilder(env) + java_class = SCons.Tool.CreateJavaClassFileBuilder(env) + java_class_dir = SCons.Tool.CreateJavaClassDirBuilder(env) + java_class.add_emitter(None, emit_java_classes) + java_class.add_emitter(env.subst('$JAVASUFFIX'), emit_java_classes) + java_class_dir.emitter = emit_java_classes + + env.AddMethod(Java) + + env['JAVAC'] = 'javac' + env['JAVACFLAGS'] = SCons.Util.CLVar('') + env['JAVABOOTCLASSPATH'] = [] + env['JAVACLASSPATH'] = [] + env['JAVASOURCEPATH'] = [] + env['_javapathopt'] = pathopt + env['_JAVABOOTCLASSPATH'] = '${_javapathopt("-bootclasspath", "JAVABOOTCLASSPATH")} ' + env['_JAVACLASSPATH'] = '${_javapathopt("-classpath", "JAVACLASSPATH")} ' + env['_JAVASOURCEPATH'] = '${_javapathopt("-sourcepath", "JAVASOURCEPATH", "_JAVASOURCEPATHDEFAULT")} ' + env['_JAVASOURCEPATHDEFAULT'] = '${TARGET.attributes.java_sourcedir}' + env['_JAVACCOM'] = '$JAVAC $JAVACFLAGS $_JAVABOOTCLASSPATH $_JAVACLASSPATH -d ${TARGET.attributes.java_classdir} $_JAVASOURCEPATH $SOURCES' + env['JAVACCOM'] = "${TEMPFILE('$_JAVACCOM')}" + env['JAVACLASSSUFFIX'] = '.class' + env['JAVASUFFIX'] = '.java' + +def exists(env): + return 1 + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/javac.xml b/src/engine/SCons/Tool/javac.xml new file mode 100644 index 0000000..a55e514 --- /dev/null +++ b/src/engine/SCons/Tool/javac.xml @@ -0,0 +1,224 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="javac"> +<summary> +Sets construction variables for the &javac; compiler. +</summary> +<sets> +JAVAC +JAVACFLAGS +JAVACCOM +JAVACLASSSUFFIX +JAVASUFFIX +JAVABOOTCLASSPATH +JAVACLASSPATH +JAVASOURCEPATH +</sets> +<uses> +JAVACCOMSTR +</uses> +</tool> + +<builder name="Java"> +<summary> +Builds one or more Java class files. +The sources may be any combination of explicit +<filename>.java</filename> files, +or directory trees which will be scanned +for <filename>.java</filename> files. + +SCons will parse each source <filename>.java</filename> file +to find the classes +(including inner classes) +defined within that file, +and from that figure out the +target <filename>.class</filename> files that will be created. +The class files will be placed underneath +the specified target directory. + +SCons will also search each Java file +for the Java package name, +which it assumes can be found on a line +beginning with the string +<literal>package</literal> +in the first column; +the resulting <filename>.class</filename> files +will be placed in a directory reflecting +the specified package name. +For example, +the file +<filename>Foo.java</filename> +defining a single public +<classname>Foo</classname> +class and +containing a package name of +<classname>sub.dir</classname> +will generate a corresponding +<filename>sub/dir/Foo.class</filename> +class file. + +Examples: + +<example> +env.Java(target = 'classes', source = 'src') +env.Java(target = 'classes', source = ['src1', 'src2']) +env.Java(target = 'classes', source = ['File1.java', 'File2.java']) +</example> + +Java source files can use the native encoding for the underlying OS. +Since SCons compiles in simple ASCII mode by default, +the compiler will generate warnings about unmappable characters, +which may lead to errors as the file is processed further. +In this case, the user must specify the <literal>LANG</literal> +environment variable to tell the compiler what encoding is used. +For portibility, it's best if the encoding is hard-coded +so that the compile will work if it is done on a system +with a different encoding. + +<example> +env = Environment() +env['ENV']['LANG'] = 'en_GB.UTF-8' +</example> +</summary> +</builder> + +<cvar name="JAVABOOTCLASSPATH"> +<summary> +Specifies the list of directories that +will be added to the +&javac; command line +via the <option>-bootclasspath</option> option. +The individual directory names will be +separated by the operating system's path separate character +(<filename>:</filename> on UNIX/Linux/POSIX, +<filename>;</filename> on Windows). +</summary> +</cvar> + +<cvar name="JAVAC"> +<summary> +The Java compiler. +</summary> +</cvar> + +<cvar name="JAVACCOM"> +<summary> +The command line used to compile a directory tree containing +Java source files to +corresponding Java class files. +Any options specified in the &cv-link-JAVACFLAGS; construction variable +are included on this command line. +</summary> +</cvar> + +<cvar name="JAVACCOMSTR"> +<summary> +The string displayed when compiling +a directory tree of Java source files to +corresponding Java class files. +If this is not set, then &cv-link-JAVACCOM; (the command line) is displayed. + +<example> +env = Environment(JAVACCOMSTR = "Compiling class files $TARGETS from $SOURCES") +</example> +</summary> +</cvar> + +<cvar name="JAVACFLAGS"> +<summary> +General options that are passed to the Java compiler. +</summary> +</cvar> + +<cvar name="JAVACLASSDIR"> +<summary> +The directory in which Java class files may be found. +This is stripped from the beginning of any Java .class +file names supplied to the +<literal>JavaH</literal> +builder. +</summary> +</cvar> + +<cvar name="JAVACLASSPATH"> +<summary> +Specifies the list of directories that +will be searched for Java +<filename>.class</filename> file. +The directories in this list will be added to the +&javac; and &javah; command lines +via the <option>-classpath</option> option. +The individual directory names will be +separated by the operating system's path separate character +(<filename>:</filename> on UNIX/Linux/POSIX, +<filename>;</filename> on Windows). + +Note that this currently just adds the specified +directory via the <option>-classpath</option> option. +&SCons; does not currently search the +&cv-JAVACLASSPATH; directories for dependency +<filename>.class</filename> files. +</summary> +</cvar> + +<cvar name="JAVACLASSSUFFIX"> +<summary> +The suffix for Java class files; +<filename>.class</filename> +by default. +</summary> +</cvar> + +<cvar name="JAVASOURCEPATH"> +<summary> +Specifies the list of directories that +will be searched for input +<filename>.java</filename> file. +The directories in this list will be added to the +&javac; command line +via the <option>-sourcepath</option> option. +The individual directory names will be +separated by the operating system's path separate character +(<filename>:</filename> on UNIX/Linux/POSIX, +<filename>;</filename> on Windows). + +Note that this currently just adds the specified +directory via the <option>-sourcepath</option> option. +&SCons; does not currently search the +&cv-JAVASOURCEPATH; directories for dependency +<filename>.java</filename> files. +</summary> +</cvar> + +<cvar name="JAVASUFFIX"> +<summary> +The suffix for Java files; +<filename>.java</filename> +by default. +</summary> +</cvar> + +<cvar name="JAVAVERSION"> +<summary> +Specifies the Java version being used by the &b-Java; builder. +This is <emphasis>not</emphasis> currently used to select one +version of the Java compiler vs. another. +Instead, you should set this to specify the version of Java +supported by your &javac; compiler. +The default is <literal>1.4</literal>. + +This is sometimes necessary because +Java 1.5 changed the file names that are created +for nested anonymous inner classes, +which can cause a mismatch with the files +that &SCons; expects will be generated by the &javac; compiler. +Setting &cv-JAVAVERSION; to <literal>1.5</literal> +(or <literal>1.6</literal>, as appropriate) +can make &SCons; realize that a Java 1.5 or 1.6 +build is actually up to date. +</summary> +</cvar> diff --git a/src/engine/SCons/Tool/javah.py b/src/engine/SCons/Tool/javah.py new file mode 100644 index 0000000..0a54005 --- /dev/null +++ b/src/engine/SCons/Tool/javah.py @@ -0,0 +1,138 @@ +"""SCons.Tool.javah + +Tool-specific initialization for javah. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/javah.py 4577 2009/12/27 19:44:43 scons" + +import os.path +import string + +import SCons.Action +import SCons.Builder +import SCons.Node.FS +import SCons.Tool.javac +import SCons.Util + +def emit_java_headers(target, source, env): + """Create and return lists of Java stub header files that will + be created from a set of class files. + """ + class_suffix = env.get('JAVACLASSSUFFIX', '.class') + classdir = env.get('JAVACLASSDIR') + + if not classdir: + try: + s = source[0] + except IndexError: + classdir = '.' + else: + try: + classdir = s.attributes.java_classdir + except AttributeError: + classdir = '.' + classdir = env.Dir(classdir).rdir() + + if str(classdir) == '.': + c_ = None + else: + c_ = str(classdir) + os.sep + + slist = [] + for src in source: + try: + classname = src.attributes.java_classname + except AttributeError: + classname = str(src) + if c_ and classname[:len(c_)] == c_: + classname = classname[len(c_):] + if class_suffix and classname[-len(class_suffix):] == class_suffix: + classname = classname[:-len(class_suffix)] + classname = SCons.Tool.javac.classname(classname) + s = src.rfile() + s.attributes.java_classname = classname + slist.append(s) + + s = source[0].rfile() + if not hasattr(s.attributes, 'java_classdir'): + s.attributes.java_classdir = classdir + + if target[0].__class__ is SCons.Node.FS.File: + tlist = target + else: + if not isinstance(target[0], SCons.Node.FS.Dir): + target[0].__class__ = SCons.Node.FS.Dir + target[0]._morph() + tlist = [] + for s in source: + fname = string.replace(s.attributes.java_classname, '.', '_') + '.h' + t = target[0].File(fname) + t.attributes.java_lookupdir = target[0] + tlist.append(t) + + return tlist, source + +def JavaHOutFlagGenerator(target, source, env, for_signature): + try: + t = target[0] + except (AttributeError, IndexError, TypeError): + t = target + try: + return '-d ' + str(t.attributes.java_lookupdir) + except AttributeError: + return '-o ' + str(t) + +def getJavaHClassPath(env,target, source, for_signature): + path = "${SOURCE.attributes.java_classdir}" + if env.has_key('JAVACLASSPATH') and env['JAVACLASSPATH']: + path = SCons.Util.AppendPath(path, env['JAVACLASSPATH']) + return "-classpath %s" % (path) + +def generate(env): + """Add Builders and construction variables for javah to an Environment.""" + java_javah = SCons.Tool.CreateJavaHBuilder(env) + java_javah.emitter = emit_java_headers + + env['_JAVAHOUTFLAG'] = JavaHOutFlagGenerator + env['JAVAH'] = 'javah' + env['JAVAHFLAGS'] = SCons.Util.CLVar('') + env['_JAVAHCLASSPATH'] = getJavaHClassPath + env['JAVAHCOM'] = '$JAVAH $JAVAHFLAGS $_JAVAHOUTFLAG $_JAVAHCLASSPATH ${SOURCES.attributes.java_classname}' + env['JAVACLASSSUFFIX'] = '.class' + +def exists(env): + return env.Detect('javah') + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/javah.xml b/src/engine/SCons/Tool/javah.xml new file mode 100644 index 0000000..8a31662 --- /dev/null +++ b/src/engine/SCons/Tool/javah.xml @@ -0,0 +1,100 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="javah"> +<summary> +Sets construction variables for the &javah; tool. +</summary> +<sets> +JAVAH +JAVAHFLAGS +JAVAHCOM +JAVACLASSSUFFIX +</sets> +<uses> +JAVAHCOMSTR +JAVACLASSPATH +</uses> +</tool> + +<builder name="JavaH"> +<summary> +Builds C header and source files for +implementing Java native methods. +The target can be either a directory +in which the header files will be written, +or a header file name which +will contain all of the definitions. +The source can be the names of <filename>.class</filename> files, +the names of <filename>.java</filename> files +to be compiled into <filename>.class</filename> files +by calling the &b-link-Java; builder method, +or the objects returned from the +&b-Java; +builder method. + +If the construction variable +&cv-link-JAVACLASSDIR; +is set, either in the environment +or in the call to the +&b-JavaH; +builder method itself, +then the value of the variable +will be stripped from the +beginning of any <filename>.class</filename> file names. + +Examples: + +<example> +# builds java_native.h +classes = env.Java(target = 'classdir', source = 'src') +env.JavaH(target = 'java_native.h', source = classes) + +# builds include/package_foo.h and include/package_bar.h +env.JavaH(target = 'include', + source = ['package/foo.class', 'package/bar.class']) + +# builds export/foo.h and export/bar.h +env.JavaH(target = 'export', + source = ['classes/foo.class', 'classes/bar.class'], + JAVACLASSDIR = 'classes') +</example> +</summary> +</builder> + +<cvar name="JAVAH"> +<summary> +The Java generator for C header and stub files. +</summary> +</cvar> + +<cvar name="JAVAHCOM"> +<summary> +The command line used to generate C header and stub files +from Java classes. +Any options specified in the &cv-link-JAVAHFLAGS; construction variable +are included on this command line. +</summary> +</cvar> + +<cvar name="JAVAHCOMSTR"> +<summary> +The string displayed when C header and stub files +are generated from Java classes. +If this is not set, then &cv-link-JAVAHCOM; (the command line) is displayed. + +<example> +env = Environment(JAVAHCOMSTR = "Generating header/stub file(s) $TARGETS from $SOURCES") +</example> +</summary> +</cvar> + +<cvar name="JAVAHFLAGS"> +<summary> +General options passed to the C header and stub file generator +for Java classes. +</summary> +</cvar> diff --git a/src/engine/SCons/Tool/latex.py b/src/engine/SCons/Tool/latex.py new file mode 100644 index 0000000..d5b75ae --- /dev/null +++ b/src/engine/SCons/Tool/latex.py @@ -0,0 +1,79 @@ +"""SCons.Tool.latex + +Tool-specific initialization for LaTeX. +Generates .dvi files from .latex or .ltx files + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/latex.py 4577 2009/12/27 19:44:43 scons" + +import SCons.Action +import SCons.Defaults +import SCons.Scanner.LaTeX +import SCons.Util +import SCons.Tool +import SCons.Tool.tex + +def LaTeXAuxFunction(target = None, source= None, env=None): + result = SCons.Tool.tex.InternalLaTeXAuxAction( SCons.Tool.tex.LaTeXAction, target, source, env ) + if result != 0: + print env['LATEX']," returned an error, check the log file" + return result + +LaTeXAuxAction = SCons.Action.Action(LaTeXAuxFunction, + strfunction=SCons.Tool.tex.TeXLaTeXStrFunction) + +def generate(env): + """Add Builders and construction variables for LaTeX to an Environment.""" + + env.AppendUnique(LATEXSUFFIXES=SCons.Tool.LaTeXSuffixes) + + import dvi + dvi.generate(env) + + import pdf + pdf.generate(env) + + bld = env['BUILDERS']['DVI'] + bld.add_action('.ltx', LaTeXAuxAction) + bld.add_action('.latex', LaTeXAuxAction) + bld.add_emitter('.ltx', SCons.Tool.tex.tex_eps_emitter) + bld.add_emitter('.latex', SCons.Tool.tex.tex_eps_emitter) + + SCons.Tool.tex.generate_common(env) + +def exists(env): + return env.Detect('latex') + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/latex.xml b/src/engine/SCons/Tool/latex.xml new file mode 100644 index 0000000..aac9866 --- /dev/null +++ b/src/engine/SCons/Tool/latex.xml @@ -0,0 +1,71 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="latex"> +<summary> +Sets construction variables for the &latex; utility. +</summary> +<sets> +LATEX +LATEXFLAGS +LATEXCOM +</sets> +<uses> +LATEXCOMSTR +</uses> +</tool> + +<cvar name="LATEX"> +<summary> +The LaTeX structured formatter and typesetter. +</summary> +</cvar> + +<cvar name="LATEXCOM"> +<summary> +The command line used to call the LaTeX structured formatter and typesetter. +</summary> +</cvar> + +<cvar name="LATEXCOMSTR"> +<summary> +The string displayed when calling +the LaTeX structured formatter and typesetter. +If this is not set, then &cv-link-LATEXCOM; (the command line) is displayed. + +<example> +env = Environment(LATEXCOMSTR = "Building $TARGET from LaTeX input $SOURCES") +</example> +</summary> +</cvar> + +<cvar name="LATEXFLAGS"> +<summary> +General options passed to the LaTeX structured formatter and typesetter. +</summary> +</cvar> + +<cvar name="LATEXRETRIES"> +<summary> +The maximum number of times that LaTeX +will be re-run if the +<filename>.log</filename> +generated by the &cv-link-LATEXCOM; command +indicates that there are undefined references. +The default is to try to resolve undefined references +by re-running LaTeX up to three times. +</summary> +</cvar> + +<cvar name="TEXINPUTS"> +<summary> +List of directories that the LaTeX programm will search +for include directories. +The LaTeX implicit dependency scanner will search these +directories for \include and \import files. +</summary> +</cvar> + diff --git a/src/engine/SCons/Tool/lex.py b/src/engine/SCons/Tool/lex.py new file mode 100644 index 0000000..57d7cca --- /dev/null +++ b/src/engine/SCons/Tool/lex.py @@ -0,0 +1,99 @@ +"""SCons.Tool.lex + +Tool-specific initialization for lex. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/lex.py 4577 2009/12/27 19:44:43 scons" + +import os.path + +import string + +import SCons.Action +import SCons.Tool +import SCons.Util + +LexAction = SCons.Action.Action("$LEXCOM", "$LEXCOMSTR") + +def lexEmitter(target, source, env): + sourceBase, sourceExt = os.path.splitext(SCons.Util.to_String(source[0])) + + if sourceExt == ".lm": # If using Objective-C + target = [sourceBase + ".m"] # the extension is ".m". + + # This emitter essentially tries to add to the target all extra + # files generated by flex. + + # Different options that are used to trigger the creation of extra files. + fileGenOptions = ["--header-file=", "--tables-file="] + + lexflags = env.subst("$LEXFLAGS", target=target, source=source) + for option in SCons.Util.CLVar(lexflags): + for fileGenOption in fileGenOptions: + l = len(fileGenOption) + if option[:l] == fileGenOption: + # A file generating option is present, so add the + # file name to the target list. + fileName = string.strip(option[l:]) + target.append(fileName) + return (target, source) + +def generate(env): + """Add Builders and construction variables for lex to an Environment.""" + c_file, cxx_file = SCons.Tool.createCFileBuilders(env) + + # C + c_file.add_action(".l", LexAction) + c_file.add_emitter(".l", lexEmitter) + + c_file.add_action(".lex", LexAction) + c_file.add_emitter(".lex", lexEmitter) + + # Objective-C + cxx_file.add_action(".lm", LexAction) + cxx_file.add_emitter(".lm", lexEmitter) + + # C++ + cxx_file.add_action(".ll", LexAction) + cxx_file.add_emitter(".ll", lexEmitter) + + env["LEX"] = env.Detect("flex") or "lex" + env["LEXFLAGS"] = SCons.Util.CLVar("") + env["LEXCOM"] = "$LEX $LEXFLAGS -t $SOURCES > $TARGET" + +def exists(env): + return env.Detect(["flex", "lex"]) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/lex.xml b/src/engine/SCons/Tool/lex.xml new file mode 100644 index 0000000..8b3fcf8 --- /dev/null +++ b/src/engine/SCons/Tool/lex.xml @@ -0,0 +1,50 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="lex"> +<summary> +Sets construction variables for the &lex; lexical analyser. +</summary> +<sets> +LEX +LEXFLAGS +LEXCOM +</sets> +<uses> +LEXCOMSTR +</uses> +</tool> + +<cvar name="LEX"> +<summary> +The lexical analyzer generator. +</summary> +</cvar> + +<cvar name="LEXCOM"> +<summary> +The command line used to call the lexical analyzer generator +to generate a source file. +</summary> +</cvar> + +<cvar name="LEXCOMSTR"> +<summary> +The string displayed when generating a source file +using the lexical analyzer generator. +If this is not set, then &cv-link-LEXCOM; (the command line) is displayed. + +<example> +env = Environment(LEXCOMSTR = "Lex'ing $TARGET from $SOURCES") +</example> +</summary> +</cvar> + +<cvar name="LEXFLAGS"> +<summary> +General options passed to the lexical analyzer generator. +</summary> +</cvar> diff --git a/src/engine/SCons/Tool/link.py b/src/engine/SCons/Tool/link.py new file mode 100644 index 0000000..09938d6 --- /dev/null +++ b/src/engine/SCons/Tool/link.py @@ -0,0 +1,121 @@ +"""SCons.Tool.link + +Tool-specific initialization for the generic Posix linker. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/link.py 4577 2009/12/27 19:44:43 scons" + +import SCons.Defaults +import SCons.Tool +import SCons.Util +import SCons.Warnings + +from SCons.Tool.FortranCommon import isfortran + +cplusplus = __import__('c++', globals(), locals(), []) + +issued_mixed_link_warning = False + +def smart_link(source, target, env, for_signature): + has_cplusplus = cplusplus.iscplusplus(source) + has_fortran = isfortran(env, source) + if has_cplusplus and has_fortran: + global issued_mixed_link_warning + if not issued_mixed_link_warning: + msg = "Using $CXX to link Fortran and C++ code together.\n\t" + \ + "This may generate a buggy executable if the '%s'\n\t" + \ + "compiler does not know how to deal with Fortran runtimes." + SCons.Warnings.warn(SCons.Warnings.FortranCxxMixWarning, + msg % env.subst('$CXX')) + issued_mixed_link_warning = True + return '$CXX' + elif has_fortran: + return '$FORTRAN' + elif has_cplusplus: + return '$CXX' + return '$CC' + +def shlib_emitter(target, source, env): + for tgt in target: + tgt.attributes.shared = 1 + return (target, source) + +def generate(env): + """Add Builders and construction variables for gnulink to an Environment.""" + SCons.Tool.createSharedLibBuilder(env) + SCons.Tool.createProgBuilder(env) + + env['SHLINK'] = '$LINK' + env['SHLINKFLAGS'] = SCons.Util.CLVar('$LINKFLAGS -shared') + env['SHLINKCOM'] = '$SHLINK -o $TARGET $SHLINKFLAGS $SOURCES $_LIBDIRFLAGS $_LIBFLAGS' + # don't set up the emitter, cause AppendUnique will generate a list + # starting with None :-( + env.Append(SHLIBEMITTER = [shlib_emitter]) + env['SMARTLINK'] = smart_link + env['LINK'] = "$SMARTLINK" + env['LINKFLAGS'] = SCons.Util.CLVar('') + env['LINKCOM'] = '$LINK -o $TARGET $LINKFLAGS $SOURCES $_LIBDIRFLAGS $_LIBFLAGS' + env['LIBDIRPREFIX']='-L' + env['LIBDIRSUFFIX']='' + env['_LIBFLAGS']='${_stripixes(LIBLINKPREFIX, LIBS, LIBLINKSUFFIX, LIBPREFIXES, LIBSUFFIXES, __env__)}' + env['LIBLINKPREFIX']='-l' + env['LIBLINKSUFFIX']='' + + if env['PLATFORM'] == 'hpux': + env['SHLIBSUFFIX'] = '.sl' + elif env['PLATFORM'] == 'aix': + env['SHLIBSUFFIX'] = '.a' + + # For most platforms, a loadable module is the same as a shared + # library. Platforms which are different can override these, but + # setting them the same means that LoadableModule works everywhere. + SCons.Tool.createLoadableModuleBuilder(env) + env['LDMODULE'] = '$SHLINK' + # don't set up the emitter, cause AppendUnique will generate a list + # starting with None :-( + env.Append(LDMODULEEMITTER='$SHLIBEMITTER') + env['LDMODULEPREFIX'] = '$SHLIBPREFIX' + env['LDMODULESUFFIX'] = '$SHLIBSUFFIX' + env['LDMODULEFLAGS'] = '$SHLINKFLAGS' + env['LDMODULECOM'] = '$LDMODULE -o $TARGET $LDMODULEFLAGS $SOURCES $_LIBDIRFLAGS $_LIBFLAGS' + + + +def exists(env): + # This module isn't really a Tool on its own, it's common logic for + # other linkers. + return None + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/link.xml b/src/engine/SCons/Tool/link.xml new file mode 100644 index 0000000..b9a6a11 --- /dev/null +++ b/src/engine/SCons/Tool/link.xml @@ -0,0 +1,175 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="link"> +<summary> +Sets construction variables for generic POSIX linkers. +</summary> +<sets> +SHLINK +SHLINKFLAGS +SHLINKCOM +LINK +LINKFLAGS +LINKCOM +LIBDIRPREFIX +LIBDIRSUFFIX +LIBLINKPREFIX +LIBLINKSUFFIX +SHLIBSUFFIX +LDMODULE +LDMODULEPREFIX +LDMODULESUFFIX +LDMODULEFLAGS +LDMODULECOM +</sets> +<uses> +SHLINKCOMSTR +LINKCOMSTR +LDMODULECOMSTR +</uses> +</tool> + +<cvar name="LDMODULE"> +<summary> +The linker for building loadable modules. +By default, this is the same as &cv-link-SHLINK;. +</summary> +</cvar> + +<cvar name="LDMODULECOM"> +<summary> +The command line for building loadable modules. +On Mac OS X, this uses the &cv-link-LDMODULE;, +&cv-link-LDMODULEFLAGS; and +&cv-link-FRAMEWORKSFLAGS; variables. +On other systems, this is the same as &cv-link-SHLINK;. +</summary> +</cvar> + +<cvar name="LDMODULECOMSTR"> +<summary> +The string displayed when building loadable modules. +If this is not set, then &cv-link-LDMODULECOM; (the command line) is displayed. +</summary> +</cvar> + +<cvar name="LDMODULEFLAGS"> +<summary> +General user options passed to the linker for building loadable modules. +</summary> +</cvar> + +<cvar name="LDMODULEPREFIX"> +<summary> +The prefix used for loadable module file names. +On Mac OS X, this is null; +on other systems, this is +the same as &cv-link-SHLIBPREFIX;. +</summary> +</cvar> + +<cvar name="LDMODULESUFFIX"> +<summary> +The suffix used for loadable module file names. +On Mac OS X, this is null; +on other systems, this is +the same as $SHLIBSUFFIX. +</summary> +</cvar> + +<cvar name="LINK"> +<summary> +The linker. +</summary> +</cvar> + +<cvar name="LINKCOM"> +<summary> +The command line used to link object files into an executable. +</summary> +</cvar> + +<cvar name="LINKCOMSTR"> +<summary> +The string displayed when object files +are linked into an executable. +If this is not set, then &cv-link-LINKCOM; (the command line) is displayed. + +<example> +env = Environment(LINKCOMSTR = "Linking $TARGET") +</example> +</summary> +</cvar> + +<cvar name="LINKFLAGS"> +<summary> +General user options passed to the linker. +Note that this variable should +<emphasis>not</emphasis> +contain +<option>-l</option> +(or similar) options for linking with the libraries listed in &cv-link-LIBS;, +nor +<option>-L</option> +(or similar) library search path options +that scons generates automatically from &cv-link-LIBPATH;. +See +&cv-link-_LIBFLAGS; +above, +for the variable that expands to library-link options, +and +&cv-link-_LIBDIRFLAGS; +above, +for the variable that expands to library search path options. +</summary> +</cvar> + +<cvar name="SHLINK"> +<summary> +The linker for programs that use shared libraries. +</summary> +</cvar> + +<cvar name="SHLINKCOM"> +<summary> +The command line used to link programs using shared libaries. +</summary> +</cvar> + +<cvar name="SHLINKCOMSTR"> +<summary> +The string displayed when programs using shared libraries are linked. +If this is not set, then &cv-link-SHLINKCOM; (the command line) is displayed. + +<example> +env = Environment(SHLINKCOMSTR = "Linking shared $TARGET") +</example> +</summary> +</cvar> + +<cvar name="SHLINKFLAGS"> +<summary> +General user options passed to the linker for programs using shared libraries. +Note that this variable should +<emphasis>not</emphasis> +contain +<option>-l</option> +(or similar) options for linking with the libraries listed in &cv-link-LIBS;, +nor +<option>-L</option> +(or similar) include search path options +that scons generates automatically from &cv-link-LIBPATH;. +See +&cv-link-_LIBFLAGS; +above, +for the variable that expands to library-link options, +and +&cv-link-_LIBDIRFLAGS; +above, +for the variable that expands to library search path options. +</summary> +</cvar> diff --git a/src/engine/SCons/Tool/linkloc.py b/src/engine/SCons/Tool/linkloc.py new file mode 100644 index 0000000..0c50dc8 --- /dev/null +++ b/src/engine/SCons/Tool/linkloc.py @@ -0,0 +1,112 @@ +"""SCons.Tool.linkloc + +Tool specification for the LinkLoc linker for the Phar Lap ETS embedded +operating system. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/linkloc.py 4577 2009/12/27 19:44:43 scons" + +import os.path +import re + +import SCons.Action +import SCons.Defaults +import SCons.Errors +import SCons.Tool +import SCons.Util + +from SCons.Tool.MSCommon import msvs_exists, merge_default_version +from SCons.Tool.PharLapCommon import addPharLapPaths + +_re_linker_command = re.compile(r'(\s)@\s*([^\s]+)') + +def repl_linker_command(m): + # Replaces any linker command file directives (e.g. "@foo.lnk") with + # the actual contents of the file. + try: + f=open(m.group(2), "r") + return m.group(1) + f.read() + except IOError: + # the linker should return an error if it can't + # find the linker command file so we will remain quiet. + # However, we will replace the @ with a # so we will not continue + # to find it with recursive substitution + return m.group(1) + '#' + m.group(2) + +class LinklocGenerator: + def __init__(self, cmdline): + self.cmdline = cmdline + + def __call__(self, env, target, source, for_signature): + if for_signature: + # Expand the contents of any linker command files recursively + subs = 1 + strsub = env.subst(self.cmdline, target=target, source=source) + while subs: + strsub, subs = _re_linker_command.subn(repl_linker_command, strsub) + return strsub + else: + return "${TEMPFILE('" + self.cmdline + "')}" + +def generate(env): + """Add Builders and construction variables for ar to an Environment.""" + SCons.Tool.createSharedLibBuilder(env) + SCons.Tool.createProgBuilder(env) + + env['SUBST_CMD_FILE'] = LinklocGenerator + env['SHLINK'] = '$LINK' + env['SHLINKFLAGS'] = SCons.Util.CLVar('$LINKFLAGS') + env['SHLINKCOM'] = '${SUBST_CMD_FILE("$SHLINK $SHLINKFLAGS $_LIBDIRFLAGS $_LIBFLAGS -dll $TARGET $SOURCES")}' + env['SHLIBEMITTER']= None + env['LINK'] = "linkloc" + env['LINKFLAGS'] = SCons.Util.CLVar('') + env['LINKCOM'] = '${SUBST_CMD_FILE("$LINK $LINKFLAGS $_LIBDIRFLAGS $_LIBFLAGS -exe $TARGET $SOURCES")}' + env['LIBDIRPREFIX']='-libpath ' + env['LIBDIRSUFFIX']='' + env['LIBLINKPREFIX']='-lib ' + env['LIBLINKSUFFIX']='$LIBSUFFIX' + + # Set-up ms tools paths for default version + merge_default_version(env) + + addPharLapPaths(env) + +def exists(env): + if msvs_exists(): + return env.Detect('linkloc') + else: + return 0 + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/linkloc.xml b/src/engine/SCons/Tool/linkloc.xml new file mode 100644 index 0000000..bcec6a9 --- /dev/null +++ b/src/engine/SCons/Tool/linkloc.xml @@ -0,0 +1,31 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="linkloc"> +<summary> +Sets construction variables for the +<application>LinkLoc</application> +linker for the Phar Lap ETS embedded operating system. +</summary> +<sets> +<!--SUBST_CMD_FILE--> +SHLINK +SHLINKFLAGS +SHLINKCOM +<!--SHLINKEMITTER--> +LINK +LINKFLAGS +LINKCOM +LIBDIRPREFIX +LIBDIRSUFFIX +LIBLINKPREFIX +LIBLINKSUFFIX +</sets> +<uses> +SHLINKCOMSTR +LINKCOMSTR +</uses> +</tool> diff --git a/src/engine/SCons/Tool/m4.py b/src/engine/SCons/Tool/m4.py new file mode 100644 index 0000000..f3f1d28 --- /dev/null +++ b/src/engine/SCons/Tool/m4.py @@ -0,0 +1,63 @@ +"""SCons.Tool.m4 + +Tool-specific initialization for m4. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/m4.py 4577 2009/12/27 19:44:43 scons" + +import SCons.Action +import SCons.Builder +import SCons.Util + +def generate(env): + """Add Builders and construction variables for m4 to an Environment.""" + M4Action = SCons.Action.Action('$M4COM', '$M4COMSTR') + bld = SCons.Builder.Builder(action = M4Action, src_suffix = '.m4') + + env['BUILDERS']['M4'] = bld + + # .m4 files might include other files, and it would be pretty hard + # to write a scanner for it, so let's just cd to the dir of the m4 + # file and run from there. + # The src_suffix setup is like so: file.c.m4 -> file.c, + # file.cpp.m4 -> file.cpp etc. + env['M4'] = 'm4' + env['M4FLAGS'] = SCons.Util.CLVar('-E') + env['M4COM'] = 'cd ${SOURCE.rsrcdir} && $M4 $M4FLAGS < ${SOURCE.file} > ${TARGET.abspath}' + +def exists(env): + return env.Detect('m4') + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/m4.xml b/src/engine/SCons/Tool/m4.xml new file mode 100644 index 0000000..dbca146 --- /dev/null +++ b/src/engine/SCons/Tool/m4.xml @@ -0,0 +1,61 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="m4"> +<summary> +Sets construction variables for the &m4; macro processor. +</summary> +<sets> +M4 +M4FLAGS +M4COM +</sets> +<uses> +M4COMSTR +</uses> +</tool> + +<builder name="M4"> +<summary> +Builds an output file from an M4 input file. +This uses a default &cv-link-M4FLAGS; value of +<option>-E</option>, +which considers all warnings to be fatal +and stops on the first warning +when using the GNU version of m4. +Example: + +<example> +env.M4(target = 'foo.c', source = 'foo.c.m4') +</example> +</summary> +</builder> + +<cvar name="M4"> +<summary> +The M4 macro preprocessor. +</summary> +</cvar> + +<cvar name="M4COM"> +<summary> +The command line used to pass files through the M4 macro preprocessor. +</summary> +</cvar> + +<cvar name="M4COMSTR"> +<summary> +The string displayed when +a file is passed through the M4 macro preprocessor. +If this is not set, then &cv-link-M4COM; (the command line) is displayed. +</summary> +</cvar> + +<cvar name="M4FLAGS"> +<summary> +General options passed to the M4 macro preprocessor. +</summary> +</cvar> diff --git a/src/engine/SCons/Tool/masm.py b/src/engine/SCons/Tool/masm.py new file mode 100644 index 0000000..01db60a --- /dev/null +++ b/src/engine/SCons/Tool/masm.py @@ -0,0 +1,77 @@ +"""SCons.Tool.masm + +Tool-specific initialization for the Microsoft Assembler. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/masm.py 4577 2009/12/27 19:44:43 scons" + +import SCons.Defaults +import SCons.Tool +import SCons.Util + +ASSuffixes = ['.s', '.asm', '.ASM'] +ASPPSuffixes = ['.spp', '.SPP', '.sx'] +if SCons.Util.case_sensitive_suffixes('.s', '.S'): + ASPPSuffixes.extend(['.S']) +else: + ASSuffixes.extend(['.S']) + +def generate(env): + """Add Builders and construction variables for masm to an Environment.""" + static_obj, shared_obj = SCons.Tool.createObjBuilders(env) + + for suffix in ASSuffixes: + static_obj.add_action(suffix, SCons.Defaults.ASAction) + shared_obj.add_action(suffix, SCons.Defaults.ASAction) + static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter) + shared_obj.add_emitter(suffix, SCons.Defaults.SharedObjectEmitter) + + for suffix in ASPPSuffixes: + static_obj.add_action(suffix, SCons.Defaults.ASPPAction) + shared_obj.add_action(suffix, SCons.Defaults.ASPPAction) + static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter) + shared_obj.add_emitter(suffix, SCons.Defaults.SharedObjectEmitter) + + env['AS'] = 'ml' + env['ASFLAGS'] = SCons.Util.CLVar('/nologo') + env['ASPPFLAGS'] = '$ASFLAGS' + env['ASCOM'] = '$AS $ASFLAGS /c /Fo$TARGET $SOURCES' + env['ASPPCOM'] = '$CC $ASPPFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS /c /Fo$TARGET $SOURCES' + env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1 + +def exists(env): + return env.Detect('ml') + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/masm.xml b/src/engine/SCons/Tool/masm.xml new file mode 100644 index 0000000..3cc0ff2 --- /dev/null +++ b/src/engine/SCons/Tool/masm.xml @@ -0,0 +1,26 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="masm"> +<summary> +Sets construction variables for the Microsoft assembler. +</summary> +<sets> +AS +ASFLAGS +ASPPFLAGS +ASCOM +ASPPCOM +<!--STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME--> +</sets> +<uses> +ASCOMSTR +ASPPCOMSTR +CPPFLAGS +_CPPDEFFLAGS +_CPPINCFLAGS +</uses> +</tool> diff --git a/src/engine/SCons/Tool/midl.py b/src/engine/SCons/Tool/midl.py new file mode 100644 index 0000000..9a20677 --- /dev/null +++ b/src/engine/SCons/Tool/midl.py @@ -0,0 +1,90 @@ +"""SCons.Tool.midl + +Tool-specific initialization for midl (Microsoft IDL compiler). + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/midl.py 4577 2009/12/27 19:44:43 scons" + +import string + +import SCons.Action +import SCons.Builder +import SCons.Defaults +import SCons.Scanner.IDL +import SCons.Util + +from MSCommon import msvc_exists + +def midl_emitter(target, source, env): + """Produces a list of outputs from the MIDL compiler""" + base, ext = SCons.Util.splitext(str(target[0])) + tlb = target[0] + incl = base + '.h' + interface = base + '_i.c' + t = [tlb, incl, interface] + + midlcom = env['MIDLCOM'] + + if string.find(midlcom, '/proxy') != -1: + proxy = base + '_p.c' + t.append(proxy) + if string.find(midlcom, '/dlldata') != -1: + dlldata = base + '_data.c' + t.append(dlldata) + + return (t,source) + +idl_scanner = SCons.Scanner.IDL.IDLScan() + +midl_action = SCons.Action.Action('$MIDLCOM', '$MIDLCOMSTR') + +midl_builder = SCons.Builder.Builder(action = midl_action, + src_suffix = '.idl', + suffix='.tlb', + emitter = midl_emitter, + source_scanner = idl_scanner) + +def generate(env): + """Add Builders and construction variables for midl to an Environment.""" + + env['MIDL'] = 'MIDL.EXE' + env['MIDLFLAGS'] = SCons.Util.CLVar('/nologo') + env['MIDLCOM'] = '$MIDL $MIDLFLAGS /tlb ${TARGETS[0]} /h ${TARGETS[1]} /iid ${TARGETS[2]} /proxy ${TARGETS[3]} /dlldata ${TARGETS[4]} $SOURCE 2> NUL' + env['BUILDERS']['TypeLibrary'] = midl_builder + +def exists(env): + return msvc_exists() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/midl.xml b/src/engine/SCons/Tool/midl.xml new file mode 100644 index 0000000..640207d --- /dev/null +++ b/src/engine/SCons/Tool/midl.xml @@ -0,0 +1,68 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="midl"> +<summary> +Sets construction variables for the Microsoft IDL compiler. +</summary> +<sets> +MIDL +MIDLFLAGS +MIDLCOM +</sets> +<uses> +MIDLCOMSTR +</uses> +</tool> + +<builder name="TypeLibrary"> +<summary> +Builds a Windows type library (<filename>.tlb</filename>) +file from an input IDL file (<filename>.idl</filename>). +In addition, it will build the associated inteface stub and +proxy source files, +naming them according to the base name of the <filename>.idl</filename> file. +For example, + +<example> +env.TypeLibrary(source="foo.idl") +</example> + +Will create <filename>foo.tlb</filename>, +<filename>foo.h</filename>, +<filename>foo_i.c</filename>, +<filename>foo_p.c</filename> +and +<filename>foo_data.c</filename> +files. +</summary> +</builder> + +<cvar name="MIDL"> +<summary> +The Microsoft IDL compiler. +</summary> +</cvar> + +<cvar name="MIDLCOM"> +<summary> +The command line used to pass files to the Microsoft IDL compiler. +</summary> +</cvar> + +<cvar name="MIDLCOMSTR"> +<summary> +The string displayed when +the Microsoft IDL copmiler is called. +If this is not set, then &cv-link-MIDLCOM; (the command line) is displayed. +</summary> +</cvar> + +<cvar name="MIDLFLAGS"> +<summary> +General options passed to the Microsoft IDL compiler. +</summary> +</cvar> diff --git a/src/engine/SCons/Tool/mingw.py b/src/engine/SCons/Tool/mingw.py new file mode 100644 index 0000000..61980e3 --- /dev/null +++ b/src/engine/SCons/Tool/mingw.py @@ -0,0 +1,159 @@ +"""SCons.Tool.gcc + +Tool-specific initialization for MinGW (http://www.mingw.org/) + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/mingw.py 4577 2009/12/27 19:44:43 scons" + +import os +import os.path +import string + +import SCons.Action +import SCons.Builder +import SCons.Defaults +import SCons.Tool +import SCons.Util + +# This is what we search for to find mingw: +key_program = 'mingw32-gcc' + +def find(env): + # First search in the SCons path and then the OS path: + return env.WhereIs(key_program) or SCons.Util.WhereIs(key_program) + +def shlib_generator(target, source, env, for_signature): + cmd = SCons.Util.CLVar(['$SHLINK', '$SHLINKFLAGS']) + + dll = env.FindIxes(target, 'SHLIBPREFIX', 'SHLIBSUFFIX') + if dll: cmd.extend(['-o', dll]) + + cmd.extend(['$SOURCES', '$_LIBDIRFLAGS', '$_LIBFLAGS']) + + implib = env.FindIxes(target, 'LIBPREFIX', 'LIBSUFFIX') + if implib: cmd.append('-Wl,--out-implib,'+implib.get_string(for_signature)) + + def_target = env.FindIxes(target, 'WINDOWSDEFPREFIX', 'WINDOWSDEFSUFFIX') + insert_def = env.subst("$WINDOWS_INSERT_DEF") + if not insert_def in ['', '0', 0] and def_target: \ + cmd.append('-Wl,--output-def,'+def_target.get_string(for_signature)) + + return [cmd] + +def shlib_emitter(target, source, env): + dll = env.FindIxes(target, 'SHLIBPREFIX', 'SHLIBSUFFIX') + no_import_lib = env.get('no_import_lib', 0) + + if not dll: + raise SCons.Errors.UserError, "A shared library should have exactly one target with the suffix: %s" % env.subst("$SHLIBSUFFIX") + + if not no_import_lib and \ + not env.FindIxes(target, 'LIBPREFIX', 'LIBSUFFIX'): + + # Append an import library to the list of targets. + target.append(env.ReplaceIxes(dll, + 'SHLIBPREFIX', 'SHLIBSUFFIX', + 'LIBPREFIX', 'LIBSUFFIX')) + + # Append a def file target if there isn't already a def file target + # or a def file source. There is no option to disable def file + # target emitting, because I can't figure out why someone would ever + # want to turn it off. + def_source = env.FindIxes(source, 'WINDOWSDEFPREFIX', 'WINDOWSDEFSUFFIX') + def_target = env.FindIxes(target, 'WINDOWSDEFPREFIX', 'WINDOWSDEFSUFFIX') + if not def_source and not def_target: + target.append(env.ReplaceIxes(dll, + 'SHLIBPREFIX', 'SHLIBSUFFIX', + 'WINDOWSDEFPREFIX', 'WINDOWSDEFSUFFIX')) + + return (target, source) + + +shlib_action = SCons.Action.Action(shlib_generator, generator=1) + +res_action = SCons.Action.Action('$RCCOM', '$RCCOMSTR') + +res_builder = SCons.Builder.Builder(action=res_action, suffix='.o', + source_scanner=SCons.Tool.SourceFileScanner) +SCons.Tool.SourceFileScanner.add_scanner('.rc', SCons.Defaults.CScan) + +def generate(env): + mingw = find(env) + if mingw: + dir = os.path.dirname(mingw) + env.PrependENVPath('PATH', dir ) + + + # Most of mingw is the same as gcc and friends... + gnu_tools = ['gcc', 'g++', 'gnulink', 'ar', 'gas', 'm4'] + for tool in gnu_tools: + SCons.Tool.Tool(tool)(env) + + #... but a few things differ: + env['CC'] = 'gcc' + env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS') + env['CXX'] = 'g++' + env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS') + env['SHLINKFLAGS'] = SCons.Util.CLVar('$LINKFLAGS -shared') + env['SHLINKCOM'] = shlib_action + env['LDMODULECOM'] = shlib_action + env.Append(SHLIBEMITTER = [shlib_emitter]) + env['AS'] = 'as' + + env['WIN32DEFPREFIX'] = '' + env['WIN32DEFSUFFIX'] = '.def' + env['WINDOWSDEFPREFIX'] = '${WIN32DEFPREFIX}' + env['WINDOWSDEFSUFFIX'] = '${WIN32DEFSUFFIX}' + + env['SHOBJSUFFIX'] = '.o' + env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1 + + env['RC'] = 'windres' + env['RCFLAGS'] = SCons.Util.CLVar('') + env['RCINCFLAGS'] = '$( ${_concat(RCINCPREFIX, CPPPATH, RCINCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)' + env['RCINCPREFIX'] = '--include-dir ' + env['RCINCSUFFIX'] = '' + env['RCCOM'] = '$RC $_CPPDEFFLAGS $RCINCFLAGS ${RCINCPREFIX} ${SOURCE.dir} $RCFLAGS -i $SOURCE -o $TARGET' + env['BUILDERS']['RES'] = res_builder + + # Some setting from the platform also have to be overridden: + env['OBJSUFFIX'] = '.o' + env['LIBPREFIX'] = 'lib' + env['LIBSUFFIX'] = '.a' + +def exists(env): + return find(env) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/mingw.xml b/src/engine/SCons/Tool/mingw.xml new file mode 100644 index 0000000..5be291c --- /dev/null +++ b/src/engine/SCons/Tool/mingw.xml @@ -0,0 +1,38 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="mingw"> +<summary> +Sets construction variables for MinGW (Minimal Gnu on Windows). +</summary> +<sets> +CC +SHCCFLAGS +CXX +SHCXXFLAGS +SHLINKFLAGS +SHLINKCOM +LDMODULECOM +AS +WINDOWSDEFPREFIX +WINDOWSDEFSUFFIX +SHOBJSUFFIX +<!--STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME--> +RC +RCFLAGS +RCINCFLAGS +RCINCPREFIX +RCINCSUFFIX +RCCOM +OBJSUFFIX +LIBPREFIX +LIBSUFFIX +</sets> +<uses> +SHLINKCOMSTR +RCCOMSTR +</uses> +</tool> diff --git a/src/engine/SCons/Tool/mslib.py b/src/engine/SCons/Tool/mslib.py new file mode 100644 index 0000000..6945efd --- /dev/null +++ b/src/engine/SCons/Tool/mslib.py @@ -0,0 +1,64 @@ +"""SCons.Tool.mslib + +Tool-specific initialization for lib (MicroSoft library archiver). + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/mslib.py 4577 2009/12/27 19:44:43 scons" + +import SCons.Defaults +import SCons.Tool +import SCons.Tool.msvs +import SCons.Tool.msvc +import SCons.Util + +from MSCommon import msvc_exists, msvc_setup_env_once + +def generate(env): + """Add Builders and construction variables for lib to an Environment.""" + SCons.Tool.createStaticLibBuilder(env) + + # Set-up ms tools paths + msvc_setup_env_once(env) + + env['AR'] = 'lib' + env['ARFLAGS'] = SCons.Util.CLVar('/nologo') + env['ARCOM'] = "${TEMPFILE('$AR $ARFLAGS /OUT:$TARGET $SOURCES')}" + env['LIBPREFIX'] = '' + env['LIBSUFFIX'] = '.lib' + +def exists(env): + return msvc_exists() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/mslib.xml b/src/engine/SCons/Tool/mslib.xml new file mode 100644 index 0000000..0bd4ccb --- /dev/null +++ b/src/engine/SCons/Tool/mslib.xml @@ -0,0 +1,23 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="mslib"> +<summary> +Sets construction variables for the Microsoft +<application>mslib</application> +library archiver. +</summary> +<sets> +AR +ARFLAGS +ARCOM +LIBPREFIX +LIBSUFFIX +</sets> +<uses> +ARCOMSTR +</uses> +</tool> diff --git a/src/engine/SCons/Tool/mslink.py b/src/engine/SCons/Tool/mslink.py new file mode 100644 index 0000000..4a7aa6c --- /dev/null +++ b/src/engine/SCons/Tool/mslink.py @@ -0,0 +1,266 @@ +"""SCons.Tool.mslink + +Tool-specific initialization for the Microsoft linker. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/mslink.py 4577 2009/12/27 19:44:43 scons" + +import os.path + +import SCons.Action +import SCons.Defaults +import SCons.Errors +import SCons.Platform.win32 +import SCons.Tool +import SCons.Tool.msvc +import SCons.Tool.msvs +import SCons.Util + +from MSCommon import msvc_setup_env_once, msvc_exists + +def pdbGenerator(env, target, source, for_signature): + try: + return ['/PDB:%s' % target[0].attributes.pdb, '/DEBUG'] + except (AttributeError, IndexError): + return None + +def _dllTargets(target, source, env, for_signature, paramtp): + listCmd = [] + dll = env.FindIxes(target, '%sPREFIX' % paramtp, '%sSUFFIX' % paramtp) + if dll: listCmd.append("/out:%s"%dll.get_string(for_signature)) + + implib = env.FindIxes(target, 'LIBPREFIX', 'LIBSUFFIX') + if implib: listCmd.append("/implib:%s"%implib.get_string(for_signature)) + + return listCmd + +def _dllSources(target, source, env, for_signature, paramtp): + listCmd = [] + + deffile = env.FindIxes(source, "WINDOWSDEFPREFIX", "WINDOWSDEFSUFFIX") + for src in source: + # Check explicitly for a non-None deffile so that the __cmp__ + # method of the base SCons.Util.Proxy class used for some Node + # proxies doesn't try to use a non-existent __dict__ attribute. + if deffile and src == deffile: + # Treat this source as a .def file. + listCmd.append("/def:%s" % src.get_string(for_signature)) + else: + # Just treat it as a generic source file. + listCmd.append(src) + return listCmd + +def windowsShlinkTargets(target, source, env, for_signature): + return _dllTargets(target, source, env, for_signature, 'SHLIB') + +def windowsShlinkSources(target, source, env, for_signature): + return _dllSources(target, source, env, for_signature, 'SHLIB') + +def _windowsLdmodTargets(target, source, env, for_signature): + """Get targets for loadable modules.""" + return _dllTargets(target, source, env, for_signature, 'LDMODULE') + +def _windowsLdmodSources(target, source, env, for_signature): + """Get sources for loadable modules.""" + return _dllSources(target, source, env, for_signature, 'LDMODULE') + +def _dllEmitter(target, source, env, paramtp): + """Common implementation of dll emitter.""" + SCons.Tool.msvc.validate_vars(env) + + extratargets = [] + extrasources = [] + + dll = env.FindIxes(target, '%sPREFIX' % paramtp, '%sSUFFIX' % paramtp) + no_import_lib = env.get('no_import_lib', 0) + + if not dll: + raise SCons.Errors.UserError, 'A shared library should have exactly one target with the suffix: %s' % env.subst('$%sSUFFIX' % paramtp) + + insert_def = env.subst("$WINDOWS_INSERT_DEF") + if not insert_def in ['', '0', 0] and \ + not env.FindIxes(source, "WINDOWSDEFPREFIX", "WINDOWSDEFSUFFIX"): + + # append a def file to the list of sources + extrasources.append( + env.ReplaceIxes(dll, + '%sPREFIX' % paramtp, '%sSUFFIX' % paramtp, + "WINDOWSDEFPREFIX", "WINDOWSDEFSUFFIX")) + + version_num, suite = SCons.Tool.msvs.msvs_parse_version(env.get('MSVS_VERSION', '6.0')) + if version_num >= 8.0 and env.get('WINDOWS_INSERT_MANIFEST', 0): + # MSVC 8 automatically generates .manifest files that must be installed + extratargets.append( + env.ReplaceIxes(dll, + '%sPREFIX' % paramtp, '%sSUFFIX' % paramtp, + "WINDOWSSHLIBMANIFESTPREFIX", "WINDOWSSHLIBMANIFESTSUFFIX")) + + if env.has_key('PDB') and env['PDB']: + pdb = env.arg2nodes('$PDB', target=target, source=source)[0] + extratargets.append(pdb) + target[0].attributes.pdb = pdb + + if not no_import_lib and \ + not env.FindIxes(target, "LIBPREFIX", "LIBSUFFIX"): + # Append an import library to the list of targets. + extratargets.append( + env.ReplaceIxes(dll, + '%sPREFIX' % paramtp, '%sSUFFIX' % paramtp, + "LIBPREFIX", "LIBSUFFIX")) + # and .exp file is created if there are exports from a DLL + extratargets.append( + env.ReplaceIxes(dll, + '%sPREFIX' % paramtp, '%sSUFFIX' % paramtp, + "WINDOWSEXPPREFIX", "WINDOWSEXPSUFFIX")) + + return (target+extratargets, source+extrasources) + +def windowsLibEmitter(target, source, env): + return _dllEmitter(target, source, env, 'SHLIB') + +def ldmodEmitter(target, source, env): + """Emitter for loadable modules. + + Loadable modules are identical to shared libraries on Windows, but building + them is subject to different parameters (LDMODULE*). + """ + return _dllEmitter(target, source, env, 'LDMODULE') + +def prog_emitter(target, source, env): + SCons.Tool.msvc.validate_vars(env) + + extratargets = [] + + exe = env.FindIxes(target, "PROGPREFIX", "PROGSUFFIX") + if not exe: + raise SCons.Errors.UserError, "An executable should have exactly one target with the suffix: %s" % env.subst("$PROGSUFFIX") + + version_num, suite = SCons.Tool.msvs.msvs_parse_version(env.get('MSVS_VERSION', '6.0')) + if version_num >= 8.0 and env.get('WINDOWS_INSERT_MANIFEST', 0): + # MSVC 8 automatically generates .manifest files that have to be installed + extratargets.append( + env.ReplaceIxes(exe, + "PROGPREFIX", "PROGSUFFIX", + "WINDOWSPROGMANIFESTPREFIX", "WINDOWSPROGMANIFESTSUFFIX")) + + if env.has_key('PDB') and env['PDB']: + pdb = env.arg2nodes('$PDB', target=target, source=source)[0] + extratargets.append(pdb) + target[0].attributes.pdb = pdb + + return (target+extratargets,source) + +def RegServerFunc(target, source, env): + if env.has_key('register') and env['register']: + ret = regServerAction([target[0]], [source[0]], env) + if ret: + raise SCons.Errors.UserError, "Unable to register %s" % target[0] + else: + print "Registered %s sucessfully" % target[0] + return ret + return 0 + +regServerAction = SCons.Action.Action("$REGSVRCOM", "$REGSVRCOMSTR") +regServerCheck = SCons.Action.Action(RegServerFunc, None) +shlibLinkAction = SCons.Action.Action('${TEMPFILE("$SHLINK $SHLINKFLAGS $_SHLINK_TARGETS $_LIBDIRFLAGS $_LIBFLAGS $_PDB $_SHLINK_SOURCES")}') +compositeShLinkAction = shlibLinkAction + regServerCheck +ldmodLinkAction = SCons.Action.Action('${TEMPFILE("$LDMODULE $LDMODULEFLAGS $_LDMODULE_TARGETS $_LIBDIRFLAGS $_LIBFLAGS $_PDB $_LDMODULE_SOURCES")}') +compositeLdmodAction = ldmodLinkAction + regServerCheck + +def generate(env): + """Add Builders and construction variables for ar to an Environment.""" + SCons.Tool.createSharedLibBuilder(env) + SCons.Tool.createProgBuilder(env) + + env['SHLINK'] = '$LINK' + env['SHLINKFLAGS'] = SCons.Util.CLVar('$LINKFLAGS /dll') + env['_SHLINK_TARGETS'] = windowsShlinkTargets + env['_SHLINK_SOURCES'] = windowsShlinkSources + env['SHLINKCOM'] = compositeShLinkAction + env.Append(SHLIBEMITTER = [windowsLibEmitter]) + env['LINK'] = 'link' + env['LINKFLAGS'] = SCons.Util.CLVar('/nologo') + env['_PDB'] = pdbGenerator + env['LINKCOM'] = '${TEMPFILE("$LINK $LINKFLAGS /OUT:$TARGET.windows $_LIBDIRFLAGS $_LIBFLAGS $_PDB $SOURCES.windows")}' + env.Append(PROGEMITTER = [prog_emitter]) + env['LIBDIRPREFIX']='/LIBPATH:' + env['LIBDIRSUFFIX']='' + env['LIBLINKPREFIX']='' + env['LIBLINKSUFFIX']='$LIBSUFFIX' + + env['WIN32DEFPREFIX'] = '' + env['WIN32DEFSUFFIX'] = '.def' + env['WIN32_INSERT_DEF'] = 0 + env['WINDOWSDEFPREFIX'] = '${WIN32DEFPREFIX}' + env['WINDOWSDEFSUFFIX'] = '${WIN32DEFSUFFIX}' + env['WINDOWS_INSERT_DEF'] = '${WIN32_INSERT_DEF}' + + env['WIN32EXPPREFIX'] = '' + env['WIN32EXPSUFFIX'] = '.exp' + env['WINDOWSEXPPREFIX'] = '${WIN32EXPPREFIX}' + env['WINDOWSEXPSUFFIX'] = '${WIN32EXPSUFFIX}' + + env['WINDOWSSHLIBMANIFESTPREFIX'] = '' + env['WINDOWSSHLIBMANIFESTSUFFIX'] = '${SHLIBSUFFIX}.manifest' + env['WINDOWSPROGMANIFESTPREFIX'] = '' + env['WINDOWSPROGMANIFESTSUFFIX'] = '${PROGSUFFIX}.manifest' + + env['REGSVRACTION'] = regServerCheck + env['REGSVR'] = os.path.join(SCons.Platform.win32.get_system_root(),'System32','regsvr32') + env['REGSVRFLAGS'] = '/s ' + env['REGSVRCOM'] = '$REGSVR $REGSVRFLAGS ${TARGET.windows}' + + # Set-up ms tools paths + msvc_setup_env_once(env) + + + # Loadable modules are on Windows the same as shared libraries, but they + # are subject to different build parameters (LDMODULE* variables). + # Therefore LDMODULE* variables correspond as much as possible to + # SHLINK*/SHLIB* ones. + SCons.Tool.createLoadableModuleBuilder(env) + env['LDMODULE'] = '$SHLINK' + env['LDMODULEPREFIX'] = '$SHLIBPREFIX' + env['LDMODULESUFFIX'] = '$SHLIBSUFFIX' + env['LDMODULEFLAGS'] = '$SHLINKFLAGS' + env['_LDMODULE_TARGETS'] = _windowsLdmodTargets + env['_LDMODULE_SOURCES'] = _windowsLdmodSources + env['LDMODULEEMITTER'] = [ldmodEmitter] + env['LDMODULECOM'] = compositeLdmodAction + +def exists(env): + return msvc_exists() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/mslink.xml b/src/engine/SCons/Tool/mslink.xml new file mode 100644 index 0000000..05b0222 --- /dev/null +++ b/src/engine/SCons/Tool/mslink.xml @@ -0,0 +1,237 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="mslink"> +<summary> +Sets construction variables for the Microsoft linker. +</summary> +<sets> +SHLINK +SHLINKFLAGS +SHLINKCOM +LINK +LINKFLAGS +LINKCOM +LIBDIRPREFIX +LIBDIRSUFFIX +LIBLINKPREFIX +LIBLINKSUFFIX +WIN32DEFPREFIX +WIN32DEFSUFFIX +WINDOWSDEFPREFIX +WINDOWSDEFSUFFIX +WINDOWS_INSERT_DEF +WIN32EXPPREFIX +WIN32EXPSUFFIX +WINDOWSEXPPREFIX +WINDOWSEXPSUFFIX +WINDOWSSHLIBMANIFESTPREFIX +WINDOWSSHLIBMANIFESTSUFFIX +WINDOWSPROGMANIFESTPREFIX +WINDOWSPROGMANIFESTSUFFIX +<!--REGSVRACTION--> +REGSVR +REGSVRFLAGS +REGSVRCOM +LDMODULE +LDMODULEPREFIX +LDMODULESUFFIX +LDMODULEFLAGS +LDMODULECOM +</sets> +<uses> +SHLINKCOMSTR +LINKCOMSTR +REGSVRCOMSTR +MSVS_IGNORE_IDE_PATHS +LDMODULECOMSTR +</uses> +</tool> + +<cvar name="no_import_lib"> +<summary> +When set to non-zero, +suppresses creation of a corresponding Windows static import lib by the +<literal>SharedLibrary</literal> +builder when used with +MinGW, Microsoft Visual Studio or Metrowerks. +This also suppresses creation +of an export (.exp) file +when using Microsoft Visual Studio. +</summary> +</cvar> + +<cvar name="PDB"> +<summary> +The Microsoft Visual C++ PDB file that will store debugging information for +object files, shared libraries, and programs. This variable is ignored by +tools other than Microsoft Visual C++. +When this variable is +defined SCons will add options to the compiler and linker command line to +cause them to generate external debugging information, and will also set up the +dependencies for the PDB file. +Example: + +<example> +env['PDB'] = 'hello.pdb' +</example> + +The Visual C++ compiler switch that SCons uses by default +to generate PDB information is <option>/Z7</option>. +This works correctly with parallel (<option>-j</option>) builds +because it embeds the debug information in the intermediate object files, +as opposed to sharing a single PDB file between multiple object files. +This is also the only way to get debug information +embedded into a static library. +Using the <option>/Zi</option> instead may yield improved +link-time performance, +although parallel builds will no longer work. +You can generate PDB files with the <option>/Zi</option> +switch by overriding the default &cv-link-CCPDBFLAGS; variable; +see the entry for that variable for specific examples. +</summary> +</cvar> + +<cvar name="REGSVR"> +<summary> +The program used on Windows systems +to register a newly-built DLL library +whenever the &b-SharedLibrary; builder +is passed a keyword argument of <literal>register=1</literal>. +</summary> +</cvar> + +<cvar name="REGSVRCOM"> +<summary> +The command line used on Windows systems +to register a newly-built DLL library +whenever the &b-SharedLibrary; builder +is passed a keyword argument of <literal>register=1</literal>. +</summary> +</cvar> + +<cvar name="REGSVRCOMSTR"> +<summary> +The string displayed when registering a newly-built DLL file. +If this is not set, then &cv-link-REGSVRCOM; (the command line) is displayed. +</summary> +</cvar> + +<cvar name="REGSVRFLAGS"> +<summary> +Flags passed to the DLL registration program +on Windows systems when a newly-built DLL library is registered. +By default, +this includes the <option>/s</option> +that prevents dialog boxes from popping up +and requiring user attention. +</summary> +</cvar> + +<cvar name="WIN32_INSERT_DEF"> +<summary> +A deprecated synonym for &cv-link-WINDOWS_INSERT_DEF;. +</summary> +</cvar> + +<cvar name="WIN32DEFPREFIX"> +<summary> +A deprecated synonym for &cv-link-WINDOWSDEFPREFIX;. +</summary> +</cvar> + +<cvar name="WIN32DEFSUFFIX"> +<summary> +A deprecated synonym for &cv-link-WINDOWSDEFSUFFIX;. +</summary> +</cvar> + +<cvar name="WIN32EXPPREFIX"> +<summary> +A deprecated synonym for &cv-link-WINDOWSEXPSUFFIX;. +</summary> +</cvar> + +<cvar name="WIN32EXPSUFFIX"> +<summary> +A deprecated synonym for &cv-link-WINDOWSEXPSUFFIX;. +</summary> +</cvar> + +<cvar name="WINDOWS_INSERT_DEF"> +<summary> +When this is set to true, +a library build of a Windows shared library +(<filename>.dll</filename>file) +will also build a corresponding <filename>.def</filename> file +at the same time, +if a <filename>.def</filename> file +is not already listed as a build target. +The default is 0 (do not build a <filename>.def</filename> file). +</summary> +</cvar> + +<cvar name="WINDOWS_INSERT_MANIFEST"> +<summary> +When this is set to true, +&scons; +will be aware of the +<filename>.manifest</filename> +files generated by Microsoft Visua C/C++ 8. +</summary> +</cvar> + +<cvar name="WINDOWSDEFPREFIX"> +<summary> +The prefix used for Windows <filename>.def</filename>file names. +</summary> +</cvar> + +<cvar name="WINDOWSDEFSUFFIX"> +<summary> +The suffix used for Windows <filename>.def</filename> file names. +</summary> +</cvar> + +<cvar name="WINDOWSEXPPREFIX"> +<summary> +The prefix used for Windows <filename>.exp</filename> file names. +</summary> +</cvar> + +<cvar name="WINDOWSEXPSUFFIX"> +<summary> +The suffix used for Windows <filename>.exp</filename> file names. +</summary> +</cvar> + +<cvar name="WINDOWSPROGMANIFESTPREFIX"> +<summary> +The prefix used for executable program <filename>.manifest</filename> files +generated by Microsoft Visual C/C++. +</summary> +</cvar> + +<cvar name="WINDOWSPROGMANIFESTSUFFIX"> +<summary> +The suffix used for executable program <filename>.manifest</filename> files +generated by Microsoft Visual C/C++. +</summary> +</cvar> + +<cvar name="WINDOWSSHLIBMANIFESTPREFIX"> +<summary> +The prefix used for shared library <filename>.manifest</filename> files +generated by Microsoft Visual C/C++. +</summary> +</cvar> + +<cvar name="WINDOWSSHLIBMANIFESTSUFFIX"> +<summary> +The suffix used for shared library <filename>.manifest</filename> files +generated by Microsoft Visual C/C++. +</summary> +</cvar> diff --git a/src/engine/SCons/Tool/mssdk.py b/src/engine/SCons/Tool/mssdk.py new file mode 100644 index 0000000..9f7cc6f --- /dev/null +++ b/src/engine/SCons/Tool/mssdk.py @@ -0,0 +1,50 @@ +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/mssdk.py 4577 2009/12/27 19:44:43 scons" + +"""engine.SCons.Tool.mssdk + +Tool-specific initialization for Microsoft SDKs, both Platform +SDKs and Windows SDKs. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. +""" + +from MSCommon import mssdk_exists, \ + mssdk_setup_env + +def generate(env): + """Add construction variables for an MS SDK to an Environment.""" + mssdk_setup_env(env) + +def exists(env): + return mssdk_exists() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/mssdk.xml b/src/engine/SCons/Tool/mssdk.xml new file mode 100644 index 0000000..9c2e6d0 --- /dev/null +++ b/src/engine/SCons/Tool/mssdk.xml @@ -0,0 +1,50 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="mssdk"> +<summary> +Sets variables for Microsoft Platform SDK and/or Windows SDK. +Note that unlike most other Tool modules, +mssdk does not set construction variables, +but sets the <emphasis>environment variables</emphasis> +in the environment &SCons; uses to execute +the Microsoft toolchain: +<literal>%INCLUDE%</literal>, +<literal>%LIB%</literal>, +<literal>%LIBPATH%</literal> and +<literal>%PATH%</literal>. +</summary> +<sets> +</sets> +<uses> +MSSDK_DIR +MSSDK_VERSION +MSVS_VERSION +</uses> +</tool> + +<cvar name="MSSDK_DIR"> +<summary> +The directory containing the Microsoft SDK +(either Platform SDK or Windows SDK) +to be used for compilation. +</summary> +</cvar> + +<cvar name="MSSDK_VERSION"> +<summary> +The version string of the Microsoft SDK +(either Platform SDK or Windows SDK) +to be used for compilation. +Supported versions include +<literal>6.1</literal>, +<literal>6.0A</literal>, +<literal>6.0</literal>, +<literal>2003R2</literal> +and +<literal>2003R1</literal>. +</summary> +</cvar> diff --git a/src/engine/SCons/Tool/msvc.py b/src/engine/SCons/Tool/msvc.py new file mode 100644 index 0000000..0d3ec66 --- /dev/null +++ b/src/engine/SCons/Tool/msvc.py @@ -0,0 +1,257 @@ +"""engine.SCons.Tool.msvc + +Tool-specific initialization for Microsoft Visual C/C++. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/msvc.py 4577 2009/12/27 19:44:43 scons" + +import os.path +import re +import string +import sys + +import SCons.Action +import SCons.Builder +import SCons.Errors +import SCons.Platform.win32 +import SCons.Tool +import SCons.Tool.msvs +import SCons.Util +import SCons.Warnings +import SCons.Scanner.RC + +from MSCommon import msvc_exists, msvc_setup_env_once + +CSuffixes = ['.c', '.C'] +CXXSuffixes = ['.cc', '.cpp', '.cxx', '.c++', '.C++'] + +def validate_vars(env): + """Validate the PCH and PCHSTOP construction variables.""" + if env.has_key('PCH') and env['PCH']: + if not env.has_key('PCHSTOP'): + raise SCons.Errors.UserError, "The PCHSTOP construction must be defined if PCH is defined." + if not SCons.Util.is_String(env['PCHSTOP']): + raise SCons.Errors.UserError, "The PCHSTOP construction variable must be a string: %r"%env['PCHSTOP'] + +def pch_emitter(target, source, env): + """Adds the object file target.""" + + validate_vars(env) + + pch = None + obj = None + + for t in target: + if SCons.Util.splitext(str(t))[1] == '.pch': + pch = t + if SCons.Util.splitext(str(t))[1] == '.obj': + obj = t + + if not obj: + obj = SCons.Util.splitext(str(pch))[0]+'.obj' + + target = [pch, obj] # pch must be first, and obj second for the PCHCOM to work + + return (target, source) + +def object_emitter(target, source, env, parent_emitter): + """Sets up the PCH dependencies for an object file.""" + + validate_vars(env) + + parent_emitter(target, source, env) + + if env.has_key('PCH') and env['PCH']: + env.Depends(target, env['PCH']) + + return (target, source) + +def static_object_emitter(target, source, env): + return object_emitter(target, source, env, + SCons.Defaults.StaticObjectEmitter) + +def shared_object_emitter(target, source, env): + return object_emitter(target, source, env, + SCons.Defaults.SharedObjectEmitter) + +pch_action = SCons.Action.Action('$PCHCOM', '$PCHCOMSTR') +pch_builder = SCons.Builder.Builder(action=pch_action, suffix='.pch', + emitter=pch_emitter, + source_scanner=SCons.Tool.SourceFileScanner) + + +# Logic to build .rc files into .res files (resource files) +res_scanner = SCons.Scanner.RC.RCScan() +res_action = SCons.Action.Action('$RCCOM', '$RCCOMSTR') +res_builder = SCons.Builder.Builder(action=res_action, + src_suffix='.rc', + suffix='.res', + src_builder=[], + source_scanner=res_scanner) + +def msvc_batch_key(action, env, target, source): + """ + Returns a key to identify unique batches of sources for compilation. + + If batching is enabled (via the $MSVC_BATCH setting), then all + target+source pairs that use the same action, defined by the same + environment, and have the same target and source directories, will + be batched. + + Returning None specifies that the specified target+source should not + be batched with other compilations. + """ + b = env.subst('$MSVC_BATCH') + if b in (None, '', '0'): + # We're not using batching; return no key. + return None + t = target[0] + s = source[0] + if os.path.splitext(t.name)[0] != os.path.splitext(s.name)[0]: + # The base names are different, so this *must* be compiled + # separately; return no key. + return None + return (id(action), id(env), t.dir, s.dir) + +def msvc_output_flag(target, source, env, for_signature): + """ + Returns the correct /Fo flag for batching. + + If batching is disabled or there's only one source file, then we + return an /Fo string that specifies the target explicitly. Otherwise, + we return an /Fo string that just specifies the first target's + directory (where the Visual C/C++ compiler will put the .obj files). + """ + b = env.subst('$MSVC_BATCH') + if b in (None, '', '0') or len(source) == 1: + return '/Fo$TARGET' + else: + # The Visual C/C++ compiler requires a \ at the end of the /Fo + # option to indicate an output directory. We use os.sep here so + # that the test(s) for this can be run on non-Windows systems + # without having a hard-coded backslash mess up command-line + # argument parsing. + return '/Fo${TARGET.dir}' + os.sep + +CAction = SCons.Action.Action("$CCCOM", "$CCCOMSTR", + batch_key=msvc_batch_key, + targets='$CHANGED_TARGETS') +ShCAction = SCons.Action.Action("$SHCCCOM", "$SHCCCOMSTR", + batch_key=msvc_batch_key, + targets='$CHANGED_TARGETS') +CXXAction = SCons.Action.Action("$CXXCOM", "$CXXCOMSTR", + batch_key=msvc_batch_key, + targets='$CHANGED_TARGETS') +ShCXXAction = SCons.Action.Action("$SHCXXCOM", "$SHCXXCOMSTR", + batch_key=msvc_batch_key, + targets='$CHANGED_TARGETS') + +def generate(env): + """Add Builders and construction variables for MSVC++ to an Environment.""" + static_obj, shared_obj = SCons.Tool.createObjBuilders(env) + + # TODO(batch): shouldn't reach in to cmdgen this way; necessary + # for now to bypass the checks in Builder.DictCmdGenerator.__call__() + # and allow .cc and .cpp to be compiled in the same command line. + static_obj.cmdgen.source_ext_match = False + shared_obj.cmdgen.source_ext_match = False + + for suffix in CSuffixes: + static_obj.add_action(suffix, CAction) + shared_obj.add_action(suffix, ShCAction) + static_obj.add_emitter(suffix, static_object_emitter) + shared_obj.add_emitter(suffix, shared_object_emitter) + + for suffix in CXXSuffixes: + static_obj.add_action(suffix, CXXAction) + shared_obj.add_action(suffix, ShCXXAction) + static_obj.add_emitter(suffix, static_object_emitter) + shared_obj.add_emitter(suffix, shared_object_emitter) + + env['CCPDBFLAGS'] = SCons.Util.CLVar(['${(PDB and "/Z7") or ""}']) + env['CCPCHFLAGS'] = SCons.Util.CLVar(['${(PCH and "/Yu%s /Fp%s"%(PCHSTOP or "",File(PCH))) or ""}']) + env['_MSVC_OUTPUT_FLAG'] = msvc_output_flag + env['_CCCOMCOM'] = '$CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS $CCPCHFLAGS $CCPDBFLAGS' + env['CC'] = 'cl' + env['CCFLAGS'] = SCons.Util.CLVar('/nologo') + env['CFLAGS'] = SCons.Util.CLVar('') + env['CCCOM'] = '$CC $_MSVC_OUTPUT_FLAG /c $CHANGED_SOURCES $CFLAGS $CCFLAGS $_CCCOMCOM' + env['SHCC'] = '$CC' + env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS') + env['SHCFLAGS'] = SCons.Util.CLVar('$CFLAGS') + env['SHCCCOM'] = '$SHCC $_MSVC_OUTPUT_FLAG /c $CHANGED_SOURCES $SHCFLAGS $SHCCFLAGS $_CCCOMCOM' + env['CXX'] = '$CC' + env['CXXFLAGS'] = SCons.Util.CLVar('$( /TP $)') + env['CXXCOM'] = '$CXX $_MSVC_OUTPUT_FLAG /c $CHANGED_SOURCES $CXXFLAGS $CCFLAGS $_CCCOMCOM' + env['SHCXX'] = '$CXX' + env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS') + env['SHCXXCOM'] = '$SHCXX $_MSVC_OUTPUT_FLAG /c $CHANGED_SOURCES $SHCXXFLAGS $SHCCFLAGS $_CCCOMCOM' + env['CPPDEFPREFIX'] = '/D' + env['CPPDEFSUFFIX'] = '' + env['INCPREFIX'] = '/I' + env['INCSUFFIX'] = '' +# env.Append(OBJEMITTER = [static_object_emitter]) +# env.Append(SHOBJEMITTER = [shared_object_emitter]) + env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1 + + env['RC'] = 'rc' + env['RCFLAGS'] = SCons.Util.CLVar('') + env['RCSUFFIXES']=['.rc','.rc2'] + env['RCCOM'] = '$RC $_CPPDEFFLAGS $_CPPINCFLAGS $RCFLAGS /fo$TARGET $SOURCES' + env['BUILDERS']['RES'] = res_builder + env['OBJPREFIX'] = '' + env['OBJSUFFIX'] = '.obj' + env['SHOBJPREFIX'] = '$OBJPREFIX' + env['SHOBJSUFFIX'] = '$OBJSUFFIX' + + # Set-up ms tools paths + msvc_setup_env_once(env) + + env['CFILESUFFIX'] = '.c' + env['CXXFILESUFFIX'] = '.cc' + + env['PCHPDBFLAGS'] = SCons.Util.CLVar(['${(PDB and "/Yd") or ""}']) + env['PCHCOM'] = '$CXX /Fo${TARGETS[1]} $CXXFLAGS $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS /c $SOURCES /Yc$PCHSTOP /Fp${TARGETS[0]} $CCPDBFLAGS $PCHPDBFLAGS' + env['BUILDERS']['PCH'] = pch_builder + + if not env.has_key('ENV'): + env['ENV'] = {} + if not env['ENV'].has_key('SystemRoot'): # required for dlls in the winsxs folders + env['ENV']['SystemRoot'] = SCons.Platform.win32.get_system_root() + +def exists(env): + return msvc_exists() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/msvc.xml b/src/engine/SCons/Tool/msvc.xml new file mode 100644 index 0000000..c744903 --- /dev/null +++ b/src/engine/SCons/Tool/msvc.xml @@ -0,0 +1,316 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="msvc"> +<summary> +Sets construction variables for the Microsoft Visual C/C++ compiler. +</summary> +<sets> +CCPDBFLAGS +CCPCHFLAGS +<!--CCCOMFLAGS--> +CC +CCFLAGS +CFLAGS +CCCOM +SHCC +SHCCFLAGS +SHCFLAGS +SHCCCOM +CXX +CXXFLAGS +CXXCOM +SHCXX +SHCXXFLAGS +SHCXXCOM +CPPDEFPREFIX +CPPDEFSUFFIX +INCPREFIX +INCSUFFIX +<!--STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME--> +RC +RCFLAGS +RCCOM +BUILDERS +OBJPREFIX +OBJSUFFIX +SHOBJPREFIX +SHOBJSUFFIX +CFILESUFFIX +CXXFILESUFFIX +PCHPDBFLAGS +PCHCOM +</sets> +<uses> +CCCOMSTR +SHCCCOMSTR +CXXCOMSTR +SHCXXCOMSTR +PCH +PCHSTOP +PDB +</uses> +</tool> + +<builder name="PCH"> +<summary> +Builds a Microsoft Visual C++ precompiled header. +Calling this builder method +returns a list of two targets: the PCH as the first element, and the object +file as the second element. Normally the object file is ignored. +This builder method is only +provided when Microsoft Visual C++ is being used as the compiler. +The PCH builder method is generally used in +conjuction with the PCH construction variable to force object files to use +the precompiled header: + +<example> +env['PCH'] = env.PCH('StdAfx.cpp')[0] +</example> +</summary> +</builder> + +<builder name="RES"> +<summary> +Builds a Microsoft Visual C++ resource file. +This builder method is only provided +when Microsoft Visual C++ or MinGW is being used as the compiler. The +<filename>.res</filename> +(or +<filename>.o</filename> +for MinGW) suffix is added to the target name if no other suffix is given. +The source +file is scanned for implicit dependencies as though it were a C file. +Example: + +<example> +env.RES('resource.rc') +</example> +</summary> +</builder> + +<cvar name="CCPCHFLAGS"> +<summary> +Options added to the compiler command line +to support building with precompiled headers. +The default value expands expands to the appropriate +Microsoft Visual C++ command-line options +when the &cv-link-PCH; construction variable is set. +</summary> +</cvar> + +<cvar name="CCPDBFLAGS"> +<summary> +Options added to the compiler command line +to support storing debugging information in a +Microsoft Visual C++ PDB file. +The default value expands expands to appropriate +Microsoft Visual C++ command-line options +when the &cv-link-PDB; construction variable is set. + +The Visual C++ compiler option that SCons uses by default +to generate PDB information is <option>/Z7</option>. +This works correctly with parallel (<option>-j</option>) builds +because it embeds the debug information in the intermediate object files, +as opposed to sharing a single PDB file between multiple object files. +This is also the only way to get debug information +embedded into a static library. +Using the <option>/Zi</option> instead may yield improved +link-time performance, +although parallel builds will no longer work. + +You can generate PDB files with the <option>/Zi</option> +switch by overriding the default &cv-link-CCPDBFLAGS; variable as follows: + +<example> +env['CCPDBFLAGS'] = ['${(PDB and "/Zi /Fd%s" % File(PDB)) or ""}'] +</example> + +An alternative would be to use the <option>/Zi</option> +to put the debugging information in a separate <filename>.pdb</filename> +file for each object file by overriding +the &cv-link-CCPDBFLAGS; variable as follows: + +<example> +env['CCPDBFLAGS'] = '/Zi /Fd${TARGET}.pdb' +</example> +</summary> +</cvar> + +<cvar name="MSVC_BATCH"> +<summary> +When set to any true value, +specifies that &SCons; should batch +compilation of object files +when calling the Microsoft Visual C/C++ compiler. +All compilations of source files from the same source directory +that generate target files in a same output directory +and were configured in &SCons; using the same construction environment +will be built in a single call to the compiler. +Only source files that have changed since their +object files were built will be passed to each compiler invocation +(via the &cv-link-CHANGED_SOURCES; construction variable). +Any compilations where the object (target) file base name +(minus the <filename>.obj</filename>) +does not match the source file base name +will be compiled separately. +</summary> +</cvar> + +<cvar name="PCH"> +<summary> +The Microsoft Visual C++ precompiled header that will be used when compiling +object files. This variable is ignored by tools other than Microsoft Visual C++. +When this variable is +defined SCons will add options to the compiler command line to +cause it to use the precompiled header, and will also set up the +dependencies for the PCH file. +Example: + +<example> +env['PCH'] = 'StdAfx.pch' +</example> +</summary> +</cvar> + +<cvar name="PCHCOM"> +<summary> +The command line used by the +&b-PCH; +builder to generated a precompiled header. +</summary> +</cvar> + +<cvar name="PCHCOMSTR"> +<summary> +The string displayed when generating a precompiled header. +If this is not set, then &cv-link-PCHCOM; (the command line) is displayed. +</summary> +</cvar> + +<cvar name="PCHPDBFLAGS"> +<summary> +A construction variable that, when expanded, +adds the <literal>/yD</literal> flag to the command line +only if the &cv-PDB; construction variable is set. +</summary> +</cvar> + +<cvar name="PCHSTOP"> +<summary> +This variable specifies how much of a source file is precompiled. This +variable is ignored by tools other than Microsoft Visual C++, or when +the PCH variable is not being used. When this variable is define it +must be a string that is the name of the header that +is included at the end of the precompiled portion of the source files, or +the empty string if the "#pragma hrdstop" construct is being used: + +<example> +env['PCHSTOP'] = 'StdAfx.h' +</example> +</summary> +</cvar> + +<cvar name="RC"> +<summary> +The resource compiler used to build +a Microsoft Visual C++ resource file. +</summary> +</cvar> + +<cvar name="RCCOM"> +<summary> +The command line used to build +a Microsoft Visual C++ resource file. +</summary> +</cvar> + +<cvar name="RCCOMSTR"> +<summary> +The string displayed when invoking the resource compiler +to build a Microsoft Visual C++ resource file. +If this is not set, then &cv-link-RCCOM; (the command line) is displayed. +</summary> +</cvar> + +<cvar name="RCFLAGS"> +<summary> +The flags passed to the resource compiler by the RES builder. +</summary> +</cvar> + +<cvar name="RCINCFLAGS"> +<summary> +An automatically-generated construction variable +containing the command-line options +for specifying directories to be searched +by the resource compiler. +The value of &cv-RCINCFLAGS; is created +by appending &cv-RCINCPREFIX; and &cv-RCINCSUFFIX; +to the beginning and end +of each directory in &cv-CPPPATH;. +</summary> +</cvar> + +<cvar name="RCINCPREFIX"> +<summary> +The prefix (flag) used to specify an include directory +on the resource compiler command line. +This will be appended to the beginning of each directory +in the &cv-CPPPATH; construction variable +when the &cv-RCINCFLAGS; variable is expanded. +</summary> +</cvar> + +<cvar name="RCINCSUFFIX"> +<summary> +The suffix used to specify an include directory +on the resource compiler command line. +This will be appended to the end of each directory +in the &cv-CPPPATH; construction variable +when the &cv-RCINCFLAGS; variable is expanded. +</summary> +</cvar> + +<cvar name="MSVC_VERSION"> +<summary> +Sets the preferred version of Microsoft Visual C/C++ to use. + +If &cv-MSVC_VERSION; is not set, +&SCons; will (by default) select the latest version +of Visual C/C++ installed on your system. +If the specified version isn't installed, +tool initialization will fail. +</summary> +</cvar> + +<cvar name="HOST_ARCH"> +<summary> +Sets the host architecture for Visual Studio compiler. If not set, +default to the detected host architecture: note that this may depend +on the python you are using. + +Valid values are the same as for &cv-TARGET_ARCH;. + +This is currently only used on Windows, but in the future it will be +used on other OSes as well. +</summary> +</cvar> +<cvar name="TARGET_ARCH"> +<summary> +Sets the target architecture for Visual Studio compiler (i.e. the arch +of the binaries generated by the compiler). If not set, default to +&cv-HOST_ARCH;. +This is currently only used on Windows, but in the future it will be +used on other OSes as well. + +Valid values for Windows are 'x86', 'i386' (for 32 bits); +'amd64', 'emt64', 'x86_64' (64 bits); +and 'ia64' (Itanium). +For example, if you want to compile 64-bit binaries, you would set +TARGET_ARCH='x86_64' in your SCons environment. +</summary> +</cvar> diff --git a/src/engine/SCons/Tool/msvs.py b/src/engine/SCons/Tool/msvs.py new file mode 100644 index 0000000..a490b9c --- /dev/null +++ b/src/engine/SCons/Tool/msvs.py @@ -0,0 +1,1439 @@ +"""SCons.Tool.msvs + +Tool-specific initialization for Microsoft Visual Studio project files. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/msvs.py 4577 2009/12/27 19:44:43 scons" + +import base64 +import hashlib +import ntpath +import os +import pickle +import re +import string +import sys + +import SCons.Builder +import SCons.Node.FS +import SCons.Platform.win32 +import SCons.Script.SConscript +import SCons.Util +import SCons.Warnings + +from MSCommon import msvc_exists, msvc_setup_env_once +from SCons.Defaults import processDefines + +############################################################################## +# Below here are the classes and functions for generation of +# DSP/DSW/SLN/VCPROJ files. +############################################################################## + +def _hexdigest(s): + """Return a string as a string of hex characters. + """ + # NOTE: This routine is a method in the Python 2.0 interface + # of the native md5 module, but we want SCons to operate all + # the way back to at least Python 1.5.2, which doesn't have it. + h = string.hexdigits + r = '' + for c in s: + i = ord(c) + r = r + h[(i >> 4) & 0xF] + h[i & 0xF] + return r + +def xmlify(s): + s = string.replace(s, "&", "&") # do this first + s = string.replace(s, "'", "'") + s = string.replace(s, '"', """) + return s + +external_makefile_guid = '{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}' + +def _generateGUID(slnfile, name): + """This generates a dummy GUID for the sln file to use. It is + based on the MD5 signatures of the sln filename plus the name of + the project. It basically just needs to be unique, and not + change with each invocation.""" + m = hashlib.md5() + # Normalize the slnfile path to a Windows path (\ separators) so + # the generated file has a consistent GUID even if we generate + # it on a non-Windows platform. + m.update(ntpath.normpath(str(slnfile)) + str(name)) + # TODO(1.5) + #solution = m.hexdigest().upper() + solution = string.upper(_hexdigest(m.digest())) + # convert most of the signature to GUID form (discard the rest) + solution = "{" + solution[:8] + "-" + solution[8:12] + "-" + solution[12:16] + "-" + solution[16:20] + "-" + solution[20:32] + "}" + return solution + +version_re = re.compile(r'(\d+\.\d+)(.*)') + +def msvs_parse_version(s): + """ + Split a Visual Studio version, which may in fact be something like + '7.0Exp', into is version number (returned as a float) and trailing + "suite" portion. + """ + num, suite = version_re.match(s).groups() + return float(num), suite + +# This is how we re-invoke SCons from inside MSVS Project files. +# The problem is that we might have been invoked as either scons.bat +# or scons.py. If we were invoked directly as scons.py, then we could +# use sys.argv[0] to find the SCons "executable," but that doesn't work +# if we were invoked as scons.bat, which uses "python -c" to execute +# things and ends up with "-c" as sys.argv[0]. Consequently, we have +# the MSVS Project file invoke SCons the same way that scons.bat does, +# which works regardless of how we were invoked. +def getExecScriptMain(env, xml=None): + scons_home = env.get('SCONS_HOME') + if not scons_home and os.environ.has_key('SCONS_LIB_DIR'): + scons_home = os.environ['SCONS_LIB_DIR'] + if scons_home: + exec_script_main = "from os.path import join; import sys; sys.path = [ r'%s' ] + sys.path; import SCons.Script; SCons.Script.main()" % scons_home + else: + version = SCons.__version__ + exec_script_main = "from os.path import join; import sys; sys.path = [ join(sys.prefix, 'Lib', 'site-packages', 'scons-%(version)s'), join(sys.prefix, 'scons-%(version)s'), join(sys.prefix, 'Lib', 'site-packages', 'scons'), join(sys.prefix, 'scons') ] + sys.path; import SCons.Script; SCons.Script.main()" % locals() + if xml: + exec_script_main = xmlify(exec_script_main) + return exec_script_main + +# The string for the Python executable we tell the Project file to use +# is either sys.executable or, if an external PYTHON_ROOT environment +# variable exists, $(PYTHON)ROOT\\python.exe (generalized a little to +# pluck the actual executable name from sys.executable). +try: + python_root = os.environ['PYTHON_ROOT'] +except KeyError: + python_executable = sys.executable +else: + python_executable = os.path.join('$$(PYTHON_ROOT)', + os.path.split(sys.executable)[1]) + +class Config: + pass + +def splitFully(path): + dir, base = os.path.split(path) + if dir and dir != '' and dir != path: + return splitFully(dir)+[base] + if base == '': + return [] + return [base] + +def makeHierarchy(sources): + '''Break a list of files into a hierarchy; for each value, if it is a string, + then it is a file. If it is a dictionary, it is a folder. The string is + the original path of the file.''' + + hierarchy = {} + for file in sources: + path = splitFully(file) + if len(path): + dict = hierarchy + for part in path[:-1]: + if not dict.has_key(part): + dict[part] = {} + dict = dict[part] + dict[path[-1]] = file + #else: + # print 'Warning: failed to decompose path for '+str(file) + return hierarchy + +class _DSPGenerator: + """ Base class for DSP generators """ + + srcargs = [ + 'srcs', + 'incs', + 'localincs', + 'resources', + 'misc'] + + def __init__(self, dspfile, source, env): + self.dspfile = str(dspfile) + try: + get_abspath = dspfile.get_abspath + except AttributeError: + self.dspabs = os.path.abspath(dspfile) + else: + self.dspabs = get_abspath() + + if not env.has_key('variant'): + raise SCons.Errors.InternalError, \ + "You must specify a 'variant' argument (i.e. 'Debug' or " +\ + "'Release') to create an MSVSProject." + elif SCons.Util.is_String(env['variant']): + variants = [env['variant']] + elif SCons.Util.is_List(env['variant']): + variants = env['variant'] + + if not env.has_key('buildtarget') or env['buildtarget'] == None: + buildtarget = [''] + elif SCons.Util.is_String(env['buildtarget']): + buildtarget = [env['buildtarget']] + elif SCons.Util.is_List(env['buildtarget']): + if len(env['buildtarget']) != len(variants): + raise SCons.Errors.InternalError, \ + "Sizes of 'buildtarget' and 'variant' lists must be the same." + buildtarget = [] + for bt in env['buildtarget']: + if SCons.Util.is_String(bt): + buildtarget.append(bt) + else: + buildtarget.append(bt.get_abspath()) + else: + buildtarget = [env['buildtarget'].get_abspath()] + if len(buildtarget) == 1: + bt = buildtarget[0] + buildtarget = [] + for _ in variants: + buildtarget.append(bt) + + if not env.has_key('outdir') or env['outdir'] == None: + outdir = [''] + elif SCons.Util.is_String(env['outdir']): + outdir = [env['outdir']] + elif SCons.Util.is_List(env['outdir']): + if len(env['outdir']) != len(variants): + raise SCons.Errors.InternalError, \ + "Sizes of 'outdir' and 'variant' lists must be the same." + outdir = [] + for s in env['outdir']: + if SCons.Util.is_String(s): + outdir.append(s) + else: + outdir.append(s.get_abspath()) + else: + outdir = [env['outdir'].get_abspath()] + if len(outdir) == 1: + s = outdir[0] + outdir = [] + for v in variants: + outdir.append(s) + + if not env.has_key('runfile') or env['runfile'] == None: + runfile = buildtarget[-1:] + elif SCons.Util.is_String(env['runfile']): + runfile = [env['runfile']] + elif SCons.Util.is_List(env['runfile']): + if len(env['runfile']) != len(variants): + raise SCons.Errors.InternalError, \ + "Sizes of 'runfile' and 'variant' lists must be the same." + runfile = [] + for s in env['runfile']: + if SCons.Util.is_String(s): + runfile.append(s) + else: + runfile.append(s.get_abspath()) + else: + runfile = [env['runfile'].get_abspath()] + if len(runfile) == 1: + s = runfile[0] + runfile = [] + for v in variants: + runfile.append(s) + + self.sconscript = env['MSVSSCONSCRIPT'] + + cmdargs = env.get('cmdargs', '') + + self.env = env + + if self.env.has_key('name'): + self.name = self.env['name'] + else: + self.name = os.path.basename(SCons.Util.splitext(self.dspfile)[0]) + self.name = self.env.subst(self.name) + + sourcenames = [ + 'Source Files', + 'Header Files', + 'Local Headers', + 'Resource Files', + 'Other Files'] + + self.sources = {} + for n in sourcenames: + self.sources[n] = [] + + self.configs = {} + + self.nokeep = 0 + if env.has_key('nokeep') and env['variant'] != 0: + self.nokeep = 1 + + if self.nokeep == 0 and os.path.exists(self.dspabs): + self.Parse() + + for t in zip(sourcenames,self.srcargs): + if self.env.has_key(t[1]): + if SCons.Util.is_List(self.env[t[1]]): + for i in self.env[t[1]]: + if not i in self.sources[t[0]]: + self.sources[t[0]].append(i) + else: + if not self.env[t[1]] in self.sources[t[0]]: + self.sources[t[0]].append(self.env[t[1]]) + + for n in sourcenames: + # TODO(1.5): + #self.sources[n].sort(lambda a, b: cmp(a.lower(), b.lower())) + self.sources[n].sort(lambda a, b: cmp(string.lower(a), string.lower(b))) + + def AddConfig(self, variant, buildtarget, outdir, runfile, cmdargs, dspfile=dspfile): + config = Config() + config.buildtarget = buildtarget + config.outdir = outdir + config.cmdargs = cmdargs + config.runfile = runfile + + match = re.match('(.*)\|(.*)', variant) + if match: + config.variant = match.group(1) + config.platform = match.group(2) + else: + config.variant = variant + config.platform = 'Win32' + + self.configs[variant] = config + print "Adding '" + self.name + ' - ' + config.variant + '|' + config.platform + "' to '" + str(dspfile) + "'" + + for i in range(len(variants)): + AddConfig(self, variants[i], buildtarget[i], outdir[i], runfile[i], cmdargs) + + self.platforms = [] + for key in self.configs.keys(): + platform = self.configs[key].platform + if not platform in self.platforms: + self.platforms.append(platform) + + def Build(self): + pass + +V6DSPHeader = """\ +# Microsoft Developer Studio Project File - Name="%(name)s" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) External Target" 0x0106 + +CFG=%(name)s - Win32 %(confkey)s +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "%(name)s.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "%(name)s.mak" CFG="%(name)s - Win32 %(confkey)s" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +""" + +class _GenerateV6DSP(_DSPGenerator): + """Generates a Project file for MSVS 6.0""" + + def PrintHeader(self): + # pick a default config + confkeys = self.configs.keys() + confkeys.sort() + + name = self.name + confkey = confkeys[0] + + self.file.write(V6DSPHeader % locals()) + + for kind in confkeys: + self.file.write('!MESSAGE "%s - Win32 %s" (based on "Win32 (x86) External Target")\n' % (name, kind)) + + self.file.write('!MESSAGE \n\n') + + def PrintProject(self): + name = self.name + self.file.write('# Begin Project\n' + '# PROP AllowPerConfigDependencies 0\n' + '# PROP Scc_ProjName ""\n' + '# PROP Scc_LocalPath ""\n\n') + + first = 1 + confkeys = self.configs.keys() + confkeys.sort() + for kind in confkeys: + outdir = self.configs[kind].outdir + buildtarget = self.configs[kind].buildtarget + if first == 1: + self.file.write('!IF "$(CFG)" == "%s - Win32 %s"\n\n' % (name, kind)) + first = 0 + else: + self.file.write('\n!ELSEIF "$(CFG)" == "%s - Win32 %s"\n\n' % (name, kind)) + + env_has_buildtarget = self.env.has_key('MSVSBUILDTARGET') + if not env_has_buildtarget: + self.env['MSVSBUILDTARGET'] = buildtarget + + # have to write this twice, once with the BASE settings, and once without + for base in ("BASE ",""): + self.file.write('# PROP %sUse_MFC 0\n' + '# PROP %sUse_Debug_Libraries ' % (base, base)) + # TODO(1.5): + #if kind.lower().find('debug') < 0: + if string.find(string.lower(kind), 'debug') < 0: + self.file.write('0\n') + else: + self.file.write('1\n') + self.file.write('# PROP %sOutput_Dir "%s"\n' + '# PROP %sIntermediate_Dir "%s"\n' % (base,outdir,base,outdir)) + cmd = 'echo Starting SCons && ' + self.env.subst('$MSVSBUILDCOM', 1) + self.file.write('# PROP %sCmd_Line "%s"\n' + '# PROP %sRebuild_Opt "-c && %s"\n' + '# PROP %sTarget_File "%s"\n' + '# PROP %sBsc_Name ""\n' + '# PROP %sTarget_Dir ""\n'\ + %(base,cmd,base,cmd,base,buildtarget,base,base)) + + if not env_has_buildtarget: + del self.env['MSVSBUILDTARGET'] + + self.file.write('\n!ENDIF\n\n' + '# Begin Target\n\n') + for kind in confkeys: + self.file.write('# Name "%s - Win32 %s"\n' % (name,kind)) + self.file.write('\n') + first = 0 + for kind in confkeys: + if first == 0: + self.file.write('!IF "$(CFG)" == "%s - Win32 %s"\n\n' % (name,kind)) + first = 1 + else: + self.file.write('!ELSEIF "$(CFG)" == "%s - Win32 %s"\n\n' % (name,kind)) + self.file.write('!ENDIF \n\n') + self.PrintSourceFiles() + self.file.write('# End Target\n' + '# End Project\n') + + if self.nokeep == 0: + # now we pickle some data and add it to the file -- MSDEV will ignore it. + pdata = pickle.dumps(self.configs,1) + pdata = base64.encodestring(pdata) + self.file.write(pdata + '\n') + pdata = pickle.dumps(self.sources,1) + pdata = base64.encodestring(pdata) + self.file.write(pdata + '\n') + + def PrintSourceFiles(self): + categories = {'Source Files': 'cpp|c|cxx|l|y|def|odl|idl|hpj|bat', + 'Header Files': 'h|hpp|hxx|hm|inl', + 'Local Headers': 'h|hpp|hxx|hm|inl', + 'Resource Files': 'r|rc|ico|cur|bmp|dlg|rc2|rct|bin|cnt|rtf|gif|jpg|jpeg|jpe', + 'Other Files': ''} + + cats = categories.keys() + # TODO(1.5): + #cats.sort(lambda a, b: cmp(a.lower(), b.lower())) + cats.sort(lambda a, b: cmp(string.lower(a), string.lower(b))) + for kind in cats: + if not self.sources[kind]: + continue # skip empty groups + + self.file.write('# Begin Group "' + kind + '"\n\n') + # TODO(1.5) + #typelist = categories[kind].replace('|', ';') + typelist = string.replace(categories[kind], '|', ';') + self.file.write('# PROP Default_Filter "' + typelist + '"\n') + + for file in self.sources[kind]: + file = os.path.normpath(file) + self.file.write('# Begin Source File\n\n' + 'SOURCE="' + file + '"\n' + '# End Source File\n') + self.file.write('# End Group\n') + + # add the SConscript file outside of the groups + self.file.write('# Begin Source File\n\n' + 'SOURCE="' + str(self.sconscript) + '"\n' + '# End Source File\n') + + def Parse(self): + try: + dspfile = open(self.dspabs,'r') + except IOError: + return # doesn't exist yet, so can't add anything to configs. + + line = dspfile.readline() + while line: + # TODO(1.5): + #if line.find("# End Project") > -1: + if string.find(line, "# End Project") > -1: + break + line = dspfile.readline() + + line = dspfile.readline() + datas = line + while line and line != '\n': + line = dspfile.readline() + datas = datas + line + + # OK, we've found our little pickled cache of data. + try: + datas = base64.decodestring(datas) + data = pickle.loads(datas) + except KeyboardInterrupt: + raise + except: + return # unable to unpickle any data for some reason + + self.configs.update(data) + + data = None + line = dspfile.readline() + datas = line + while line and line != '\n': + line = dspfile.readline() + datas = datas + line + + # OK, we've found our little pickled cache of data. + # it has a "# " in front of it, so we strip that. + try: + datas = base64.decodestring(datas) + data = pickle.loads(datas) + except KeyboardInterrupt: + raise + except: + return # unable to unpickle any data for some reason + + self.sources.update(data) + + def Build(self): + try: + self.file = open(self.dspabs,'w') + except IOError, detail: + raise SCons.Errors.InternalError, 'Unable to open "' + self.dspabs + '" for writing:' + str(detail) + else: + self.PrintHeader() + self.PrintProject() + self.file.close() + +V7DSPHeader = """\ +<?xml version="1.0" encoding = "%(encoding)s"?> +<VisualStudioProject +\tProjectType="Visual C++" +\tVersion="%(versionstr)s" +\tName="%(name)s" +%(scc_attrs)s +\tKeyword="MakeFileProj"> +""" + +V7DSPConfiguration = """\ +\t\t<Configuration +\t\t\tName="%(variant)s|%(platform)s" +\t\t\tOutputDirectory="%(outdir)s" +\t\t\tIntermediateDirectory="%(outdir)s" +\t\t\tConfigurationType="0" +\t\t\tUseOfMFC="0" +\t\t\tATLMinimizesCRunTimeLibraryUsage="FALSE"> +\t\t\t<Tool +\t\t\t\tName="VCNMakeTool" +\t\t\t\tBuildCommandLine="%(buildcmd)s" +\t\t\t\tCleanCommandLine="%(cleancmd)s" +\t\t\t\tRebuildCommandLine="%(rebuildcmd)s" +\t\t\t\tOutput="%(runfile)s"/> +\t\t</Configuration> +""" + +V8DSPHeader = """\ +<?xml version="1.0" encoding="%(encoding)s"?> +<VisualStudioProject +\tProjectType="Visual C++" +\tVersion="%(versionstr)s" +\tName="%(name)s" +%(scc_attrs)s +\tRootNamespace="%(name)s" +\tKeyword="MakeFileProj"> +""" + +V8DSPConfiguration = """\ +\t\t<Configuration +\t\t\tName="%(variant)s|%(platform)s" +\t\t\tConfigurationType="0" +\t\t\tUseOfMFC="0" +\t\t\tATLMinimizesCRunTimeLibraryUsage="false" +\t\t\t> +\t\t\t<Tool +\t\t\t\tName="VCNMakeTool" +\t\t\t\tBuildCommandLine="%(buildcmd)s" +\t\t\t\tReBuildCommandLine="%(rebuildcmd)s" +\t\t\t\tCleanCommandLine="%(cleancmd)s" +\t\t\t\tOutput="%(runfile)s" +\t\t\t\tPreprocessorDefinitions="%(preprocdefs)s" +\t\t\t\tIncludeSearchPath="%(includepath)s" +\t\t\t\tForcedIncludes="" +\t\t\t\tAssemblySearchPath="" +\t\t\t\tForcedUsingAssemblies="" +\t\t\t\tCompileAsManaged="" +\t\t\t/> +\t\t</Configuration> +""" +class _GenerateV7DSP(_DSPGenerator): + """Generates a Project file for MSVS .NET""" + + def __init__(self, dspfile, source, env): + _DSPGenerator.__init__(self, dspfile, source, env) + self.version = env['MSVS_VERSION'] + self.version_num, self.suite = msvs_parse_version(self.version) + if self.version_num >= 8.0: + self.versionstr = '8.00' + self.dspheader = V8DSPHeader + self.dspconfiguration = V8DSPConfiguration + else: + if self.version_num >= 7.1: + self.versionstr = '7.10' + else: + self.versionstr = '7.00' + self.dspheader = V7DSPHeader + self.dspconfiguration = V7DSPConfiguration + self.file = None + + def PrintHeader(self): + env = self.env + versionstr = self.versionstr + name = self.name + encoding = self.env.subst('$MSVSENCODING') + scc_provider = env.get('MSVS_SCC_PROVIDER', '') + scc_project_name = env.get('MSVS_SCC_PROJECT_NAME', '') + scc_aux_path = env.get('MSVS_SCC_AUX_PATH', '') + scc_local_path = env.get('MSVS_SCC_LOCAL_PATH', '') + project_guid = env.get('MSVS_PROJECT_GUID', '') + if self.version_num >= 8.0 and not project_guid: + project_guid = _generateGUID(self.dspfile, '') + if scc_provider != '': + scc_attrs = ('\tProjectGUID="%s"\n' + '\tSccProjectName="%s"\n' + '\tSccAuxPath="%s"\n' + '\tSccLocalPath="%s"\n' + '\tSccProvider="%s"' % (project_guid, scc_project_name, scc_aux_path, scc_local_path, scc_provider)) + else: + scc_attrs = ('\tProjectGUID="%s"\n' + '\tSccProjectName="%s"\n' + '\tSccLocalPath="%s"' % (project_guid, scc_project_name, scc_local_path)) + + self.file.write(self.dspheader % locals()) + + self.file.write('\t<Platforms>\n') + for platform in self.platforms: + self.file.write( + '\t\t<Platform\n' + '\t\t\tName="%s"/>\n' % platform) + self.file.write('\t</Platforms>\n') + + if self.version_num >= 8.0: + self.file.write('\t<ToolFiles>\n' + '\t</ToolFiles>\n') + + def PrintProject(self): + self.file.write('\t<Configurations>\n') + + confkeys = self.configs.keys() + confkeys.sort() + for kind in confkeys: + variant = self.configs[kind].variant + platform = self.configs[kind].platform + outdir = self.configs[kind].outdir + buildtarget = self.configs[kind].buildtarget + runfile = self.configs[kind].runfile + cmdargs = self.configs[kind].cmdargs + + env_has_buildtarget = self.env.has_key('MSVSBUILDTARGET') + if not env_has_buildtarget: + self.env['MSVSBUILDTARGET'] = buildtarget + + starting = 'echo Starting SCons && ' + if cmdargs: + cmdargs = ' ' + cmdargs + else: + cmdargs = '' + buildcmd = xmlify(starting + self.env.subst('$MSVSBUILDCOM', 1) + cmdargs) + rebuildcmd = xmlify(starting + self.env.subst('$MSVSREBUILDCOM', 1) + cmdargs) + cleancmd = xmlify(starting + self.env.subst('$MSVSCLEANCOM', 1) + cmdargs) + + # TODO(1.5) + #preprocdefs = xmlify(';'.join(self.env.get('CPPDEFINES', []))) + #includepath = xmlify(';'.join(self.env.get('CPPPATH', []))) + preprocdefs = xmlify(string.join(processDefines(self.env.get('CPPDEFINES', [])), ';')) + includepath = xmlify(string.join(self.env.get('CPPPATH', []), ';')) + + if not env_has_buildtarget: + del self.env['MSVSBUILDTARGET'] + + self.file.write(self.dspconfiguration % locals()) + + self.file.write('\t</Configurations>\n') + + if self.version_num >= 7.1: + self.file.write('\t<References>\n' + '\t</References>\n') + + self.PrintSourceFiles() + + self.file.write('</VisualStudioProject>\n') + + if self.nokeep == 0: + # now we pickle some data and add it to the file -- MSDEV will ignore it. + pdata = pickle.dumps(self.configs,1) + pdata = base64.encodestring(pdata) + self.file.write('<!-- SCons Data:\n' + pdata + '\n') + pdata = pickle.dumps(self.sources,1) + pdata = base64.encodestring(pdata) + self.file.write(pdata + '-->\n') + + def printSources(self, hierarchy, commonprefix): + sorteditems = hierarchy.items() + # TODO(1.5): + #sorteditems.sort(lambda a, b: cmp(a[0].lower(), b[0].lower())) + sorteditems.sort(lambda a, b: cmp(string.lower(a[0]), string.lower(b[0]))) + + # First folders, then files + for key, value in sorteditems: + if SCons.Util.is_Dict(value): + self.file.write('\t\t\t<Filter\n' + '\t\t\t\tName="%s"\n' + '\t\t\t\tFilter="">\n' % (key)) + self.printSources(value, commonprefix) + self.file.write('\t\t\t</Filter>\n') + + for key, value in sorteditems: + if SCons.Util.is_String(value): + file = value + if commonprefix: + file = os.path.join(commonprefix, value) + file = os.path.normpath(file) + self.file.write('\t\t\t<File\n' + '\t\t\t\tRelativePath="%s">\n' + '\t\t\t</File>\n' % (file)) + + def PrintSourceFiles(self): + categories = {'Source Files': 'cpp;c;cxx;l;y;def;odl;idl;hpj;bat', + 'Header Files': 'h;hpp;hxx;hm;inl', + 'Local Headers': 'h;hpp;hxx;hm;inl', + 'Resource Files': 'r;rc;ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe', + 'Other Files': ''} + + self.file.write('\t<Files>\n') + + cats = categories.keys() + # TODO(1.5) + #cats.sort(lambda a, b: cmp(a.lower(), b.lower())) + cats.sort(lambda a, b: cmp(string.lower(a), string.lower(b))) + cats = filter(lambda k, s=self: s.sources[k], cats) + for kind in cats: + if len(cats) > 1: + self.file.write('\t\t<Filter\n' + '\t\t\tName="%s"\n' + '\t\t\tFilter="%s">\n' % (kind, categories[kind])) + + sources = self.sources[kind] + + # First remove any common prefix + commonprefix = None + if len(sources) > 1: + s = map(os.path.normpath, sources) + # take the dirname because the prefix may include parts + # of the filenames (e.g. if you have 'dir\abcd' and + # 'dir\acde' then the cp will be 'dir\a' ) + cp = os.path.dirname( os.path.commonprefix(s) ) + if cp and s[0][len(cp)] == os.sep: + # +1 because the filename starts after the separator + sources = map(lambda s, l=len(cp)+1: s[l:], sources) + commonprefix = cp + elif len(sources) == 1: + commonprefix = os.path.dirname( sources[0] ) + sources[0] = os.path.basename( sources[0] ) + + hierarchy = makeHierarchy(sources) + self.printSources(hierarchy, commonprefix=commonprefix) + + if len(cats)>1: + self.file.write('\t\t</Filter>\n') + + # add the SConscript file outside of the groups + self.file.write('\t\t<File\n' + '\t\t\tRelativePath="%s">\n' + '\t\t</File>\n' % str(self.sconscript)) + + self.file.write('\t</Files>\n' + '\t<Globals>\n' + '\t</Globals>\n') + + def Parse(self): + try: + dspfile = open(self.dspabs,'r') + except IOError: + return # doesn't exist yet, so can't add anything to configs. + + line = dspfile.readline() + while line: + # TODO(1.5) + #if line.find('<!-- SCons Data:') > -1: + if string.find(line, '<!-- SCons Data:') > -1: + break + line = dspfile.readline() + + line = dspfile.readline() + datas = line + while line and line != '\n': + line = dspfile.readline() + datas = datas + line + + # OK, we've found our little pickled cache of data. + try: + datas = base64.decodestring(datas) + data = pickle.loads(datas) + except KeyboardInterrupt: + raise + except: + return # unable to unpickle any data for some reason + + self.configs.update(data) + + data = None + line = dspfile.readline() + datas = line + while line and line != '\n': + line = dspfile.readline() + datas = datas + line + + # OK, we've found our little pickled cache of data. + try: + datas = base64.decodestring(datas) + data = pickle.loads(datas) + except KeyboardInterrupt: + raise + except: + return # unable to unpickle any data for some reason + + self.sources.update(data) + + def Build(self): + try: + self.file = open(self.dspabs,'w') + except IOError, detail: + raise SCons.Errors.InternalError, 'Unable to open "' + self.dspabs + '" for writing:' + str(detail) + else: + self.PrintHeader() + self.PrintProject() + self.file.close() + +class _DSWGenerator: + """ Base class for DSW generators """ + def __init__(self, dswfile, source, env): + self.dswfile = os.path.normpath(str(dswfile)) + self.env = env + + if not env.has_key('projects'): + raise SCons.Errors.UserError, \ + "You must specify a 'projects' argument to create an MSVSSolution." + projects = env['projects'] + if not SCons.Util.is_List(projects): + raise SCons.Errors.InternalError, \ + "The 'projects' argument must be a list of nodes." + projects = SCons.Util.flatten(projects) + if len(projects) < 1: + raise SCons.Errors.UserError, \ + "You must specify at least one project to create an MSVSSolution." + self.dspfiles = map(str, projects) + + if self.env.has_key('name'): + self.name = self.env['name'] + else: + self.name = os.path.basename(SCons.Util.splitext(self.dswfile)[0]) + self.name = self.env.subst(self.name) + + def Build(self): + pass + +class _GenerateV7DSW(_DSWGenerator): + """Generates a Solution file for MSVS .NET""" + def __init__(self, dswfile, source, env): + _DSWGenerator.__init__(self, dswfile, source, env) + + self.file = None + self.version = self.env['MSVS_VERSION'] + self.version_num, self.suite = msvs_parse_version(self.version) + self.versionstr = '7.00' + if self.version_num >= 8.0: + self.versionstr = '9.00' + elif self.version_num >= 7.1: + self.versionstr = '8.00' + if self.version_num >= 8.0: + self.versionstr = '9.00' + + if env.has_key('slnguid') and env['slnguid']: + self.slnguid = env['slnguid'] + else: + self.slnguid = _generateGUID(dswfile, self.name) + + self.configs = {} + + self.nokeep = 0 + if env.has_key('nokeep') and env['variant'] != 0: + self.nokeep = 1 + + if self.nokeep == 0 and os.path.exists(self.dswfile): + self.Parse() + + def AddConfig(self, variant, dswfile=dswfile): + config = Config() + + match = re.match('(.*)\|(.*)', variant) + if match: + config.variant = match.group(1) + config.platform = match.group(2) + else: + config.variant = variant + config.platform = 'Win32' + + self.configs[variant] = config + print "Adding '" + self.name + ' - ' + config.variant + '|' + config.platform + "' to '" + str(dswfile) + "'" + + if not env.has_key('variant'): + raise SCons.Errors.InternalError, \ + "You must specify a 'variant' argument (i.e. 'Debug' or " +\ + "'Release') to create an MSVS Solution File." + elif SCons.Util.is_String(env['variant']): + AddConfig(self, env['variant']) + elif SCons.Util.is_List(env['variant']): + for variant in env['variant']: + AddConfig(self, variant) + + self.platforms = [] + for key in self.configs.keys(): + platform = self.configs[key].platform + if not platform in self.platforms: + self.platforms.append(platform) + + def Parse(self): + try: + dswfile = open(self.dswfile,'r') + except IOError: + return # doesn't exist yet, so can't add anything to configs. + + line = dswfile.readline() + while line: + if line[:9] == "EndGlobal": + break + line = dswfile.readline() + + line = dswfile.readline() + datas = line + while line: + line = dswfile.readline() + datas = datas + line + + # OK, we've found our little pickled cache of data. + try: + datas = base64.decodestring(datas) + data = pickle.loads(datas) + except KeyboardInterrupt: + raise + except: + return # unable to unpickle any data for some reason + + self.configs.update(data) + + def PrintSolution(self): + """Writes a solution file""" + self.file.write('Microsoft Visual Studio Solution File, Format Version %s\n' % self.versionstr ) + if self.version_num >= 8.0: + self.file.write('# Visual Studio 2005\n') + for p in self.dspfiles: + name = os.path.basename(p) + base, suffix = SCons.Util.splitext(name) + if suffix == '.vcproj': + name = base + guid = _generateGUID(p, '') + self.file.write('Project("%s") = "%s", "%s", "%s"\n' + % ( external_makefile_guid, name, p, guid ) ) + if self.version_num >= 7.1 and self.version_num < 8.0: + self.file.write('\tProjectSection(ProjectDependencies) = postProject\n' + '\tEndProjectSection\n') + self.file.write('EndProject\n') + + self.file.write('Global\n') + + env = self.env + if env.has_key('MSVS_SCC_PROVIDER'): + dspfile_base = os.path.basename(self.dspfile) + slnguid = self.slnguid + scc_provider = env.get('MSVS_SCC_PROVIDER', '') + scc_provider = string.replace(scc_provider, ' ', r'\u0020') + scc_project_name = env.get('MSVS_SCC_PROJECT_NAME', '') + # scc_aux_path = env.get('MSVS_SCC_AUX_PATH', '') + scc_local_path = env.get('MSVS_SCC_LOCAL_PATH', '') + scc_project_base_path = env.get('MSVS_SCC_PROJECT_BASE_PATH', '') + # project_guid = env.get('MSVS_PROJECT_GUID', '') + + self.file.write('\tGlobalSection(SourceCodeControl) = preSolution\n' + '\t\tSccNumberOfProjects = 2\n' + '\t\tSccProjectUniqueName0 = %(dspfile_base)s\n' + '\t\tSccLocalPath0 = %(scc_local_path)s\n' + '\t\tCanCheckoutShared = true\n' + '\t\tSccProjectFilePathRelativizedFromConnection0 = %(scc_project_base_path)s\n' + '\t\tSccProjectName1 = %(scc_project_name)s\n' + '\t\tSccLocalPath1 = %(scc_local_path)s\n' + '\t\tSccProvider1 = %(scc_provider)s\n' + '\t\tCanCheckoutShared = true\n' + '\t\tSccProjectFilePathRelativizedFromConnection1 = %(scc_project_base_path)s\n' + '\t\tSolutionUniqueID = %(slnguid)s\n' + '\tEndGlobalSection\n' % locals()) + + if self.version_num >= 8.0: + self.file.write('\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n') + else: + self.file.write('\tGlobalSection(SolutionConfiguration) = preSolution\n') + + confkeys = self.configs.keys() + confkeys.sort() + cnt = 0 + for name in confkeys: + variant = self.configs[name].variant + platform = self.configs[name].platform + if self.version_num >= 8.0: + self.file.write('\t\t%s|%s = %s|%s\n' % (variant, platform, variant, platform)) + else: + self.file.write('\t\tConfigName.%d = %s\n' % (cnt, variant)) + cnt = cnt + 1 + self.file.write('\tEndGlobalSection\n') + if self.version_num < 7.1: + self.file.write('\tGlobalSection(ProjectDependencies) = postSolution\n' + '\tEndGlobalSection\n') + if self.version_num >= 8.0: + self.file.write('\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n') + else: + self.file.write('\tGlobalSection(ProjectConfiguration) = postSolution\n') + + for name in confkeys: + variant = self.configs[name].variant + platform = self.configs[name].platform + if self.version_num >= 8.0: + for p in self.dspfiles: + guid = _generateGUID(p, '') + self.file.write('\t\t%s.%s|%s.ActiveCfg = %s|%s\n' + '\t\t%s.%s|%s.Build.0 = %s|%s\n' % (guid,variant,platform,variant,platform,guid,variant,platform,variant,platform)) + else: + for p in self.dspfiles: + guid = _generateGUID(p, '') + self.file.write('\t\t%s.%s.ActiveCfg = %s|%s\n' + '\t\t%s.%s.Build.0 = %s|%s\n' %(guid,variant,variant,platform,guid,variant,variant,platform)) + + self.file.write('\tEndGlobalSection\n') + + if self.version_num >= 8.0: + self.file.write('\tGlobalSection(SolutionProperties) = preSolution\n' + '\t\tHideSolutionNode = FALSE\n' + '\tEndGlobalSection\n') + else: + self.file.write('\tGlobalSection(ExtensibilityGlobals) = postSolution\n' + '\tEndGlobalSection\n' + '\tGlobalSection(ExtensibilityAddIns) = postSolution\n' + '\tEndGlobalSection\n') + self.file.write('EndGlobal\n') + if self.nokeep == 0: + pdata = pickle.dumps(self.configs,1) + pdata = base64.encodestring(pdata) + self.file.write(pdata + '\n') + + def Build(self): + try: + self.file = open(self.dswfile,'w') + except IOError, detail: + raise SCons.Errors.InternalError, 'Unable to open "' + self.dswfile + '" for writing:' + str(detail) + else: + self.PrintSolution() + self.file.close() + +V6DSWHeader = """\ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "%(name)s"="%(dspfile)s" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### +""" + +class _GenerateV6DSW(_DSWGenerator): + """Generates a Workspace file for MSVS 6.0""" + + def PrintWorkspace(self): + """ writes a DSW file """ + name = self.name + dspfile = self.dspfiles[0] + self.file.write(V6DSWHeader % locals()) + + def Build(self): + try: + self.file = open(self.dswfile,'w') + except IOError, detail: + raise SCons.Errors.InternalError, 'Unable to open "' + self.dswfile + '" for writing:' + str(detail) + else: + self.PrintWorkspace() + self.file.close() + + +def GenerateDSP(dspfile, source, env): + """Generates a Project file based on the version of MSVS that is being used""" + + version_num = 6.0 + if env.has_key('MSVS_VERSION'): + version_num, suite = msvs_parse_version(env['MSVS_VERSION']) + if version_num >= 7.0: + g = _GenerateV7DSP(dspfile, source, env) + g.Build() + else: + g = _GenerateV6DSP(dspfile, source, env) + g.Build() + +def GenerateDSW(dswfile, source, env): + """Generates a Solution/Workspace file based on the version of MSVS that is being used""" + + version_num = 6.0 + if env.has_key('MSVS_VERSION'): + version_num, suite = msvs_parse_version(env['MSVS_VERSION']) + if version_num >= 7.0: + g = _GenerateV7DSW(dswfile, source, env) + g.Build() + else: + g = _GenerateV6DSW(dswfile, source, env) + g.Build() + + +############################################################################## +# Above here are the classes and functions for generation of +# DSP/DSW/SLN/VCPROJ files. +############################################################################## + +def GetMSVSProjectSuffix(target, source, env, for_signature): + return env['MSVS']['PROJECTSUFFIX'] + +def GetMSVSSolutionSuffix(target, source, env, for_signature): + return env['MSVS']['SOLUTIONSUFFIX'] + +def GenerateProject(target, source, env): + # generate the dsp file, according to the version of MSVS. + builddspfile = target[0] + dspfile = builddspfile.srcnode() + + # this detects whether or not we're using a VariantDir + if not dspfile is builddspfile: + try: + bdsp = open(str(builddspfile), "w+") + except IOError, detail: + print 'Unable to open "' + str(dspfile) + '" for writing:',detail,'\n' + raise + + bdsp.write("This is just a placeholder file.\nThe real project file is here:\n%s\n" % dspfile.get_abspath()) + + GenerateDSP(dspfile, source, env) + + if env.get('auto_build_solution', 1): + builddswfile = target[1] + dswfile = builddswfile.srcnode() + + if not dswfile is builddswfile: + + try: + bdsw = open(str(builddswfile), "w+") + except IOError, detail: + print 'Unable to open "' + str(dspfile) + '" for writing:',detail,'\n' + raise + + bdsw.write("This is just a placeholder file.\nThe real workspace file is here:\n%s\n" % dswfile.get_abspath()) + + GenerateDSW(dswfile, source, env) + +def GenerateSolution(target, source, env): + GenerateDSW(target[0], source, env) + +def projectEmitter(target, source, env): + """Sets up the DSP dependencies.""" + + # todo: Not sure what sets source to what user has passed as target, + # but this is what happens. When that is fixed, we also won't have + # to make the user always append env['MSVSPROJECTSUFFIX'] to target. + if source[0] == target[0]: + source = [] + + # make sure the suffix is correct for the version of MSVS we're running. + (base, suff) = SCons.Util.splitext(str(target[0])) + suff = env.subst('$MSVSPROJECTSUFFIX') + target[0] = base + suff + + if not source: + source = 'prj_inputs:' + source = source + env.subst('$MSVSSCONSCOM', 1) + source = source + env.subst('$MSVSENCODING', 1) + + if env.has_key('buildtarget') and env['buildtarget'] != None: + if SCons.Util.is_String(env['buildtarget']): + source = source + ' "%s"' % env['buildtarget'] + elif SCons.Util.is_List(env['buildtarget']): + for bt in env['buildtarget']: + if SCons.Util.is_String(bt): + source = source + ' "%s"' % bt + else: + try: source = source + ' "%s"' % bt.get_abspath() + except AttributeError: raise SCons.Errors.InternalError, \ + "buildtarget can be a string, a node, a list of strings or nodes, or None" + else: + try: source = source + ' "%s"' % env['buildtarget'].get_abspath() + except AttributeError: raise SCons.Errors.InternalError, \ + "buildtarget can be a string, a node, a list of strings or nodes, or None" + + if env.has_key('outdir') and env['outdir'] != None: + if SCons.Util.is_String(env['outdir']): + source = source + ' "%s"' % env['outdir'] + elif SCons.Util.is_List(env['outdir']): + for s in env['outdir']: + if SCons.Util.is_String(s): + source = source + ' "%s"' % s + else: + try: source = source + ' "%s"' % s.get_abspath() + except AttributeError: raise SCons.Errors.InternalError, \ + "outdir can be a string, a node, a list of strings or nodes, or None" + else: + try: source = source + ' "%s"' % env['outdir'].get_abspath() + except AttributeError: raise SCons.Errors.InternalError, \ + "outdir can be a string, a node, a list of strings or nodes, or None" + + if env.has_key('name'): + if SCons.Util.is_String(env['name']): + source = source + ' "%s"' % env['name'] + else: + raise SCons.Errors.InternalError, "name must be a string" + + if env.has_key('variant'): + if SCons.Util.is_String(env['variant']): + source = source + ' "%s"' % env['variant'] + elif SCons.Util.is_List(env['variant']): + for variant in env['variant']: + if SCons.Util.is_String(variant): + source = source + ' "%s"' % variant + else: + raise SCons.Errors.InternalError, "name must be a string or a list of strings" + else: + raise SCons.Errors.InternalError, "variant must be a string or a list of strings" + else: + raise SCons.Errors.InternalError, "variant must be specified" + + for s in _DSPGenerator.srcargs: + if env.has_key(s): + if SCons.Util.is_String(env[s]): + source = source + ' "%s' % env[s] + elif SCons.Util.is_List(env[s]): + for t in env[s]: + if SCons.Util.is_String(t): + source = source + ' "%s"' % t + else: + raise SCons.Errors.InternalError, s + " must be a string or a list of strings" + else: + raise SCons.Errors.InternalError, s + " must be a string or a list of strings" + + source = source + ' "%s"' % str(target[0]) + source = [SCons.Node.Python.Value(source)] + + targetlist = [target[0]] + sourcelist = source + + if env.get('auto_build_solution', 1): + env['projects'] = targetlist + t, s = solutionEmitter(target, target, env) + targetlist = targetlist + t + + return (targetlist, sourcelist) + +def solutionEmitter(target, source, env): + """Sets up the DSW dependencies.""" + + # todo: Not sure what sets source to what user has passed as target, + # but this is what happens. When that is fixed, we also won't have + # to make the user always append env['MSVSSOLUTIONSUFFIX'] to target. + if source[0] == target[0]: + source = [] + + # make sure the suffix is correct for the version of MSVS we're running. + (base, suff) = SCons.Util.splitext(str(target[0])) + suff = env.subst('$MSVSSOLUTIONSUFFIX') + target[0] = base + suff + + if not source: + source = 'sln_inputs:' + + if env.has_key('name'): + if SCons.Util.is_String(env['name']): + source = source + ' "%s"' % env['name'] + else: + raise SCons.Errors.InternalError, "name must be a string" + + if env.has_key('variant'): + if SCons.Util.is_String(env['variant']): + source = source + ' "%s"' % env['variant'] + elif SCons.Util.is_List(env['variant']): + for variant in env['variant']: + if SCons.Util.is_String(variant): + source = source + ' "%s"' % variant + else: + raise SCons.Errors.InternalError, "name must be a string or a list of strings" + else: + raise SCons.Errors.InternalError, "variant must be a string or a list of strings" + else: + raise SCons.Errors.InternalError, "variant must be specified" + + if env.has_key('slnguid'): + if SCons.Util.is_String(env['slnguid']): + source = source + ' "%s"' % env['slnguid'] + else: + raise SCons.Errors.InternalError, "slnguid must be a string" + + if env.has_key('projects'): + if SCons.Util.is_String(env['projects']): + source = source + ' "%s"' % env['projects'] + elif SCons.Util.is_List(env['projects']): + for t in env['projects']: + if SCons.Util.is_String(t): + source = source + ' "%s"' % t + + source = source + ' "%s"' % str(target[0]) + source = [SCons.Node.Python.Value(source)] + + return ([target[0]], source) + +projectAction = SCons.Action.Action(GenerateProject, None) + +solutionAction = SCons.Action.Action(GenerateSolution, None) + +projectBuilder = SCons.Builder.Builder(action = '$MSVSPROJECTCOM', + suffix = '$MSVSPROJECTSUFFIX', + emitter = projectEmitter) + +solutionBuilder = SCons.Builder.Builder(action = '$MSVSSOLUTIONCOM', + suffix = '$MSVSSOLUTIONSUFFIX', + emitter = solutionEmitter) + +default_MSVS_SConscript = None + +def generate(env): + """Add Builders and construction variables for Microsoft Visual + Studio project files to an Environment.""" + try: + env['BUILDERS']['MSVSProject'] + except KeyError: + env['BUILDERS']['MSVSProject'] = projectBuilder + + try: + env['BUILDERS']['MSVSSolution'] + except KeyError: + env['BUILDERS']['MSVSSolution'] = solutionBuilder + + env['MSVSPROJECTCOM'] = projectAction + env['MSVSSOLUTIONCOM'] = solutionAction + + if SCons.Script.call_stack: + # XXX Need to find a way to abstract this; the build engine + # shouldn't depend on anything in SCons.Script. + env['MSVSSCONSCRIPT'] = SCons.Script.call_stack[0].sconscript + else: + global default_MSVS_SConscript + if default_MSVS_SConscript is None: + default_MSVS_SConscript = env.File('SConstruct') + env['MSVSSCONSCRIPT'] = default_MSVS_SConscript + + env['MSVSSCONS'] = '"%s" -c "%s"' % (python_executable, getExecScriptMain(env)) + env['MSVSSCONSFLAGS'] = '-C "${MSVSSCONSCRIPT.dir.abspath}" -f ${MSVSSCONSCRIPT.name}' + env['MSVSSCONSCOM'] = '$MSVSSCONS $MSVSSCONSFLAGS' + env['MSVSBUILDCOM'] = '$MSVSSCONSCOM "$MSVSBUILDTARGET"' + env['MSVSREBUILDCOM'] = '$MSVSSCONSCOM "$MSVSBUILDTARGET"' + env['MSVSCLEANCOM'] = '$MSVSSCONSCOM -c "$MSVSBUILDTARGET"' + env['MSVSENCODING'] = 'Windows-1252' + + # Set-up ms tools paths for default version + msvc_setup_env_once(env) + + if env.has_key('MSVS_VERSION'): + version_num, suite = msvs_parse_version(env['MSVS_VERSION']) + else: + (version_num, suite) = (7.0, None) # guess at a default + if not env.has_key('MSVS'): + env['MSVS'] = {} + if (version_num < 7.0): + env['MSVS']['PROJECTSUFFIX'] = '.dsp' + env['MSVS']['SOLUTIONSUFFIX'] = '.dsw' + else: + env['MSVS']['PROJECTSUFFIX'] = '.vcproj' + env['MSVS']['SOLUTIONSUFFIX'] = '.sln' + + env['GET_MSVSPROJECTSUFFIX'] = GetMSVSProjectSuffix + env['GET_MSVSSOLUTIONSUFFIX'] = GetMSVSSolutionSuffix + env['MSVSPROJECTSUFFIX'] = '${GET_MSVSPROJECTSUFFIX}' + env['MSVSSOLUTIONSUFFIX'] = '${GET_MSVSSOLUTIONSUFFIX}' + env['SCONS_HOME'] = os.environ.get('SCONS_HOME') + +def exists(env): + return msvc_exists() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/msvs.xml b/src/engine/SCons/Tool/msvs.xml new file mode 100644 index 0000000..a04ee05 --- /dev/null +++ b/src/engine/SCons/Tool/msvs.xml @@ -0,0 +1,640 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="msvs"> +<summary> +Sets construction variables for Microsoft Visual Studio. +</summary> +<sets> +MSVSPROJECTCOM +MSVSSOLUTIONCOM +MSVSSCONSCRIPT +MSVSSCONS +MSVSSCONSFLAGS +MSVSSCONSCOM +MSVSBUILDCOM +MSVSREBUILDCOM +MSVSCLEANCOM +MSVSENCODING +</sets> +<uses> +</uses> +</tool> + +<builder name ="MSVSProject"> +<summary> +Builds a Microsoft Visual Studio project file, +and by default builds a solution file as well. + +This builds a Visual Studio project file, based on the version of +Visual Studio that is configured (either the latest installed version, +or the version specified by +&cv-link-MSVS_VERSION; +in the Environment constructor). +For Visual Studio 6, it will generate a +<filename>.dsp</filename> +file. +For Visual Studio 7 (.NET) and later versions, it will generate a +<filename>.vcproj</filename> +file. + +By default, +this also generates a solution file +for the specified project, +a +<filename>.dsw</filename> +file for Visual Studio 6 +or a +<filename>.sln</filename> +file for Visual Studio 7 (.NET). +This behavior may be disabled by specifying +<literal>auto_build_solution=0</literal> +when you call +&b-MSVSProject;, +in which case you presumably want to +build the solution file(s) +by calling the +&b-MSVSSolution; +Builder (see below). + +The &b-MSVSProject; builder +takes several lists of filenames +to be placed into the project file. +These are currently limited to +<literal>srcs</literal>, +<literal>incs</literal>, +<literal>localincs</literal>, +<literal>resources</literal>, +and +<literal>misc</literal>. +These are pretty self-explanatory, but it should be noted that these +lists are added to the &cv-link-SOURCES; construction variable as strings, +NOT as SCons File Nodes. This is because they represent file +names to be added to the project file, not the source files used to +build the project file. + +The above filename lists are all optional, +although at least one must be specified +for the resulting project file to be non-empty. + +In addition to the above lists of values, +the following values may be specified: + +<literal>target</literal>: +The name of the target +<filename>.dsp</filename> +or +<filename>.vcproj</filename> +file. +The correct +suffix for the version of Visual Studio must be used, +but the +&cv-link-MSVSPROJECTSUFFIX; +construction variable +will be defined to the correct value (see example below). + +<literal>variant</literal>: +The name of this particular variant. +For Visual Studio 7 projects, +this can also be a list of variant names. +These are typically things like "Debug" or "Release", but really +can be anything you want. +For Visual Studio 7 projects, +they may also specify a target platform +separated from the variant name by a +<literal>|</literal> +(vertical pipe) +character: +<literal>Debug|Xbox</literal>. +The default target platform is Win32. +Multiple calls to +&b-MSVSProject; +with different variants are allowed; +all variants will be added to the project file with their appropriate +build targets and sources. + +<literal>buildtarget</literal>: +An optional string, node, or list of strings or nodes +(one per build variant), to tell the Visual Studio debugger +what output target to use in what build variant. +The number of +<literal>buildtarget</literal> +entries must match the number of +<literal>variant</literal> +entries. + +<literal>runfile</literal>: +The name of the file that Visual Studio 7 and later +will run and debug. +This appears as the value of the +<literal>Output</literal> +field in the resutling Visual Studio project file. +If this is not specified, +the default is the same as the specified +<literal>buildtarget</literal> +value. + +Note that because &SCons; always executes its build commands +from the directory in which the &SConstruct; file is located, +if you generate a project file in a different directory +than the &SConstruct; directory, +users will not be able to double-click +on the file name in compilation error messages +displayed in the Visual Studio console output window. +This can be remedied by adding the +Visual C/C++ +.B /FC +compiler option to the &cv-link-CCFLAGS; variable +so that the compiler will print +the full path name of any +files that cause compilation errors. + +Example usage: + +<example> +barsrcs = ['bar.cpp'], +barincs = ['bar.h'], +barlocalincs = ['StdAfx.h'] +barresources = ['bar.rc','resource.h'] +barmisc = ['bar_readme.txt'] + +dll = env.SharedLibrary(target = 'bar.dll', + source = barsrcs) + +env.MSVSProject(target = 'Bar' + env['MSVSPROJECTSUFFIX'], + srcs = barsrcs, + incs = barincs, + localincs = barlocalincs, + resources = barresources, + misc = barmisc, + buildtarget = dll, + variant = 'Release') +</example> +</summary> +</builder> + +<builder name ="MSVSSolution"> +<summary> +Builds a Microsoft Visual Studio solution file. + +This builds a Visual Studio solution file, +based on the version of Visual Studio that is configured +(either the latest installed version, +or the version specified by +&cv-link-MSVS_VERSION; +in the construction environment). +For Visual Studio 6, it will generate a +<filename>.dsw</filename> +file. +For Visual Studio 7 (.NET), it will +generate a +<filename>.sln</filename> +file. + +The following values must be specified: + +<literal>target</literal>: +The name of the target .dsw or .sln file. The correct +suffix for the version of Visual Studio must be used, but the value +&cv-link-MSVSSOLUTIONSUFFIX; +will be defined to the correct value (see example below). + +<literal>variant</literal>: +The name of this particular variant, or a list of variant +names (the latter is only supported for MSVS 7 solutions). These are +typically things like "Debug" or "Release", but really can be anything +you want. For MSVS 7 they may also specify target platform, like this +"Debug|Xbox". Default platform is Win32. + +<literal>projects</literal>: +A list of project file names, or Project nodes returned by calls to the +&b-MSVSProject; +Builder, +to be placed into the solution file. +It should be noted that these file names are NOT added to the $SOURCES +environment variable in form of files, but rather as strings. This +is because they represent file names to be added to the solution file, +not the source files used to build the solution file. + +(NOTE: Currently only one project is supported per solution.) + +Example Usage: + +<example> +env.MSVSSolution(target = 'Bar' + env['MSVSSOLUTIONSUFFIX'], + projects = ['bar' + env['MSVSPROJECTSUFFIX']], + variant = 'Release') +</example> +</summary> +</builder> + +<cvar name="MSVS"> +<summary> +When the Microsoft Visual Studio tools are initialized, they set up +this dictionary with the following keys: + +<envar>VERSION</envar>: +the version of MSVS being used (can be set via +&cv-link-MSVS_VERSION;) + +<envar>VERSIONS</envar>: +the available versions of MSVS installed + +<envar>VCINSTALLDIR</envar>: +installed directory of Visual C++ + +<envar>VSINSTALLDIR</envar>: +installed directory of Visual Studio + +<envar>FRAMEWORKDIR</envar>: +installed directory of the .NET framework + +<envar>FRAMEWORKVERSIONS</envar>: +list of installed versions of the .NET framework, sorted latest to oldest. + +<envar>FRAMEWORKVERSION</envar>: +latest installed version of the .NET framework + +<envar>FRAMEWORKSDKDIR</envar>: +installed location of the .NET SDK. + +<envar>PLATFORMSDKDIR</envar>: +installed location of the Platform SDK. + +<envar>PLATFORMSDK_MODULES</envar>: +dictionary of installed Platform SDK modules, +where the dictionary keys are keywords for the various modules, and +the values are 2-tuples where the first is the release date, and the +second is the version number. + +If a value isn't set, it wasn't available in the registry. +</summary> +</cvar> + +<cvar name="MSVS_ARCH"> +<summary> +Sets the architecture for which the generated project(s) should build. + +The default value is <literal>x86</literal>. +<literal>amd64</literal> is also supported +by &SCons; for some Visual Studio versions. +Trying to set &cv-MSVS_ARCH; to an architecture that's not +supported for a given Visual Studio version +will generate an error. +</summary> +</cvar> + +<cvar name="MSVS_IGNORE_IDE_PATHS"> +<summary> +Tells the MS Visual Studio tools to use minimal INCLUDE, LIB, and PATH settings, +instead of the settings from the IDE. + +For Visual Studio, SCons will (by default) automatically determine +where MSVS is installed, and use the LIB, INCLUDE, and PATH variables +set by the IDE. You can override this behavior by setting these +variables after Environment initialization, or by setting +<envar>MSVS_IGNORE_IDE_PATHS = 1</envar> +in the Environment initialization. +Specifying this will not leave these unset, but will set them to a +minimal set of paths needed to run the tools successfully. + +For VS6, the mininimal set is: +<example> + INCLUDE:'<VSDir>\VC98\ATL\include;<VSDir>\VC98\MFC\include;<VSDir>\VC98\include' + LIB:'<VSDir>\VC98\MFC\lib;<VSDir>\VC98\lib' + PATH:'<VSDir>\Common\MSDev98\bin;<VSDir>\VC98\bin' +</example> +For VS7, it is: +<example> + INCLUDE:'<VSDir>\Vc7\atlmfc\include;<VSDir>\Vc7\include' + LIB:'<VSDir>\Vc7\atlmfc\lib;<VSDir>\Vc7\lib' + PATH:'<VSDir>\Common7\Tools\bin;<VSDir>\Common7\Tools;<VSDir>\Vc7\bin' +</example> + +Where '<VSDir>' is the installed location of Visual Studio. +</summary> +</cvar> + +<cvar name="MSVS_PROJECT_BASE_PATH"> +<summary> +The string +placed in a generated Microsoft Visual Studio solution file +as the value of the +<literal>SccProjectFilePathRelativizedFromConnection0</literal> +and +<literal>SccProjectFilePathRelativizedFromConnection1</literal> +attributes of the +<literal>GlobalSection(SourceCodeControl)</literal> +section. +There is no default value. +</summary> +</cvar> + +<cvar name="MSVS_PROJECT_GUID"> +<summary> +The string +placed in a generated Microsoft Visual Studio project file +as the value of the +<literal>ProjectGUID</literal> +attribute. +The string is also placed in the +<literal>SolutionUniqueID</literal> +attribute of the +<literal>GlobalSection(SourceCodeControl)</literal> +section of the Microsoft Visual Studio solution file. +There is no default value. +</summary> +</cvar> + +<cvar name="MSVS_SCC_AUX_PATH"> +<summary> +The path name +placed in a generated Microsoft Visual Studio project file +as the value of the +<literal>SccAuxPath</literal> +attribute +if the +<envar>MSVS_SCC_PROVIDER</envar> +construction variable is also set. +There is no default value. +</summary> +</cvar> + +<cvar name="MSVS_SCC_LOCAL_PATH"> +<summary> +The path name +placed in a generated Microsoft Visual Studio project file +as the value of the +<literal>SccLocalPath</literal> +attribute +if the +<envar>MSVS_SCC_PROVIDER</envar> +construction variable is also set. +The path name is also placed in the +<literal>SccLocalPath0</literal> +and +<literal>SccLocalPath1</literal> +attributes of the +<literal>GlobalSection(SourceCodeControl)</literal> +section of the Microsoft Visual Studio solution file. +There is no default value. +</summary> +</cvar> + +<cvar name="MSVS_SCC_PROJECT_NAME"> +<summary> +The project name +placed in a generated Microsoft Visual Studio project file +as the value of the +<literal>SccProjectName</literal> +attribute. +There is no default value. +</summary> +</cvar> + +<cvar name="MSVS_SCC_PROVIDER"> +<summary> +The string +placed in a generated Microsoft Visual Studio project file +as the value of the +<literal>SccProvider</literal> +attribute. +The string is also placed in the +<literal>SccProvider1</literal> +attribute of the +<literal>GlobalSection(SourceCodeControl)</literal> +section of the Microsoft Visual Studio solution file. +There is no default value. +</summary> +</cvar> + +<cvar name="MSVS_USE_MFC_DIRS"> +<summary> +Tells the MS Visual Studio tool(s) to use +the MFC directories in its default paths +for compiling and linking. +The &cv-MSVS_USE_MFC_DIRS; variable has no effect if the +<envar>INCLUDE</envar> +or +<envar>LIB</envar> +environment variables are set explictly. + +Under Visual Studio version 6, +setting +&cv-MSVS_USE_MFC_DIRS; +to a non-zero value +adds the +<filename>ATL\include</filename> +and +<filename>MFC\include</filename> +directories to +the default +<envar>INCLUDE</envar> +external environment variable, +and adds the +<filename>MFC\lib</filename> +directory to +the default +<envar>LIB</envar> +external environment variable. + +Under Visual Studio version 7, +setting +&cv-MSVS_USE_MFC_DIRS; +to a non-zero value +adds the +<filename>atlmfc\include</filename> +directory to the default +<envar>INCLUDE</envar> +external environment variable, +and adds the +<filename>atlmfc\lib</filename> +directory to the default +<envar>LIB</envar> +external environment variable. + +Under Visual Studio version 8, +setting +&cv-MSVS_USE_MFC_DIRS; +to a non-zero value will, +by default, +add the +<filename>atlmfc\include</filename> +directory to the default +<envar>INCLUDE</envar> +external environment variable, +and the +<filename>atlmfc\lib</filename> +directory to the default +<envar>LIB</envar> +external environment variable. +If, however, the +<envar>['MSVS']['PLATFORMSDKDIR']</envar> +variable is set, +then the +<filename>mfc</filename> +and the +<filename>atl</filename> +subdirectories of the +<envar>PLATFORMSDKDIR</envar> +are added to the default value of the +<envar>INCLUDE</envar> +external environment variable, +and the default value of the +<envar>LIB</envar> +external environment variable is left untouched. +</summary> +</cvar> + +<cvar name="MSVS_VERSION"> +<summary> +Sets the preferred version of Microsoft Visual Studio to use. + +If &cv-MSVS_VERSION; is not set, +&SCons; will (by default) select the latest version +of Visual Studio installed on your system. +So, if you have version 6 and version 7 (MSVS .NET) installed, +it will prefer version 7. +You can override this by +specifying the +<envar>MSVS_VERSION</envar> +variable in the Environment initialization, setting it to the +appropriate version ('6.0' or '7.0', for example). +If the specified version isn't installed, +tool initialization will fail. + +This is obsolete: use &cv-MSVC_VERSION; instead. If &cv-MSVS_VERSION; is set and +&cv-MSVC_VERSION; is not, &cv-MSVC_VERSION; will be set automatically to &cv-MSVS_VERSION;. +If both are set to different values, scons will raise an error. +</summary> +</cvar> + +<cvar name="MSVSBUILDCOM"> +<summary> +The build command line placed in +a generated Microsoft Visual Studio project file. +The default is to have Visual Studio invoke SCons with any specified +build targets. +</summary> +</cvar> + +<cvar name="MSVSCLEANCOM"> +<summary> +The clean command line placed in +a generated Microsoft Visual Studio project file. +The default is to have Visual Studio invoke SCons with the -c option +to remove any specified targets. +</summary> +</cvar> + +<cvar name="MSVSENCODING"> +<summary> +The encoding string placed in +a generated Microsoft Visual Studio project file. +The default is encoding +<literal>Windows-1252</literal>. +</summary> +</cvar> + +<cvar name="MSVSPROJECTCOM"> +<summary> +The action used to generate Microsoft Visual Studio project files. +</summary> +</cvar> + +<cvar name="MSVSPROJECTSUFFIX"> +<summary> +The suffix used for Microsoft Visual Studio project (DSP) files. +The default value is +<filename>.vcproj</filename> +when using Visual Studio version 7.x (.NET) +or later version, +and +<filename>.dsp</filename> +when using earlier versions of Visual Studio. +</summary> +</cvar> + +<cvar name="MSVSREBUILDCOM"> +<summary> +The rebuild command line placed in +a generated Microsoft Visual Studio project file. +The default is to have Visual Studio invoke SCons with any specified +rebuild targets. +</summary> +</cvar> + +<cvar name="MSVSSCONS"> +<summary> +The SCons used in generated Microsoft Visual Studio project files. +The default is the version of SCons being +used to generate the project file. +</summary> +</cvar> + +<cvar name="MSVSSCONSFLAGS"> +<summary> +The SCons flags used in generated Microsoft Visual Studio +project files. +</summary> +</cvar> + +<cvar name="MSVSSCONSCOM"> +<summary> +The default SCons command used in generated Microsoft Visual Studio +project files. +</summary> +</cvar> + +<cvar name="MSVSSCONSCRIPT"> +<summary> +The sconscript file +(that is, +&SConstruct; +or +&SConscript; +file) +that will be invoked by Visual Studio +project files +(through the +&cv-link-MSVSSCONSCOM; +variable). +The default is the same sconscript file +that contains the call to +&b-MSVSProject; +to build the project file. +</summary> +</cvar> + +<cvar name="MSVSSOLUTIONCOM"> +<summary> +The action used to generate Microsoft Visual Studio solution files. +</summary> +</cvar> + +<cvar name="MSVSSOLUTIONSUFFIX"> +<summary> +The suffix used for Microsoft Visual Studio solution (DSW) files. +The default value is +<filename>.sln</filename> +when using Visual Studio version 7.x (.NET), +and +<filename>.dsw</filename> +when using earlier versions of Visual Studio. +</summary> +</cvar> + +<cvar name="SCONS_HOME"> +<summary> +The (optional) path to the SCons library directory, +initialized from the external environment. +If set, this is used to construct a shorter and more +efficient search path in the +&cv-link-MSVSSCONS; +command line executed +from Microsoft Visual Studio project files. +</summary> +</cvar> diff --git a/src/engine/SCons/Tool/msvsTests.py b/src/engine/SCons/Tool/msvsTests.py new file mode 100644 index 0000000..08066fb --- /dev/null +++ b/src/engine/SCons/Tool/msvsTests.py @@ -0,0 +1,757 @@ +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/msvsTests.py 4577 2009/12/27 19:44:43 scons" + +import os +import string +import sys +import TestCmd +import unittest +import copy + +from SCons.Tool.msvs import * +import SCons.Util +import SCons.Warnings + +from SCons.Tool.MSCommon.common import debug + +from SCons.Tool.MSCommon import get_default_version, \ + query_versions + +regdata_6a = string.split(r'''[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio] +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\6.0] +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\6.0\ServicePacks] +"sp3"="" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\6.0\Setup] +"VsCommonDir"="C:\Program Files\Microsoft Visual Studio\Common" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\6.0\Setup\Microsoft Developer Network Library - Visual Studio 6.0a] +"ProductDir"="C:\Program Files\Microsoft Visual Studio\MSDN98\98VSa\1033" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\6.0\Setup\Microsoft Visual C++] +"ProductDir"="C:\Program Files\Microsoft Visual Studio\VC98" +''','\n') + +regdata_6b = string.split(r'''[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio] +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\6.0] +"InstallDir"="C:\VS6\Common\IDE\IDE98" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\6.0\ServicePacks] +"sp5"="" +"latest"=dword:00000005 +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\6.0\Setup] +"VsCommonDir"="C:\VS6\Common" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\6.0\Setup\Microsoft Visual Basic] +"ProductDir"="C:\VS6\VB98" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\6.0\Setup\Microsoft Visual C++] +"ProductDir"="C:\VS6\VC98" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\6.0\Setup\Microsoft Visual Studio] +"ProductDir"="C:\VS6" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\6.0\Setup\Microsoft VSEE Client] +"ProductDir"="C:\VS6\Common\Tools" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\6.0\Setup\Visual Studio 98] +''','\n') + +regdata_7 = string.split(r''' +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.0] +"InstallDir"="C:\Program Files\Microsoft Visual Studio .NET\Common7\IDE\" +"Source Directories"="C:\Program Files\Microsoft Visual Studio .NET\Vc7\crt\;C:\Program Files\Microsoft Visual Studio .NET\Vc7\atlmfc\src\mfc\;C:\Program Files\Microsoft Visual Studio .NET\Vc7\atlmfc\src\atl\" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.0\InstalledProducts] +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.0\InstalledProducts\CrystalReports] +@="#15007" +"Package"="{F05E92C6-8346-11D3-B4AD-00A0C9B04E7B}" +"ProductDetails"="#15009" +"LogoID"="0" +"PID"="#15008" +"UseInterface"=dword:00000001 +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.0\InstalledProducts\Visual Basic.NET] +@="" +"DefaultProductAttribute"="VB" +"Package"="{164B10B9-B200-11D0-8C61-00A0C91E29D5}" +"UseInterface"=dword:00000001 +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.0\InstalledProducts\Visual C#] +@="" +"Package"="{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}" +"UseInterface"=dword:00000001 +"DefaultProductAttribute"="C#" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.0\InstalledProducts\VisualC++] +"UseInterface"=dword:00000001 +"Package"="{F1C25864-3097-11D2-A5C5-00C04F7968B4}" +"DefaultProductAttribute"="VC" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.0\Setup] +"Dbghelp_path"="C:\Program Files\Microsoft Visual Studio .NET\Common7\IDE\" +"dw_dir"="C:\Program Files\Microsoft Visual Studio .NET\Common7\IDE\" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.0\Setup\MSDN] +"ProductDir"="C:\Program Files\Microsoft Visual Studio .NET\Msdn\1033\" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.0\Setup\Servicing\SKU] +"Visual Studio .NET Professional - English"="{D0610409-7D65-11D5-A54F-0090278A1BB8}" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.0\Setup\VB] +"ProductDir"="C:\Program Files\Microsoft Visual Studio .NET\Vb7\" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.0\Setup\VC] +"ProductDir"="C:\Program Files\Microsoft Visual Studio .NET\Vc7\" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.0\Setup\VC#] +"ProductDir"="C:\Program Files\Microsoft Visual Studio .NET\VC#\" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.0\Setup\Visual Studio .NET Professional - English] +"InstallSuccess"=dword:00000001 +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.0\Setup\VS] +"EnvironmentDirectory"="C:\Program Files\Microsoft Visual Studio .NET\Common7\IDE\" +"EnvironmentPath"="C:\Program Files\Microsoft Visual Studio .NET\Common7\IDE\devenv.exe" +"VS7EnvironmentLocation"="C:\Program Files\Microsoft Visual Studio .NET\Common7\IDE\devenv.exe" +"MSMDir"="C:\Program Files\Common Files\Merge Modules\" +"ProductDir"="C:\Program Files\Microsoft Visual Studio .NET\" +"VS7CommonBinDir"="C:\Program Files\Microsoft Visual Studio .NET\Common7\Tools\" +"VS7CommonDir"="C:\Program Files\Microsoft Visual Studio .NET\Common7\" +"VSUpdateDir"="C:\Program Files\Microsoft Visual Studio .NET\Setup\VSUpdate\" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.0\Setup\VS\BuildNumber] +"1033"="7.0.9466" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.0\Setup\VS\Pro] +"ProductDir"="C:\Program Files\Microsoft Visual Studio .NET\" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.0\VC] +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.0\VC\VC_OBJECTS_PLATFORM_INFO] +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.0\VC\VC_OBJECTS_PLATFORM_INFO\Win32] +@="{A54AAE91-30C2-11D3-87BF-A04A4CC10000}" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.0\VC\VC_OBJECTS_PLATFORM_INFO\Win32\Directories] +"Path Dirs"="$(VCInstallDir)bin;$(VSInstallDir)Common7\Tools\bin\prerelease;$(VSInstallDir)Common7\Tools\bin;$(VSInstallDir)Common7\tools;$(VSInstallDir)Common7\ide;C:\Program Files\HTML Help Workshop\;$(FrameworkSDKDir)bin;$(FrameworkDir)$(FrameworkVersion);C:\perl\bin;C:\cygwin\bin;c:\cygwin\usr\bin;C:\bin;C:\program files\perforce;C:\cygwin\usr\local\bin\i686-pc-cygwin;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem" +"Library Dirs"="$(VCInstallDir)lib;$(VCInstallDir)atlmfc\lib;$(VCInstallDir)PlatformSDK\lib\prerelease;$(VCInstallDir)PlatformSDK\lib;$(FrameworkSDKDir)lib" +"Include Dirs"="$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(VCInstallDir)PlatformSDK\include\prerelease;$(VCInstallDir)PlatformSDK\include;$(FrameworkSDKDir)include" +"Source Dirs"="$(VCInstallDir)atlmfc\src\mfc;$(VCInstallDir)atlmfc\src\atl;$(VCInstallDir)crt\src" +"Reference Dirs"="" +''','\n') + +regdata_7_1 = string.split(r''' +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.1] +@="" +"Source Directories"="C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\crt\src\;C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\atlmfc\src\mfc\;C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\atlmfc\src\atl\" +"ThisVersionSolutionCLSID"="{246C57AE-40DD-4d6b-9E8D-B0F5757BB2A8}" +"ThisVersionDTECLSID"="{8CD2DD97-4EC1-4bc4-9359-89A3EEDD57A6}" +"InstallDir"="C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\IDE\" +"CLR Version"="v1.1.4322" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.1\InstalledProducts] +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.1\InstalledProducts\Smart Device Extensions] +"UseInterface"=dword:00000001 +"VS7InstallDir"="C:\Program Files\Microsoft Visual Studio .NET 2003\" +"VBDeviceInstallDir"="C:\Program Files\Microsoft Visual Studio .NET 2003\VB7\" +"CSharpDeviceInstallDir"="C:\Program Files\Microsoft Visual Studio .NET 2003\VC#\" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.1\InstalledProducts\Visual Basic.NET] +"UseInterface"=dword:00000001 +"Package"="{164B10B9-B200-11D0-8C61-00A0C91E29D5}" +"DefaultProductAttribute"="VB" +@="" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.1\InstalledProducts\Visual C#] +"DefaultProductAttribute"="C#" +"UseInterface"=dword:00000001 +"Package"="{FAE04EC1-301F-11D3-BF4B-00C04F79EFBC}" +@="" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.1\InstalledProducts\Visual JSharp] +@="" +"Package"="{E6FDF8B0-F3D1-11D4-8576-0002A516ECE8}" +"UseInterface"=dword:00000001 +"DefaultProductAttribute"="Visual JSharp" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.1\InstalledProducts\VisualC++] +"UseInterface"=dword:00000001 +"Package"="{F1C25864-3097-11D2-A5C5-00C04F7968B4}" +"DefaultProductAttribute"="VC" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.1\Setup] +"Dbghelp_path"="C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\IDE\" +"dw_dir"="C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\IDE\" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.1\Setup\CSDPROJ] +"ProductDir"="C:\Program Files\Microsoft Visual Studio .NET 2003\VC#\" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.1\Setup\JSHPROJ] +"ProductDir"="C:\Program Files\Microsoft Visual Studio .NET 2003\VJ#\" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.1\Setup\Servicing] +"CurrentSULevel"=dword:00000000 +"CurrentSPLevel"=dword:00000000 +"Server Path"="" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.1\Setup\Servicing\Package] +"FxSDK"="" +"VB"="" +"VC"="" +"VCS"="" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.1\Setup\Servicing\SKU] +"Visual Studio .NET Professional 2003 - English"="{20610409-CA18-41A6-9E21-A93AE82EE7C5}" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.1\Setup\VB] +"ProductDir"="C:\Program Files\Microsoft Visual Studio .NET 2003\Vb7\" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.1\Setup\VBDPROJ] +"ProductDir"="C:\Program Files\Microsoft Visual Studio .NET 2003\Vb7\" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.1\Setup\VC] +"ProductDir"="C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.1\Setup\VC#] +"ProductDir"="C:\Program Files\Microsoft Visual Studio .NET 2003\VC#\" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.1\Setup\Visual Studio .NET Professional 2003 - English] +"InstallSuccess"=dword:00000001 +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.1\Setup\VS] +"EnvironmentDirectory"="C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\IDE\" +"EnvironmentPath"="C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\IDE\devenv.exe" +"VS7EnvironmentLocation"="C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\IDE\devenv.exe" +"MSMDir"="C:\Program Files\Common Files\Merge Modules\" +"VS7CommonBinDir"="C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Tools\" +"VS7CommonDir"="C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\" +"ProductDir"="C:\Program Files\Microsoft Visual Studio .NET 2003\" +"VSUpdateDir"="C:\Program Files\Microsoft Visual Studio .NET 2003\Setup\VSUpdate\" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.1\Setup\VS\BuildNumber] +"1033"="7.1.3088" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.1\Setup\VS\Pro] +"ProductDir"="C:\Program Files\Microsoft Visual Studio .NET 2003\" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.1\VC] +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.1\VC\VC_OBJECTS_PLATFORM_INFO] +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.1\VC\VC_OBJECTS_PLATFORM_INFO\Win32] +@="{759354D0-6B42-4705-AFFB-56E34D2BC3D4}" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.1\VC\VC_OBJECTS_PLATFORM_INFO\Win32\Directories] +"Path Dirs"="$(VCInstallDir)bin;$(VSInstallDir)Common7\Tools\bin\prerelease;$(VSInstallDir)Common7\Tools\bin;$(VSInstallDir)Common7\tools;$(VSInstallDir)Common7\ide;C:\Program Files\HTML Help Workshop\;$(FrameworkSDKDir)bin;$(FrameworkDir)$(FrameworkVersion);C:\Perl\bin\;c:\bin;c:\cygwin\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\Program Files\Common Files\Avid;C:\Program Files\backburner 2\;C:\Program Files\cvsnt;C:\Program Files\Subversion\bin;C:\Program Files\Common Files\Adobe\AGL;C:\Program Files\HTMLDoc" +"Library Dirs"="$(VCInstallDir)lib;$(VCInstallDir)atlmfc\lib;$(VCInstallDir)PlatformSDK\lib\prerelease;$(VCInstallDir)PlatformSDK\lib;$(FrameworkSDKDir)lib" +"Include Dirs"="$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(VCInstallDir)PlatformSDK\include\prerelease;$(VCInstallDir)PlatformSDK\include;$(FrameworkSDKDir)include" +"Source Dirs"="$(VCInstallDir)atlmfc\src\mfc;$(VCInstallDir)atlmfc\src\atl;$(VCInstallDir)crt\src" +"Reference Dirs"="$(FrameWorkDir)$(FrameWorkVersion)" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.1\VC\VC_OBJECTS_PLATFORM_INFO\Win32\ToolDefaultExtensionLists] +"VCCLCompilerTool"="*.cpp;*.cxx;*.cc;*.c" +"VCLinkerTool"="*.obj;*.res;*.lib;*.rsc" +"VCLibrarianTool"="*.obj;*.res;*.lib;*.rsc" +"VCMIDLTool"="*.idl;*.odl" +"VCCustomBuildTool"="*.bat" +"VCResourceCompilerTool"="*.rc" +"VCPreBuildEventTool"="*.bat" +"VCPreLinkEventTool"="*.bat" +"VCPostBuildEventTool"="*.bat" +"VCBscMakeTool"="*.sbr" +"VCNMakeTool"="" +"VCWebServiceProxyGeneratorTool"="*.discomap" +"VCWebDeploymentTool"="" +"VCALinkTool"="*.resources" +"VCManagedResourceCompilerTool"="*.resx" +"VCXMLDataGeneratorTool"="*.xsd" +"VCManagedWrapperGeneratorTool"="" +"VCAuxiliaryManagedWrapperGeneratorTool"="" +"VCPrimaryInteropTool"="" +''','\n') + +regdata_8exp = string.split(r''' +[HKEY_LOCAL_MACHINE\Software\Microsoft\VCExpress\8.0] +"CLR Version"="v2.0.50727" +"ApplicationID"="VCExpress" +"SecurityAppID"="{741726F6-1EAE-4680-86A6-6085E8872CF8}" +"InstallDir"="C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\" +"EnablePreloadCLR"=dword:00000001 +"RestoreAppPath"=dword:00000001 +[HKEY_LOCAL_MACHINE\Software\Microsoft\VCExpress\8.0\InstalledProducts] +[HKEY_LOCAL_MACHINE\Software\Microsoft\VCExpress\8.0\InstalledProducts\Microsoft Visual C++] +"UseInterface"=dword:00000001 +"Package"="{F1C25864-3097-11D2-A5C5-00C04F7968B4}" +"DefaultProductAttribute"="VC" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VCExpress\8.0\Setup] +[HKEY_LOCAL_MACHINE\Software\Microsoft\VCExpress\8.0\Setup\VC] +"ProductDir"="C:\Program Files\Microsoft Visual Studio 8\VC\" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VCExpress\8.0\Setup\VS] +"ProductDir"="C:\Program Files\Microsoft Visual Studio 8\" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VCExpress\8.0\VC] +[HKEY_LOCAL_MACHINE\Software\Microsoft\VCExpress\8.0\VC\VC_OBJECTS_PLATFORM_INFO] +[HKEY_LOCAL_MACHINE\Software\Microsoft\VCExpress\8.0\VC\VC_OBJECTS_PLATFORM_INFO\Win32] +@="{72f11281-2429-11d7-8bf6-00b0d03daa06}" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VCExpress\8.0\VC\VC_OBJECTS_PLATFORM_INFO\Win32\ToolDefaultExtensionLists] +"VCCLCompilerTool"="*.cpp;*.cxx;*.cc;*.c" +"VCLinkerTool"="*.obj;*.res;*.lib;*.rsc;*.licenses" +"VCLibrarianTool"="*.obj;*.res;*.lib;*.rsc" +"VCMIDLTool"="*.idl;*.odl" +"VCCustomBuildTool"="*.bat" +"VCResourceCompilerTool"="*.rc" +"VCPreBuildEventTool"="*.bat" +"VCPreLinkEventTool"="*.bat" +"VCPostBuildEventTool"="*.bat" +"VCBscMakeTool"="*.sbr" +"VCFxCopTool"="*.dll;*.exe" +"VCNMakeTool"="" +"VCWebServiceProxyGeneratorTool"="*.discomap" +"VCWebDeploymentTool"="" +"VCALinkTool"="*.resources" +"VCManagedResourceCompilerTool"="*.resx" +"VCXMLDataGeneratorTool"="*.xsd" +"VCManifestTool"="*.manifest" +"VCXDCMakeTool"="*.xdc" +''','\n') + +regdata_80 = string.split(r''' +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\8.0] +"CLR Version"="v2.0.50727" +"ApplicationID"="VisualStudio" +"ThisVersionDTECLSID"="{BA018599-1DB3-44f9-83B4-461454C84BF8}" +"ThisVersionSolutionCLSID"="{1B2EEDD6-C203-4d04-BD59-78906E3E8AAB}" +"SecurityAppID"="{DF99D4F5-9F04-4CEF-9D39-095821B49C77}" +"InstallDir"="C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\" +"EnablePreloadCLR"=dword:00000001 +"RestoreAppPath"=dword:00000001 +"Source Directories"="C:\Program Files\Microsoft Visual Studio 8\VC\crt\src\;C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\src\mfc\;C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\src\atl\;C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\include\" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\8.0\InstalledProducts] +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\8.0\InstalledProducts\Microsoft Visual C++] +"UseInterface"=dword:00000001 +"Package"="{F1C25864-3097-11D2-A5C5-00C04F7968B4}" +"DefaultProductAttribute"="VC" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\8.0\Setup] +"Dbghelp_path"="C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\8.0\Setup\EF] +"ProductDir"="C:\Program Files\Microsoft Visual Studio 8\EnterpriseFrameworks\" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\8.0\Setup\Microsoft Visual Studio 2005 Professional Edition - ENU] +"SrcPath"="d:\vs\" +"InstallSuccess"=dword:00000001 +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\8.0\Setup\VC] +"ProductDir"="C:\Program Files\Microsoft Visual Studio 8\VC\" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\8.0\Setup\VS] +"ProductDir"="C:\Program Files\Microsoft Visual Studio 8\" +"VS7EnvironmentLocation"="C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\devenv.exe" +"EnvironmentPath"="C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\devenv.exe" +"EnvironmentDirectory"="C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\" +"VS7CommonDir"="C:\Program Files\Microsoft Visual Studio 8\Common7\" +"VS7CommonBinDir"="C:\Program Files\Microsoft Visual Studio 8\Common7\Tools\" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\8.0\Setup\VS\BuildNumber] +"1033"="8.0.50727.42" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\8.0\Setup\VS\Pro] +"ProductDir"="C:\Program Files\Microsoft Visual Studio 8\" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\8.0\VC] +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\8.0\VC\VC_OBJECTS_PLATFORM_INFO] +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\8.0\VC\VC_OBJECTS_PLATFORM_INFO\Win32] +@="{72f11281-2429-11d7-8bf6-00b0d03daa06}" +[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\8.0\VC\VC_OBJECTS_PLATFORM_INFO\Win32\ToolDefaultExtensionLists] +"VCCLCompilerTool"="*.cpp;*.cxx;*.cc;*.c" +"VCLinkerTool"="*.obj;*.res;*.lib;*.rsc;*.licenses" +"VCLibrarianTool"="*.obj;*.res;*.lib;*.rsc" +"VCMIDLTool"="*.idl;*.odl" +"VCCustomBuildTool"="*.bat" +"VCResourceCompilerTool"="*.rc" +"VCPreBuildEventTool"="*.bat" +"VCPreLinkEventTool"="*.bat" +"VCPostBuildEventTool"="*.bat" +"VCBscMakeTool"="*.sbr" +"VCFxCopTool"="*.dll;*.exe" +"VCNMakeTool"="" +"VCWebServiceProxyGeneratorTool"="*.discomap" +"VCWebDeploymentTool"="" +"VCALinkTool"="*.resources" +"VCManagedResourceCompilerTool"="*.resx" +"VCXMLDataGeneratorTool"="*.xsd" +"VCManifestTool"="*.manifest" +"VCXDCMakeTool"="*.xdc" +''','\n') + +regdata_cv = string.split(r'''[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion] +"ProgramFilesDir"="C:\Program Files" +"CommonFilesDir"="C:\Program Files\Common Files" +"MediaPath"="C:\WINDOWS\Media" +''','\n') + + +regdata_none = [] + +class DummyEnv: + def __init__(self, dict=None): + if dict: + self.dict = dict + else: + self.dict = {} + + def Dictionary(self, key = None): + if not key: + return self.dict + return self.dict[key] + + def __setitem__(self,key,value): + self.dict[key] = value + + def __getitem__(self,key): + return self.dict[key] + + def has_key(self,name): + return self.dict.has_key(name) + +class RegKey: + """key class for storing an 'open' registry key""" + def __init__(self,key): + self.key = key + +# Warning: this is NOT case-insensitive, unlike the Windows registry. +# So e.g. HKLM\Software is NOT the same key as HKLM\SOFTWARE. +class RegNode: + """node in the dummy registry""" + def __init__(self,name): + self.valdict = {} + self.keydict = {} + self.keyarray = [] + self.valarray = [] + self.name = name + + def value(self,val): + if self.valdict.has_key(val): + return (self.valdict[val],1) + else: + raise SCons.Util.RegError + + def addValue(self,name,val): + self.valdict[name] = val + self.valarray.append(name) + + def valindex(self,index): + rv = None + try: + rv = (self.valarray[index],self.valdict[self.valarray[index]],1) + except KeyError: + raise SCons.Util.RegError + return rv + + def key(self,key,sep = '\\'): + if key.find(sep) != -1: + keyname, subkeys = key.split(sep,1) + else: + keyname = key + subkeys = "" + try: + # recurse, and return the lowest level key node + if subkeys: + return self.keydict[keyname].key(subkeys) + else: + return self.keydict[keyname] + except KeyError: + raise SCons.Util.RegError + + def addKey(self,name,sep = '\\'): + if string.find(name, sep) != -1: + keyname, subkeys = string.split(name, sep, 1) + else: + keyname = name + subkeys = "" + + if not self.keydict.has_key(keyname): + self.keydict[keyname] = RegNode(keyname) + self.keyarray.append(keyname) + + # recurse, and return the lowest level key node + if subkeys: + return self.keydict[keyname].addKey(subkeys) + else: + return self.keydict[keyname] + + def keyindex(self,index): + return self.keydict[self.keyarray[index]] + + def __str__(self): + return self._doStr() + + def _doStr(self, indent = ''): + rv = "" + for value in self.valarray: + rv = rv + '%s"%s" = "%s"\n' % (indent, value, self.valdict[value]) + for key in self.keyarray: + rv = rv + "%s%s: {\n"%(indent, key) + rv = rv + self.keydict[key]._doStr(indent + ' ') + rv = rv + indent + '}\n' + return rv + +class DummyRegistry: + """registry class for storing fake registry attributes""" + def __init__(self,data): + """parse input data into the fake registry""" + self.root = RegNode('REGISTRY') + self.root.addKey('HKEY_LOCAL_MACHINE') + self.root.addKey('HKEY_CURRENT_USER') + self.root.addKey('HKEY_USERS') + self.root.addKey('HKEY_CLASSES_ROOT') + + self.parse(data) + + def parse(self, data): + parent = self.root + keymatch = re.compile('^\[(.*)\]$') + valmatch = re.compile('^(?:"(.*)"|[@])="(.*)"$') + for line in data: + m1 = keymatch.match(line) + if m1: + # add a key, set it to current parent + parent = self.root.addKey(m1.group(1)) + else: + m2 = valmatch.match(line) + if m2: + parent.addValue(m2.group(1),m2.group(2)) + + def OpenKeyEx(self,root,key): + if root == SCons.Util.HKEY_CLASSES_ROOT: + mykey = 'HKEY_CLASSES_ROOT\\' + key + if root == SCons.Util.HKEY_USERS: + mykey = 'HKEY_USERS\\' + key + if root == SCons.Util.HKEY_CURRENT_USER: + mykey = 'HKEY_CURRENT_USER\\' + key + if root == SCons.Util.HKEY_LOCAL_MACHINE: + mykey = 'HKEY_LOCAL_MACHINE\\' + key + debug("Open Key:%s"%mykey) + return self.root.key(mykey) + +def DummyOpenKeyEx(root, key): + return registry.OpenKeyEx(root,key) + +def DummyEnumKey(key, index): + rv = None + try: + rv = key.keyarray[index] + except IndexError: + raise SCons.Util.RegError +# print "Enum Key",key.name,"[",index,"] =>",rv + return rv + +def DummyEnumValue(key, index): + rv = key.valindex(index) +# print "Enum Value",key.name,"[",index,"] =>",rv + return rv + +def DummyQueryValue(key, value): + rv = key.value(value) +# print "Query Value",key.name+"\\"+value,"=>",rv + return rv + +def DummyExists(path): + return 1 + +class msvsTestCase(unittest.TestCase): + """This test case is run several times with different defaults. + See its subclasses below.""" + def setUp(self): + debug("THIS TYPE :%s"%self) + global registry + registry = self.registry + from SCons.Tool.MSCommon.vs import reset_installed_visual_studios + reset_installed_visual_studios() + + def test_get_default_version(self): + """Test retrieval of the default visual studio version""" + + debug("Testing for default version %s"%self.default_version) + env = DummyEnv() + v1 = get_default_version(env) + assert env['MSVS_VERSION'] == self.default_version, \ + ("env['MSVS_VERSION'] != self.default_version",self.default_version, env['MSVS_VERSION']) + assert env['MSVS']['VERSION'] == self.default_version, \ + ("env['MSVS']['VERSION'] != self.default_version",self.default_version, env['MSVS']['VERSION']) + assert v1 == self.default_version, (self.default_version, v1) + + env = DummyEnv({'MSVS_VERSION':'7.0'}) + v2 = get_default_version(env) + assert env['MSVS_VERSION'] == '7.0', env['MSVS_VERSION'] + assert env['MSVS']['VERSION'] == '7.0', env['MSVS']['VERSION'] + assert v2 == '7.0', v2 + + env = DummyEnv() + v3 = get_default_version(env) + if v3 == '7.1': + override = '7.0' + else: + override = '7.1' + env['MSVS_VERSION'] = override + v3 = get_default_version(env) + assert env['MSVS_VERSION'] == override, env['MSVS_VERSION'] + assert env['MSVS']['VERSION'] == override, env['MSVS']['VERSION'] + assert v3 == override, v3 + + def _TODO_test_merge_default_version(self): + """Test the merge_default_version() function""" + pass + + def test_query_versions(self): + """Test retrieval of the list of visual studio versions""" + v1 = query_versions() + assert not v1 or str(v1[0]) == self.highest_version, \ + (v1, self.highest_version) + assert len(v1) == self.number_of_versions, v1 + +class msvs6aTestCase(msvsTestCase): + """Test MSVS 6 Registry""" + registry = DummyRegistry(regdata_6a + regdata_cv) + default_version = '6.0' + highest_version = '6.0' + number_of_versions = 1 + install_locs = { + '6.0' : {'VSINSTALLDIR': 'C:\\Program Files\\Microsoft Visual Studio\\VC98', 'VCINSTALLDIR': 'C:\\Program Files\\Microsoft Visual Studio\\VC98\\Bin'}, + '7.0' : {}, + '7.1' : {}, + '8.0' : {}, + '8.0Exp' : {}, + } + default_install_loc = install_locs['6.0'] + +class msvs6bTestCase(msvsTestCase): + """Test Other MSVS 6 Registry""" + registry = DummyRegistry(regdata_6b + regdata_cv) + default_version = '6.0' + highest_version = '6.0' + number_of_versions = 1 + install_locs = { + '6.0' : {'VSINSTALLDIR': 'C:\\VS6\\VC98', 'VCINSTALLDIR': 'C:\\VS6\\VC98\\Bin'}, + '7.0' : {}, + '7.1' : {}, + '8.0' : {}, + '8.0Exp' : {}, + } + default_install_loc = install_locs['6.0'] + +class msvs6and7TestCase(msvsTestCase): + """Test MSVS 6 & 7 Registry""" + registry = DummyRegistry(regdata_6b + regdata_7 + regdata_cv) + default_version = '7.0' + highest_version = '7.0' + number_of_versions = 2 + install_locs = { + '6.0' : {'VSINSTALLDIR': 'C:\\VS6\\VC98', + 'VCINSTALLDIR': 'C:\\VS6\\VC98\\Bin'}, + '7.0' : {'VSINSTALLDIR': 'C:\\Program Files\\Microsoft Visual Studio .NET\\Common7', + 'VCINSTALLDIR': 'C:\\Program Files\\Microsoft Visual Studio .NET\\Common7\\Tools'}, + '7.1' : {}, + '8.0' : {}, + '8.0Exp' : {}, + } + default_install_loc = install_locs['7.0'] + +class msvs7TestCase(msvsTestCase): + """Test MSVS 7 Registry""" + registry = DummyRegistry(regdata_7 + regdata_cv) + default_version = '7.0' + highest_version = '7.0' + number_of_versions = 1 + install_locs = { + '6.0' : {}, + '7.0' : {'VSINSTALLDIR': 'C:\\Program Files\\Microsoft Visual Studio .NET\\Common7', + 'VCINSTALLDIR': 'C:\\Program Files\\Microsoft Visual Studio .NET\\Common7\\Tools'}, + '7.1' : {}, + '8.0' : {}, + '8.0Exp' : {}, + } + default_install_loc = install_locs['7.0'] + +class msvs71TestCase(msvsTestCase): + """Test MSVS 7.1 Registry""" + registry = DummyRegistry(regdata_7_1 + regdata_cv) + default_version = '7.1' + highest_version = '7.1' + number_of_versions = 1 + install_locs = { + '6.0' : {}, + '7.0' : {}, + '7.1' : {'VSINSTALLDIR': 'C:\\Program Files\\Microsoft Visual Studio .NET 2003\\Common7', + 'VCINSTALLDIR': 'C:\\Program Files\\Microsoft Visual Studio .NET 2003\\Common7\\Tools'}, + '8.0' : {}, + '8.0Exp' : {}, + } + default_install_loc = install_locs['7.1'] + +class msvs8ExpTestCase(msvsTestCase): # XXX: only one still not working + """Test MSVS 8 Express Registry""" + registry = DummyRegistry(regdata_8exp + regdata_cv) + default_version = '8.0Exp' + highest_version = '8.0Exp' + number_of_versions = 1 + install_locs = { + '6.0' : {}, + '7.0' : {}, + '7.1' : {}, + '8.0' : {}, + '8.0Exp' : {'VSINSTALLDIR': 'C:\\Program Files\\Microsoft Visual Studio 8', + 'VCINSTALLDIR': 'C:\\Program Files\\Microsoft Visual Studio 8\\VC'}, + } + default_install_loc = install_locs['8.0Exp'] + +class msvs80TestCase(msvsTestCase): + """Test MSVS 8 Registry""" + registry = DummyRegistry(regdata_80 + regdata_cv) + default_version = '8.0' + highest_version = '8.0' + number_of_versions = 1 + install_locs = { + '6.0' : {}, + '7.0' : {}, + '7.1' : {}, + '8.0' : {'VSINSTALLDIR': 'C:\\Program Files\\Microsoft Visual Studio 8', + 'VCINSTALLDIR': 'C:\\Program Files\\Microsoft Visual Studio 8\\VC'}, + '8.0Exp' : {}, + } + default_install_loc = install_locs['8.0'] + +class msvsEmptyTestCase(msvsTestCase): + """Test Empty Registry""" + registry = DummyRegistry(regdata_none) + default_version = '9.0' + highest_version = None + number_of_versions = 0 + install_locs = { + '6.0' : {}, + '7.0' : {}, + '7.1' : {}, + '8.0' : {}, + '8.0Exp' : {}, + } + default_install_loc = install_locs['8.0Exp'] + +if __name__ == "__main__": + + # only makes sense to test this on win32 + if sys.platform != 'win32': + sys.stdout.write("NO RESULT for msvsTests.py: '%s' is not win32\n" % sys.platform) + sys.exit(0) + + SCons.Util.RegOpenKeyEx = DummyOpenKeyEx + SCons.Util.RegEnumKey = DummyEnumKey + SCons.Util.RegEnumValue = DummyEnumValue + SCons.Util.RegQueryValueEx = DummyQueryValue + + os.path.exists = DummyExists # make sure all files exist :-) + os.path.isfile = DummyExists # make sure all files are files :-) + os.path.isdir = DummyExists # make sure all dirs are dirs :-) + + exit_val = 0 + + test_classes = [ + msvs6aTestCase, + msvs6bTestCase, + msvs6and7TestCase, + msvs7TestCase, + msvs71TestCase, + msvs8ExpTestCase, + msvs80TestCase, + msvsEmptyTestCase, + ] + + for test_class in test_classes: + print "TEST: ", test_class.__doc__ + back_osenv = copy.deepcopy(os.environ) + try: + # XXX: overriding the os.environ is bad, but doing it + # correctly is too complicated for now. Those tests should + # be fixed + for k in ['VS71COMNTOOLS', + 'VS80COMNTOOLS', + 'VS90COMNTOOLS']: + if os.environ.has_key(k): + del os.environ[k] + + suite = unittest.makeSuite(test_class, 'test_') + if not unittest.TextTestRunner().run(suite).wasSuccessful(): + exit_val = 1 + finally: + os.env = back_osenv + + sys.exit(exit_val) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/mwcc.py b/src/engine/SCons/Tool/mwcc.py new file mode 100644 index 0000000..885f009 --- /dev/null +++ b/src/engine/SCons/Tool/mwcc.py @@ -0,0 +1,208 @@ +"""SCons.Tool.mwcc + +Tool-specific initialization for the Metrowerks CodeWarrior compiler. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/mwcc.py 4577 2009/12/27 19:44:43 scons" + +import os +import os.path +import string + +import SCons.Util + +def set_vars(env): + """Set MWCW_VERSION, MWCW_VERSIONS, and some codewarrior environment vars + + MWCW_VERSIONS is set to a list of objects representing installed versions + + MWCW_VERSION is set to the version object that will be used for building. + MWCW_VERSION can be set to a string during Environment + construction to influence which version is chosen, otherwise + the latest one from MWCW_VERSIONS is used. + + Returns true if at least one version is found, false otherwise + """ + desired = env.get('MWCW_VERSION', '') + + # return right away if the variables are already set + if isinstance(desired, MWVersion): + return 1 + elif desired is None: + return 0 + + versions = find_versions() + version = None + + if desired: + for v in versions: + if str(v) == desired: + version = v + elif versions: + version = versions[-1] + + env['MWCW_VERSIONS'] = versions + env['MWCW_VERSION'] = version + + if version is None: + return 0 + + env.PrependENVPath('PATH', version.clpath) + env.PrependENVPath('PATH', version.dllpath) + ENV = env['ENV'] + ENV['CWFolder'] = version.path + ENV['LM_LICENSE_FILE'] = version.license + plus = lambda x: '+%s' % x + ENV['MWCIncludes'] = string.join(map(plus, version.includes), os.pathsep) + ENV['MWLibraries'] = string.join(map(plus, version.libs), os.pathsep) + return 1 + + +def find_versions(): + """Return a list of MWVersion objects representing installed versions""" + versions = [] + + ### This function finds CodeWarrior by reading from the registry on + ### Windows. Some other method needs to be implemented for other + ### platforms, maybe something that calls env.WhereIs('mwcc') + + if SCons.Util.can_read_reg: + try: + HLM = SCons.Util.HKEY_LOCAL_MACHINE + product = 'SOFTWARE\\Metrowerks\\CodeWarrior\\Product Versions' + product_key = SCons.Util.RegOpenKeyEx(HLM, product) + + i = 0 + while 1: + name = product + '\\' + SCons.Util.RegEnumKey(product_key, i) + name_key = SCons.Util.RegOpenKeyEx(HLM, name) + + try: + version = SCons.Util.RegQueryValueEx(name_key, 'VERSION') + path = SCons.Util.RegQueryValueEx(name_key, 'PATH') + mwv = MWVersion(version[0], path[0], 'Win32-X86') + versions.append(mwv) + except SCons.Util.RegError: + pass + + i = i + 1 + + except SCons.Util.RegError: + pass + + return versions + + +class MWVersion: + def __init__(self, version, path, platform): + self.version = version + self.path = path + self.platform = platform + self.clpath = os.path.join(path, 'Other Metrowerks Tools', + 'Command Line Tools') + self.dllpath = os.path.join(path, 'Bin') + + # The Metrowerks tools don't store any configuration data so they + # are totally dumb when it comes to locating standard headers, + # libraries, and other files, expecting all the information + # to be handed to them in environment variables. The members set + # below control what information scons injects into the environment + + ### The paths below give a normal build environment in CodeWarrior for + ### Windows, other versions of CodeWarrior might need different paths. + + msl = os.path.join(path, 'MSL') + support = os.path.join(path, '%s Support' % platform) + + self.license = os.path.join(path, 'license.dat') + self.includes = [msl, support] + self.libs = [msl, support] + + def __str__(self): + return self.version + + +CSuffixes = ['.c', '.C'] +CXXSuffixes = ['.cc', '.cpp', '.cxx', '.c++', '.C++'] + + +def generate(env): + """Add Builders and construction variables for the mwcc to an Environment.""" + import SCons.Defaults + import SCons.Tool + + set_vars(env) + + static_obj, shared_obj = SCons.Tool.createObjBuilders(env) + + for suffix in CSuffixes: + static_obj.add_action(suffix, SCons.Defaults.CAction) + shared_obj.add_action(suffix, SCons.Defaults.ShCAction) + + for suffix in CXXSuffixes: + static_obj.add_action(suffix, SCons.Defaults.CXXAction) + shared_obj.add_action(suffix, SCons.Defaults.ShCXXAction) + + env['CCCOMFLAGS'] = '$CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -nolink -o $TARGET $SOURCES' + + env['CC'] = 'mwcc' + env['CCCOM'] = '$CC $CFLAGS $CCFLAGS $CCCOMFLAGS' + + env['CXX'] = 'mwcc' + env['CXXCOM'] = '$CXX $CXXFLAGS $CCCOMFLAGS' + + env['SHCC'] = '$CC' + env['SHCCFLAGS'] = '$CCFLAGS' + env['SHCFLAGS'] = '$CFLAGS' + env['SHCCCOM'] = '$SHCC $SHCFLAGS $SHCCFLAGS $CCCOMFLAGS' + + env['SHCXX'] = '$CXX' + env['SHCXXFLAGS'] = '$CXXFLAGS' + env['SHCXXCOM'] = '$SHCXX $SHCXXFLAGS $CCCOMFLAGS' + + env['CFILESUFFIX'] = '.c' + env['CXXFILESUFFIX'] = '.cpp' + env['CPPDEFPREFIX'] = '-D' + env['CPPDEFSUFFIX'] = '' + env['INCPREFIX'] = '-I' + env['INCSUFFIX'] = '' + + #env['PCH'] = ? + #env['PCHSTOP'] = ? + + +def exists(env): + return set_vars(env) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/mwcc.xml b/src/engine/SCons/Tool/mwcc.xml new file mode 100644 index 0000000..e7df1f3 --- /dev/null +++ b/src/engine/SCons/Tool/mwcc.xml @@ -0,0 +1,53 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="mwcc"> +<summary> +Sets construction variables for the Metrowerks CodeWarrior compiler. +</summary> +<sets> +MWCW_VERSIONS +MWCW_VERSION +<!--CCCOMFLAGS--> +CC +CCCOM +CXX +CXXCOM +SHCC +SHCCFLAGS +SHCFLAGS +SHCCCOM +SHCXX +SHCXXFLAGS +SHCXXCOM +CFILESUFFIX +CXXFILESUFFIX +CPPDEFPREFIX +CPPDEFSUFFIX +INCPREFIX +INCSUFFIX +</sets> +<uses> +CCCOMSTR +CXXCOMSTR +SHCCCOMSTR +SHCXXCOMSTR +</uses> +</tool> + +<cvar name="MWCW_VERSION"> +<summary> +The version number of the MetroWerks CodeWarrior C compiler +to be used. +</summary> +</cvar> + +<cvar name="MWCW_VERSIONS"> +<summary> +A list of installed versions of the MetroWerks CodeWarrior C compiler +on this system. +</summary> +</cvar> diff --git a/src/engine/SCons/Tool/mwld.py b/src/engine/SCons/Tool/mwld.py new file mode 100644 index 0000000..e0e1484 --- /dev/null +++ b/src/engine/SCons/Tool/mwld.py @@ -0,0 +1,107 @@ +"""SCons.Tool.mwld + +Tool-specific initialization for the Metrowerks CodeWarrior linker. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/mwld.py 4577 2009/12/27 19:44:43 scons" + +import SCons.Tool + + +def generate(env): + """Add Builders and construction variables for lib to an Environment.""" + SCons.Tool.createStaticLibBuilder(env) + SCons.Tool.createSharedLibBuilder(env) + SCons.Tool.createProgBuilder(env) + + env['AR'] = 'mwld' + env['ARCOM'] = '$AR $ARFLAGS -library -o $TARGET $SOURCES' + + env['LIBDIRPREFIX'] = '-L' + env['LIBDIRSUFFIX'] = '' + env['LIBLINKPREFIX'] = '-l' + env['LIBLINKSUFFIX'] = '.lib' + + env['LINK'] = 'mwld' + env['LINKCOM'] = '$LINK $LINKFLAGS -o $TARGET $SOURCES $_LIBDIRFLAGS $_LIBFLAGS' + + env['SHLINK'] = '$LINK' + env['SHLINKFLAGS'] = '$LINKFLAGS' + env['SHLINKCOM'] = shlib_action + env['SHLIBEMITTER']= shlib_emitter + + +def exists(env): + import SCons.Tool.mwcc + return SCons.Tool.mwcc.set_vars(env) + + +def shlib_generator(target, source, env, for_signature): + cmd = ['$SHLINK', '$SHLINKFLAGS', '-shared'] + + no_import_lib = env.get('no_import_lib', 0) + if no_import_lib: cmd.extend('-noimplib') + + dll = env.FindIxes(target, 'SHLIBPREFIX', 'SHLIBSUFFIX') + if dll: cmd.extend(['-o', dll]) + + implib = env.FindIxes(target, 'LIBPREFIX', 'LIBSUFFIX') + if implib: cmd.extend(['-implib', implib.get_string(for_signature)]) + + cmd.extend(['$SOURCES', '$_LIBDIRFLAGS', '$_LIBFLAGS']) + + return [cmd] + + +def shlib_emitter(target, source, env): + dll = env.FindIxes(target, 'SHLIBPREFIX', 'SHLIBSUFFIX') + no_import_lib = env.get('no_import_lib', 0) + + if not dll: + raise SCons.Errors.UserError, "A shared library should have exactly one target with the suffix: %s" % env.subst("$SHLIBSUFFIX") + + if not no_import_lib and \ + not env.FindIxes(target, 'LIBPREFIX', 'LIBSUFFIX'): + + # Append an import library to the list of targets. + target.append(env.ReplaceIxes(dll, + 'SHLIBPREFIX', 'SHLIBSUFFIX', + 'LIBPREFIX', 'LIBSUFFIX')) + + return target, source + + +shlib_action = SCons.Action.Action(shlib_generator, generator=1) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/mwld.xml b/src/engine/SCons/Tool/mwld.xml new file mode 100644 index 0000000..368d658 --- /dev/null +++ b/src/engine/SCons/Tool/mwld.xml @@ -0,0 +1,27 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="mwld"> +<summary> +Sets construction variables for the Metrowerks CodeWarrior linker. +</summary> +<sets> +AR +ARCOM +LIBDIRPREFIX +LIBDIRSUFFIX +LIBLINKPREFIX +LIBLINKSUFFIX +LINK +LINKCOM +SHLINK +SHLINKFLAGS +SHLINKCOM +<!--SHLIBEMITTER--> +</sets> +<uses> +</uses> +</tool> diff --git a/src/engine/SCons/Tool/nasm.py b/src/engine/SCons/Tool/nasm.py new file mode 100644 index 0000000..16ef193 --- /dev/null +++ b/src/engine/SCons/Tool/nasm.py @@ -0,0 +1,72 @@ +"""SCons.Tool.nasm + +Tool-specific initialization for nasm, the famous Netwide Assembler. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/nasm.py 4577 2009/12/27 19:44:43 scons" + +import SCons.Defaults +import SCons.Tool +import SCons.Util + +ASSuffixes = ['.s', '.asm', '.ASM'] +ASPPSuffixes = ['.spp', '.SPP', '.sx'] +if SCons.Util.case_sensitive_suffixes('.s', '.S'): + ASPPSuffixes.extend(['.S']) +else: + ASSuffixes.extend(['.S']) + +def generate(env): + """Add Builders and construction variables for nasm to an Environment.""" + static_obj, shared_obj = SCons.Tool.createObjBuilders(env) + + for suffix in ASSuffixes: + static_obj.add_action(suffix, SCons.Defaults.ASAction) + static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter) + + for suffix in ASPPSuffixes: + static_obj.add_action(suffix, SCons.Defaults.ASPPAction) + static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter) + + env['AS'] = 'nasm' + env['ASFLAGS'] = SCons.Util.CLVar('') + env['ASPPFLAGS'] = '$ASFLAGS' + env['ASCOM'] = '$AS $ASFLAGS -o $TARGET $SOURCES' + env['ASPPCOM'] = '$CC $ASPPFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES' + +def exists(env): + return env.Detect('nasm') + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/nasm.xml b/src/engine/SCons/Tool/nasm.xml new file mode 100644 index 0000000..725c186 --- /dev/null +++ b/src/engine/SCons/Tool/nasm.xml @@ -0,0 +1,23 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="nasm"> +<summary> +Sets construction variables for the +<application>nasm</application> Netwide Assembler. +</summary> +<sets> +AS +ASFLAGS +ASPPFLAGS +ASCOM +ASPPCOM +</sets> +<uses> +ASCOMSTR +ASPPCOMSTR +</uses> +</tool> diff --git a/src/engine/SCons/Tool/packaging.xml b/src/engine/SCons/Tool/packaging.xml new file mode 100644 index 0000000..0e36128 --- /dev/null +++ b/src/engine/SCons/Tool/packaging.xml @@ -0,0 +1,73 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="packaging"> +<summary> +A framework for building binary and source packages. +</summary> +</tool> + +<builder name="Package"> +<summary> +Builds a Binary Package of the given source files. + +<example> +env.Package(source = FindInstalledFiles()) +</example> +</summary> +</builder> + +<cvar name="JAR"> +<summary> +The Java archive tool. +</summary> +</cvar> + +<cvar name="JARCHDIR"> +<summary> +The directory to which the Java archive tool should change +(using the +<option>-C</option> +option). +</summary> +</cvar> + +<cvar name="JARCOM"> +<summary> +The command line used to call the Java archive tool. +</summary> +</cvar> + +<cvar name="JARCOMSTR"> +<summary> +The string displayed when the Java archive tool +is called +If this is not set, then &cv-JARCOM; (the command line) is displayed. + +<example> +env = Environment(JARCOMSTR = "JARchiving $SOURCES into $TARGET") +</example> +</summary> +</cvar> + +<cvar name="JARFLAGS"> +<summary> +General options passed to the Java archive tool. +By default this is set to +<option>cf</option> +to create the necessary +<command>jar</command> +file. +</summary> +</cvar> + +<cvar name="JARSUFFIX"> +<summary> +The suffix for Java archives: +<filename>.jar</filename> +by default. +</summary> +</cvar> diff --git a/src/engine/SCons/Tool/packaging/__init__.py b/src/engine/SCons/Tool/packaging/__init__.py new file mode 100644 index 0000000..90947e4 --- /dev/null +++ b/src/engine/SCons/Tool/packaging/__init__.py @@ -0,0 +1,314 @@ +"""SCons.Tool.Packaging + +SCons Packaging Tool. +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/packaging/__init__.py 4577 2009/12/27 19:44:43 scons" + +import SCons.Environment +from SCons.Variables import * +from SCons.Errors import * +from SCons.Util import is_List, make_path_relative +from SCons.Warnings import warn, Warning + +import os, imp +import SCons.Defaults + +__all__ = [ 'src_targz', 'src_tarbz2', 'src_zip', 'tarbz2', 'targz', 'zip', 'rpm', 'msi', 'ipk' ] + +# +# Utility and Builder function +# +def Tag(env, target, source, *more_tags, **kw_tags): + """ Tag a file with the given arguments, just sets the accordingly named + attribute on the file object. + + TODO: FIXME + """ + if not target: + target=source + first_tag=None + else: + first_tag=source + + if first_tag: + kw_tags[first_tag[0]] = '' + + if len(kw_tags) == 0 and len(more_tags) == 0: + raise UserError, "No tags given." + + # XXX: sanity checks + for x in more_tags: + kw_tags[x] = '' + + if not SCons.Util.is_List(target): + target=[target] + else: + # hmm, sometimes the target list, is a list of a list + # make sure it is flattened prior to processing. + # TODO: perhaps some bug ?!? + target=env.Flatten(target) + + for t in target: + for (k,v) in kw_tags.items(): + # all file tags have to start with PACKAGING_, so we can later + # differentiate between "normal" object attributes and the + # packaging attributes. As the user should not be bothered with + # that, the prefix will be added here if missing. + #if not k.startswith('PACKAGING_'): + if k[:10] != 'PACKAGING_': + k='PACKAGING_'+k + setattr(t, k, v) + +def Package(env, target=None, source=None, **kw): + """ Entry point for the package tool. + """ + # check if we need to find the source files ourself + if not source: + source = env.FindInstalledFiles() + + if len(source)==0: + raise UserError, "No source for Package() given" + + # decide which types of packages shall be built. Can be defined through + # four mechanisms: command line argument, keyword argument, + # environment argument and default selection( zip or tar.gz ) in that + # order. + try: kw['PACKAGETYPE']=env['PACKAGETYPE'] + except KeyError: pass + + if not kw.get('PACKAGETYPE'): + from SCons.Script import GetOption + kw['PACKAGETYPE'] = GetOption('package_type') + + if kw['PACKAGETYPE'] == None: + if env['BUILDERS'].has_key('Tar'): + kw['PACKAGETYPE']='targz' + elif env['BUILDERS'].has_key('Zip'): + kw['PACKAGETYPE']='zip' + else: + raise UserError, "No type for Package() given" + + PACKAGETYPE=kw['PACKAGETYPE'] + if not is_List(PACKAGETYPE): + PACKAGETYPE=string.split(PACKAGETYPE, ',') + + # load the needed packagers. + def load_packager(type): + try: + file,path,desc=imp.find_module(type, __path__) + return imp.load_module(type, file, path, desc) + except ImportError, e: + raise EnvironmentError("packager %s not available: %s"%(type,str(e))) + + packagers=map(load_packager, PACKAGETYPE) + + # set up targets and the PACKAGEROOT + try: + # fill up the target list with a default target name until the PACKAGETYPE + # list is of the same size as the target list. + if not target: target = [] + + size_diff = len(PACKAGETYPE)-len(target) + default_name = "%(NAME)s-%(VERSION)s" + + if size_diff>0: + default_target = default_name%kw + target.extend( [default_target]*size_diff ) + + if not kw.has_key('PACKAGEROOT'): + kw['PACKAGEROOT'] = default_name%kw + + except KeyError, e: + raise SCons.Errors.UserError( "Missing Packagetag '%s'"%e.args[0] ) + + # setup the source files + source=env.arg2nodes(source, env.fs.Entry) + + # call the packager to setup the dependencies. + targets=[] + try: + for packager in packagers: + t=[target.pop(0)] + t=apply(packager.package, [env,t,source], kw) + targets.extend(t) + + assert( len(target) == 0 ) + + except KeyError, e: + raise SCons.Errors.UserError( "Missing Packagetag '%s' for %s packager"\ + % (e.args[0],packager.__name__) ) + except TypeError, e: + # this exception means that a needed argument for the packager is + # missing. As our packagers get their "tags" as named function + # arguments we need to find out which one is missing. + from inspect import getargspec + args,varargs,varkw,defaults=getargspec(packager.package) + if defaults!=None: + args=args[:-len(defaults)] # throw away arguments with default values + args.remove('env') + args.remove('target') + args.remove('source') + # now remove any args for which we have a value in kw. + #args=[x for x in args if not kw.has_key(x)] + args=filter(lambda x, kw=kw: not kw.has_key(x), args) + + if len(args)==0: + raise # must be a different error, so reraise + elif len(args)==1: + raise SCons.Errors.UserError( "Missing Packagetag '%s' for %s packager"\ + % (args[0],packager.__name__) ) + else: + raise SCons.Errors.UserError( "Missing Packagetags '%s' for %s packager"\ + % (", ".join(args),packager.__name__) ) + + target=env.arg2nodes(target, env.fs.Entry) + targets.extend(env.Alias( 'package', targets )) + return targets + +# +# SCons tool initialization functions +# + +added = None + +def generate(env): + from SCons.Script import AddOption + global added + if not added: + added = 1 + AddOption('--package-type', + dest='package_type', + default=None, + type="string", + action="store", + help='The type of package to create.') + + try: + env['BUILDERS']['Package'] + env['BUILDERS']['Tag'] + except KeyError: + env['BUILDERS']['Package'] = Package + env['BUILDERS']['Tag'] = Tag + +def exists(env): + return 1 + +# XXX +def options(opts): + opts.AddVariables( + EnumVariable( 'PACKAGETYPE', + 'the type of package to create.', + None, allowed_values=map( str, __all__ ), + ignorecase=2 + ) + ) + +# +# Internal utility functions +# + +def copy_attr(f1, f2): + """ copies the special packaging file attributes from f1 to f2. + """ + #pattrs = [x for x in dir(f1) if not hasattr(f2, x) and\ + # x.startswith('PACKAGING_')] + copyit = lambda x, f2=f2: not hasattr(f2, x) and x[:10] == 'PACKAGING_' + pattrs = filter(copyit, dir(f1)) + for attr in pattrs: + setattr(f2, attr, getattr(f1, attr)) +def putintopackageroot(target, source, env, pkgroot, honor_install_location=1): + """ Uses the CopyAs builder to copy all source files to the directory given + in pkgroot. + + If honor_install_location is set and the copied source file has an + PACKAGING_INSTALL_LOCATION attribute, the PACKAGING_INSTALL_LOCATION is + used as the new name of the source file under pkgroot. + + The source file will not be copied if it is already under the the pkgroot + directory. + + All attributes of the source file will be copied to the new file. + """ + # make sure the packageroot is a Dir object. + if SCons.Util.is_String(pkgroot): pkgroot=env.Dir(pkgroot) + if not SCons.Util.is_List(source): source=[source] + + new_source = [] + for file in source: + if SCons.Util.is_String(file): file = env.File(file) + + if file.is_under(pkgroot): + new_source.append(file) + else: + if hasattr(file, 'PACKAGING_INSTALL_LOCATION') and\ + honor_install_location: + new_name=make_path_relative(file.PACKAGING_INSTALL_LOCATION) + else: + new_name=make_path_relative(file.get_path()) + + new_file=pkgroot.File(new_name) + new_file=env.CopyAs(new_file, file)[0] + copy_attr(file, new_file) + new_source.append(new_file) + + return (target, new_source) + +def stripinstallbuilder(target, source, env): + """ strips the install builder action from the source list and stores + the final installation location as the "PACKAGING_INSTALL_LOCATION" of + the source of the source file. This effectively removes the final installed + files from the source list while remembering the installation location. + + It also warns about files which have no install builder attached. + """ + def has_no_install_location(file): + return not (file.has_builder() and\ + hasattr(file.builder, 'name') and\ + (file.builder.name=="InstallBuilder" or\ + file.builder.name=="InstallAsBuilder")) + + if len(filter(has_no_install_location, source)): + warn(Warning, "there are files to package which have no\ + InstallBuilder attached, this might lead to irreproducible packages") + + n_source=[] + for s in source: + if has_no_install_location(s): + n_source.append(s) + else: + for ss in s.sources: + n_source.append(ss) + copy_attr(s, ss) + setattr(ss, 'PACKAGING_INSTALL_LOCATION', s.get_path()) + + return (target, n_source) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/packaging/__init__.xml b/src/engine/SCons/Tool/packaging/__init__.xml new file mode 100644 index 0000000..521c9f6 --- /dev/null +++ b/src/engine/SCons/Tool/packaging/__init__.xml @@ -0,0 +1,659 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="Packaging"> +<summary> +Sets construction variables for the &b-Package; Builder. +</summary> +<sets> +</sets> +<uses> +</uses> +</tool> + +<builder name="Package"> +<summary> +Builds software distribution packages. +Packages consist of files to install and packaging information. +The former may be specified with the &source; parameter and may be left out, +in which case the &FindInstalledFiles; function will collect +all files that have an &b-Install; or &b-InstallAs; Builder attached. +If the ⌖ is not specified +it will be deduced from additional information given to this Builder. + +The packaging information is specified +with the help of construction variables documented below. +This information is called a tag to stress that +some of them can also be attached to files with the &Tag; function. +The mandatory ones will complain if they were not specified. +They vary depending on chosen target packager. + +The target packager may be selected with the "PACKAGETYPE" command line +option or with the &cv-PACKAGETYPE; construction variable. Currently +the following packagers available: + + * msi - Microsoft Installer + * rpm - Redhat Package Manger + * ipkg - Itsy Package Management System + * tarbz2 - compressed tar + * targz - compressed tar + * zip - zip file + * src_tarbz2 - compressed tar source + * src_targz - compressed tar source + * src_zip - zip file source + +An updated list is always available under the "package_type" option when +running "scons --help" on a project that has packaging activated. +<example> +env = Environment(tools=['default', 'packaging']) +env.Install('/bin/', 'my_program') +env.Package( NAME = 'foo', + VERSION = '1.2.3', + PACKAGEVERSION = 0, + PACKAGETYPE = 'rpm', + LICENSE = 'gpl', + SUMMARY = 'balalalalal', + DESCRIPTION = 'this should be really really long', + X_RPM_GROUP = 'Application/fu', + SOURCE_URL = 'http://foo.org/foo-1.2.3.tar.gz' + ) +</example> +</summary> +</builder> + +<cvar name="ARCHITECTURE"> +<summary> +Specifies the system architecture for which +the package is being built. +The default is the system architecture +of the machine on which SCons is running. +This is used to fill in the +<literal>Architecture:</literal> +field in an Ipkg +<filename>control</filename> file, +and as part of the name of a generated RPM file. +</summary> +</cvar> + +<cvar name="CHANGE_SPECFILE"> +<summary> +A hook for modifying the file that controls the packaging build +(the <filename>.spec</filename> for RPM, +the <filename>control</filename> for Ipkg, +the <filename>.wxs</filename> for MSI). +If set, the function will be called +after the SCons template for the file has been written. +XXX +</summary> +</cvar> + +<cvar name="CHANGELOG"> +<summary> +The name of a file containing the change log text +to be included in the package. +This is included as the +<literal>%changelog</literal> +section of the RPM +<filename>.spec</filename> file. +</summary> +</cvar> + +<cvar name="DESCRIPTION"> +<summary> +A long description of the project being packaged. +This is included in the relevant section +of the file that controls the packaging build. +</summary> +</cvar> + +<cvar name="DESCRIPTION_lang"> +<summary> +A language-specific long description for +the specified <varname>lang</varname>. +This is used to populate a +<literal>%description -l</literal> +section of an RPM +<filename>.spec</filename> file. +</summary> +</cvar> + +<cvar name="LICENSE"> +<summary> +The abbreviated name of the license under which +this project is released (gpl, lpgl, bsd etc.). +See http://www.opensource.org/licenses/alphabetical +for a list of license names. +</summary> +</cvar> + +<cvar name="NAME"> +<summary> +Specfies the name of the project to package. +</summary> +</cvar> + +<cvar name="PACKAGEROOT"> +<summary> +Specifies the directory where all files in resulting archive will be +placed if applicable. The default value is "$NAME-$VERSION". +</summary> +</cvar> + +<cvar name="PACKAGETYPE"> +<summary> +Selects the package type to build. Currently these are available: + + * msi - Microsoft Installer + * rpm - Redhat Package Manger + * ipkg - Itsy Package Management System + * tarbz2 - compressed tar + * targz - compressed tar + * zip - zip file + * src_tarbz2 - compressed tar source + * src_targz - compressed tar source + * src_zip - zip file source + +This may be overridden with the "package_type" command line option. +</summary> +</cvar> + +<cvar name="PACKAGEVERSION"> +<summary> +The version of the package (not the underlying project). +This is currently only used by the rpm packager +and should reflect changes in the packaging, +not the underlying project code itself. +</summary> +</cvar> + +<cvar name="SOURCE_URL"> +<summary> +The URL +(web address) +of the location from which the project was retrieved. +This is used to fill in the +<literal>Source:</literal> +field in the controlling information for Ipkg and RPM packages. +</summary> +</cvar> + +<cvar name="SUMMARY"> +<summary> +A short summary of what the project is about. +This is used to fill in the +<literal>Summary:</literal> +field in the controlling information for Ipkg and RPM packages, +and as the +<literal>Description:</literal> +field in MSI packages. +</summary> +</cvar> + +<cvar name="VENDOR"> +<summary> +The person or organization who supply the packaged software. +This is used to fill in the +<literal>Vendor:</literal> +field in the controlling information for RPM packages, +and the +<literal>Manufacturer:</literal> +field in the controlling information for MSI packages. +</summary> +</cvar> + +<cvar name="VERSION"> +<summary> +The version of the project, specified as a string. +</summary> +</cvar> + + +<cvar name="X_IPK_DEPENDS"> +<summary> +This is used to fill in the +<literal>Depends:</literal> +field in the controlling information for Ipkg packages. +</summary> +</cvar> + +<cvar name="X_IPK_DESCRIPTION"> +<summary> +This is used to fill in the +<literal>Description:</literal> +field in the controlling information for Ipkg packages. +The default value is +<literal>$SUMMARY\n$DESCRIPTION</literal> +</summary> +</cvar> + +<cvar name="X_IPK_MAINTAINER"> +<summary> +This is used to fill in the +<literal>Maintainer:</literal> +field in the controlling information for Ipkg packages. +</summary> +</cvar> + +<cvar name="X_IPK_PRIORITY"> +<summary> +This is used to fill in the +<literal>Priority:</literal> +field in the controlling information for Ipkg packages. +</summary> +</cvar> + +<cvar name="X_IPK_SECTION"> +<summary> +This is used to fill in the +<literal>Section:</literal> +field in the controlling information for Ipkg packages. +</summary> +</cvar> + + + +<cvar name="X_MSI_LANGUAGE"> +<summary> +This is used to fill in the +<literal>Language:</literal> +attribute in the controlling information for MSI packages. +</summary> +</cvar> + +<cvar name="X_MSI_LICENSE_TEXT"> +<summary> +The text of the software license in RTF format. +Carriage return characters will be +replaced with the RTF equivalent \\par. +</summary> +</cvar> + +<cvar name="X_MSI_UPGRADE_CODE"> +<summary> +TODO +</summary> +</cvar> + + +<cvar name="X_RPM_AUTOREQPROV"> +<summary> +This is used to fill in the +<literal>AutoReqProv:</literal> +field in the RPM +<filename>.spec</filename> file. +</summary> +</cvar> + +<cvar name="X_RPM_BUILD"> +<summary> +internal, but overridable +</summary> +</cvar> + +<cvar name="X_RPM_BUILDREQUIRES"> +<summary> +This is used to fill in the +<literal>BuildRequires:</literal> +field in the RPM +<filename>.spec</filename> file. +</summary> +</cvar> + +<cvar name="X_RPM_BUILDROOT"> +<summary> +internal, but overridable +</summary> +</cvar> + +<cvar name="X_RPM_CLEAN"> +<summary> +internal, but overridable +</summary> +</cvar> + +<cvar name="X_RPM_CONFLICTS"> +<summary> +This is used to fill in the +<literal>Conflicts:</literal> +field in the RPM +<filename>.spec</filename> file. +</summary> +</cvar> + +<cvar name="X_RPM_DEFATTR"> +<summary> +This value is used as the default attributes +for the files in the RPM package. +The default value is +<literal>(-,root,root)</literal>. +</summary> +</cvar> + +<cvar name="X_RPM_DISTRIBUTION"> +<summary> +This is used to fill in the +<literal>Distribution:</literal> +field in the RPM +<filename>.spec</filename> file. +</summary> +</cvar> + +<cvar name="X_RPM_EPOCH"> +<summary> +This is used to fill in the +<literal>Epoch:</literal> +field in the controlling information for RPM packages. +</summary> +</cvar> + +<cvar name="X_RPM_EXCLUDEARCH"> +<summary> +This is used to fill in the +<literal>ExcludeArch:</literal> +field in the RPM +<filename>.spec</filename> file. +</summary> +</cvar> + +<cvar name="X_RPM_EXLUSIVEARCH"> +<summary> +This is used to fill in the +<literal>ExclusiveArch:</literal> +field in the RPM +<filename>.spec</filename> file. +</summary> +</cvar> + +<cvar name="X_RPM_GROUP"> +<summary> +This is used to fill in the +<literal>Group:</literal> +field in the RPM +<filename>.spec</filename> file. +</summary> +</cvar> + +<cvar name="X_RPM_GROUP_lang"> +<summary> +This is used to fill in the +<literal>Group(lang):</literal> +field in the RPM +<filename>.spec</filename> file. +Note that +<varname>lang</varname> +is not literal +and should be replaced by +the appropriate language code. +</summary> +</cvar> + +<cvar name="X_RPM_ICON"> +<summary> +This is used to fill in the +<literal>Icon:</literal> +field in the RPM +<filename>.spec</filename> file. +</summary> +</cvar> + +<cvar name="X_RPM_INSTALL"> +<summary> +internal, but overridable +</summary> +</cvar> + +<cvar name="X_RPM_PACKAGER"> +<summary> +This is used to fill in the +<literal>Packager:</literal> +field in the RPM +<filename>.spec</filename> file. +</summary> +</cvar> + +<cvar name="X_RPM_PROVIDES"> +<summary> +This is used to fill in the +<literal>Provides:</literal> +field in the RPM +<filename>.spec</filename> file. +</summary> +</cvar> + +<cvar name="X_RPM_POSTINSTALL"> +<summary> +This is used to fill in the +<literal>%post:</literal> +section in the RPM +<filename>.spec</filename> file. +</summary> +</cvar> + +<cvar name="X_RPM_PREINSTALL"> +<summary> +This is used to fill in the +<literal>%pre:</literal> +section in the RPM +<filename>.spec</filename> file. +</summary> +</cvar> + +<cvar name="X_RPM_PREFIX"> +<summary> +This is used to fill in the +<literal>Prefix:</literal> +field in the RPM +<filename>.spec</filename> file. +</summary> +</cvar> + +<cvar name="X_RPM_PREP"> +<summary> +internal, but overridable +</summary> +</cvar> + +<cvar name="X_RPM_POSTUNINSTALL"> +<summary> +This is used to fill in the +<literal>%postun:</literal> +section in the RPM +<filename>.spec</filename> file. +</summary> +</cvar> + +<cvar name="X_RPM_PREUNINSTALL"> +<summary> +This is used to fill in the +<literal>%preun:</literal> +section in the RPM +<filename>.spec</filename> file. +</summary> +</cvar> + +<cvar name="X_RPM_REQUIRES"> +<summary> +This is used to fill in the +<literal>Requires:</literal> +field in the RPM +<filename>.spec</filename> file. +</summary> +</cvar> + +<cvar name="X_RPM_SERIAL"> +<summary> +This is used to fill in the +<literal>Serial:</literal> +field in the RPM +<filename>.spec</filename> file. +</summary> +</cvar> + +<cvar name="X_RPM_URL"> +<summary> +This is used to fill in the +<literal>Url:</literal> +field in the RPM +<filename>.spec</filename> file. +</summary> +</cvar> + + + +<!-- + +THE FOLLOWING AREN'T CONSTRUCTION VARIABLES, +THEY'RE "TAGS" THAT CAN BE ATTACHED +TO DIFFERENT FILES OR DIRECTORIES. +NOT SURE YET WHAT TO DO ABOUT THESE. + +<cvar name="CONFIG"> +<summary> +TODO +</summary> +</cvar> + +<cvar name="CONFIG_NOREPLACE"> +<summary> +TODO +</summary> +</cvar> + +<cvar name="DOC"> +<summary> +TODO +</summary> +</cvar> + +<cvar name="INSTALL_LOCATION"> +<summary> +internal, but overridable, TODO +</summary> +</cvar> + +<cvar name="LANG_lang"> +<summary> +TODO +</summary> +</cvar> + +<cvar name="UNIX_ATTR"> +<summary> +TODO +</summary> +</cvar> + +<cvar name="X_IPK_POSTINST"> +<summary> +TODO +</summary> +</cvar> + +<cvar name="X_IPK_POSTRM"> +<summary> +TODO +</summary> +</cvar> + +<cvar name="X_IPK_PREINST"> +<summary> +TODO +</summary> +</cvar> + +<cvar name="X_IPK_PRERM"> +<summary> +TODO +</summary> +</cvar> + +<cvar name="X_MSI_FEATURE"> +<summary> +TODO +</summary> +</cvar> + +<cvar name="X_MSI_FILEID"> +<summary> +TODO +</summary> +</cvar> + +<cvar name="X_MSI_LONGNAME"> +<summary> +TODO +</summary> +</cvar> + +<cvar name="X_MSI_SHORTNAME"> +<summary> +TODO +</summary> +</cvar> + +<cvar name="X_MSI_VITAL"> +<summary> +TODO +</summary> +</cvar> + +<cvar name="X_RPM_DIR"> +<summary> +TODO +</summary> +</cvar> + +<cvar name="X_RPM_DOCDIR"> +<summary> +TODO +</summary> +</cvar> + +<cvar name="X_RPM_GHOST"> +<summary> +TODO +</summary> +</cvar> + +<cvar name="X_RPM_VERIFY"> +<summary> +TODO +</summary> +</cvar> + +--> + + +<!-- +<builder name="Tag"> +<summary> +Leaves hints for the Package() Builder on how specific +files or directories should be packaged. +All tags are optional. + +<example> +# makes sure the built library will be installed with 0644 file +# access mode +Tag( Library( 'lib.c' ), unix-attr="0644" ) + +# marks file2.txt to be a documentation file +Tag( 'file2.txt', doc ) +</example> +</summary> +</builder> + +<function name="FindSourceFiles"> +<summary> +A convenience function which returns all leaves of the build tree. +</summary> +</function> + +<builder name="FindInstalledFiles"> +<summary> +Returns all files "built" by the &b-Install; or &b-InstallAs; builders. +</summary> +</function> +--> diff --git a/src/engine/SCons/Tool/packaging/ipk.py b/src/engine/SCons/Tool/packaging/ipk.py new file mode 100644 index 0000000..d566f48 --- /dev/null +++ b/src/engine/SCons/Tool/packaging/ipk.py @@ -0,0 +1,185 @@ +"""SCons.Tool.Packaging.ipk +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/packaging/ipk.py 4577 2009/12/27 19:44:43 scons" + +import SCons.Builder +import SCons.Node.FS +import os + +from SCons.Tool.packaging import stripinstallbuilder, putintopackageroot + +def package(env, target, source, PACKAGEROOT, NAME, VERSION, DESCRIPTION, + SUMMARY, X_IPK_PRIORITY, X_IPK_SECTION, SOURCE_URL, + X_IPK_MAINTAINER, X_IPK_DEPENDS, **kw): + """ this function prepares the packageroot directory for packaging with the + ipkg builder. + """ + SCons.Tool.Tool('ipkg').generate(env) + + # setup the Ipkg builder + bld = env['BUILDERS']['Ipkg'] + target, source = stripinstallbuilder(target, source, env) + target, source = putintopackageroot(target, source, env, PACKAGEROOT) + + # This should be overridable from the construction environment, + # which it is by using ARCHITECTURE=. + # Guessing based on what os.uname() returns at least allows it + # to work for both i386 and x86_64 Linux systems. + archmap = { + 'i686' : 'i386', + 'i586' : 'i386', + 'i486' : 'i386', + } + + buildarchitecture = os.uname()[4] + buildarchitecture = archmap.get(buildarchitecture, buildarchitecture) + + if kw.has_key('ARCHITECTURE'): + buildarchitecture = kw['ARCHITECTURE'] + + # setup the kw to contain the mandatory arguments to this fucntion. + # do this before calling any builder or setup function + loc=locals() + del loc['kw'] + kw.update(loc) + del kw['source'], kw['target'], kw['env'] + + # generate the specfile + specfile = gen_ipk_dir(PACKAGEROOT, source, env, kw) + + # override the default target. + if str(target[0])=="%s-%s"%(NAME, VERSION): + target=[ "%s_%s_%s.ipk"%(NAME, VERSION, buildarchitecture) ] + + # now apply the Ipkg builder + return apply(bld, [env, target, specfile], kw) + +def gen_ipk_dir(proot, source, env, kw): + # make sure the packageroot is a Dir object. + if SCons.Util.is_String(proot): proot=env.Dir(proot) + + # create the specfile builder + s_bld=SCons.Builder.Builder( + action = build_specfiles, + ) + + # create the specfile targets + spec_target=[] + control=proot.Dir('CONTROL') + spec_target.append(control.File('control')) + spec_target.append(control.File('conffiles')) + spec_target.append(control.File('postrm')) + spec_target.append(control.File('prerm')) + spec_target.append(control.File('postinst')) + spec_target.append(control.File('preinst')) + + # apply the builder to the specfile targets + apply(s_bld, [env, spec_target, source], kw) + + # the packageroot directory does now contain the specfiles. + return proot + +def build_specfiles(source, target, env): + """ filter the targets for the needed files and use the variables in env + to create the specfile. + """ + # + # At first we care for the CONTROL/control file, which is the main file for ipk. + # + # For this we need to open multiple files in random order, so we store into + # a dict so they can be easily accessed. + # + # + opened_files={} + def open_file(needle, haystack): + try: + return opened_files[needle] + except KeyError: + file=filter(lambda x: x.get_path().rfind(needle)!=-1, haystack)[0] + opened_files[needle]=open(file.abspath, 'w') + return opened_files[needle] + + control_file=open_file('control', target) + + if not env.has_key('X_IPK_DESCRIPTION'): + env['X_IPK_DESCRIPTION']="%s\n %s"%(env['SUMMARY'], + env['DESCRIPTION'].replace('\n', '\n ')) + + + content = """ +Package: $NAME +Version: $VERSION +Priority: $X_IPK_PRIORITY +Section: $X_IPK_SECTION +Source: $SOURCE_URL +Architecture: $ARCHITECTURE +Maintainer: $X_IPK_MAINTAINER +Depends: $X_IPK_DEPENDS +Description: $X_IPK_DESCRIPTION +""" + + control_file.write(env.subst(content)) + + # + # now handle the various other files, which purpose it is to set post-, + # pre-scripts and mark files as config files. + # + # We do so by filtering the source files for files which are marked with + # the "config" tag and afterwards we do the same for x_ipk_postrm, + # x_ipk_prerm, x_ipk_postinst and x_ipk_preinst tags. + # + # The first one will write the name of the file into the file + # CONTROL/configfiles, the latter add the content of the x_ipk_* variable + # into the same named file. + # + for f in [x for x in source if 'PACKAGING_CONFIG' in dir(x)]: + config=open_file('conffiles') + config.write(f.PACKAGING_INSTALL_LOCATION) + config.write('\n') + + for str in 'POSTRM PRERM POSTINST PREINST'.split(): + name="PACKAGING_X_IPK_%s"%str + for f in [x for x in source if name in dir(x)]: + file=open_file(name) + file.write(env[str]) + + # + # close all opened files + for f in opened_files.values(): + f.close() + + # call a user specified function + if env.has_key('CHANGE_SPECFILE'): + content += env['CHANGE_SPECFILE'](target) + + return 0 + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/packaging/msi.py b/src/engine/SCons/Tool/packaging/msi.py new file mode 100644 index 0000000..3806df9 --- /dev/null +++ b/src/engine/SCons/Tool/packaging/msi.py @@ -0,0 +1,526 @@ +"""SCons.Tool.packaging.msi + +The msi packager. +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/packaging/msi.py 4577 2009/12/27 19:44:43 scons" + +import os +import SCons +from SCons.Action import Action +from SCons.Builder import Builder + +from xml.dom.minidom import * +from xml.sax.saxutils import escape + +from SCons.Tool.packaging import stripinstallbuilder + +# +# Utility functions +# +def convert_to_id(s, id_set): + """ Some parts of .wxs need an Id attribute (for example: The File and + Directory directives. The charset is limited to A-Z, a-z, digits, + underscores, periods. Each Id must begin with a letter or with a + underscore. Google for "CNDL0015" for information about this. + + Requirements: + * the string created must only contain chars from the target charset. + * the string created must have a minimal editing distance from the + original string. + * the string created must be unique for the whole .wxs file. + + Observation: + * There are 62 chars in the charset. + + Idea: + * filter out forbidden characters. Check for a collision with the help + of the id_set. Add the number of the number of the collision at the + end of the created string. Furthermore care for a correct start of + the string. + """ + charset = 'ABCDEFGHIJKLMNOPQRSTUVWXYabcdefghijklmnopqrstuvwxyz0123456789_.' + if s[0] in '0123456789.': + s += '_'+s + id = filter( lambda c : c in charset, s ) + + # did we already generate an id for this file? + try: + return id_set[id][s] + except KeyError: + # no we did not so initialize with the id + if not id_set.has_key(id): id_set[id] = { s : id } + # there is a collision, generate an id which is unique by appending + # the collision number + else: id_set[id][s] = id + str(len(id_set[id])) + + return id_set[id][s] + +def is_dos_short_file_name(file): + """ examine if the given file is in the 8.3 form. + """ + fname, ext = os.path.splitext(file) + proper_ext = len(ext) == 0 or (2 <= len(ext) <= 4) # the ext contains the dot + proper_fname = file.isupper() and len(fname) <= 8 + + return proper_ext and proper_fname + +def gen_dos_short_file_name(file, filename_set): + """ see http://support.microsoft.com/default.aspx?scid=kb;en-us;Q142982 + + These are no complete 8.3 dos short names. The ~ char is missing and + replaced with one character from the filename. WiX warns about such + filenames, since a collision might occur. Google for "CNDL1014" for + more information. + """ + # guard this to not confuse the generation + if is_dos_short_file_name(file): + return file + + fname, ext = os.path.splitext(file) # ext contains the dot + + # first try if it suffices to convert to upper + file = file.upper() + if is_dos_short_file_name(file): + return file + + # strip forbidden characters. + forbidden = '."/[]:;=, ' + fname = filter( lambda c : c not in forbidden, fname ) + + # check if we already generated a filename with the same number: + # thisis1.txt, thisis2.txt etc. + duplicate, num = not None, 1 + while duplicate: + shortname = "%s%s" % (fname[:8-len(str(num))].upper(),\ + str(num)) + if len(ext) >= 2: + shortname = "%s%s" % (shortname, ext[:4].upper()) + + duplicate, num = shortname in filename_set, num+1 + + assert( is_dos_short_file_name(shortname) ), 'shortname is %s, longname is %s' % (shortname, file) + filename_set.append(shortname) + return shortname + +def create_feature_dict(files): + """ X_MSI_FEATURE and doc FileTag's can be used to collect files in a + hierarchy. This function collects the files into this hierarchy. + """ + dict = {} + + def add_to_dict( feature, file ): + if not SCons.Util.is_List( feature ): + feature = [ feature ] + + for f in feature: + if not dict.has_key( f ): + dict[ f ] = [ file ] + else: + dict[ f ].append( file ) + + for file in files: + if hasattr( file, 'PACKAGING_X_MSI_FEATURE' ): + add_to_dict(file.PACKAGING_X_MSI_FEATURE, file) + elif hasattr( file, 'PACKAGING_DOC' ): + add_to_dict( 'PACKAGING_DOC', file ) + else: + add_to_dict( 'default', file ) + + return dict + +def generate_guids(root): + """ generates globally unique identifiers for parts of the xml which need + them. + + Component tags have a special requirement. Their UUID is only allowed to + change if the list of their contained resources has changed. This allows + for clean removal and proper updates. + + To handle this requirement, the uuid is generated with an md5 hashing the + whole subtree of a xml node. + """ + from hashlib import md5 + + # specify which tags need a guid and in which attribute this should be stored. + needs_id = { 'Product' : 'Id', + 'Package' : 'Id', + 'Component' : 'Guid', + } + + # find all XMl nodes matching the key, retrieve their attribute, hash their + # subtree, convert hash to string and add as a attribute to the xml node. + for (key,value) in needs_id.items(): + node_list = root.getElementsByTagName(key) + attribute = value + for node in node_list: + hash = md5(node.toxml()).hexdigest() + hash_str = '%s-%s-%s-%s-%s' % ( hash[:8], hash[8:12], hash[12:16], hash[16:20], hash[20:] ) + node.attributes[attribute] = hash_str + + + +def string_wxsfile(target, source, env): + return "building WiX file %s"%( target[0].path ) + +def build_wxsfile(target, source, env): + """ compiles a .wxs file from the keywords given in env['msi_spec'] and + by analyzing the tree of source nodes and their tags. + """ + file = open(target[0].abspath, 'w') + + try: + # Create a document with the Wix root tag + doc = Document() + root = doc.createElement( 'Wix' ) + root.attributes['xmlns']='http://schemas.microsoft.com/wix/2003/01/wi' + doc.appendChild( root ) + + filename_set = [] # this is to circumvent duplicates in the shortnames + id_set = {} # this is to circumvent duplicates in the ids + + # Create the content + build_wxsfile_header_section(root, env) + build_wxsfile_file_section(root, source, env['NAME'], env['VERSION'], env['VENDOR'], filename_set, id_set) + generate_guids(root) + build_wxsfile_features_section(root, source, env['NAME'], env['VERSION'], env['SUMMARY'], id_set) + build_wxsfile_default_gui(root) + build_license_file(target[0].get_dir(), env) + + # write the xml to a file + file.write( doc.toprettyxml() ) + + # call a user specified function + if env.has_key('CHANGE_SPECFILE'): + env['CHANGE_SPECFILE'](target, source) + + except KeyError, e: + raise SCons.Errors.UserError( '"%s" package field for MSI is missing.' % e.args[0] ) + +# +# setup function +# +def create_default_directory_layout(root, NAME, VERSION, VENDOR, filename_set): + """ Create the wix default target directory layout and return the innermost + directory. + + We assume that the XML tree delivered in the root argument already contains + the Product tag. + + Everything is put under the PFiles directory property defined by WiX. + After that a directory with the 'VENDOR' tag is placed and then a + directory with the name of the project and its VERSION. This leads to the + following TARGET Directory Layout: + C:\<PFiles>\<Vendor>\<Projectname-Version>\ + Example: C:\Programme\Company\Product-1.2\ + """ + doc = Document() + d1 = doc.createElement( 'Directory' ) + d1.attributes['Id'] = 'TARGETDIR' + d1.attributes['Name'] = 'SourceDir' + + d2 = doc.createElement( 'Directory' ) + d2.attributes['Id'] = 'ProgramFilesFolder' + d2.attributes['Name'] = 'PFiles' + + d3 = doc.createElement( 'Directory' ) + d3.attributes['Id'] = 'VENDOR_folder' + d3.attributes['Name'] = escape( gen_dos_short_file_name( VENDOR, filename_set ) ) + d3.attributes['LongName'] = escape( VENDOR ) + + d4 = doc.createElement( 'Directory' ) + project_folder = "%s-%s" % ( NAME, VERSION ) + d4.attributes['Id'] = 'MY_DEFAULT_FOLDER' + d4.attributes['Name'] = escape( gen_dos_short_file_name( project_folder, filename_set ) ) + d4.attributes['LongName'] = escape( project_folder ) + + d1.childNodes.append( d2 ) + d2.childNodes.append( d3 ) + d3.childNodes.append( d4 ) + + root.getElementsByTagName('Product')[0].childNodes.append( d1 ) + + return d4 + +# +# mandatory and optional file tags +# +def build_wxsfile_file_section(root, files, NAME, VERSION, VENDOR, filename_set, id_set): + """ builds the Component sections of the wxs file with their included files. + + Files need to be specified in 8.3 format and in the long name format, long + filenames will be converted automatically. + + Features are specficied with the 'X_MSI_FEATURE' or 'DOC' FileTag. + """ + root = create_default_directory_layout( root, NAME, VERSION, VENDOR, filename_set ) + components = create_feature_dict( files ) + factory = Document() + + def get_directory( node, dir ): + """ returns the node under the given node representing the directory. + + Returns the component node if dir is None or empty. + """ + if dir == '' or not dir: + return node + + Directory = node + dir_parts = dir.split(os.path.sep) + + # to make sure that our directory ids are unique, the parent folders are + # consecutively added to upper_dir + upper_dir = '' + + # walk down the xml tree finding parts of the directory + dir_parts = filter( lambda d: d != '', dir_parts ) + for d in dir_parts[:]: + already_created = filter( lambda c: c.nodeName == 'Directory' and c.attributes['LongName'].value == escape(d), Directory.childNodes ) + + if already_created != []: + Directory = already_created[0] + dir_parts.remove(d) + upper_dir += d + else: + break + + for d in dir_parts: + nDirectory = factory.createElement( 'Directory' ) + nDirectory.attributes['LongName'] = escape( d ) + nDirectory.attributes['Name'] = escape( gen_dos_short_file_name( d, filename_set ) ) + upper_dir += d + nDirectory.attributes['Id'] = convert_to_id( upper_dir, id_set ) + + Directory.childNodes.append( nDirectory ) + Directory = nDirectory + + return Directory + + for file in files: + drive, path = os.path.splitdrive( file.PACKAGING_INSTALL_LOCATION ) + filename = os.path.basename( path ) + dirname = os.path.dirname( path ) + + h = { + # tagname : default value + 'PACKAGING_X_MSI_VITAL' : 'yes', + 'PACKAGING_X_MSI_FILEID' : convert_to_id(filename, id_set), + 'PACKAGING_X_MSI_LONGNAME' : filename, + 'PACKAGING_X_MSI_SHORTNAME' : gen_dos_short_file_name(filename, filename_set), + 'PACKAGING_X_MSI_SOURCE' : file.get_path(), + } + + # fill in the default tags given above. + for k,v in [ (k, v) for (k,v) in h.items() if not hasattr(file, k) ]: + setattr( file, k, v ) + + File = factory.createElement( 'File' ) + File.attributes['LongName'] = escape( file.PACKAGING_X_MSI_LONGNAME ) + File.attributes['Name'] = escape( file.PACKAGING_X_MSI_SHORTNAME ) + File.attributes['Source'] = escape( file.PACKAGING_X_MSI_SOURCE ) + File.attributes['Id'] = escape( file.PACKAGING_X_MSI_FILEID ) + File.attributes['Vital'] = escape( file.PACKAGING_X_MSI_VITAL ) + + # create the <Component> Tag under which this file should appear + Component = factory.createElement('Component') + Component.attributes['DiskId'] = '1' + Component.attributes['Id'] = convert_to_id( filename, id_set ) + + # hang the component node under the root node and the file node + # under the component node. + Directory = get_directory( root, dirname ) + Directory.childNodes.append( Component ) + Component.childNodes.append( File ) + +# +# additional functions +# +def build_wxsfile_features_section(root, files, NAME, VERSION, SUMMARY, id_set): + """ This function creates the <features> tag based on the supplied xml tree. + + This is achieved by finding all <component>s and adding them to a default target. + + It should be called after the tree has been built completly. We assume + that a MY_DEFAULT_FOLDER Property is defined in the wxs file tree. + + Furthermore a top-level with the name and VERSION of the software will be created. + + An PACKAGING_X_MSI_FEATURE can either be a string, where the feature + DESCRIPTION will be the same as its title or a Tuple, where the first + part will be its title and the second its DESCRIPTION. + """ + factory = Document() + Feature = factory.createElement('Feature') + Feature.attributes['Id'] = 'complete' + Feature.attributes['ConfigurableDirectory'] = 'MY_DEFAULT_FOLDER' + Feature.attributes['Level'] = '1' + Feature.attributes['Title'] = escape( '%s %s' % (NAME, VERSION) ) + Feature.attributes['Description'] = escape( SUMMARY ) + Feature.attributes['Display'] = 'expand' + + for (feature, files) in create_feature_dict(files).items(): + SubFeature = factory.createElement('Feature') + SubFeature.attributes['Level'] = '1' + + if SCons.Util.is_Tuple(feature): + SubFeature.attributes['Id'] = convert_to_id( feature[0], id_set ) + SubFeature.attributes['Title'] = escape(feature[0]) + SubFeature.attributes['Description'] = escape(feature[1]) + else: + SubFeature.attributes['Id'] = convert_to_id( feature, id_set ) + if feature=='default': + SubFeature.attributes['Description'] = 'Main Part' + SubFeature.attributes['Title'] = 'Main Part' + elif feature=='PACKAGING_DOC': + SubFeature.attributes['Description'] = 'Documentation' + SubFeature.attributes['Title'] = 'Documentation' + else: + SubFeature.attributes['Description'] = escape(feature) + SubFeature.attributes['Title'] = escape(feature) + + # build the componentrefs. As one of the design decision is that every + # file is also a component we walk the list of files and create a + # reference. + for f in files: + ComponentRef = factory.createElement('ComponentRef') + ComponentRef.attributes['Id'] = convert_to_id( os.path.basename(f.get_path()), id_set ) + SubFeature.childNodes.append(ComponentRef) + + Feature.childNodes.append(SubFeature) + + root.getElementsByTagName('Product')[0].childNodes.append(Feature) + +def build_wxsfile_default_gui(root): + """ this function adds a default GUI to the wxs file + """ + factory = Document() + Product = root.getElementsByTagName('Product')[0] + + UIRef = factory.createElement('UIRef') + UIRef.attributes['Id'] = 'WixUI_Mondo' + Product.childNodes.append(UIRef) + + UIRef = factory.createElement('UIRef') + UIRef.attributes['Id'] = 'WixUI_ErrorProgressText' + Product.childNodes.append(UIRef) + +def build_license_file(directory, spec): + """ creates a License.rtf file with the content of "X_MSI_LICENSE_TEXT" + in the given directory + """ + name, text = '', '' + + try: + name = spec['LICENSE'] + text = spec['X_MSI_LICENSE_TEXT'] + except KeyError: + pass # ignore this as X_MSI_LICENSE_TEXT is optional + + if name!='' or text!='': + file = open( os.path.join(directory.get_path(), 'License.rtf'), 'w' ) + file.write('{\\rtf') + if text!='': + file.write(text.replace('\n', '\\par ')) + else: + file.write(name+'\\par\\par') + file.write('}') + file.close() + +# +# mandatory and optional package tags +# +def build_wxsfile_header_section(root, spec): + """ Adds the xml file node which define the package meta-data. + """ + # Create the needed DOM nodes and add them at the correct position in the tree. + factory = Document() + Product = factory.createElement( 'Product' ) + Package = factory.createElement( 'Package' ) + + root.childNodes.append( Product ) + Product.childNodes.append( Package ) + + # set "mandatory" default values + if not spec.has_key('X_MSI_LANGUAGE'): + spec['X_MSI_LANGUAGE'] = '1033' # select english + + # mandatory sections, will throw a KeyError if the tag is not available + Product.attributes['Name'] = escape( spec['NAME'] ) + Product.attributes['Version'] = escape( spec['VERSION'] ) + Product.attributes['Manufacturer'] = escape( spec['VENDOR'] ) + Product.attributes['Language'] = escape( spec['X_MSI_LANGUAGE'] ) + Package.attributes['Description'] = escape( spec['SUMMARY'] ) + + # now the optional tags, for which we avoid the KeyErrror exception + if spec.has_key( 'DESCRIPTION' ): + Package.attributes['Comments'] = escape( spec['DESCRIPTION'] ) + + if spec.has_key( 'X_MSI_UPGRADE_CODE' ): + Package.attributes['X_MSI_UPGRADE_CODE'] = escape( spec['X_MSI_UPGRADE_CODE'] ) + + # We hardcode the media tag as our current model cannot handle it. + Media = factory.createElement('Media') + Media.attributes['Id'] = '1' + Media.attributes['Cabinet'] = 'default.cab' + Media.attributes['EmbedCab'] = 'yes' + root.getElementsByTagName('Product')[0].childNodes.append(Media) + +# this builder is the entry-point for .wxs file compiler. +wxs_builder = Builder( + action = Action( build_wxsfile, string_wxsfile ), + ensure_suffix = '.wxs' ) + +def package(env, target, source, PACKAGEROOT, NAME, VERSION, + DESCRIPTION, SUMMARY, VENDOR, X_MSI_LANGUAGE, **kw): + # make sure that the Wix Builder is in the environment + SCons.Tool.Tool('wix').generate(env) + + # get put the keywords for the specfile compiler. These are the arguments + # given to the package function and all optional ones stored in kw, minus + # the the source, target and env one. + loc = locals() + del loc['kw'] + kw.update(loc) + del kw['source'], kw['target'], kw['env'] + + # strip the install builder from the source files + target, source = stripinstallbuilder(target, source, env) + + # put the arguments into the env and call the specfile builder. + env['msi_spec'] = kw + specfile = apply( wxs_builder, [env, target, source], kw ) + + # now call the WiX Tool with the built specfile added as a source. + msifile = env.WiX(target, specfile) + + # return the target and source tuple. + return (msifile, source+[specfile]) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/packaging/rpm.py b/src/engine/SCons/Tool/packaging/rpm.py new file mode 100644 index 0000000..461b4b1 --- /dev/null +++ b/src/engine/SCons/Tool/packaging/rpm.py @@ -0,0 +1,367 @@ +"""SCons.Tool.Packaging.rpm + +The rpm packager. +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/packaging/rpm.py 4577 2009/12/27 19:44:43 scons" + +import os +import string + +import SCons.Builder + +from SCons.Environment import OverrideEnvironment +from SCons.Tool.packaging import stripinstallbuilder, src_targz +from SCons.Errors import UserError + +def package(env, target, source, PACKAGEROOT, NAME, VERSION, + PACKAGEVERSION, DESCRIPTION, SUMMARY, X_RPM_GROUP, LICENSE, + **kw): + # initialize the rpm tool + SCons.Tool.Tool('rpm').generate(env) + + bld = env['BUILDERS']['Rpm'] + + # Generate a UserError whenever the target name has been set explicitly, + # since rpm does not allow for controlling it. This is detected by + # checking if the target has been set to the default by the Package() + # Environment function. + if str(target[0])!="%s-%s"%(NAME, VERSION): + raise UserError( "Setting target is not supported for rpm." ) + else: + # This should be overridable from the construction environment, + # which it is by using ARCHITECTURE=. + # Guessing based on what os.uname() returns at least allows it + # to work for both i386 and x86_64 Linux systems. + archmap = { + 'i686' : 'i386', + 'i586' : 'i386', + 'i486' : 'i386', + } + + buildarchitecture = os.uname()[4] + buildarchitecture = archmap.get(buildarchitecture, buildarchitecture) + + if kw.has_key('ARCHITECTURE'): + buildarchitecture = kw['ARCHITECTURE'] + + fmt = '%s-%s-%s.%s.rpm' + srcrpm = fmt % (NAME, VERSION, PACKAGEVERSION, 'src') + binrpm = fmt % (NAME, VERSION, PACKAGEVERSION, buildarchitecture) + + target = [ srcrpm, binrpm ] + + # get the correct arguments into the kw hash + loc=locals() + del loc['kw'] + kw.update(loc) + del kw['source'], kw['target'], kw['env'] + + # if no "SOURCE_URL" tag is given add a default one. + if not kw.has_key('SOURCE_URL'): + #kw['SOURCE_URL']=(str(target[0])+".tar.gz").replace('.rpm', '') + kw['SOURCE_URL']=string.replace(str(target[0])+".tar.gz", '.rpm', '') + + # mangle the source and target list for the rpmbuild + env = OverrideEnvironment(env, kw) + target, source = stripinstallbuilder(target, source, env) + target, source = addspecfile(target, source, env) + target, source = collectintargz(target, source, env) + + # now call the rpm builder to actually build the packet. + return apply(bld, [env, target, source], kw) + +def collectintargz(target, source, env): + """ Puts all source files into a tar.gz file. """ + # the rpm tool depends on a source package, until this is chagned + # this hack needs to be here that tries to pack all sources in. + sources = env.FindSourceFiles() + + # filter out the target we are building the source list for. + #sources = [s for s in sources if not (s in target)] + sources = filter(lambda s, t=target: not (s in t), sources) + + # find the .spec file for rpm and add it since it is not necessarily found + # by the FindSourceFiles function. + #sources.extend( [s for s in source if str(s).rfind('.spec')!=-1] ) + spec_file = lambda s: string.rfind(str(s), '.spec') != -1 + sources.extend( filter(spec_file, source) ) + + # as the source contains the url of the source package this rpm package + # is built from, we extract the target name + #tarball = (str(target[0])+".tar.gz").replace('.rpm', '') + tarball = string.replace(str(target[0])+".tar.gz", '.rpm', '') + try: + #tarball = env['SOURCE_URL'].split('/')[-1] + tarball = string.split(env['SOURCE_URL'], '/')[-1] + except KeyError, e: + raise SCons.Errors.UserError( "Missing PackageTag '%s' for RPM packager" % e.args[0] ) + + tarball = src_targz.package(env, source=sources, target=tarball, + PACKAGEROOT=env['PACKAGEROOT'], ) + + return (target, tarball) + +def addspecfile(target, source, env): + specfile = "%s-%s" % (env['NAME'], env['VERSION']) + + bld = SCons.Builder.Builder(action = build_specfile, + suffix = '.spec', + target_factory = SCons.Node.FS.File) + + source.extend(bld(env, specfile, source)) + + return (target,source) + +def build_specfile(target, source, env): + """ Builds a RPM specfile from a dictionary with string metadata and + by analyzing a tree of nodes. + """ + file = open(target[0].abspath, 'w') + str = "" + + try: + file.write( build_specfile_header(env) ) + file.write( build_specfile_sections(env) ) + file.write( build_specfile_filesection(env, source) ) + file.close() + + # call a user specified function + if env.has_key('CHANGE_SPECFILE'): + env['CHANGE_SPECFILE'](target, source) + + except KeyError, e: + raise SCons.Errors.UserError( '"%s" package field for RPM is missing.' % e.args[0] ) + + +# +# mandatory and optional package tag section +# +def build_specfile_sections(spec): + """ Builds the sections of a rpm specfile. + """ + str = "" + + mandatory_sections = { + 'DESCRIPTION' : '\n%%description\n%s\n\n', } + + str = str + SimpleTagCompiler(mandatory_sections).compile( spec ) + + optional_sections = { + 'DESCRIPTION_' : '%%description -l %s\n%s\n\n', + 'CHANGELOG' : '%%changelog\n%s\n\n', + 'X_RPM_PREINSTALL' : '%%pre\n%s\n\n', + 'X_RPM_POSTINSTALL' : '%%post\n%s\n\n', + 'X_RPM_PREUNINSTALL' : '%%preun\n%s\n\n', + 'X_RPM_POSTUNINSTALL' : '%%postun\n%s\n\n', + 'X_RPM_VERIFY' : '%%verify\n%s\n\n', + + # These are for internal use but could possibly be overriden + 'X_RPM_PREP' : '%%prep\n%s\n\n', + 'X_RPM_BUILD' : '%%build\n%s\n\n', + 'X_RPM_INSTALL' : '%%install\n%s\n\n', + 'X_RPM_CLEAN' : '%%clean\n%s\n\n', + } + + # Default prep, build, install and clean rules + # TODO: optimize those build steps, to not compile the project a second time + if not spec.has_key('X_RPM_PREP'): + spec['X_RPM_PREP'] = '[ -n "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ] && rm -rf "$RPM_BUILD_ROOT"' + '\n%setup -q' + + if not spec.has_key('X_RPM_BUILD'): + spec['X_RPM_BUILD'] = 'mkdir "$RPM_BUILD_ROOT"' + + if not spec.has_key('X_RPM_INSTALL'): + spec['X_RPM_INSTALL'] = 'scons --install-sandbox="$RPM_BUILD_ROOT" "$RPM_BUILD_ROOT"' + + if not spec.has_key('X_RPM_CLEAN'): + spec['X_RPM_CLEAN'] = '[ -n "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ] && rm -rf "$RPM_BUILD_ROOT"' + + str = str + SimpleTagCompiler(optional_sections, mandatory=0).compile( spec ) + + return str + +def build_specfile_header(spec): + """ Builds all section but the %file of a rpm specfile + """ + str = "" + + # first the mandatory sections + mandatory_header_fields = { + 'NAME' : '%%define name %s\nName: %%{name}\n', + 'VERSION' : '%%define version %s\nVersion: %%{version}\n', + 'PACKAGEVERSION' : '%%define release %s\nRelease: %%{release}\n', + 'X_RPM_GROUP' : 'Group: %s\n', + 'SUMMARY' : 'Summary: %s\n', + 'LICENSE' : 'License: %s\n', } + + str = str + SimpleTagCompiler(mandatory_header_fields).compile( spec ) + + # now the optional tags + optional_header_fields = { + 'VENDOR' : 'Vendor: %s\n', + 'X_RPM_URL' : 'Url: %s\n', + 'SOURCE_URL' : 'Source: %s\n', + 'SUMMARY_' : 'Summary(%s): %s\n', + 'X_RPM_DISTRIBUTION' : 'Distribution: %s\n', + 'X_RPM_ICON' : 'Icon: %s\n', + 'X_RPM_PACKAGER' : 'Packager: %s\n', + 'X_RPM_GROUP_' : 'Group(%s): %s\n', + + 'X_RPM_REQUIRES' : 'Requires: %s\n', + 'X_RPM_PROVIDES' : 'Provides: %s\n', + 'X_RPM_CONFLICTS' : 'Conflicts: %s\n', + 'X_RPM_BUILDREQUIRES' : 'BuildRequires: %s\n', + + 'X_RPM_SERIAL' : 'Serial: %s\n', + 'X_RPM_EPOCH' : 'Epoch: %s\n', + 'X_RPM_AUTOREQPROV' : 'AutoReqProv: %s\n', + 'X_RPM_EXCLUDEARCH' : 'ExcludeArch: %s\n', + 'X_RPM_EXCLUSIVEARCH' : 'ExclusiveArch: %s\n', + 'X_RPM_PREFIX' : 'Prefix: %s\n', + 'X_RPM_CONFLICTS' : 'Conflicts: %s\n', + + # internal use + 'X_RPM_BUILDROOT' : 'BuildRoot: %s\n', } + + # fill in default values: + # Adding a BuildRequires renders the .rpm unbuildable under System, which + # are not managed by rpm, since the database to resolve this dependency is + # missing (take Gentoo as an example) +# if not s.has_key('x_rpm_BuildRequires'): +# s['x_rpm_BuildRequires'] = 'scons' + + if not spec.has_key('X_RPM_BUILDROOT'): + spec['X_RPM_BUILDROOT'] = '%{_tmppath}/%{name}-%{version}-%{release}' + + str = str + SimpleTagCompiler(optional_header_fields, mandatory=0).compile( spec ) + return str + +# +# mandatory and optional file tags +# +def build_specfile_filesection(spec, files): + """ builds the %file section of the specfile + """ + str = '%files\n' + + if not spec.has_key('X_RPM_DEFATTR'): + spec['X_RPM_DEFATTR'] = '(-,root,root)' + + str = str + '%%defattr %s\n' % spec['X_RPM_DEFATTR'] + + supported_tags = { + 'PACKAGING_CONFIG' : '%%config %s', + 'PACKAGING_CONFIG_NOREPLACE' : '%%config(noreplace) %s', + 'PACKAGING_DOC' : '%%doc %s', + 'PACKAGING_UNIX_ATTR' : '%%attr %s', + 'PACKAGING_LANG_' : '%%lang(%s) %s', + 'PACKAGING_X_RPM_VERIFY' : '%%verify %s', + 'PACKAGING_X_RPM_DIR' : '%%dir %s', + 'PACKAGING_X_RPM_DOCDIR' : '%%docdir %s', + 'PACKAGING_X_RPM_GHOST' : '%%ghost %s', } + + for file in files: + # build the tagset + tags = {} + for k in supported_tags.keys(): + try: + tags[k]=getattr(file, k) + except AttributeError: + pass + + # compile the tagset + str = str + SimpleTagCompiler(supported_tags, mandatory=0).compile( tags ) + + str = str + ' ' + str = str + file.PACKAGING_INSTALL_LOCATION + str = str + '\n\n' + + return str + +class SimpleTagCompiler: + """ This class is a simple string substition utility: + the replacement specfication is stored in the tagset dictionary, something + like: + { "abc" : "cdef %s ", + "abc_" : "cdef %s %s" } + + the compile function gets a value dictionary, which may look like: + { "abc" : "ghij", + "abc_gh" : "ij" } + + The resulting string will be: + "cdef ghij cdef gh ij" + """ + def __init__(self, tagset, mandatory=1): + self.tagset = tagset + self.mandatory = mandatory + + def compile(self, values): + """ compiles the tagset and returns a str containing the result + """ + def is_international(tag): + #return tag.endswith('_') + return tag[-1:] == '_' + + def get_country_code(tag): + return tag[-2:] + + def strip_country_code(tag): + return tag[:-2] + + replacements = self.tagset.items() + + str = "" + #domestic = [ (k,v) for k,v in replacements if not is_international(k) ] + domestic = filter(lambda t, i=is_international: not i(t[0]), replacements) + for key, replacement in domestic: + try: + str = str + replacement % values[key] + except KeyError, e: + if self.mandatory: + raise e + + #international = [ (k,v) for k,v in replacements if is_international(k) ] + international = filter(lambda t, i=is_international: i(t[0]), replacements) + for key, replacement in international: + try: + #int_values_for_key = [ (get_country_code(k),v) for k,v in values.items() if strip_country_code(k) == key ] + x = filter(lambda t,key=key,s=strip_country_code: s(t[0]) == key, values.items()) + int_values_for_key = map(lambda t,g=get_country_code: (g(t[0]),t[1]), x) + for v in int_values_for_key: + str = str + replacement % v + except KeyError, e: + if self.mandatory: + raise e + + return str + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/packaging/src_tarbz2.py b/src/engine/SCons/Tool/packaging/src_tarbz2.py new file mode 100644 index 0000000..aaeb7a8 --- /dev/null +++ b/src/engine/SCons/Tool/packaging/src_tarbz2.py @@ -0,0 +1,43 @@ +"""SCons.Tool.Packaging.tarbz2 + +The tarbz2 SRC packager. +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/packaging/src_tarbz2.py 4577 2009/12/27 19:44:43 scons" + +from SCons.Tool.packaging import putintopackageroot + +def package(env, target, source, PACKAGEROOT, **kw): + bld = env['BUILDERS']['Tar'] + bld.set_suffix('.tar.bz2') + target, source = putintopackageroot(target, source, env, PACKAGEROOT, honor_install_location=0) + return bld(env, target, source, TARFLAGS='-jc') + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/packaging/src_targz.py b/src/engine/SCons/Tool/packaging/src_targz.py new file mode 100644 index 0000000..5be52e6 --- /dev/null +++ b/src/engine/SCons/Tool/packaging/src_targz.py @@ -0,0 +1,43 @@ +"""SCons.Tool.Packaging.targz + +The targz SRC packager. +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/packaging/src_targz.py 4577 2009/12/27 19:44:43 scons" + +from SCons.Tool.packaging import putintopackageroot + +def package(env, target, source, PACKAGEROOT, **kw): + bld = env['BUILDERS']['Tar'] + bld.set_suffix('.tar.gz') + target, source = putintopackageroot(target, source, env, PACKAGEROOT, honor_install_location=0) + return bld(env, target, source, TARFLAGS='-zc') + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/packaging/src_zip.py b/src/engine/SCons/Tool/packaging/src_zip.py new file mode 100644 index 0000000..cfa73b1 --- /dev/null +++ b/src/engine/SCons/Tool/packaging/src_zip.py @@ -0,0 +1,43 @@ +"""SCons.Tool.Packaging.zip + +The zip SRC packager. +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/packaging/src_zip.py 4577 2009/12/27 19:44:43 scons" + +from SCons.Tool.packaging import putintopackageroot + +def package(env, target, source, PACKAGEROOT, **kw): + bld = env['BUILDERS']['Zip'] + bld.set_suffix('.zip') + target, source = putintopackageroot(target, source, env, PACKAGEROOT, honor_install_location=0) + return bld(env, target, source) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/packaging/tarbz2.py b/src/engine/SCons/Tool/packaging/tarbz2.py new file mode 100644 index 0000000..a0c2b81 --- /dev/null +++ b/src/engine/SCons/Tool/packaging/tarbz2.py @@ -0,0 +1,44 @@ +"""SCons.Tool.Packaging.tarbz2 + +The tarbz2 SRC packager. +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/packaging/tarbz2.py 4577 2009/12/27 19:44:43 scons" + +from SCons.Tool.packaging import stripinstallbuilder, putintopackageroot + +def package(env, target, source, PACKAGEROOT, **kw): + bld = env['BUILDERS']['Tar'] + bld.set_suffix('.tar.gz') + target, source = putintopackageroot(target, source, env, PACKAGEROOT) + target, source = stripinstallbuilder(target, source, env) + return bld(env, target, source, TARFLAGS='-jc') + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/packaging/targz.py b/src/engine/SCons/Tool/packaging/targz.py new file mode 100644 index 0000000..b985163 --- /dev/null +++ b/src/engine/SCons/Tool/packaging/targz.py @@ -0,0 +1,44 @@ +"""SCons.Tool.Packaging.targz + +The targz SRC packager. +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/packaging/targz.py 4577 2009/12/27 19:44:43 scons" + +from SCons.Tool.packaging import stripinstallbuilder, putintopackageroot + +def package(env, target, source, PACKAGEROOT, **kw): + bld = env['BUILDERS']['Tar'] + bld.set_suffix('.tar.gz') + target, source = stripinstallbuilder(target, source, env) + target, source = putintopackageroot(target, source, env, PACKAGEROOT) + return bld(env, target, source, TARFLAGS='-zc') + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/packaging/zip.py b/src/engine/SCons/Tool/packaging/zip.py new file mode 100644 index 0000000..590c975 --- /dev/null +++ b/src/engine/SCons/Tool/packaging/zip.py @@ -0,0 +1,44 @@ +"""SCons.Tool.Packaging.zip + +The zip SRC packager. +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/packaging/zip.py 4577 2009/12/27 19:44:43 scons" + +from SCons.Tool.packaging import stripinstallbuilder, putintopackageroot + +def package(env, target, source, PACKAGEROOT, **kw): + bld = env['BUILDERS']['Zip'] + bld.set_suffix('.zip') + target, source = stripinstallbuilder(target, source, env) + target, source = putintopackageroot(target, source, env, PACKAGEROOT) + return bld(env, target, source) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/pdf.py b/src/engine/SCons/Tool/pdf.py new file mode 100644 index 0000000..1ce561e --- /dev/null +++ b/src/engine/SCons/Tool/pdf.py @@ -0,0 +1,78 @@ +"""SCons.Tool.pdf + +Common PDF Builder definition for various other Tool modules that use it. +Add an explicit action to run epstopdf to convert .eps files to .pdf + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/pdf.py 4577 2009/12/27 19:44:43 scons" + +import SCons.Builder +import SCons.Tool + +PDFBuilder = None + +EpsPdfAction = SCons.Action.Action('$EPSTOPDFCOM', '$EPSTOPDFCOMSTR') + +def generate(env): + try: + env['BUILDERS']['PDF'] + except KeyError: + global PDFBuilder + if PDFBuilder is None: + PDFBuilder = SCons.Builder.Builder(action = {}, + source_scanner = SCons.Tool.PDFLaTeXScanner, + prefix = '$PDFPREFIX', + suffix = '$PDFSUFFIX', + emitter = {}, + source_ext_match = None, + single_source=True) + env['BUILDERS']['PDF'] = PDFBuilder + + env['PDFPREFIX'] = '' + env['PDFSUFFIX'] = '.pdf' + +# put the epstopdf builder in this routine so we can add it after +# the pdftex builder so that one is the default for no source suffix +def generate2(env): + bld = env['BUILDERS']['PDF'] + #bld.add_action('.ps', EpsPdfAction) # this is covered by direct Ghostcript action in gs.py + bld.add_action('.eps', EpsPdfAction) + + env['EPSTOPDF'] = 'epstopdf' + env['EPSTOPDFFLAGS'] = SCons.Util.CLVar('') + env['EPSTOPDFCOM'] = '$EPSTOPDF $EPSTOPDFFLAGS ${SOURCE} --outfile=${TARGET}' + +def exists(env): + # This only puts a skeleton Builder in place, so if someone + # references this Tool directly, it's always "available." + return 1 + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/pdf.xml b/src/engine/SCons/Tool/pdf.xml new file mode 100644 index 0000000..a695079 --- /dev/null +++ b/src/engine/SCons/Tool/pdf.xml @@ -0,0 +1,49 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="pdf"> +<summary> +Sets construction variables for the Portable Document Format builder. +</summary> +<sets> +PDFPREFIX +PDFSUFFIX +</sets> +</tool> + +<builder name="PDF"> +<summary> +Builds a <filename>.pdf</filename> file +from a <filename>.dvi</filename> input file +(or, by extension, a <filename>.tex</filename>, +<filename>.ltx</filename>, +or +<filename>.latex</filename> input file). +The suffix specified by the &cv-link-PDFSUFFIX; construction variable +(<filename>.pdf</filename> by default) +is added automatically to the target +if it is not already present. Example: + +<example> +# builds from aaa.tex +env.PDF(target = 'aaa.pdf', source = 'aaa.tex') +# builds bbb.pdf from bbb.dvi +env.PDF(target = 'bbb', source = 'bbb.dvi') +</example> +</summary> +</builder> + +<cvar name="PDFPREFIX"> +<summary> +The prefix used for PDF file names. +</summary> +</cvar> + +<cvar name="PDFSUFFIX"> +<summary> +The suffix used for PDF file names. +</summary> +</cvar> diff --git a/src/engine/SCons/Tool/pdflatex.py b/src/engine/SCons/Tool/pdflatex.py new file mode 100644 index 0000000..8a008b3 --- /dev/null +++ b/src/engine/SCons/Tool/pdflatex.py @@ -0,0 +1,83 @@ +"""SCons.Tool.pdflatex + +Tool-specific initialization for pdflatex. +Generates .pdf files from .latex or .ltx files + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/pdflatex.py 4577 2009/12/27 19:44:43 scons" + +import SCons.Action +import SCons.Util +import SCons.Tool.pdf +import SCons.Tool.tex + +PDFLaTeXAction = None + +def PDFLaTeXAuxFunction(target = None, source= None, env=None): + result = SCons.Tool.tex.InternalLaTeXAuxAction( PDFLaTeXAction, target, source, env ) + if result != 0: + print env['PDFLATEX']," returned an error, check the log file" + return result + +PDFLaTeXAuxAction = None + +def generate(env): + """Add Builders and construction variables for pdflatex to an Environment.""" + global PDFLaTeXAction + if PDFLaTeXAction is None: + PDFLaTeXAction = SCons.Action.Action('$PDFLATEXCOM', '$PDFLATEXCOMSTR') + + global PDFLaTeXAuxAction + if PDFLaTeXAuxAction is None: + PDFLaTeXAuxAction = SCons.Action.Action(PDFLaTeXAuxFunction, + strfunction=SCons.Tool.tex.TeXLaTeXStrFunction) + + env.AppendUnique(LATEXSUFFIXES=SCons.Tool.LaTeXSuffixes) + + import pdf + pdf.generate(env) + + bld = env['BUILDERS']['PDF'] + bld.add_action('.ltx', PDFLaTeXAuxAction) + bld.add_action('.latex', PDFLaTeXAuxAction) + bld.add_emitter('.ltx', SCons.Tool.tex.tex_pdf_emitter) + bld.add_emitter('.latex', SCons.Tool.tex.tex_pdf_emitter) + + SCons.Tool.tex.generate_common(env) + +def exists(env): + return env.Detect('pdflatex') + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/pdflatex.xml b/src/engine/SCons/Tool/pdflatex.xml new file mode 100644 index 0000000..3a4eaeb --- /dev/null +++ b/src/engine/SCons/Tool/pdflatex.xml @@ -0,0 +1,49 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="pdflatex"> +<summary> +Sets construction variables for the &pdflatex; utility. +</summary> +<sets> +PDFLATEX +PDFLATEXFLAGS +PDFLATEXCOM +LATEXRETRIES +</sets> +<uses> +PDFLATEXCOMSTR +</uses> +</tool> + +<cvar name="PDFLATEX"> +<summary> +The &pdflatex; utility. +</summary> +</cvar> + +<cvar name="PDFLATEXCOM"> +<summary> +The command line used to call the &pdflatex; utility. +</summary> +</cvar> + +<cvar name="PDFLATEXCOMSTR"> +<summary> +The string displayed when calling the &pdflatex; utility. +If this is not set, then &cv-link-PDFLATEXCOM; (the command line) is displayed. + +<example> +env = Environment(PDFLATEX;COMSTR = "Building $TARGET from LaTeX input $SOURCES") +</example> +</summary> +</cvar> + +<cvar name="PDFLATEXFLAGS"> +<summary> +General options passed to the &pdflatex; utility. +</summary> +</cvar> diff --git a/src/engine/SCons/Tool/pdftex.py b/src/engine/SCons/Tool/pdftex.py new file mode 100644 index 0000000..0733d16 --- /dev/null +++ b/src/engine/SCons/Tool/pdftex.py @@ -0,0 +1,108 @@ +"""SCons.Tool.pdftex + +Tool-specific initialization for pdftex. +Generates .pdf files from .tex files + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/pdftex.py 4577 2009/12/27 19:44:43 scons" + +import os +import SCons.Action +import SCons.Util +import SCons.Tool.tex + +PDFTeXAction = None + +# This action might be needed more than once if we are dealing with +# labels and bibtex. +PDFLaTeXAction = None + +def PDFLaTeXAuxAction(target = None, source= None, env=None): + result = SCons.Tool.tex.InternalLaTeXAuxAction( PDFLaTeXAction, target, source, env ) + return result + +def PDFTeXLaTeXFunction(target = None, source= None, env=None): + """A builder for TeX and LaTeX that scans the source file to + decide the "flavor" of the source and then executes the appropriate + program.""" + basedir = os.path.split(str(source[0]))[0] + abspath = os.path.abspath(basedir) + + if SCons.Tool.tex.is_LaTeX(source,env,abspath): + result = PDFLaTeXAuxAction(target,source,env) + if result != 0: + print env['PDFLATEX']," returned an error, check the log file" + else: + result = PDFTeXAction(target,source,env) + if result != 0: + print env['PDFTEX']," returned an error, check the log file" + return result + +PDFTeXLaTeXAction = None + +def generate(env): + """Add Builders and construction variables for pdftex to an Environment.""" + global PDFTeXAction + if PDFTeXAction is None: + PDFTeXAction = SCons.Action.Action('$PDFTEXCOM', '$PDFTEXCOMSTR') + + global PDFLaTeXAction + if PDFLaTeXAction is None: + PDFLaTeXAction = SCons.Action.Action("$PDFLATEXCOM", "$PDFLATEXCOMSTR") + + global PDFTeXLaTeXAction + if PDFTeXLaTeXAction is None: + PDFTeXLaTeXAction = SCons.Action.Action(PDFTeXLaTeXFunction, + strfunction=SCons.Tool.tex.TeXLaTeXStrFunction) + + env.AppendUnique(LATEXSUFFIXES=SCons.Tool.LaTeXSuffixes) + + import pdf + pdf.generate(env) + + bld = env['BUILDERS']['PDF'] + bld.add_action('.tex', PDFTeXLaTeXAction) + bld.add_emitter('.tex', SCons.Tool.tex.tex_pdf_emitter) + + # Add the epstopdf builder after the pdftex builder + # so pdftex is the default for no source suffix + pdf.generate2(env) + + SCons.Tool.tex.generate_common(env) + +def exists(env): + return env.Detect('pdftex') + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/pdftex.xml b/src/engine/SCons/Tool/pdftex.xml new file mode 100644 index 0000000..15614a2 --- /dev/null +++ b/src/engine/SCons/Tool/pdftex.xml @@ -0,0 +1,53 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="pdftex"> +<summary> +Sets construction variables for the &pdftex; utility. +</summary> +<sets> +PDFTEX +PDFTEXFLAGS +PDFTEXCOM +PDFLATEX +PDFLATEXFLAGS +PDFLATEXCOM +LATEXRETRIES +</sets> +<uses> +PDFTEXCOMSTR +PDFLATEXCOMSTR +</uses> +</tool> + +<cvar name="PDFTEX"> +<summary> +The &pdftex; utility. +</summary> +</cvar> + +<cvar name="PDFTEXCOM"> +<summary> +The command line used to call the &pdftex; utility. +</summary> +</cvar> + +<cvar name="PDFTEXCOMSTR"> +<summary> +The string displayed when calling the &pdftex; utility. +If this is not set, then &cv-link-PDFTEXCOM; (the command line) is displayed. + +<example> +env = Environment(PDFTEXCOMSTR = "Building $TARGET from TeX input $SOURCES") +</example> +</summary> +</cvar> + +<cvar name="PDFTEXFLAGS"> +<summary> +General options passed to the &pdftex; utility. +</summary> +</cvar> diff --git a/src/engine/SCons/Tool/qt.py b/src/engine/SCons/Tool/qt.py new file mode 100644 index 0000000..72ae194 --- /dev/null +++ b/src/engine/SCons/Tool/qt.py @@ -0,0 +1,336 @@ + +"""SCons.Tool.qt + +Tool-specific initialization for Qt. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/qt.py 4577 2009/12/27 19:44:43 scons" + +import os.path +import re + +import SCons.Action +import SCons.Builder +import SCons.Defaults +import SCons.Scanner +import SCons.Tool +import SCons.Util + +class ToolQtWarning(SCons.Warnings.Warning): + pass + +class GeneratedMocFileNotIncluded(ToolQtWarning): + pass + +class QtdirNotFound(ToolQtWarning): + pass + +SCons.Warnings.enableWarningClass(ToolQtWarning) + +header_extensions = [".h", ".hxx", ".hpp", ".hh"] +if SCons.Util.case_sensitive_suffixes('.h', '.H'): + header_extensions.append('.H') +cplusplus = __import__('c++', globals(), locals(), []) +cxx_suffixes = cplusplus.CXXSuffixes + +def checkMocIncluded(target, source, env): + moc = target[0] + cpp = source[0] + # looks like cpp.includes is cleared before the build stage :-( + # not really sure about the path transformations (moc.cwd? cpp.cwd?) :-/ + path = SCons.Defaults.CScan.path(env, moc.cwd) + includes = SCons.Defaults.CScan(cpp, env, path) + if not moc in includes: + SCons.Warnings.warn( + GeneratedMocFileNotIncluded, + "Generated moc file '%s' is not included by '%s'" % + (str(moc), str(cpp))) + +def find_file(filename, paths, node_factory): + for dir in paths: + node = node_factory(filename, dir) + if node.rexists(): + return node + return None + +class _Automoc: + """ + Callable class, which works as an emitter for Programs, SharedLibraries and + StaticLibraries. + """ + + def __init__(self, objBuilderName): + self.objBuilderName = objBuilderName + + def __call__(self, target, source, env): + """ + Smart autoscan function. Gets the list of objects for the Program + or Lib. Adds objects and builders for the special qt files. + """ + try: + if int(env.subst('$QT_AUTOSCAN')) == 0: + return target, source + except ValueError: + pass + try: + debug = int(env.subst('$QT_DEBUG')) + except ValueError: + debug = 0 + + # some shortcuts used in the scanner + splitext = SCons.Util.splitext + objBuilder = getattr(env, self.objBuilderName) + + # some regular expressions: + # Q_OBJECT detection + q_object_search = re.compile(r'[^A-Za-z0-9]Q_OBJECT[^A-Za-z0-9]') + # cxx and c comment 'eater' + #comment = re.compile(r'(//.*)|(/\*(([^*])|(\*[^/]))*\*/)') + # CW: something must be wrong with the regexp. See also bug #998222 + # CURRENTLY THERE IS NO TEST CASE FOR THAT + + # The following is kind of hacky to get builders working properly (FIXME) + objBuilderEnv = objBuilder.env + objBuilder.env = env + mocBuilderEnv = env.Moc.env + env.Moc.env = env + + # make a deep copy for the result; MocH objects will be appended + out_sources = source[:] + + for obj in source: + if not obj.has_builder(): + # binary obj file provided + if debug: + print "scons: qt: '%s' seems to be a binary. Discarded." % str(obj) + continue + cpp = obj.sources[0] + if not splitext(str(cpp))[1] in cxx_suffixes: + if debug: + print "scons: qt: '%s' is no cxx file. Discarded." % str(cpp) + # c or fortran source + continue + #cpp_contents = comment.sub('', cpp.get_text_contents()) + cpp_contents = cpp.get_text_contents() + h=None + for h_ext in header_extensions: + # try to find the header file in the corresponding source + # directory + hname = splitext(cpp.name)[0] + h_ext + h = find_file(hname, (cpp.get_dir(),), env.File) + if h: + if debug: + print "scons: qt: Scanning '%s' (header of '%s')" % (str(h), str(cpp)) + #h_contents = comment.sub('', h.get_text_contents()) + h_contents = h.get_text_contents() + break + if not h and debug: + print "scons: qt: no header for '%s'." % (str(cpp)) + if h and q_object_search.search(h_contents): + # h file with the Q_OBJECT macro found -> add moc_cpp + moc_cpp = env.Moc(h) + moc_o = objBuilder(moc_cpp) + out_sources.append(moc_o) + #moc_cpp.target_scanner = SCons.Defaults.CScan + if debug: + print "scons: qt: found Q_OBJECT macro in '%s', moc'ing to '%s'" % (str(h), str(moc_cpp)) + if cpp and q_object_search.search(cpp_contents): + # cpp file with Q_OBJECT macro found -> add moc + # (to be included in cpp) + moc = env.Moc(cpp) + env.Ignore(moc, moc) + if debug: + print "scons: qt: found Q_OBJECT macro in '%s', moc'ing to '%s'" % (str(cpp), str(moc)) + #moc.source_scanner = SCons.Defaults.CScan + # restore the original env attributes (FIXME) + objBuilder.env = objBuilderEnv + env.Moc.env = mocBuilderEnv + + return (target, out_sources) + +AutomocShared = _Automoc('SharedObject') +AutomocStatic = _Automoc('StaticObject') + +def _detect(env): + """Not really safe, but fast method to detect the QT library""" + QTDIR = None + if not QTDIR: + QTDIR = env.get('QTDIR',None) + if not QTDIR: + QTDIR = os.environ.get('QTDIR',None) + if not QTDIR: + moc = env.WhereIs('moc') + if moc: + QTDIR = os.path.dirname(os.path.dirname(moc)) + SCons.Warnings.warn( + QtdirNotFound, + "Could not detect qt, using moc executable as a hint (QTDIR=%s)" % QTDIR) + else: + QTDIR = None + SCons.Warnings.warn( + QtdirNotFound, + "Could not detect qt, using empty QTDIR") + return QTDIR + +def uicEmitter(target, source, env): + adjustixes = SCons.Util.adjustixes + bs = SCons.Util.splitext(str(source[0].name))[0] + bs = os.path.join(str(target[0].get_dir()),bs) + # first target (header) is automatically added by builder + if len(target) < 2: + # second target is implementation + target.append(adjustixes(bs, + env.subst('$QT_UICIMPLPREFIX'), + env.subst('$QT_UICIMPLSUFFIX'))) + if len(target) < 3: + # third target is moc file + target.append(adjustixes(bs, + env.subst('$QT_MOCHPREFIX'), + env.subst('$QT_MOCHSUFFIX'))) + return target, source + +def uicScannerFunc(node, env, path): + lookout = [] + lookout.extend(env['CPPPATH']) + lookout.append(str(node.rfile().dir)) + includes = re.findall("<include.*?>(.*?)</include>", node.get_text_contents()) + result = [] + for incFile in includes: + dep = env.FindFile(incFile,lookout) + if dep: + result.append(dep) + return result + +uicScanner = SCons.Scanner.Base(uicScannerFunc, + name = "UicScanner", + node_class = SCons.Node.FS.File, + node_factory = SCons.Node.FS.File, + recursive = 0) + +def generate(env): + """Add Builders and construction variables for qt to an Environment.""" + CLVar = SCons.Util.CLVar + Action = SCons.Action.Action + Builder = SCons.Builder.Builder + + env.SetDefault(QTDIR = _detect(env), + QT_BINPATH = os.path.join('$QTDIR', 'bin'), + QT_CPPPATH = os.path.join('$QTDIR', 'include'), + QT_LIBPATH = os.path.join('$QTDIR', 'lib'), + QT_MOC = os.path.join('$QT_BINPATH','moc'), + QT_UIC = os.path.join('$QT_BINPATH','uic'), + QT_LIB = 'qt', # may be set to qt-mt + + QT_AUTOSCAN = 1, # scan for moc'able sources + + # Some QT specific flags. I don't expect someone wants to + # manipulate those ... + QT_UICIMPLFLAGS = CLVar(''), + QT_UICDECLFLAGS = CLVar(''), + QT_MOCFROMHFLAGS = CLVar(''), + QT_MOCFROMCXXFLAGS = CLVar('-i'), + + # suffixes/prefixes for the headers / sources to generate + QT_UICDECLPREFIX = '', + QT_UICDECLSUFFIX = '.h', + QT_UICIMPLPREFIX = 'uic_', + QT_UICIMPLSUFFIX = '$CXXFILESUFFIX', + QT_MOCHPREFIX = 'moc_', + QT_MOCHSUFFIX = '$CXXFILESUFFIX', + QT_MOCCXXPREFIX = '', + QT_MOCCXXSUFFIX = '.moc', + QT_UISUFFIX = '.ui', + + # Commands for the qt support ... + # command to generate header, implementation and moc-file + # from a .ui file + QT_UICCOM = [ + CLVar('$QT_UIC $QT_UICDECLFLAGS -o ${TARGETS[0]} $SOURCE'), + CLVar('$QT_UIC $QT_UICIMPLFLAGS -impl ${TARGETS[0].file} ' + '-o ${TARGETS[1]} $SOURCE'), + CLVar('$QT_MOC $QT_MOCFROMHFLAGS -o ${TARGETS[2]} ${TARGETS[0]}')], + # command to generate meta object information for a class + # declarated in a header + QT_MOCFROMHCOM = ( + '$QT_MOC $QT_MOCFROMHFLAGS -o ${TARGETS[0]} $SOURCE'), + # command to generate meta object information for a class + # declarated in a cpp file + QT_MOCFROMCXXCOM = [ + CLVar('$QT_MOC $QT_MOCFROMCXXFLAGS -o ${TARGETS[0]} $SOURCE'), + Action(checkMocIncluded,None)]) + + # ... and the corresponding builders + uicBld = Builder(action=SCons.Action.Action('$QT_UICCOM', '$QT_UICCOMSTR'), + emitter=uicEmitter, + src_suffix='$QT_UISUFFIX', + suffix='$QT_UICDECLSUFFIX', + prefix='$QT_UICDECLPREFIX', + source_scanner=uicScanner) + mocBld = Builder(action={}, prefix={}, suffix={}) + for h in header_extensions: + act = SCons.Action.Action('$QT_MOCFROMHCOM', '$QT_MOCFROMHCOMSTR') + mocBld.add_action(h, act) + mocBld.prefix[h] = '$QT_MOCHPREFIX' + mocBld.suffix[h] = '$QT_MOCHSUFFIX' + for cxx in cxx_suffixes: + act = SCons.Action.Action('$QT_MOCFROMCXXCOM', '$QT_MOCFROMCXXCOMSTR') + mocBld.add_action(cxx, act) + mocBld.prefix[cxx] = '$QT_MOCCXXPREFIX' + mocBld.suffix[cxx] = '$QT_MOCCXXSUFFIX' + + # register the builders + env['BUILDERS']['Uic'] = uicBld + env['BUILDERS']['Moc'] = mocBld + static_obj, shared_obj = SCons.Tool.createObjBuilders(env) + static_obj.add_src_builder('Uic') + shared_obj.add_src_builder('Uic') + + # We use the emitters of Program / StaticLibrary / SharedLibrary + # to scan for moc'able files + # We can't refer to the builders directly, we have to fetch them + # as Environment attributes because that sets them up to be called + # correctly later by our emitter. + env.AppendUnique(PROGEMITTER =[AutomocStatic], + SHLIBEMITTER=[AutomocShared], + LIBEMITTER =[AutomocStatic], + # Of course, we need to link against the qt libraries + CPPPATH=["$QT_CPPPATH"], + LIBPATH=["$QT_LIBPATH"], + LIBS=['$QT_LIB']) + +def exists(env): + return _detect(env) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/qt.xml b/src/engine/SCons/Tool/qt.xml new file mode 100644 index 0000000..3e41c68 --- /dev/null +++ b/src/engine/SCons/Tool/qt.xml @@ -0,0 +1,314 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="qt"> +<summary> +Sets construction variables for building Qt applications. +</summary> +<sets> +QTDIR +QT_BINPATH +QT_CPPPATH +QT_LIBPATH +QT_MOC +QT_UIC +QT_LIB +QT_AUTOSCAN +QT_UICIMPLFLAGS +QT_UICDECLFLAGS +QT_MOCFROMHFLAGS +QT_MOCFROMCXXFLAGS +QT_UICDECLPREFIX +QT_UICDECLSUFFIX +QT_UICIMPLPREFIX +QT_UICIMPLSUFFIX +QT_MOCHPREFIX +QT_MOCHSUFFIX +QT_MOCCXXPREFIX +QT_MOCCXXSUFFIX +QT_UISUFFIX +QT_UICCOM +QT_MOCFROMHCOM +QT_MOCFROMCXXCOM +</sets> +<uses> +</uses> +</tool> + +<builder name="Moc"> +<summary> +Builds an output file from a moc input file. Moc input files are either +header files or cxx files. This builder is only available after using the +tool 'qt'. See the &cv-link-QTDIR; variable for more information. +Example: + +<example> +env.Moc('foo.h') # generates moc_foo.cc +env.Moc('foo.cpp') # generates foo.moc +</example> +</summary> +</builder> + +<builder name="Uic"> +<summary> +Builds a header file, an implementation file and a moc file from an ui file. +and returns the corresponding nodes in the above order. +This builder is only available after using the tool 'qt'. Note: you can +specify <filename>.ui</filename> files directly as source +files to the &b-Program;, +&b-Library; and &b-SharedLibrary; builders +without using this builder. Using this builder lets you override the standard +naming conventions (be careful: prefixes are always prepended to names of +built files; if you don't want prefixes, you may set them to ``). +See the &cv-link-QTDIR; variable for more information. +Example: + +<example> +env.Uic('foo.ui') # -> ['foo.h', 'uic_foo.cc', 'moc_foo.cc'] +env.Uic(target = Split('include/foo.h gen/uicfoo.cc gen/mocfoo.cc'), + source = 'foo.ui') # -> ['include/foo.h', 'gen/uicfoo.cc', 'gen/mocfoo.cc'] +</example> +</summary> +</builder> + +<cvar name="QTDIR"> +<summary> +The qt tool tries to take this from os.environ. +It also initializes all QT_* +construction variables listed below. +(Note that all paths are constructed +with python's os.path.join() method, +but are listed here with the '/' separator +for easier reading.) +In addition, the construction environment +variables &cv-link-CPPPATH;, +&cv-link-LIBPATH; and +&cv-link-LIBS; may be modified +and the variables +PROGEMITTER, SHLIBEMITTER and LIBEMITTER +are modified. Because the build-performance is affected when using this tool, +you have to explicitly specify it at Environment creation: + +<example> +Environment(tools=['default','qt']) +</example> + +The qt tool supports the following operations: + +<emphasis Role="strong">Automatic moc file generation from header files.</emphasis> +You do not have to specify moc files explicitly, the tool does it for you. +However, there are a few preconditions to do so: Your header file must have +the same filebase as your implementation file and must stay in the same +directory. It must have one of the suffixes .h, .hpp, .H, .hxx, .hh. You +can turn off automatic moc file generation by setting QT_AUTOSCAN to 0. +See also the corresponding builder method +.B Moc() + +<emphasis Role="strong">Automatic moc file generation from cxx files.</emphasis> +As stated in the qt documentation, include the moc file at the end of +the cxx file. Note that you have to include the file, which is generated +by the transformation ${QT_MOCCXXPREFIX}<basename>${QT_MOCCXXSUFFIX}, by default +<basename>.moc. A warning is generated after building the moc file, if you +do not include the correct file. If you are using VariantDir, you may +need to specify duplicate=1. You can turn off automatic moc file generation +by setting QT_AUTOSCAN to 0. See also the corresponding +&b-Moc; +builder method. + +<emphasis Role="strong">Automatic handling of .ui files.</emphasis> +The implementation files generated from .ui files are handled much the same +as yacc or lex files. Each .ui file given as a source of Program, Library or +SharedLibrary will generate three files, the declaration file, the +implementation file and a moc file. Because there are also generated headers, +you may need to specify duplicate=1 in calls to VariantDir. +See also the corresponding +&b-Uic; +builder method. +</summary> +</cvar> + +<cvar name="QT_AUTOSCAN"> +<summary> +Turn off scanning for mocable files. Use the Moc Builder to explicitely +specify files to run moc on. +</summary> +</cvar> + +<cvar name="QT_BINPATH"> +<summary> +The path where the qt binaries are installed. +The default value is '&cv-link-QTDIR;/bin'. +</summary> +</cvar> + +<cvar name="QT_CPPPATH"> +<summary> +The path where the qt header files are installed. +The default value is '&cv-link-QTDIR;/include'. +Note: If you set this variable to None, +the tool won't change the &cv-link-CPPPATH; +construction variable. +</summary> +</cvar> + +<cvar name="QT_DEBUG"> +<summary> +Prints lots of debugging information while scanning for moc files. +</summary> +</cvar> + +<cvar name="QT_LIB"> +<summary> +Default value is 'qt'. You may want to set this to 'qt-mt'. Note: If you set +this variable to None, the tool won't change the &cv-link-LIBS; variable. +</summary> +</cvar> + +<cvar name="QT_LIBPATH"> +<summary> +The path where the qt libraries are installed. +The default value is '&cv-link-QTDIR;/lib'. +Note: If you set this variable to None, +the tool won't change the &cv-link-LIBPATH; +construction variable. +</summary> +</cvar> + +<cvar name="QT_MOC"> +<summary> +Default value is '&cv-link-QT_BINPATH;/moc'. +</summary> +</cvar> + +<cvar name="QT_MOCCXXPREFIX"> +<summary> +Default value is ''. Prefix for moc output files, when source is a cxx file. +</summary> +</cvar> + +<cvar name="QT_MOCCXXSUFFIX"> +<summary> +Default value is '.moc'. Suffix for moc output files, when source is a cxx +file. +</summary> +</cvar> + +<cvar name="QT_MOCFROMCXXFLAGS"> +<summary> +Default value is '-i'. These flags are passed to moc, when moccing a +C++ file. +</summary> +</cvar> + +<cvar name="QT_MOCFROMCXXCOM"> +<summary> +Command to generate a moc file from a cpp file. +</summary> +</cvar> + +<cvar name="QT_MOCFROMCXXCOMSTR"> +<summary> +The string displayed when generating a moc file from a cpp file. +If this is not set, then &cv-link-QT_MOCFROMCXXCOM; (the command line) is displayed. +</summary> +</cvar> + +<cvar name="QT_MOCFROMHCOM"> +<summary> +Command to generate a moc file from a header. +</summary> +</cvar> + +<cvar name="QT_MOCFROMHCOMSTR"> +<summary> +The string displayed when generating a moc file from a cpp file. +If this is not set, then &cv-link-QT_MOCFROMHCOM; (the command line) is displayed. +</summary> +</cvar> + +<cvar name="QT_MOCFROMHFLAGS"> +<summary> +Default value is ''. These flags are passed to moc, when moccing a header +file. +</summary> +</cvar> + +<cvar name="QT_MOCHPREFIX"> +<summary> +Default value is 'moc_'. Prefix for moc output files, when source is a header. +</summary> +</cvar> + +<cvar name="QT_MOCHSUFFIX"> +<summary> +Default value is '&cv-link-CXXFILESUFFIX;'. Suffix for moc output files, when source is +a header. +</summary> +</cvar> + +<cvar name="QT_UIC"> +<summary> +Default value is '&cv-link-QT_BINPATH;/uic'. +</summary> +</cvar> + +<cvar name="QT_UICCOM"> +<summary> +Command to generate header files from .ui files. +</summary> +</cvar> + +<cvar name="QT_UICCOMSTR"> +<summary> +The string displayed when generating header files from .ui files. +If this is not set, then &cv-link-QT_UICCOM; (the command line) is displayed. +</summary> +</cvar> + +<cvar name="QT_UICDECLFLAGS"> +<summary> +Default value is ''. These flags are passed to uic, when creating a a h +file from a .ui file. +</summary> +</cvar> + +<cvar name="QT_UICDECLPREFIX"> +<summary> +Default value is ''. Prefix for uic generated header files. +</summary> +</cvar> + +<cvar name="QT_UICDECLSUFFIX"> +<summary> +Default value is '.h'. Suffix for uic generated header files. +</summary> +</cvar> + +<cvar name="QT_UICIMPLFLAGS"> +<summary> +Default value is ''. These flags are passed to uic, when creating a cxx +file from a .ui file. +</summary> +</cvar> + +<cvar name="QT_UICIMPLPREFIX"> +<summary> +Default value is 'uic_'. Prefix for uic generated implementation files. +</summary> +</cvar> + +<cvar name="QT_UICIMPLSUFFIX"> +<summary> +Default value is '&cv-link-CXXFILESUFFIX;'. Suffix for uic generated implementation +files. +</summary> +</cvar> + +<cvar name="QT_UISUFFIX"> +<summary> +Default value is '.ui'. Suffix of designer input files. +</summary> +</cvar> diff --git a/src/engine/SCons/Tool/rmic.py b/src/engine/SCons/Tool/rmic.py new file mode 100644 index 0000000..f41b38c --- /dev/null +++ b/src/engine/SCons/Tool/rmic.py @@ -0,0 +1,121 @@ +"""SCons.Tool.rmic + +Tool-specific initialization for rmic. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/rmic.py 4577 2009/12/27 19:44:43 scons" + +import os.path +import string + +import SCons.Action +import SCons.Builder +import SCons.Node.FS +import SCons.Util + +def emit_rmic_classes(target, source, env): + """Create and return lists of Java RMI stub and skeleton + class files to be created from a set of class files. + """ + class_suffix = env.get('JAVACLASSSUFFIX', '.class') + classdir = env.get('JAVACLASSDIR') + + if not classdir: + try: + s = source[0] + except IndexError: + classdir = '.' + else: + try: + classdir = s.attributes.java_classdir + except AttributeError: + classdir = '.' + classdir = env.Dir(classdir).rdir() + if str(classdir) == '.': + c_ = None + else: + c_ = str(classdir) + os.sep + + slist = [] + for src in source: + try: + classname = src.attributes.java_classname + except AttributeError: + classname = str(src) + if c_ and classname[:len(c_)] == c_: + classname = classname[len(c_):] + if class_suffix and classname[:-len(class_suffix)] == class_suffix: + classname = classname[-len(class_suffix):] + s = src.rfile() + s.attributes.java_classdir = classdir + s.attributes.java_classname = classname + slist.append(s) + + stub_suffixes = ['_Stub'] + if env.get('JAVAVERSION') == '1.4': + stub_suffixes.append('_Skel') + + tlist = [] + for s in source: + for suff in stub_suffixes: + fname = string.replace(s.attributes.java_classname, '.', os.sep) + \ + suff + class_suffix + t = target[0].File(fname) + t.attributes.java_lookupdir = target[0] + tlist.append(t) + + return tlist, source + +RMICAction = SCons.Action.Action('$RMICCOM', '$RMICCOMSTR') + +RMICBuilder = SCons.Builder.Builder(action = RMICAction, + emitter = emit_rmic_classes, + src_suffix = '$JAVACLASSSUFFIX', + target_factory = SCons.Node.FS.Dir, + source_factory = SCons.Node.FS.File) + +def generate(env): + """Add Builders and construction variables for rmic to an Environment.""" + env['BUILDERS']['RMIC'] = RMICBuilder + + env['RMIC'] = 'rmic' + env['RMICFLAGS'] = SCons.Util.CLVar('') + env['RMICCOM'] = '$RMIC $RMICFLAGS -d ${TARGET.attributes.java_lookupdir} -classpath ${SOURCE.attributes.java_classdir} ${SOURCES.attributes.java_classname}' + env['JAVACLASSSUFFIX'] = '.class' + +def exists(env): + return env.Detect('rmic') + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/rmic.xml b/src/engine/SCons/Tool/rmic.xml new file mode 100644 index 0000000..eacc6bf --- /dev/null +++ b/src/engine/SCons/Tool/rmic.xml @@ -0,0 +1,93 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="rmic"> +<summary> +Sets construction variables for the &rmic; utility. +</summary> +<sets> +RMIC +RMICFLAGS +RMICCOM +JAVACLASSSUFFIX +</sets> +<uses> +RMICCOMSTR +</uses> +</tool> + +<builder name="RMIC"> +<summary> +Builds stub and skeleton class files +for remote objects +from Java <filename>.class</filename> files. +The target is a directory +relative to which the stub +and skeleton class files will be written. +The source can be the names of <filename>.class</filename> files, +or the objects return from the +&b-Java; +builder method. + +If the construction variable +&cv-link-JAVACLASSDIR; +is set, either in the environment +or in the call to the +&b-RMIC; +builder method itself, +then the value of the variable +will be stripped from the +beginning of any <filename>.class </filename> +file names. + +<example> +classes = env.Java(target = 'classdir', source = 'src') +env.RMIC(target = 'outdir1', source = classes) + +env.RMIC(target = 'outdir2', + source = ['package/foo.class', 'package/bar.class']) + +env.RMIC(target = 'outdir3', + source = ['classes/foo.class', 'classes/bar.class'], + JAVACLASSDIR = 'classes') +</example> +</summary> +</builder> + +<cvar name="RMIC"> +<summary> +The Java RMI stub compiler. +</summary> +</cvar> + +<cvar name="RMICCOM"> +<summary> +The command line used to compile stub +and skeleton class files +from Java classes that contain RMI implementations. +Any options specified in the &cv-link-RMICFLAGS; construction variable +are included on this command line. +</summary> +</cvar> + +<cvar name="RMICCOMSTR"> +<summary> +The string displayed when compiling +stub and skeleton class files +from Java classes that contain RMI implementations. +If this is not set, then &cv-link-RMICCOM; (the command line) is displayed. + +<example> +env = Environment(RMICCOMSTR = "Generating stub/skeleton class files $TARGETS from $SOURCES") +</example> +</summary> +</cvar> + +<cvar name="RMICFLAGS"> +<summary> +General options passed to the Java RMI stub compiler. +</summary> +</cvar> diff --git a/src/engine/SCons/Tool/rpcgen.py b/src/engine/SCons/Tool/rpcgen.py new file mode 100644 index 0000000..86feac9 --- /dev/null +++ b/src/engine/SCons/Tool/rpcgen.py @@ -0,0 +1,70 @@ +"""SCons.Tool.rpcgen + +Tool-specific initialization for RPCGEN tools. + +Three normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/rpcgen.py 4577 2009/12/27 19:44:43 scons" + +from SCons.Builder import Builder +import SCons.Util + +cmd = "cd ${SOURCE.dir} && $RPCGEN -%s $RPCGENFLAGS %s -o ${TARGET.abspath} ${SOURCE.file}" + +rpcgen_client = cmd % ('l', '$RPCGENCLIENTFLAGS') +rpcgen_header = cmd % ('h', '$RPCGENHEADERFLAGS') +rpcgen_service = cmd % ('m', '$RPCGENSERVICEFLAGS') +rpcgen_xdr = cmd % ('c', '$RPCGENXDRFLAGS') + +def generate(env): + "Add RPCGEN Builders and construction variables for an Environment." + + client = Builder(action=rpcgen_client, suffix='_clnt.c', src_suffix='.x') + header = Builder(action=rpcgen_header, suffix='.h', src_suffix='.x') + service = Builder(action=rpcgen_service, suffix='_svc.c', src_suffix='.x') + xdr = Builder(action=rpcgen_xdr, suffix='_xdr.c', src_suffix='.x') + env.Append(BUILDERS={'RPCGenClient' : client, + 'RPCGenHeader' : header, + 'RPCGenService' : service, + 'RPCGenXDR' : xdr}) + env['RPCGEN'] = 'rpcgen' + env['RPCGENFLAGS'] = SCons.Util.CLVar('') + env['RPCGENCLIENTFLAGS'] = SCons.Util.CLVar('') + env['RPCGENHEADERFLAGS'] = SCons.Util.CLVar('') + env['RPCGENSERVICEFLAGS'] = SCons.Util.CLVar('') + env['RPCGENXDRFLAGS'] = SCons.Util.CLVar('') + +def exists(env): + return env.Detect('rpcgen') + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/rpcgen.xml b/src/engine/SCons/Tool/rpcgen.xml new file mode 100644 index 0000000..60848be --- /dev/null +++ b/src/engine/SCons/Tool/rpcgen.xml @@ -0,0 +1,137 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="rpcgen"> +<summary> +Sets construction variables for building with RPCGEN. +</summary> +<sets> +RPCGEN +RPCGENFLAGS +RPCGENCLIENTFLAGS +RPCGENHEADERFLAGS +RPCGENSERVICEFLAGS +RPCGENXDRFLAGS +</sets> +<uses> +</uses> +</tool> + +<builder name="RPCGenClient"> +<summary> +Generates an RPC client stub (<filename>_clnt.c</filename>) file +from a specified RPC (<filename>.x</filename>) source file. +Because rpcgen only builds output files +in the local directory, +the command will be executed +in the source file's directory by default. + +<example> +# Builds src/rpcif_clnt.c +env.RPCGenClient('src/rpcif.x') +</example> +</summary> +</builder> + +<builder name="RPCGenHeader"> +<summary> +Generates an RPC header (<filename>.h</filename>) file +from a specified RPC (<filename>.x</filename>) source file. +Because rpcgen only builds output files +in the local directory, +the command will be executed +in the source file's directory by default. + +<example> +# Builds src/rpcif.h +env.RPCGenHeader('src/rpcif.x') +</example> +</summary> +</builder> + +<builder name="RPCGenService"> +<summary> +Generates an RPC server-skeleton (<filename>_svc.c</filename>) file +from a specified RPC (<filename>.x</filename>) source file. +Because rpcgen only builds output files +in the local directory, +the command will be executed +in the source file's directory by default. + +<example> +# Builds src/rpcif_svc.c +env.RPCGenClient('src/rpcif.x') +</example> +</summary> +</builder> + +<builder name="RPCGenXDR"> +<summary> +Generates an RPC XDR routine (<filename>_xdr.c</filename>) file +from a specified RPC (<filename>.x</filename>) source file. +Because rpcgen only builds output files +in the local directory, +the command will be executed +in the source file's directory by default. + +<example> +# Builds src/rpcif_xdr.c +env.RPCGenClient('src/rpcif.x') +</example> +</summary> +</builder> + +<cvar name="RPCGEN"> +<summary> +The RPC protocol compiler. +</summary> +</cvar> + +<cvar name="RPCGENCLIENTFLAGS"> +<summary> +Options passed to the RPC protocol compiler +when generating client side stubs. +These are in addition to any flags specified in the +&cv-link-RPCGENFLAGS; +construction variable. +</summary> +</cvar> + +<cvar name="RPCGENFLAGS"> +<summary> +General options passed to the RPC protocol compiler. +</summary> +</cvar> + +<cvar name="RPCGENHEADERFLAGS"> +<summary> +Options passed to the RPC protocol compiler +when generating a header file. +These are in addition to any flags specified in the +&cv-link-RPCGENFLAGS; +construction variable. +</summary> +</cvar> + +<cvar name="RPCGENSERVICEFLAGS"> +<summary> +Options passed to the RPC protocol compiler +when generating server side stubs. +These are in addition to any flags specified in the +&cv-link-RPCGENFLAGS; +construction variable. +</summary> +</cvar> + +<cvar name="RPCGENXDRFLAGS"> +<summary> +Options passed to the RPC protocol compiler +when generating XDR routines. +These are in addition to any flags specified in the +&cv-link-RPCGENFLAGS; +construction variable. +</summary> +</cvar> diff --git a/src/engine/SCons/Tool/rpm.py b/src/engine/SCons/Tool/rpm.py new file mode 100644 index 0000000..19edd56 --- /dev/null +++ b/src/engine/SCons/Tool/rpm.py @@ -0,0 +1,132 @@ +"""SCons.Tool.rpm + +Tool-specific initialization for rpm. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +The rpm tool calls the rpmbuild command. The first and only argument should a +tar.gz consisting of the source file and a specfile. +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/rpm.py 4577 2009/12/27 19:44:43 scons" + +import os +import re +import shutil +import subprocess + +import SCons.Builder +import SCons.Node.FS +import SCons.Util +import SCons.Action +import SCons.Defaults + +def get_cmd(source, env): + tar_file_with_included_specfile = source + if SCons.Util.is_List(source): + tar_file_with_included_specfile = source[0] + return "%s %s %s"%(env['RPM'], env['RPMFLAGS'], + tar_file_with_included_specfile.abspath ) + +def build_rpm(target, source, env): + # create a temporary rpm build root. + tmpdir = os.path.join( os.path.dirname( target[0].abspath ), 'rpmtemp' ) + if os.path.exists(tmpdir): + shutil.rmtree(tmpdir) + + # now create the mandatory rpm directory structure. + for d in ['RPMS', 'SRPMS', 'SPECS', 'BUILD']: + os.makedirs( os.path.join( tmpdir, d ) ) + + # set the topdir as an rpmflag. + env.Prepend( RPMFLAGS = '--define \'_topdir %s\'' % tmpdir ) + + # now call rpmbuild to create the rpm package. + handle = subprocess.Popen(get_cmd(source, env), + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + shell=True) + output = handle.stdout.read() + status = handle.wait() + + if status: + raise SCons.Errors.BuildError( node=target[0], + errstr=output, + filename=str(target[0]) ) + else: + # XXX: assume that LC_ALL=c is set while running rpmbuild + output_files = re.compile( 'Wrote: (.*)' ).findall( output ) + + for output, input in zip( output_files, target ): + rpm_output = os.path.basename(output) + expected = os.path.basename(input.get_path()) + + assert expected == rpm_output, "got %s but expected %s" % (rpm_output, expected) + shutil.copy( output, input.abspath ) + + + # cleanup before leaving. + shutil.rmtree(tmpdir) + + return status + +def string_rpm(target, source, env): + try: + return env['RPMCOMSTR'] + except KeyError: + return get_cmd(source, env) + +rpmAction = SCons.Action.Action(build_rpm, string_rpm) + +RpmBuilder = SCons.Builder.Builder(action = SCons.Action.Action('$RPMCOM', '$RPMCOMSTR'), + source_scanner = SCons.Defaults.DirScanner, + suffix = '$RPMSUFFIX') + + + +def generate(env): + """Add Builders and construction variables for rpm to an Environment.""" + try: + bld = env['BUILDERS']['Rpm'] + except KeyError: + bld = RpmBuilder + env['BUILDERS']['Rpm'] = bld + + env.SetDefault(RPM = 'LC_ALL=c rpmbuild') + env.SetDefault(RPMFLAGS = SCons.Util.CLVar('-ta')) + env.SetDefault(RPMCOM = rpmAction) + env.SetDefault(RPMSUFFIX = '.rpm') + +def exists(env): + return env.Detect('rpmbuild') + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/sgiar.py b/src/engine/SCons/Tool/sgiar.py new file mode 100644 index 0000000..278b4c6 --- /dev/null +++ b/src/engine/SCons/Tool/sgiar.py @@ -0,0 +1,68 @@ +"""SCons.Tool.sgiar + +Tool-specific initialization for SGI ar (library archive). If CC +exists, static libraries should be built with it, so the prelinker has +a chance to resolve C++ template instantiations. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/sgiar.py 4577 2009/12/27 19:44:43 scons" + +import SCons.Defaults +import SCons.Tool +import SCons.Util + +def generate(env): + """Add Builders and construction variables for ar to an Environment.""" + SCons.Tool.createStaticLibBuilder(env) + + if env.Detect('CC'): + env['AR'] = 'CC' + env['ARFLAGS'] = SCons.Util.CLVar('-ar') + env['ARCOM'] = '$AR $ARFLAGS -o $TARGET $SOURCES' + else: + env['AR'] = 'ar' + env['ARFLAGS'] = SCons.Util.CLVar('r') + env['ARCOM'] = '$AR $ARFLAGS $TARGET $SOURCES' + + env['SHLINK'] = '$LINK' + env['SHLINKFLAGS'] = SCons.Util.CLVar('$LINKFLAGS -shared') + env['SHLINKCOM'] = '$SHLINK $SHLINKFLAGS -o $TARGET $SOURCES $_LIBDIRFLAGS $_LIBFLAGS' + env['LIBPREFIX'] = 'lib' + env['LIBSUFFIX'] = '.a' + +def exists(env): + return env.Detect('CC') or env.Detect('ar') + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/sgiar.xml b/src/engine/SCons/Tool/sgiar.xml new file mode 100644 index 0000000..38be862 --- /dev/null +++ b/src/engine/SCons/Tool/sgiar.xml @@ -0,0 +1,24 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="sgiar"> +<summary> +Sets construction variables for the SGI library archiver. +</summary> +<sets> +AR +ARFLAGS +ARCOMSTR +SHLINK +SHLINKFLAGS +LIBPREFIX +LIBSUFFIX +</sets> +<uses> +ARCOMSTR +SHLINKCOMSTR +</uses> +</tool> diff --git a/src/engine/SCons/Tool/sgic++.py b/src/engine/SCons/Tool/sgic++.py new file mode 100644 index 0000000..8aece3a --- /dev/null +++ b/src/engine/SCons/Tool/sgic++.py @@ -0,0 +1,58 @@ +"""SCons.Tool.sgic++ + +Tool-specific initialization for MIPSpro C++ on SGI. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/sgic++.py 4577 2009/12/27 19:44:43 scons" + +import SCons.Util + +cplusplus = __import__('c++', globals(), locals(), []) + +def generate(env): + """Add Builders and construction variables for SGI MIPS C++ to an Environment.""" + + cplusplus.generate(env) + + env['CXX'] = 'CC' + env['CXXFLAGS'] = SCons.Util.CLVar('-LANG:std') + env['SHCXX'] = '$CXX' + env['SHOBJSUFFIX'] = '.o' + env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1 + +def exists(env): + return env.Detect('CC') + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/sgic++.xml b/src/engine/SCons/Tool/sgic++.xml new file mode 100644 index 0000000..918988b --- /dev/null +++ b/src/engine/SCons/Tool/sgic++.xml @@ -0,0 +1,18 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="sgic++"> +<summary> +Sets construction variables for the SGI C++ compiler. +</summary> +<sets> +CXX +CXXFLAGS +SHCXX +SHOBJSUFFIX +<!--STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME--> +</sets> +</tool> diff --git a/src/engine/SCons/Tool/sgicc.py b/src/engine/SCons/Tool/sgicc.py new file mode 100644 index 0000000..ac311db --- /dev/null +++ b/src/engine/SCons/Tool/sgicc.py @@ -0,0 +1,53 @@ +"""SCons.Tool.sgicc + +Tool-specific initialization for MIPSPro cc on SGI. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/sgicc.py 4577 2009/12/27 19:44:43 scons" + +import cc + +def generate(env): + """Add Builders and construction variables for gcc to an Environment.""" + cc.generate(env) + + env['CXX'] = 'CC' + env['SHOBJSUFFIX'] = '.o' + env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1 + +def exists(env): + return env.Detect('cc') + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/sgicc.xml b/src/engine/SCons/Tool/sgicc.xml new file mode 100644 index 0000000..668ecd1 --- /dev/null +++ b/src/engine/SCons/Tool/sgicc.xml @@ -0,0 +1,18 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="sgicc"> +<summary> +Sets construction variables for the SGI C compiler. +</summary> +<sets> +CXX +SHOBJSUFFIX +<!--STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME--> +</sets> +<uses> +</uses> +</tool> diff --git a/src/engine/SCons/Tool/sgilink.py b/src/engine/SCons/Tool/sgilink.py new file mode 100644 index 0000000..3138782 --- /dev/null +++ b/src/engine/SCons/Tool/sgilink.py @@ -0,0 +1,63 @@ +"""SCons.Tool.sgilink + +Tool-specific initialization for the SGI MIPSPro linker on SGI. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/sgilink.py 4577 2009/12/27 19:44:43 scons" + +import SCons.Util + +import link + +linkers = ['CC', 'cc'] + +def generate(env): + """Add Builders and construction variables for MIPSPro to an Environment.""" + link.generate(env) + + env['LINK'] = env.Detect(linkers) or 'cc' + env['SHLINKFLAGS'] = SCons.Util.CLVar('$LINKFLAGS -shared') + + # __RPATH is set to $_RPATH in the platform specification if that + # platform supports it. + env.Append(LINKFLAGS=['$__RPATH']) + env['RPATHPREFIX'] = '-rpath ' + env['RPATHSUFFIX'] = '' + env['_RPATH'] = '${_concat(RPATHPREFIX, RPATH, RPATHSUFFIX, __env__)}' + +def exists(env): + return env.Detect(linkers) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/sgilink.xml b/src/engine/SCons/Tool/sgilink.xml new file mode 100644 index 0000000..2618133 --- /dev/null +++ b/src/engine/SCons/Tool/sgilink.xml @@ -0,0 +1,17 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="sgilink"> +<summary> +Sets construction variables for the SGI linker. +</summary> +<sets> +LINK +SHLINKFLAGS +RPATHPREFIX +RPATHSUFFIX +</sets> +</tool> diff --git a/src/engine/SCons/Tool/sunar.py b/src/engine/SCons/Tool/sunar.py new file mode 100644 index 0000000..afb1add --- /dev/null +++ b/src/engine/SCons/Tool/sunar.py @@ -0,0 +1,67 @@ +"""engine.SCons.Tool.sunar + +Tool-specific initialization for Solaris (Forte) ar (library archive). If CC +exists, static libraries should be built with it, so that template +instantians can be resolved. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/sunar.py 4577 2009/12/27 19:44:43 scons" + +import SCons.Defaults +import SCons.Tool +import SCons.Util + +def generate(env): + """Add Builders and construction variables for ar to an Environment.""" + SCons.Tool.createStaticLibBuilder(env) + + if env.Detect('CC'): + env['AR'] = 'CC' + env['ARFLAGS'] = SCons.Util.CLVar('-xar') + env['ARCOM'] = '$AR $ARFLAGS -o $TARGET $SOURCES' + else: + env['AR'] = 'ar' + env['ARFLAGS'] = SCons.Util.CLVar('r') + env['ARCOM'] = '$AR $ARFLAGS $TARGET $SOURCES' + + env['SHLINK'] = '$LINK' + env['SHLINKFLAGS'] = SCons.Util.CLVar('$LINKFLAGS -G') + env['SHLINKCOM'] = '$SHLINK $SHLINKFLAGS -o $TARGET $SOURCES $_LIBDIRFLAGS $_LIBFLAGS' + env['LIBPREFIX'] = 'lib' + env['LIBSUFFIX'] = '.a' + +def exists(env): + return env.Detect('CC') or env.Detect('ar') + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/sunar.xml b/src/engine/SCons/Tool/sunar.xml new file mode 100644 index 0000000..ab40f8f --- /dev/null +++ b/src/engine/SCons/Tool/sunar.xml @@ -0,0 +1,25 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="sunar"> +<summary> +Sets construction variables for the Sun library archiver. +</summary> +<sets> +AR +ARFLAGS +ARCOM +SHLINK +SHLINKFLAGS +SHLINKCOM +LIBPREFIX +LIBSUFFIX +</sets> +<uses> +ARCOMSTR +SHLINKCOMSTR +</uses> +</tool> diff --git a/src/engine/SCons/Tool/sunc++.py b/src/engine/SCons/Tool/sunc++.py new file mode 100644 index 0000000..dcd88ef --- /dev/null +++ b/src/engine/SCons/Tool/sunc++.py @@ -0,0 +1,142 @@ +"""SCons.Tool.sunc++ + +Tool-specific initialization for C++ on SunOS / Solaris. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/sunc++.py 4577 2009/12/27 19:44:43 scons" + +import SCons + +import os +import re +import subprocess + +cplusplus = __import__('c++', globals(), locals(), []) + +package_info = {} + +def get_package_info(package_name, pkginfo, pkgchk): + try: + return package_info[package_name] + except KeyError: + version = None + pathname = None + try: + sadm_contents = open('/var/sadm/install/contents', 'r').read() + except EnvironmentError: + pass + else: + sadm_re = re.compile('^(\S*/bin/CC)(=\S*)? %s$' % package_name, re.M) + sadm_match = sadm_re.search(sadm_contents) + if sadm_match: + pathname = os.path.dirname(sadm_match.group(1)) + + try: + p = subprocess.Popen([pkginfo, '-l', package_name], + stdout=subprocess.PIPE, + stderr=open('/dev/null', 'w')) + except EnvironmentError: + pass + else: + pkginfo_contents = p.communicate()[0] + version_re = re.compile('^ *VERSION:\s*(.*)$', re.M) + version_match = version_re.search(pkginfo_contents) + if version_match: + version = version_match.group(1) + + if pathname is None: + try: + p = subprocess.Popen([pkgchk, '-l', package_name], + stdout=subprocess.PIPE, + stderr=open('/dev/null', 'w')) + except EnvironmentError: + pass + else: + pkgchk_contents = p.communicate()[0] + pathname_re = re.compile(r'^Pathname:\s*(.*/bin/CC)$', re.M) + pathname_match = pathname_re.search(pkgchk_contents) + if pathname_match: + pathname = os.path.dirname(pathname_match.group(1)) + + package_info[package_name] = (pathname, version) + return package_info[package_name] + +# use the package installer tool lslpp to figure out where cppc and what +# version of it is installed +def get_cppc(env): + cxx = env.subst('$CXX') + if cxx: + cppcPath = os.path.dirname(cxx) + else: + cppcPath = None + + cppcVersion = None + + pkginfo = env.subst('$PKGINFO') + pkgchk = env.subst('$PKGCHK') + + for package in ['SPROcpl']: + path, version = get_package_info(package, pkginfo, pkgchk) + if path and version: + cppcPath, cppcVersion = path, version + break + + return (cppcPath, 'CC', 'CC', cppcVersion) + +def generate(env): + """Add Builders and construction variables for SunPRO C++.""" + path, cxx, shcxx, version = get_cppc(env) + if path: + cxx = os.path.join(path, cxx) + shcxx = os.path.join(path, shcxx) + + cplusplus.generate(env) + + env['CXX'] = cxx + env['SHCXX'] = shcxx + env['CXXVERSION'] = version + env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS -KPIC') + env['SHOBJPREFIX'] = 'so_' + env['SHOBJSUFFIX'] = '.o' + +def exists(env): + path, cxx, shcxx, version = get_cppc(env) + if path and cxx: + cppc = os.path.join(path, cxx) + if os.path.exists(cppc): + return cppc + return None + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/sunc++.xml b/src/engine/SCons/Tool/sunc++.xml new file mode 100644 index 0000000..e6c6dbf --- /dev/null +++ b/src/engine/SCons/Tool/sunc++.xml @@ -0,0 +1,19 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="sunc++"> +<summary> +Sets construction variables for the Sun C++ compiler. +</summary> +<sets> +CXX +SHCXX +CXXVERSION +SHCXXFLAGS +SHOBJPREFIX +SHOBJSUFFIX +</sets> +</tool> diff --git a/src/engine/SCons/Tool/suncc.py b/src/engine/SCons/Tool/suncc.py new file mode 100644 index 0000000..a37af82 --- /dev/null +++ b/src/engine/SCons/Tool/suncc.py @@ -0,0 +1,58 @@ +"""SCons.Tool.suncc + +Tool-specific initialization for Sun Solaris (Forte) CC and cc. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/suncc.py 4577 2009/12/27 19:44:43 scons" + +import SCons.Util + +import cc + +def generate(env): + """ + Add Builders and construction variables for Forte C and C++ compilers + to an Environment. + """ + cc.generate(env) + + env['CXX'] = 'CC' + env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS -KPIC') + env['SHOBJPREFIX'] = 'so_' + env['SHOBJSUFFIX'] = '.o' + +def exists(env): + return env.Detect('CC') + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/suncc.xml b/src/engine/SCons/Tool/suncc.xml new file mode 100644 index 0000000..0511180 --- /dev/null +++ b/src/engine/SCons/Tool/suncc.xml @@ -0,0 +1,17 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="suncc"> +<summary> +Sets construction variables for the Sun C compiler. +</summary> +<sets> +CXX +SHCCFLAGS +SHOBJPREFIX +SHOBJSUFFIX +</sets> +</tool> diff --git a/src/engine/SCons/Tool/sunf77.py b/src/engine/SCons/Tool/sunf77.py new file mode 100644 index 0000000..66b98ad --- /dev/null +++ b/src/engine/SCons/Tool/sunf77.py @@ -0,0 +1,63 @@ +"""SCons.Tool.sunf77 + +Tool-specific initialization for sunf77, the Sun Studio F77 compiler. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/sunf77.py 4577 2009/12/27 19:44:43 scons" + +import SCons.Util + +from FortranCommon import add_all_to_env + +compilers = ['sunf77', 'f77'] + +def generate(env): + """Add Builders and construction variables for sunf77 to an Environment.""" + add_all_to_env(env) + + fcomp = env.Detect(compilers) or 'f77' + env['FORTRAN'] = fcomp + env['F77'] = fcomp + + env['SHFORTRAN'] = '$FORTRAN' + env['SHF77'] = '$F77' + + env['SHFORTRANFLAGS'] = SCons.Util.CLVar('$FORTRANFLAGS -KPIC') + env['SHF77FLAGS'] = SCons.Util.CLVar('$F77FLAGS -KPIC') + +def exists(env): + return env.Detect(compilers) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/sunf77.xml b/src/engine/SCons/Tool/sunf77.xml new file mode 100644 index 0000000..0365bea --- /dev/null +++ b/src/engine/SCons/Tool/sunf77.xml @@ -0,0 +1,19 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="sunf77"> +<summary> +Set construction variables for the Sun &f77; Fortran compiler. +</summary> +<sets> +FORTRAN +F77 +SHFORTRAN +SHF77 +SHFORTRANFLAGS +SHF77FLAGS +</sets> +</tool> diff --git a/src/engine/SCons/Tool/sunf90.py b/src/engine/SCons/Tool/sunf90.py new file mode 100644 index 0000000..70fb2d1 --- /dev/null +++ b/src/engine/SCons/Tool/sunf90.py @@ -0,0 +1,64 @@ +"""SCons.Tool.sunf90 + +Tool-specific initialization for sunf90, the Sun Studio F90 compiler. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/sunf90.py 4577 2009/12/27 19:44:43 scons" + +import SCons.Util + +from FortranCommon import add_all_to_env + +compilers = ['sunf90', 'f90'] + +def generate(env): + """Add Builders and construction variables for sun f90 compiler to an + Environment.""" + add_all_to_env(env) + + fcomp = env.Detect(compilers) or 'f90' + env['FORTRAN'] = fcomp + env['F90'] = fcomp + + env['SHFORTRAN'] = '$FORTRAN' + env['SHF90'] = '$F90' + + env['SHFORTRANFLAGS'] = SCons.Util.CLVar('$FORTRANFLAGS -KPIC') + env['SHF90FLAGS'] = SCons.Util.CLVar('$F90FLAGS -KPIC') + +def exists(env): + return env.Detect(compilers) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/sunf90.xml b/src/engine/SCons/Tool/sunf90.xml new file mode 100644 index 0000000..f7a069a --- /dev/null +++ b/src/engine/SCons/Tool/sunf90.xml @@ -0,0 +1,19 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="sunf90"> +<summary> +Set construction variables for the Sun &f90; Fortran compiler. +</summary> +<sets> +FORTRAN +F90 +SHFORTRAN +SHF90 +SHFORTRANFLAGS +SHF90FLAGS +</sets> +</tool> diff --git a/src/engine/SCons/Tool/sunf95.py b/src/engine/SCons/Tool/sunf95.py new file mode 100644 index 0000000..16800e8 --- /dev/null +++ b/src/engine/SCons/Tool/sunf95.py @@ -0,0 +1,64 @@ +"""SCons.Tool.sunf95 + +Tool-specific initialization for sunf95, the Sun Studio F95 compiler. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/sunf95.py 4577 2009/12/27 19:44:43 scons" + +import SCons.Util + +from FortranCommon import add_all_to_env + +compilers = ['sunf95', 'f95'] + +def generate(env): + """Add Builders and construction variables for sunf95 to an + Environment.""" + add_all_to_env(env) + + fcomp = env.Detect(compilers) or 'f95' + env['FORTRAN'] = fcomp + env['F95'] = fcomp + + env['SHFORTRAN'] = '$FORTRAN' + env['SHF95'] = '$F95' + + env['SHFORTRANFLAGS'] = SCons.Util.CLVar('$FORTRANFLAGS -KPIC') + env['SHF95FLAGS'] = SCons.Util.CLVar('$F95FLAGS -KPIC') + +def exists(env): + return env.Detect(compilers) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/sunf95.xml b/src/engine/SCons/Tool/sunf95.xml new file mode 100644 index 0000000..0f1e005 --- /dev/null +++ b/src/engine/SCons/Tool/sunf95.xml @@ -0,0 +1,19 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="sunf95"> +<summary> +Set construction variables for the Sun &f95; Fortran compiler. +</summary> +<sets> +FORTRAN +F95 +SHFORTRAN +SHF95 +SHFORTRANFLAGS +SHF95FLAGS +</sets> +</tool> diff --git a/src/engine/SCons/Tool/sunlink.py b/src/engine/SCons/Tool/sunlink.py new file mode 100644 index 0000000..88abae9 --- /dev/null +++ b/src/engine/SCons/Tool/sunlink.py @@ -0,0 +1,77 @@ +"""SCons.Tool.sunlink + +Tool-specific initialization for the Sun Solaris (Forte) linker. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/sunlink.py 4577 2009/12/27 19:44:43 scons" + +import os +import os.path + +import SCons.Util + +import link + +ccLinker = None + +# search for the acc compiler and linker front end + +try: + dirs = os.listdir('/opt') +except (IOError, OSError): + # Not being able to read the directory because it doesn't exist + # (IOError) or isn't readable (OSError) is okay. + dirs = [] + +for d in dirs: + linker = '/opt/' + d + '/bin/CC' + if os.path.exists(linker): + ccLinker = linker + break + +def generate(env): + """Add Builders and construction variables for Forte to an Environment.""" + link.generate(env) + + env['SHLINKFLAGS'] = SCons.Util.CLVar('$LINKFLAGS -G') + + env.Append(LINKFLAGS=['$__RPATH']) + env['RPATHPREFIX'] = '-R' + env['RPATHSUFFIX'] = '' + env['_RPATH'] = '${_concat(RPATHPREFIX, RPATH, RPATHSUFFIX, __env__)}' + +def exists(env): + return ccLinker + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/sunlink.xml b/src/engine/SCons/Tool/sunlink.xml new file mode 100644 index 0000000..17b407f --- /dev/null +++ b/src/engine/SCons/Tool/sunlink.xml @@ -0,0 +1,16 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="sunlink"> +<summary> +Sets construction variables for the Sun linker. +</summary> +<sets> +SHLINKFLAGS +RPATHPREFIX +RPATHSUFFIX +</sets> +</tool> diff --git a/src/engine/SCons/Tool/swig.py b/src/engine/SCons/Tool/swig.py new file mode 100644 index 0000000..1dfbb40 --- /dev/null +++ b/src/engine/SCons/Tool/swig.py @@ -0,0 +1,186 @@ +"""SCons.Tool.swig + +Tool-specific initialization for swig. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/swig.py 4577 2009/12/27 19:44:43 scons" + +import os.path +import re +import string +import subprocess + +import SCons.Action +import SCons.Defaults +import SCons.Scanner +import SCons.Tool +import SCons.Util + +SwigAction = SCons.Action.Action('$SWIGCOM', '$SWIGCOMSTR') + +def swigSuffixEmitter(env, source): + if '-c++' in SCons.Util.CLVar(env.subst("$SWIGFLAGS", source=source)): + return '$SWIGCXXFILESUFFIX' + else: + return '$SWIGCFILESUFFIX' + +# Match '%module test', as well as '%module(directors="1") test' +# Also allow for test to be quoted (SWIG permits double quotes, but not single) +_reModule = re.compile(r'%module(\s*\(.*\))?\s+("?)(.+)\2') + +def _find_modules(src): + """Find all modules referenced by %module lines in `src`, a SWIG .i file. + Returns a list of all modules, and a flag set if SWIG directors have + been requested (SWIG will generate an additional header file in this + case.)""" + directors = 0 + mnames = [] + try: + matches = _reModule.findall(open(src).read()) + except IOError: + # If the file's not yet generated, guess the module name from the filename + matches = [] + mnames.append(os.path.splitext(src)[0]) + + for m in matches: + mnames.append(m[2]) + directors = directors or string.find(m[0], 'directors') >= 0 + return mnames, directors + +def _add_director_header_targets(target, env): + # Directors only work with C++ code, not C + suffix = env.subst(env['SWIGCXXFILESUFFIX']) + # For each file ending in SWIGCXXFILESUFFIX, add a new target director + # header by replacing the ending with SWIGDIRECTORSUFFIX. + for x in target[:]: + n = x.name + d = x.dir + if n[-len(suffix):] == suffix: + target.append(d.File(n[:-len(suffix)] + env['SWIGDIRECTORSUFFIX'])) + +def _swigEmitter(target, source, env): + swigflags = env.subst("$SWIGFLAGS", target=target, source=source) + flags = SCons.Util.CLVar(swigflags) + for src in source: + src = str(src.rfile()) + mnames = None + if "-python" in flags and "-noproxy" not in flags: + if mnames is None: + mnames, directors = _find_modules(src) + if directors: + _add_director_header_targets(target, env) + python_files = map(lambda m: m + ".py", mnames) + outdir = env.subst('$SWIGOUTDIR', target=target, source=source) + # .py files should be generated in SWIGOUTDIR if specified, + # otherwise in the same directory as the target + if outdir: + python_files = map(lambda j, o=outdir, e=env: + e.fs.File(os.path.join(o, j)), + python_files) + else: + python_files = map(lambda m, d=target[0].dir: + d.File(m), python_files) + target.extend(python_files) + if "-java" in flags: + if mnames is None: + mnames, directors = _find_modules(src) + if directors: + _add_director_header_targets(target, env) + java_files = map(lambda m: [m + ".java", m + "JNI.java"], mnames) + java_files = SCons.Util.flatten(java_files) + outdir = env.subst('$SWIGOUTDIR', target=target, source=source) + if outdir: + java_files = map(lambda j, o=outdir: os.path.join(o, j), java_files) + java_files = map(env.fs.File, java_files) + for jf in java_files: + t_from_s = lambda t, p, s, x: t.dir + SCons.Util.AddMethod(jf, t_from_s, 'target_from_source') + target.extend(java_files) + return (target, source) + +def _get_swig_version(env): + """Run the SWIG command line tool to get and return the version number""" + pipe = SCons.Action._subproc(env, [env['SWIG'], '-version'], + stdin = 'devnull', + stderr = 'devnull', + stdout = subprocess.PIPE) + if pipe.wait() != 0: return + + out = pipe.stdout.read() + match = re.search(r'SWIG Version\s+(\S+)$', out, re.MULTILINE) + if match: + return match.group(1) + +def generate(env): + """Add Builders and construction variables for swig to an Environment.""" + c_file, cxx_file = SCons.Tool.createCFileBuilders(env) + + c_file.suffix['.i'] = swigSuffixEmitter + cxx_file.suffix['.i'] = swigSuffixEmitter + + c_file.add_action('.i', SwigAction) + c_file.add_emitter('.i', _swigEmitter) + cxx_file.add_action('.i', SwigAction) + cxx_file.add_emitter('.i', _swigEmitter) + + java_file = SCons.Tool.CreateJavaFileBuilder(env) + + java_file.suffix['.i'] = swigSuffixEmitter + + java_file.add_action('.i', SwigAction) + java_file.add_emitter('.i', _swigEmitter) + + env['SWIG'] = 'swig' + env['SWIGVERSION'] = _get_swig_version(env) + env['SWIGFLAGS'] = SCons.Util.CLVar('') + env['SWIGDIRECTORSUFFIX'] = '_wrap.h' + env['SWIGCFILESUFFIX'] = '_wrap$CFILESUFFIX' + env['SWIGCXXFILESUFFIX'] = '_wrap$CXXFILESUFFIX' + env['_SWIGOUTDIR'] = r'${"-outdir \"%s\"" % SWIGOUTDIR}' + env['SWIGPATH'] = [] + env['SWIGINCPREFIX'] = '-I' + env['SWIGINCSUFFIX'] = '' + env['_SWIGINCFLAGS'] = '$( ${_concat(SWIGINCPREFIX, SWIGPATH, SWIGINCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)' + env['SWIGCOM'] = '$SWIG -o $TARGET ${_SWIGOUTDIR} ${_SWIGINCFLAGS} $SWIGFLAGS $SOURCES' + + expr = '^[ \t]*%[ \t]*(?:include|import|extern)[ \t]*(<|"?)([^>\s"]+)(?:>|"?)' + scanner = SCons.Scanner.ClassicCPP("SWIGScan", ".i", "SWIGPATH", expr) + + env.Append(SCANNERS = scanner) + +def exists(env): + return env.Detect(['swig']) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/swig.xml b/src/engine/SCons/Tool/swig.xml new file mode 100644 index 0000000..2716a33 --- /dev/null +++ b/src/engine/SCons/Tool/swig.xml @@ -0,0 +1,212 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="swig"> +<summary> +Sets construction variables for the SWIG interface generator. +</summary> +<sets> +SWIG +SWIGFLAGS +SWIGDIRECTORSUFFIX +SWIGCFILESUFFIX +SWIGCXXFILESUFFIX +_SWIGINCFLAGS +SWIGINCPREFIX +SWIGINCSUFFIX +SWIGCOM +SWIGPATH +SWIGVERSION +</sets> +<uses> +SWIGCOMSTR +</uses> +</tool> + +<cvar name="SWIG"> +<summary> +The scripting language wrapper and interface generator. +</summary> +</cvar> + +<cvar name="SWIGCFILESUFFIX"> +<summary> +The suffix that will be used for intermediate C +source files generated by +the scripting language wrapper and interface generator. +The default value is +<filename>_wrap</filename>&cv-link-CFILESUFFIX;. +By default, this value is used whenever the +<option>-c++</option> +option is +<emphasis>not</emphasis> +specified as part of the +&cv-link-SWIGFLAGS; +construction variable. +</summary> +</cvar> + +<cvar name="SWIGDIRECTORSUFFIX"> +<summary> +The suffix that will be used for intermediate C++ header +files generated by the scripting language wrapper and interface generator. +These are only generated for C++ code when the SWIG 'directors' feature is +turned on. +The default value is +<filename>_wrap.h</filename>. +</summary> +</cvar> + +<cvar name="SWIGCOM"> +<summary> +The command line used to call +the scripting language wrapper and interface generator. +</summary> +</cvar> + +<cvar name="SWIGCOMSTR"> +<summary> +The string displayed when calling +the scripting language wrapper and interface generator. +If this is not set, then &cv-link-SWIGCOM; (the command line) is displayed. +</summary> +</cvar> + +<cvar name="SWIGCXXFILESUFFIX"> +<summary> +The suffix that will be used for intermediate C++ +source files generated by +the scripting language wrapper and interface generator. +The default value is +<filename>_wrap</filename>&cv-link-CFILESUFFIX;. +By default, this value is used whenever the +<filename>-c++</filename> +option is specified as part of the +&cv-link-SWIGFLAGS; +construction variable. +</summary> +</cvar> + +<cvar name="SWIGFLAGS"> +<summary> +General options passed to +the scripting language wrapper and interface generator. +This is where you should set +<option>-python</option>, +<option>-perl5</option>, +<option>-tcl</option>, +or whatever other options you want to specify to SWIG. +If you set the +<option>-c++</option> +option in this variable, +&scons; +will, by default, +generate a C++ intermediate source file +with the extension that is specified as the +&cv-link-CXXFILESUFFIX; +variable. +</summary> +</cvar> + +<cvar name="_SWIGINCFLAGS"> +<summary> +An automatically-generated construction variable +containing the SWIG command-line options +for specifying directories to be searched for included files. +The value of &cv-_SWIGINCFLAGS; is created +by appending &cv-SWIGINCPREFIX; and &cv-SWIGINCSUFFIX; +to the beginning and end +of each directory in &cv-SWIGPATH;. +</summary> +</cvar> + +<cvar name="SWIGINCPREFIX"> +<summary> +The prefix used to specify an include directory on the SWIG command line. +This will be appended to the beginning of each directory +in the &cv-SWIGPATH; construction variable +when the &cv-_SWIGINCFLAGS; variable is automatically generated. +</summary> +</cvar> + +<cvar name="SWIGINCSUFFIX"> +<summary> +The suffix used to specify an include directory on the SWIG command line. +This will be appended to the end of each directory +in the &cv-SWIGPATH; construction variable +when the &cv-_SWIGINCFLAGS; variable is automatically generated. +</summary> +</cvar> + +<cvar name="SWIGOUTDIR"> +<summary> +Specifies the output directory in which +the scripting language wrapper and interface generator +should place generated language-specific files. +This will be used by SCons to identify +the files that will be generated by the &swig; call, +and translated into the +<literal>swig -outdir</literal> option on the command line. +</summary> +</cvar> + +<cvar name="SWIGPATH"> +<summary> +The list of directories that the scripting language wrapper +and interface generate will search for included files. +The SWIG implicit dependency scanner will search these +directories for include files. +The default is to use the same path +specified as &cv-CPPPATH;. + +Don't explicitly put include directory +arguments in SWIGFLAGS; +the result will be non-portable +and the directories will not be searched by the dependency scanner. +Note: directory names in SWIGPATH will be looked-up relative to the SConscript +directory when they are used in a command. +To force +&scons; +to look-up a directory relative to the root of the source tree use #: + +<example> +env = Environment(SWIGPATH='#/include') +</example> + +The directory look-up can also be forced using the +&Dir;() +function: + +<example> +include = Dir('include') +env = Environment(SWIGPATH=include) +</example> + +The directory list will be added to command lines +through the automatically-generated +&cv-_SWIGINCFLAGS; +construction variable, +which is constructed by +appending the values of the +&cv-SWIGINCPREFIX; and &cv-SWIGINCSUFFIX; +construction variables +to the beginning and end +of each directory in &cv-SWIGPATH;. +Any command lines you define that need +the SWIGPATH directory list should +include &cv-_SWIGINCFLAGS;: + +<example> +env = Environment(SWIGCOM="my_swig -o $TARGET $_SWIGINCFLAGS $SORUCES") +</example> +</summary> +</cvar> + +<cvar name="SWIGVERSION"> +<summary> +The version number of the SWIG tool. +</summary> +</cvar> diff --git a/src/engine/SCons/Tool/tar.py b/src/engine/SCons/Tool/tar.py new file mode 100644 index 0000000..7d74004 --- /dev/null +++ b/src/engine/SCons/Tool/tar.py @@ -0,0 +1,73 @@ +"""SCons.Tool.tar + +Tool-specific initialization for tar. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/tar.py 4577 2009/12/27 19:44:43 scons" + +import SCons.Action +import SCons.Builder +import SCons.Defaults +import SCons.Node.FS +import SCons.Util + +tars = ['tar', 'gtar'] + +TarAction = SCons.Action.Action('$TARCOM', '$TARCOMSTR') + +TarBuilder = SCons.Builder.Builder(action = TarAction, + source_factory = SCons.Node.FS.Entry, + source_scanner = SCons.Defaults.DirScanner, + suffix = '$TARSUFFIX', + multi = 1) + + +def generate(env): + """Add Builders and construction variables for tar to an Environment.""" + try: + bld = env['BUILDERS']['Tar'] + except KeyError: + bld = TarBuilder + env['BUILDERS']['Tar'] = bld + + env['TAR'] = env.Detect(tars) or 'gtar' + env['TARFLAGS'] = SCons.Util.CLVar('-c') + env['TARCOM'] = '$TAR $TARFLAGS -f $TARGET $SOURCES' + env['TARSUFFIX'] = '.tar' + +def exists(env): + return env.Detect(tars) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/tar.xml b/src/engine/SCons/Tool/tar.xml new file mode 100644 index 0000000..4e6926a --- /dev/null +++ b/src/engine/SCons/Tool/tar.xml @@ -0,0 +1,95 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="tar"> +<summary> +Sets construction variables for the &tar; archiver. +</summary> +<sets> +TAR +TARFLAGS +TARCOM +TARSUFFIX +</sets> +<uses> +TARCOMSTR +</uses> +</tool> + +<builder name="Tar"> +<summary> +Builds a tar archive of the specified files +and/or directories. +Unlike most builder methods, +the +&b-Tar; +builder method may be called multiple times +for a given target; +each additional call +adds to the list of entries +that will be built into the archive. +Any source directories will +be scanned for changes to +any on-disk files, +regardless of whether or not +&scons; +knows about them from other Builder or function calls. + +<example> +env.Tar('src.tar', 'src') + +# Create the stuff.tar file. +env.Tar('stuff', ['subdir1', 'subdir2']) +# Also add "another" to the stuff.tar file. +env.Tar('stuff', 'another') + +# Set TARFLAGS to create a gzip-filtered archive. +env = Environment(TARFLAGS = '-c -z') +env.Tar('foo.tar.gz', 'foo') + +# Also set the suffix to .tgz. +env = Environment(TARFLAGS = '-c -z', + TARSUFFIX = '.tgz') +env.Tar('foo') +</example> +</summary> +</builder> + +<cvar name="TAR"> +<summary> +The tar archiver. +</summary> +</cvar> + +<cvar name="TARCOM"> +<summary> +The command line used to call the tar archiver. +</summary> +</cvar> + +<cvar name="TARCOMSTR"> +<summary> +The string displayed when archiving files +using the tar archiver. +If this is not set, then &cv-link-TARCOM; (the command line) is displayed. + +<example> +env = Environment(TARCOMSTR = "Archiving $TARGET") +</example> +</summary> +</cvar> + +<cvar name="TARFLAGS"> +<summary> +General options passed to the tar archiver. +</summary> +</cvar> + +<cvar name="TARSUFFIX"> +<summary> +The suffix used for tar file names. +</summary> +</cvar> diff --git a/src/engine/SCons/Tool/tex.py b/src/engine/SCons/Tool/tex.py new file mode 100644 index 0000000..f12675f --- /dev/null +++ b/src/engine/SCons/Tool/tex.py @@ -0,0 +1,792 @@ +"""SCons.Tool.tex + +Tool-specific initialization for TeX. +Generates .dvi files from .tex files + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/tex.py 4577 2009/12/27 19:44:43 scons" + +import os.path +import re +import string +import shutil + +import SCons.Action +import SCons.Node +import SCons.Node.FS +import SCons.Util +import SCons.Scanner.LaTeX + +Verbose = False + +must_rerun_latex = True + +# these are files that just need to be checked for changes and then rerun latex +check_suffixes = ['.toc', '.lof', '.lot', '.out', '.nav', '.snm'] + +# these are files that require bibtex or makeindex to be run when they change +all_suffixes = check_suffixes + ['.bbl', '.idx', '.nlo', '.glo', '.acn'] + +# +# regular expressions used to search for Latex features +# or outputs that require rerunning latex +# +# search for all .aux files opened by latex (recorded in the .fls file) +openout_aux_re = re.compile(r"INPUT *(.*\.aux)") + +#printindex_re = re.compile(r"^[^%]*\\printindex", re.MULTILINE) +#printnomenclature_re = re.compile(r"^[^%]*\\printnomenclature", re.MULTILINE) +#printglossary_re = re.compile(r"^[^%]*\\printglossary", re.MULTILINE) + +# search to find rerun warnings +warning_rerun_str = '(^LaTeX Warning:.*Rerun)|(^Package \w+ Warning:.*Rerun)' +warning_rerun_re = re.compile(warning_rerun_str, re.MULTILINE) + +# search to find citation rerun warnings +rerun_citations_str = "^LaTeX Warning:.*\n.*Rerun to get citations correct" +rerun_citations_re = re.compile(rerun_citations_str, re.MULTILINE) + +# search to find undefined references or citations warnings +undefined_references_str = '(^LaTeX Warning:.*undefined references)|(^Package \w+ Warning:.*undefined citations)' +undefined_references_re = re.compile(undefined_references_str, re.MULTILINE) + +# used by the emitter +auxfile_re = re.compile(r".", re.MULTILINE) +tableofcontents_re = re.compile(r"^[^%\n]*\\tableofcontents", re.MULTILINE) +makeindex_re = re.compile(r"^[^%\n]*\\makeindex", re.MULTILINE) +bibliography_re = re.compile(r"^[^%\n]*\\bibliography", re.MULTILINE) +listoffigures_re = re.compile(r"^[^%\n]*\\listoffigures", re.MULTILINE) +listoftables_re = re.compile(r"^[^%\n]*\\listoftables", re.MULTILINE) +hyperref_re = re.compile(r"^[^%\n]*\\usepackage.*\{hyperref\}", re.MULTILINE) +makenomenclature_re = re.compile(r"^[^%\n]*\\makenomenclature", re.MULTILINE) +makeglossary_re = re.compile(r"^[^%\n]*\\makeglossary", re.MULTILINE) +makeglossaries_re = re.compile(r"^[^%\n]*\\makeglossaries", re.MULTILINE) +makeacronyms_re = re.compile(r"^[^%\n]*\\makeglossaries", re.MULTILINE) +beamer_re = re.compile(r"^[^%\n]*\\documentclass\{beamer\}", re.MULTILINE) + +# search to find all files included by Latex +include_re = re.compile(r'^[^%\n]*\\(?:include|input){([^}]*)}', re.MULTILINE) + +# search to find all graphics files included by Latex +includegraphics_re = re.compile(r'^[^%\n]*\\(?:includegraphics(?:\[[^\]]+\])?){([^}]*)}', re.MULTILINE) + +# search to find all files opened by Latex (recorded in .log file) +openout_re = re.compile(r"OUTPUT *(.*)") + +# list of graphics file extensions for TeX and LaTeX +TexGraphics = SCons.Scanner.LaTeX.TexGraphics +LatexGraphics = SCons.Scanner.LaTeX.LatexGraphics + +# An Action sufficient to build any generic tex file. +TeXAction = None + +# An action to build a latex file. This action might be needed more +# than once if we are dealing with labels and bibtex. +LaTeXAction = None + +# An action to run BibTeX on a file. +BibTeXAction = None + +# An action to run MakeIndex on a file. +MakeIndexAction = None + +# An action to run MakeIndex (for nomencl) on a file. +MakeNclAction = None + +# An action to run MakeIndex (for glossary) on a file. +MakeGlossaryAction = None + +# An action to run MakeIndex (for acronyms) on a file. +MakeAcronymsAction = None + +# Used as a return value of modify_env_var if the variable is not set. +_null = SCons.Scanner.LaTeX._null + +modify_env_var = SCons.Scanner.LaTeX.modify_env_var + +def FindFile(name,suffixes,paths,env,requireExt=False): + if requireExt: + name,ext = SCons.Util.splitext(name) + # if the user gave an extension use it. + if ext: + name = name + ext + if Verbose: + print " searching for '%s' with extensions: " % name,suffixes + + for path in paths: + testName = os.path.join(path,name) + if Verbose: + print " look for '%s'" % testName + if os.path.exists(testName): + if Verbose: + print " found '%s'" % testName + return env.fs.File(testName) + else: + name_ext = SCons.Util.splitext(testName)[1] + if name_ext: + continue + + # if no suffix try adding those passed in + for suffix in suffixes: + testNameExt = testName + suffix + if Verbose: + print " look for '%s'" % testNameExt + + if os.path.exists(testNameExt): + if Verbose: + print " found '%s'" % testNameExt + return env.fs.File(testNameExt) + if Verbose: + print " did not find '%s'" % name + return None + +def InternalLaTeXAuxAction(XXXLaTeXAction, target = None, source= None, env=None): + """A builder for LaTeX files that checks the output in the aux file + and decides how many times to use LaTeXAction, and BibTeXAction.""" + + global must_rerun_latex + + # This routine is called with two actions. In this file for DVI builds + # with LaTeXAction and from the pdflatex.py with PDFLaTeXAction + # set this up now for the case where the user requests a different extension + # for the target filename + if (XXXLaTeXAction == LaTeXAction): + callerSuffix = ".dvi" + else: + callerSuffix = env['PDFSUFFIX'] + + basename = SCons.Util.splitext(str(source[0]))[0] + basedir = os.path.split(str(source[0]))[0] + basefile = os.path.split(str(basename))[1] + abspath = os.path.abspath(basedir) + + targetext = os.path.splitext(str(target[0]))[1] + targetdir = os.path.split(str(target[0]))[0] + + saved_env = {} + for var in SCons.Scanner.LaTeX.LaTeX.env_variables: + saved_env[var] = modify_env_var(env, var, abspath) + + # Create base file names with the target directory since the auxiliary files + # will be made there. That's because the *COM variables have the cd + # command in the prolog. We check + # for the existence of files before opening them--even ones like the + # aux file that TeX always creates--to make it possible to write tests + # with stubs that don't necessarily generate all of the same files. + + targetbase = os.path.join(targetdir, basefile) + + # if there is a \makeindex there will be a .idx and thus + # we have to run makeindex at least once to keep the build + # happy even if there is no index. + # Same for glossaries and nomenclature + src_content = source[0].get_text_contents() + run_makeindex = makeindex_re.search(src_content) and not os.path.exists(targetbase + '.idx') + run_nomenclature = makenomenclature_re.search(src_content) and not os.path.exists(targetbase + '.nlo') + run_glossary = makeglossary_re.search(src_content) and not os.path.exists(targetbase + '.glo') + run_glossaries = makeglossaries_re.search(src_content) and not os.path.exists(targetbase + '.glo') + run_acronyms = makeacronyms_re.search(src_content) and not os.path.exists(targetbase + '.acn') + + saved_hashes = {} + suffix_nodes = {} + + for suffix in all_suffixes: + theNode = env.fs.File(targetbase + suffix) + suffix_nodes[suffix] = theNode + saved_hashes[suffix] = theNode.get_csig() + + if Verbose: + print "hashes: ",saved_hashes + + must_rerun_latex = True + + # + # routine to update MD5 hash and compare + # + # TODO(1.5): nested scopes + def check_MD5(filenode, suffix, saved_hashes=saved_hashes, targetbase=targetbase): + global must_rerun_latex + # two calls to clear old csig + filenode.clear_memoized_values() + filenode.ninfo = filenode.new_ninfo() + new_md5 = filenode.get_csig() + + if saved_hashes[suffix] == new_md5: + if Verbose: + print "file %s not changed" % (targetbase+suffix) + return False # unchanged + saved_hashes[suffix] = new_md5 + must_rerun_latex = True + if Verbose: + print "file %s changed, rerunning Latex, new hash = " % (targetbase+suffix), new_md5 + return True # changed + + # generate the file name that latex will generate + resultfilename = targetbase + callerSuffix + + count = 0 + + while (must_rerun_latex and count < int(env.subst('$LATEXRETRIES'))) : + result = XXXLaTeXAction(target, source, env) + if result != 0: + return result + + count = count + 1 + + must_rerun_latex = False + # Decide if various things need to be run, or run again. + + # Read the log file to find warnings/errors + logfilename = targetbase + '.log' + logContent = '' + if os.path.exists(logfilename): + logContent = open(logfilename, "rb").read() + + + # Read the fls file to find all .aux files + flsfilename = targetbase + '.fls' + flsContent = '' + auxfiles = [] + if os.path.exists(flsfilename): + flsContent = open(flsfilename, "rb").read() + auxfiles = openout_aux_re.findall(flsContent) + if Verbose: + print "auxfiles ",auxfiles + + # Now decide if bibtex will need to be run. + # The information that bibtex reads from the .aux file is + # pass-independent. If we find (below) that the .bbl file is unchanged, + # then the last latex saw a correct bibliography. + # Therefore only do this on the first pass + if count == 1: + for auxfilename in auxfiles: + target_aux = os.path.join(targetdir, auxfilename) + if os.path.exists(target_aux): + content = open(target_aux, "rb").read() + if string.find(content, "bibdata") != -1: + if Verbose: + print "Need to run bibtex" + bibfile = env.fs.File(targetbase) + result = BibTeXAction(bibfile, bibfile, env) + if result != 0: + print env['BIBTEX']," returned an error, check the blg file" + return result + must_rerun_latex = check_MD5(suffix_nodes['.bbl'],'.bbl') + break + + # Now decide if latex will need to be run again due to index. + if check_MD5(suffix_nodes['.idx'],'.idx') or (count == 1 and run_makeindex): + # We must run makeindex + if Verbose: + print "Need to run makeindex" + idxfile = suffix_nodes['.idx'] + result = MakeIndexAction(idxfile, idxfile, env) + if result != 0: + print env['MAKEINDEX']," returned an error, check the ilg file" + return result + + # TO-DO: need to add a way for the user to extend this list for whatever + # auxiliary files they create in other (or their own) packages + # Harder is case is where an action needs to be called -- that should be rare (I hope?) + + for index in check_suffixes: + check_MD5(suffix_nodes[index],index) + + # Now decide if latex will need to be run again due to nomenclature. + if check_MD5(suffix_nodes['.nlo'],'.nlo') or (count == 1 and run_nomenclature): + # We must run makeindex + if Verbose: + print "Need to run makeindex for nomenclature" + nclfile = suffix_nodes['.nlo'] + result = MakeNclAction(nclfile, nclfile, env) + if result != 0: + print env['MAKENCL']," (nomenclature) returned an error, check the nlg file" + #return result + + # Now decide if latex will need to be run again due to glossary. + if check_MD5(suffix_nodes['.glo'],'.glo') or (count == 1 and run_glossaries) or (count == 1 and run_glossary): + # We must run makeindex + if Verbose: + print "Need to run makeindex for glossary" + glofile = suffix_nodes['.glo'] + result = MakeGlossaryAction(glofile, glofile, env) + if result != 0: + print env['MAKEGLOSSARY']," (glossary) returned an error, check the glg file" + #return result + + # Now decide if latex will need to be run again due to acronyms. + if check_MD5(suffix_nodes['.acn'],'.acn') or (count == 1 and run_acronyms): + # We must run makeindex + if Verbose: + print "Need to run makeindex for acronyms" + acrfile = suffix_nodes['.acn'] + result = MakeAcronymsAction(acrfile, acrfile, env) + if result != 0: + print env['MAKEACRONYMS']," (acronymns) returned an error, check the alg file" + return result + + # Now decide if latex needs to be run yet again to resolve warnings. + if warning_rerun_re.search(logContent): + must_rerun_latex = True + if Verbose: + print "rerun Latex due to latex or package rerun warning" + + if rerun_citations_re.search(logContent): + must_rerun_latex = True + if Verbose: + print "rerun Latex due to 'Rerun to get citations correct' warning" + + if undefined_references_re.search(logContent): + must_rerun_latex = True + if Verbose: + print "rerun Latex due to undefined references or citations" + + if (count >= int(env.subst('$LATEXRETRIES')) and must_rerun_latex): + print "reached max number of retries on Latex ,",int(env.subst('$LATEXRETRIES')) +# end of while loop + + # rename Latex's output to what the target name is + if not (str(target[0]) == resultfilename and os.path.exists(resultfilename)): + if os.path.exists(resultfilename): + print "move %s to %s" % (resultfilename, str(target[0]), ) + shutil.move(resultfilename,str(target[0])) + + # Original comment (when TEXPICTS was not restored): + # The TEXPICTS enviroment variable is needed by a dvi -> pdf step + # later on Mac OSX so leave it + # + # It is also used when searching for pictures (implicit dependencies). + # Why not set the variable again in the respective builder instead + # of leaving local modifications in the environment? What if multiple + # latex builds in different directories need different TEXPICTS? + for var in SCons.Scanner.LaTeX.LaTeX.env_variables: + if var == 'TEXPICTS': + continue + if saved_env[var] is _null: + try: + del env['ENV'][var] + except KeyError: + pass # was never set + else: + env['ENV'][var] = saved_env[var] + + return result + +def LaTeXAuxAction(target = None, source= None, env=None): + result = InternalLaTeXAuxAction( LaTeXAction, target, source, env ) + return result + +LaTeX_re = re.compile("\\\\document(style|class)") + +def is_LaTeX(flist,env,abspath): + """Scan a file list to decide if it's TeX- or LaTeX-flavored.""" + + # We need to scan files that are included in case the + # \documentclass command is in them. + + # get path list from both env['TEXINPUTS'] and env['ENV']['TEXINPUTS'] + savedpath = modify_env_var(env, 'TEXINPUTS', abspath) + paths = env['ENV']['TEXINPUTS'] + if SCons.Util.is_List(paths): + pass + else: + # Split at os.pathsep to convert into absolute path + # TODO(1.5) + #paths = paths.split(os.pathsep) + paths = string.split(paths, os.pathsep) + + # now that we have the path list restore the env + if savedpath is _null: + try: + del env['ENV']['TEXINPUTS'] + except KeyError: + pass # was never set + else: + env['ENV']['TEXINPUTS'] = savedpath + if Verbose: + print "is_LaTeX search path ",paths + print "files to search :",flist + + # Now that we have the search path and file list, check each one + for f in flist: + if Verbose: + print " checking for Latex source ",str(f) + + content = f.get_text_contents() + if LaTeX_re.search(content): + if Verbose: + print "file %s is a LaTeX file" % str(f) + return 1 + if Verbose: + print "file %s is not a LaTeX file" % str(f) + + # now find included files + inc_files = [ ] + inc_files.extend( include_re.findall(content) ) + if Verbose: + print "files included by '%s': "%str(f),inc_files + # inc_files is list of file names as given. need to find them + # using TEXINPUTS paths. + + # search the included files + for src in inc_files: + srcNode = FindFile(src,['.tex','.ltx','.latex'],paths,env,requireExt=False) + # make this a list since is_LaTeX takes a list. + fileList = [srcNode,] + if Verbose: + print "FindFile found ",srcNode + if srcNode is not None: + file_test = is_LaTeX(fileList, env, abspath) + + # return on first file that finds latex is needed. + if file_test: + return file_test + + if Verbose: + print " done scanning ",str(f) + + return 0 + +def TeXLaTeXFunction(target = None, source= None, env=None): + """A builder for TeX and LaTeX that scans the source file to + decide the "flavor" of the source and then executes the appropriate + program.""" + + # find these paths for use in is_LaTeX to search for included files + basedir = os.path.split(str(source[0]))[0] + abspath = os.path.abspath(basedir) + + if is_LaTeX(source,env,abspath): + result = LaTeXAuxAction(target,source,env) + if result != 0: + print env['LATEX']," returned an error, check the log file" + else: + result = TeXAction(target,source,env) + if result != 0: + print env['TEX']," returned an error, check the log file" + return result + +def TeXLaTeXStrFunction(target = None, source= None, env=None): + """A strfunction for TeX and LaTeX that scans the source file to + decide the "flavor" of the source and then returns the appropriate + command string.""" + if env.GetOption("no_exec"): + + # find these paths for use in is_LaTeX to search for included files + basedir = os.path.split(str(source[0]))[0] + abspath = os.path.abspath(basedir) + + if is_LaTeX(source,env,abspath): + result = env.subst('$LATEXCOM',0,target,source)+" ..." + else: + result = env.subst("$TEXCOM",0,target,source)+" ..." + else: + result = '' + return result + +def tex_eps_emitter(target, source, env): + """An emitter for TeX and LaTeX sources when + executing tex or latex. It will accept .ps and .eps + graphics files + """ + (target, source) = tex_emitter_core(target, source, env, TexGraphics) + + return (target, source) + +def tex_pdf_emitter(target, source, env): + """An emitter for TeX and LaTeX sources when + executing pdftex or pdflatex. It will accept graphics + files of types .pdf, .jpg, .png, .gif, and .tif + """ + (target, source) = tex_emitter_core(target, source, env, LatexGraphics) + + return (target, source) + +def ScanFiles(theFile, target, paths, file_tests, file_tests_search, env, graphics_extensions, targetdir): + """ For theFile (a Node) update any file_tests and search for graphics files + then find all included files and call ScanFiles recursively for each of them""" + + content = theFile.get_text_contents() + if Verbose: + print " scanning ",str(theFile) + + for i in range(len(file_tests_search)): + if file_tests[i][0] is None: + file_tests[i][0] = file_tests_search[i].search(content) + + # recursively call this on each of the included files + inc_files = [ ] + inc_files.extend( include_re.findall(content) ) + if Verbose: + print "files included by '%s': "%str(theFile),inc_files + # inc_files is list of file names as given. need to find them + # using TEXINPUTS paths. + + for src in inc_files: + srcNode = FindFile(src,['.tex','.ltx','.latex'],paths,env,requireExt=False) + if srcNode is not None: + file_tests = ScanFiles(srcNode, target, paths, file_tests, file_tests_search, env, graphics_extensions, targetdir) + if Verbose: + print " done scanning ",str(theFile) + return file_tests + +def tex_emitter_core(target, source, env, graphics_extensions): + """An emitter for TeX and LaTeX sources. + For LaTeX sources we try and find the common created files that + are needed on subsequent runs of latex to finish tables of contents, + bibliographies, indices, lists of figures, and hyperlink references. + """ + basename = SCons.Util.splitext(str(source[0]))[0] + basefile = os.path.split(str(basename))[1] + targetdir = os.path.split(str(target[0]))[0] + targetbase = os.path.join(targetdir, basefile) + + basedir = os.path.split(str(source[0]))[0] + abspath = os.path.abspath(basedir) + target[0].attributes.path = abspath + + # + # file names we will make use of in searching the sources and log file + # + emit_suffixes = ['.aux', '.log', '.ilg', '.blg', '.nls', '.nlg', '.gls', '.glg', '.alg'] + all_suffixes + auxfilename = targetbase + '.aux' + logfilename = targetbase + '.log' + flsfilename = targetbase + '.fls' + + env.SideEffect(auxfilename,target[0]) + env.SideEffect(logfilename,target[0]) + env.SideEffect(flsfilename,target[0]) + if Verbose: + print "side effect :",auxfilename,logfilename,flsfilename + env.Clean(target[0],auxfilename) + env.Clean(target[0],logfilename) + env.Clean(target[0],flsfilename) + + content = source[0].get_text_contents() + + idx_exists = os.path.exists(targetbase + '.idx') + nlo_exists = os.path.exists(targetbase + '.nlo') + glo_exists = os.path.exists(targetbase + '.glo') + acr_exists = os.path.exists(targetbase + '.acn') + + # set up list with the regular expressions + # we use to find features used + file_tests_search = [auxfile_re, + makeindex_re, + bibliography_re, + tableofcontents_re, + listoffigures_re, + listoftables_re, + hyperref_re, + makenomenclature_re, + makeglossary_re, + makeglossaries_re, + makeacronyms_re, + beamer_re ] + # set up list with the file suffixes that need emitting + # when a feature is found + file_tests_suff = [['.aux'], + ['.idx', '.ind', '.ilg'], + ['.bbl', '.blg'], + ['.toc'], + ['.lof'], + ['.lot'], + ['.out'], + ['.nlo', '.nls', '.nlg'], + ['.glo', '.gls', '.glg'], + ['.glo', '.gls', '.glg'], + ['.acn', '.acr', '.alg'], + ['.nav', '.snm', '.out', '.toc'] ] + # build the list of lists + file_tests = [] + for i in range(len(file_tests_search)): + file_tests.append( [None, file_tests_suff[i]] ) + + # TO-DO: need to add a way for the user to extend this list for whatever + # auxiliary files they create in other (or their own) packages + + # get path list from both env['TEXINPUTS'] and env['ENV']['TEXINPUTS'] + savedpath = modify_env_var(env, 'TEXINPUTS', abspath) + paths = env['ENV']['TEXINPUTS'] + if SCons.Util.is_List(paths): + pass + else: + # Split at os.pathsep to convert into absolute path + # TODO(1.5) + #paths = paths.split(os.pathsep) + paths = string.split(paths, os.pathsep) + + # now that we have the path list restore the env + if savedpath is _null: + try: + del env['ENV']['TEXINPUTS'] + except KeyError: + pass # was never set + else: + env['ENV']['TEXINPUTS'] = savedpath + if Verbose: + print "search path ",paths + + file_tests = ScanFiles(source[0], target, paths, file_tests, file_tests_search, env, graphics_extensions, targetdir) + + for (theSearch,suffix_list) in file_tests: + if theSearch: + for suffix in suffix_list: + env.SideEffect(targetbase + suffix,target[0]) + if Verbose: + print "side effect :",targetbase + suffix + env.Clean(target[0],targetbase + suffix) + + # read fls file to get all other files that latex creates and will read on the next pass + # remove files from list that we explicitly dealt with above + if os.path.exists(flsfilename): + content = open(flsfilename, "rb").read() + out_files = openout_re.findall(content) + myfiles = [auxfilename, logfilename, flsfilename, targetbase+'.dvi',targetbase+'.pdf'] + for filename in out_files[:]: + if filename in myfiles: + out_files.remove(filename) + env.SideEffect(out_files,target[0]) + if Verbose: + print "side effect :",out_files + env.Clean(target[0],out_files) + + return (target, source) + + +TeXLaTeXAction = None + +def generate(env): + """Add Builders and construction variables for TeX to an Environment.""" + + global TeXLaTeXAction + if TeXLaTeXAction is None: + TeXLaTeXAction = SCons.Action.Action(TeXLaTeXFunction, + strfunction=TeXLaTeXStrFunction) + + env.AppendUnique(LATEXSUFFIXES=SCons.Tool.LaTeXSuffixes) + + generate_common(env) + + import dvi + dvi.generate(env) + + bld = env['BUILDERS']['DVI'] + bld.add_action('.tex', TeXLaTeXAction) + bld.add_emitter('.tex', tex_eps_emitter) + +def generate_common(env): + """Add internal Builders and construction variables for LaTeX to an Environment.""" + + # A generic tex file Action, sufficient for all tex files. + global TeXAction + if TeXAction is None: + TeXAction = SCons.Action.Action("$TEXCOM", "$TEXCOMSTR") + + # An Action to build a latex file. This might be needed more + # than once if we are dealing with labels and bibtex. + global LaTeXAction + if LaTeXAction is None: + LaTeXAction = SCons.Action.Action("$LATEXCOM", "$LATEXCOMSTR") + + # Define an action to run BibTeX on a file. + global BibTeXAction + if BibTeXAction is None: + BibTeXAction = SCons.Action.Action("$BIBTEXCOM", "$BIBTEXCOMSTR") + + # Define an action to run MakeIndex on a file. + global MakeIndexAction + if MakeIndexAction is None: + MakeIndexAction = SCons.Action.Action("$MAKEINDEXCOM", "$MAKEINDEXCOMSTR") + + # Define an action to run MakeIndex on a file for nomenclatures. + global MakeNclAction + if MakeNclAction is None: + MakeNclAction = SCons.Action.Action("$MAKENCLCOM", "$MAKENCLCOMSTR") + + # Define an action to run MakeIndex on a file for glossaries. + global MakeGlossaryAction + if MakeGlossaryAction is None: + MakeGlossaryAction = SCons.Action.Action("$MAKEGLOSSARYCOM", "$MAKEGLOSSARYCOMSTR") + + # Define an action to run MakeIndex on a file for acronyms. + global MakeAcronymsAction + if MakeAcronymsAction is None: + MakeAcronymsAction = SCons.Action.Action("$MAKEACRONYMSCOM", "$MAKEACRONYMSCOMSTR") + + env['TEX'] = 'tex' + env['TEXFLAGS'] = SCons.Util.CLVar('-interaction=nonstopmode -recorder') + env['TEXCOM'] = 'cd ${TARGET.dir} && $TEX $TEXFLAGS ${SOURCE.file}' + + env['PDFTEX'] = 'pdftex' + env['PDFTEXFLAGS'] = SCons.Util.CLVar('-interaction=nonstopmode -recorder') + env['PDFTEXCOM'] = 'cd ${TARGET.dir} && $PDFTEX $PDFTEXFLAGS ${SOURCE.file}' + + env['LATEX'] = 'latex' + env['LATEXFLAGS'] = SCons.Util.CLVar('-interaction=nonstopmode -recorder') + env['LATEXCOM'] = 'cd ${TARGET.dir} && $LATEX $LATEXFLAGS ${SOURCE.file}' + env['LATEXRETRIES'] = 3 + + env['PDFLATEX'] = 'pdflatex' + env['PDFLATEXFLAGS'] = SCons.Util.CLVar('-interaction=nonstopmode -recorder') + env['PDFLATEXCOM'] = 'cd ${TARGET.dir} && $PDFLATEX $PDFLATEXFLAGS ${SOURCE.file}' + + env['BIBTEX'] = 'bibtex' + env['BIBTEXFLAGS'] = SCons.Util.CLVar('') + env['BIBTEXCOM'] = 'cd ${TARGET.dir} && $BIBTEX $BIBTEXFLAGS ${SOURCE.filebase}' + + env['MAKEINDEX'] = 'makeindex' + env['MAKEINDEXFLAGS'] = SCons.Util.CLVar('') + env['MAKEINDEXCOM'] = 'cd ${TARGET.dir} && $MAKEINDEX $MAKEINDEXFLAGS ${SOURCE.file}' + + env['MAKEGLOSSARY'] = 'makeindex' + env['MAKEGLOSSARYSTYLE'] = '${SOURCE.filebase}.ist' + env['MAKEGLOSSARYFLAGS'] = SCons.Util.CLVar('-s ${MAKEGLOSSARYSTYLE} -t ${SOURCE.filebase}.glg') + env['MAKEGLOSSARYCOM'] = 'cd ${TARGET.dir} && $MAKEGLOSSARY ${SOURCE.filebase}.glo $MAKEGLOSSARYFLAGS -o ${SOURCE.filebase}.gls' + + env['MAKEACRONYMS'] = 'makeindex' + env['MAKEACRONYMSSTYLE'] = '${SOURCE.filebase}.ist' + env['MAKEACRONYMSFLAGS'] = SCons.Util.CLVar('-s ${MAKEACRONYMSSTYLE} -t ${SOURCE.filebase}.alg') + env['MAKEACRONYMSCOM'] = 'cd ${TARGET.dir} && $MAKEACRONYMS ${SOURCE.filebase}.acn $MAKEACRONYMSFLAGS -o ${SOURCE.filebase}.acr' + + env['MAKENCL'] = 'makeindex' + env['MAKENCLSTYLE'] = 'nomencl.ist' + env['MAKENCLFLAGS'] = '-s ${MAKENCLSTYLE} -t ${SOURCE.filebase}.nlg' + env['MAKENCLCOM'] = 'cd ${TARGET.dir} && $MAKENCL ${SOURCE.filebase}.nlo $MAKENCLFLAGS -o ${SOURCE.filebase}.nls' + +def exists(env): + return env.Detect('tex') + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/tex.xml b/src/engine/SCons/Tool/tex.xml new file mode 100644 index 0000000..e8c61c7 --- /dev/null +++ b/src/engine/SCons/Tool/tex.xml @@ -0,0 +1,126 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="tex"> +<summary> +Sets construction variables for the TeX formatter and typesetter. +</summary> +<sets> +TEX +TEXFLAGS +TEXCOM +LATEX +LATEXFLAGS +LATEXCOM +BIBTEX +BIBTEXFLAGS +BIBTEXCOM +MAKEINDEX +MAKEINDEXFLAGS +MAKEINDEXCOM +</sets> +<uses> +TEXCOMSTR +LATEXCOMSTR +BIBTEXCOMSTR +MAKEINDEXCOMSTR +</uses> +</tool> + +<cvar name="BIBTEX"> +<summary> +The bibliography generator for the TeX formatter and typesetter and the +LaTeX structured formatter and typesetter. +</summary> +</cvar> + +<cvar name="BIBTEXCOM"> +<summary> +The command line used to call the bibliography generator for the +TeX formatter and typesetter and the LaTeX structured formatter and +typesetter. +</summary> +</cvar> + +<cvar name="BIBTEXCOMSTR"> +<summary> +The string displayed when generating a bibliography +for TeX or LaTeX. +If this is not set, then &cv-link-BIBTEXCOM; (the command line) is displayed. + +<example> +env = Environment(BIBTEXCOMSTR = "Generating bibliography $TARGET") +</example> +</summary> +</cvar> + +<cvar name="BIBTEXFLAGS"> +<summary> +General options passed to the bibliography generator for the TeX formatter +and typesetter and the LaTeX structured formatter and typesetter. +</summary> +</cvar> + +<cvar name="MAKEINDEX"> +<summary> +The makeindex generator for the TeX formatter and typesetter and the +LaTeX structured formatter and typesetter. +</summary> +</cvar> + +<cvar name="MAKEINDEXCOM"> +<summary> +The command line used to call the makeindex generator for the +TeX formatter and typesetter and the LaTeX structured formatter and +typesetter. +</summary> +</cvar> + +<cvar name="MAKEINDEXCOMSTR"> +<summary> +The string displayed when calling the makeindex generator for the +TeX formatter and typesetter +and the LaTeX structured formatter and typesetter. +If this is not set, then &cv-link-MAKEINDEXCOM; (the command line) is displayed. +</summary> +</cvar> + +<cvar name="MAKEINDEXFLAGS"> +<summary> +General options passed to the makeindex generator for the TeX formatter +and typesetter and the LaTeX structured formatter and typesetter. +</summary> +</cvar> + +<cvar name="TEX"> +<summary> +The TeX formatter and typesetter. +</summary> +</cvar> + +<cvar name="TEXCOM"> +<summary> +The command line used to call the TeX formatter and typesetter. +</summary> +</cvar> + +<cvar name="TEXCOMSTR"> +<summary> +The string displayed when calling +the TeX formatter and typesetter. +If this is not set, then &cv-link-TEXCOM; (the command line) is displayed. + +<example> +env = Environment(TEXCOMSTR = "Building $TARGET from TeX input $SOURCES") +</example> +</summary> +</cvar> + +<cvar name="TEXFLAGS"> +<summary> +General options passed to the TeX formatter and typesetter. +</summary> +</cvar> diff --git a/src/engine/SCons/Tool/textfile.py b/src/engine/SCons/Tool/textfile.py new file mode 100644 index 0000000..8dea678 --- /dev/null +++ b/src/engine/SCons/Tool/textfile.py @@ -0,0 +1,175 @@ +# -*- python -*- +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__doc__ = """ +Textfile/Substfile builder for SCons. + + Create file 'target' which typically is a textfile. The 'source' + may be any combination of strings, Nodes, or lists of same. A + 'linesep' will be put between any part written and defaults to + os.linesep. + + The only difference between the Textfile builder and the Substfile + builder is that strings are converted to Value() nodes for the + former and File() nodes for the latter. To insert files in the + former or strings in the latter, wrap them in a File() or Value(), + respectively. + + The values of SUBST_DICT first have any construction variables + expanded (its keys are not expanded). If a value of SUBST_DICT is + a python callable function, it is called and the result is expanded + as the value. Values are substituted in a "random" order; if any + substitution could be further expanded by another subsitition, it + is unpredictible whether the expansion will occur. +""" + +__revision__ = "src/engine/SCons/Tool/textfile.py 4577 2009/12/27 19:44:43 scons" + +import SCons + +import os +import re + +from SCons.Node import Node +from SCons.Node.Python import Value +from SCons.Util import is_String, is_Sequence, is_Dict + +def _do_subst(node, subs): + """ + Fetch the node contents and replace all instances of the keys with + their values. For example, if subs is + {'%VERSION%': '1.2345', '%BASE%': 'MyProg', '%prefix%': '/bin'}, + then all instances of %VERSION% in the file will be replaced with + 1.2345 and so forth. + """ + contents = node.get_text_contents() + if not subs: return contents + for (k,v) in subs: + contents = re.sub(k, v, contents) + return contents + +def _action(target, source, env): + # prepare the line separator + linesep = env['LINESEPARATOR'] + if linesep is None: + linesep = os.linesep + elif is_String(linesep): + pass + elif isinstance(linesep, Value): + linesep = linesep.get_text_contents() + else: + raise SCons.Errors.UserError( + 'unexpected type/class for LINESEPARATOR: %s' + % repr(linesep), None) + + # create a dictionary to use for the substitutions + if not env.has_key('SUBST_DICT'): + subs = None # no substitutions + else: + d = env['SUBST_DICT'] + if is_Dict(d): + d = d.items() + elif is_Sequence(d): + pass + else: + raise SCons.Errors.UserError('SUBST_DICT must be dict or sequence') + subs = [] + for (k,v) in d: + if callable(v): + v = v() + if is_String(v): + v = env.subst(v) + else: + v = str(v) + subs.append((k,v)) + + # write the file + try: + fd = open(target[0].get_path(), "wb") + except (OSError,IOError), e: + raise SCons.Errors.UserError("Can't write target file %s" % target[0]) + # separate lines by 'linesep' only if linesep is not empty + lsep = None + for s in source: + if lsep: fd.write(lsep) + fd.write(_do_subst(s, subs)) + lsep = linesep + fd.close() + +def _strfunc(target, source, env): + return "Creating '%s'" % target[0] + +def _convert_list_R(newlist, sources): + for elem in sources: + if is_Sequence(elem): + _convert_list_R(newlist, elem) + elif isinstance(elem, Node): + newlist.append(elem) + else: + newlist.append(Value(elem)) +def _convert_list(target, source, env): + if len(target) != 1: + raise SCons.Errors.UserError("Only one target file allowed") + newlist = [] + _convert_list_R(newlist, source) + return target, newlist + +_common_varlist = ['SUBST_DICT', 'LINESEPARATOR'] + +_text_varlist = _common_varlist + ['TEXTFILEPREFIX', 'TEXTFILESUFFIX'] +_text_builder = SCons.Builder.Builder( + action = SCons.Action.Action(_action, _strfunc, varlist = _text_varlist), + source_factory = Value, + emitter = _convert_list, + prefix = '$TEXTFILEPREFIX', + suffix = '$TEXTFILESUFFIX', + ) + +_subst_varlist = _common_varlist + ['SUBSTFILEPREFIX', 'TEXTFILESUFFIX'] +_subst_builder = SCons.Builder.Builder( + action = SCons.Action.Action(_action, _strfunc, varlist = _subst_varlist), + source_factory = SCons.Node.FS.File, + emitter = _convert_list, + prefix = '$SUBSTFILEPREFIX', + suffix = '$SUBSTFILESUFFIX', + src_suffix = ['.in'], + ) + +def generate(env): + env['LINESEPARATOR'] = os.linesep + env['BUILDERS']['Textfile'] = _text_builder + env['TEXTFILEPREFIX'] = '' + env['TEXTFILESUFFIX'] = '.txt' + env['BUILDERS']['Substfile'] = _subst_builder + env['SUBSTFILEPREFIX'] = '' + env['SUBSTFILESUFFIX'] = '' + +def exists(env): + return 1 + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/textfile.xml b/src/engine/SCons/Tool/textfile.xml new file mode 100644 index 0000000..9b66607 --- /dev/null +++ b/src/engine/SCons/Tool/textfile.xml @@ -0,0 +1,205 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="textfile"> +<summary> +Set construction variables for the &b-Textfile; and &b-Substfile; builders. +</summary> +<sets> +LINESEPARATOR +SUBSTFILEPREFIX +SUBSTFILESUFFIX +TEXTFILEPREFIX +TEXTFILESUFFIX +</sets> +<uses> +SUBST_DICT +</uses> +</tool> + +<builder name="Textfile"> +<summary> +The &b-Textfile; builder generates a single text file. +The source strings constitute the lines; +nested lists of sources are flattened. +&cv-LINESEPARATOR; is used to separate the strings. + +If present, the &cv-SUBST_DICT; construction variable +is used to modify the strings before they are written; +see the &b-Substfile; description for details. + +The prefix and suffix specified by the &cv-TEXTFILEPREFIX; +and &cv-TEXTFILESUFFIX; construction variables +(the null string and <filename>.txt</filename> by default, respectively) +are automatically added to the target if they are not already present. +Examples: + +<example> +# builds/writes foo.txt +env.Textfile(target = 'foo.txt', source = ['Goethe', 42, 'Schiller']) + +# builds/writes bar.txt +env.Textfile(target = 'bar', + source = ['lalala', 'tanteratei'], + LINESEPARATOR='|*') + +# nested lists are flattened automatically +env.Textfile(target = 'blob', + source = ['lalala', ['Goethe', 42 'Schiller'], 'tanteratei']) + +# files may be used as input by wraping them in File() +env.Textfile(target = 'concat', # concatenate files with a marker between + source = [File('concat1'), File('concat2')], + LINESEPARATOR = '====================\n') + +Results are: +foo.txt + ....8<---- + Goethe + 42 + Schiller + ....8<---- (no linefeed at the end) + +bar.txt: + ....8<---- + lalala|*tanteratei + ....8<---- (no linefeed at the end) + +blob.txt + ....8<---- + lalala + Goethe + 42 + Schiller + tanteratei + ....8<---- (no linefeed at the end) +</example> +</summary> +</builder> + +<builder name="Substfile"> +<summary> +The &b-Substfile; builder generates a single text file +by concatenating the source files. +Nested lists of sources are flattened. +&cv-LINESEPARATOR; is used to separate the source files; +see the description of &b-Textfile; for details. + +If a single source file is present with an <filename>.in</filename> suffix, +the suffix is stripped and the remainder is used as the default target name. + +The prefix and suffix specified by the &cv-SUBSTFILEPREFIX; +and &cv-SUBSTFILESUFFIX; construction variables +(the null string by default in both cases) +are automatically added to the target if they are not already present. + +If a construction variable named &cv-SUBST_DICT; is present, +it may be either a Python dictionary or a sequence of (key,value) tuples. +If the former, +the dictionary is converted into a list of tuples in an arbitrary order, +so if one key is a prefix of another key +or if one substitution could be further expanded by another subsitition, +it is unpredictible whether the expansion will occur. + +Any occurences in the source of a key +are replaced by the corresponding value, +which may be a Python callable function or a string. +If a value is a function, +it is first called (with no arguments) to produce a string. +The string is <emphasis>subst</emphasis>-expanded +and the result replaces the key. + +<example> +env = Environment(tools = ['default', 'textfile']) + +env['prefix'] = '/usr/bin' +script_dict = {'@prefix@': '/bin', @exec_prefix@: '$prefix'} +env.Substfile('script.in', SUBST_DICT = script_dict) + +conf_dict = {'%VERSION%': '1.2.3', '%BASE%': 'MyProg'} +env.Substfile('config.h.in', conf_dict, SUBST_DICT = conf_dict) + +# UNPREDICTABLE - one key is a prefix of another +bad_foo = {'$foo': '$foo', '$foobar': '$foobar'} +env.Substfile('foo.in', SUBST_DICT = bad_foo) + +# PREDICTABLE - keys are applied longest first +good_foo = [('$foobar', '$foobar'), ('$foo', '$foo')] +env.Substfile('foo.in', SUBST_DICT = good_foo) + +# UNPREDICTABLE - one substitution could be futher expanded +bad_bar = {'@bar@': '@soap@', '@soap@': 'lye'} +env.Substfile('bar.in', SUBST_DICT = bad_bar) + +# PREDICTABLE - substitutions are expanded in order +good_bar = (('@bar@', '@soap@'), ('@soap@', 'lye')) +env.Substfile('bar.in', SUBST_DICT = good_bar) + +# the SUBST_DICT may be in common (and not an override) +substutions = {} +subst = Environment(tools = ['textfile', SUBST_DICT = substitutions) +substitutions['@foo@'] = 'foo' +subst['SUBST_DICT']['@bar@'] = 'bar' +subst.Substfile('pgm1.c', [Value('#include "@foo@.h"'), + Value('#include "@bar@.h"'), + "common.in", + "pgm1.in" + ]) +subst.Substfile('pgm2.c', [Value('#include "@foo@.h"'), + Value('#include "@bar@.h"'), + "common.in", + "pgm2.in" + ]) + +</example> +</summary> +</builder> + +<cvar name="LINESEPARATOR"> +<summary> +The separator used by the &b-Substfile; and &b-Textfile; builders. +This value is used between sources when constructing the target. +It defaults to the current system line separator. +</summary> +</cvar> + +<cvar name="SUBST_DICT"> +<summary> +The dictionary used by the &b-Substfile; or &b-Textfile; builders +for substitution values. +It can be anything acceptable to the dict() constructor, +so in addition to a dictionary, +lists of tuples are also acceptable. +</summary> +</cvar> + +<cvar name="SUBSTFILEPREFIX"> +<summary> +The prefix used for &b-Substfile; file names, +the null string by default. +</summary> +</cvar> + +<cvar name="SUBSTFILESUFFIX"> +<summary> +The suffix used for &b-Substfile; file names, +the null string by default. +</summary> +</cvar> + +<cvar name="TEXTFILEPREFIX"> +<summary> +The prefix used for &b-Textfile; file names, +the null string by default. +</summary> +</cvar> + +<cvar name="TEXTFILESUFFIX"> +<summary> +The suffix used for &b-Textfile; file names; +<filename>.txt</filename> by default. +</summary> +</cvar> diff --git a/src/engine/SCons/Tool/tlib.py b/src/engine/SCons/Tool/tlib.py new file mode 100644 index 0000000..0d6f802 --- /dev/null +++ b/src/engine/SCons/Tool/tlib.py @@ -0,0 +1,53 @@ +"""SCons.Tool.tlib + +XXX + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/tlib.py 4577 2009/12/27 19:44:43 scons" + +import SCons.Tool +import SCons.Tool.bcc32 +import SCons.Util + +def generate(env): + SCons.Tool.bcc32.findIt('tlib', env) + """Add Builders and construction variables for ar to an Environment.""" + SCons.Tool.createStaticLibBuilder(env) + env['AR'] = 'tlib' + env['ARFLAGS'] = SCons.Util.CLVar('') + env['ARCOM'] = '$AR $TARGET $ARFLAGS /a $SOURCES' + env['LIBPREFIX'] = '' + env['LIBSUFFIX'] = '.lib' + +def exists(env): + return SCons.Tool.bcc32.findIt('tlib', env) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/tlib.xml b/src/engine/SCons/Tool/tlib.xml new file mode 100644 index 0000000..fb386ec --- /dev/null +++ b/src/engine/SCons/Tool/tlib.xml @@ -0,0 +1,22 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="tlib"> +<summary> +Sets construction variables for the Borlan +<application>tib</application> library archiver. +</summary> +<sets> +AR +ARFLAGS +ARCOM +LIBPREFIX +LIBSUFFIX +</sets> +<uses> +ARCOMSTR +</uses> +</tool> diff --git a/src/engine/SCons/Tool/wix.py b/src/engine/SCons/Tool/wix.py new file mode 100644 index 0000000..350ae49 --- /dev/null +++ b/src/engine/SCons/Tool/wix.py @@ -0,0 +1,100 @@ +"""SCons.Tool.wix + +Tool-specific initialization for wix, the Windows Installer XML Tool. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/wix.py 4577 2009/12/27 19:44:43 scons" + +import SCons.Builder +import SCons.Action +import os +import string + +def generate(env): + """Add Builders and construction variables for WiX to an Environment.""" + if not exists(env): + return + + env['WIXCANDLEFLAGS'] = ['-nologo'] + env['WIXCANDLEINCLUDE'] = [] + env['WIXCANDLECOM'] = '$WIXCANDLE $WIXCANDLEFLAGS -I $WIXCANDLEINCLUDE -o ${TARGET} ${SOURCE}' + + env['WIXLIGHTFLAGS'].append( '-nologo' ) + env['WIXLIGHTCOM'] = "$WIXLIGHT $WIXLIGHTFLAGS -out ${TARGET} ${SOURCES}" + + object_builder = SCons.Builder.Builder( + action = '$WIXCANDLECOM', + suffix = '.wxiobj', + src_suffix = '.wxs') + + linker_builder = SCons.Builder.Builder( + action = '$WIXLIGHTCOM', + src_suffix = '.wxiobj', + src_builder = object_builder) + + env['BUILDERS']['WiX'] = linker_builder + +def exists(env): + env['WIXCANDLE'] = 'candle.exe' + env['WIXLIGHT'] = 'light.exe' + + # try to find the candle.exe and light.exe tools and + # add the install directory to light libpath. + #for path in os.environ['PATH'].split(os.pathsep): + for path in string.split(os.environ['PATH'], os.pathsep): + if not path: + continue + + # workaround for some weird python win32 bug. + if path[0] == '"' and path[-1:]=='"': + path = path[1:-1] + + # normalize the path + path = os.path.normpath(path) + + # search for the tools in the PATH environment variable + try: + if env['WIXCANDLE'] in os.listdir(path) and\ + env['WIXLIGHT'] in os.listdir(path): + env.PrependENVPath('PATH', path) + env['WIXLIGHTFLAGS'] = [ os.path.join( path, 'wixui.wixlib' ), + '-loc', + os.path.join( path, 'WixUI_en-us.wxl' ) ] + return 1 + except OSError: + pass # ignore this, could be a stale PATH entry. + + return None + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/yacc.py b/src/engine/SCons/Tool/yacc.py new file mode 100644 index 0000000..83636d7 --- /dev/null +++ b/src/engine/SCons/Tool/yacc.py @@ -0,0 +1,131 @@ +"""SCons.Tool.yacc + +Tool-specific initialization for yacc. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/yacc.py 4577 2009/12/27 19:44:43 scons" + +import os.path +import string + +import SCons.Defaults +import SCons.Tool +import SCons.Util + +YaccAction = SCons.Action.Action("$YACCCOM", "$YACCCOMSTR") + +def _yaccEmitter(target, source, env, ysuf, hsuf): + yaccflags = env.subst("$YACCFLAGS", target=target, source=source) + flags = SCons.Util.CLVar(yaccflags) + targetBase, targetExt = os.path.splitext(SCons.Util.to_String(target[0])) + + if '.ym' in ysuf: # If using Objective-C + target = [targetBase + ".m"] # the extension is ".m". + + + # If -d is specified on the command line, yacc will emit a .h + # or .hpp file with the same name as the .c or .cpp output file. + if '-d' in flags: + target.append(targetBase + env.subst(hsuf, target=target, source=source)) + + # If -g is specified on the command line, yacc will emit a .vcg + # file with the same base name as the .y, .yacc, .ym or .yy file. + if "-g" in flags: + base, ext = os.path.splitext(SCons.Util.to_String(source[0])) + target.append(base + env.subst("$YACCVCGFILESUFFIX")) + + # With --defines and --graph, the name of the file is totally defined + # in the options. + fileGenOptions = ["--defines=", "--graph="] + for option in flags: + for fileGenOption in fileGenOptions: + l = len(fileGenOption) + if option[:l] == fileGenOption: + # A file generating option is present, so add the file + # name to the list of targets. + fileName = string.strip(option[l:]) + target.append(fileName) + + return (target, source) + +def yEmitter(target, source, env): + return _yaccEmitter(target, source, env, ['.y', '.yacc'], '$YACCHFILESUFFIX') + +def ymEmitter(target, source, env): + return _yaccEmitter(target, source, env, ['.ym'], '$YACCHFILESUFFIX') + +def yyEmitter(target, source, env): + return _yaccEmitter(target, source, env, ['.yy'], '$YACCHXXFILESUFFIX') + +def generate(env): + """Add Builders and construction variables for yacc to an Environment.""" + c_file, cxx_file = SCons.Tool.createCFileBuilders(env) + + # C + c_file.add_action('.y', YaccAction) + c_file.add_emitter('.y', yEmitter) + + c_file.add_action('.yacc', YaccAction) + c_file.add_emitter('.yacc', yEmitter) + + # Objective-C + c_file.add_action('.ym', YaccAction) + c_file.add_emitter('.ym', ymEmitter) + + # C++ + cxx_file.add_action('.yy', YaccAction) + cxx_file.add_emitter('.yy', yyEmitter) + + env['YACC'] = env.Detect('bison') or 'yacc' + env['YACCFLAGS'] = SCons.Util.CLVar('') + env['YACCCOM'] = '$YACC $YACCFLAGS -o $TARGET $SOURCES' + env['YACCHFILESUFFIX'] = '.h' + + # Apparently, OS X now creates file.hpp like everybody else + # I have no idea when it changed; it was fixed in 10.4 + #if env['PLATFORM'] == 'darwin': + # # Bison on Mac OS X just appends ".h" to the generated target .cc + # # or .cpp file name. Hooray for delayed expansion of variables. + # env['YACCHXXFILESUFFIX'] = '${TARGET.suffix}.h' + #else: + # env['YACCHXXFILESUFFIX'] = '.hpp' + env['YACCHXXFILESUFFIX'] = '.hpp' + + env['YACCVCGFILESUFFIX'] = '.vcg' + +def exists(env): + return env.Detect(['bison', 'yacc']) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/yacc.xml b/src/engine/SCons/Tool/yacc.xml new file mode 100644 index 0000000..456c379 --- /dev/null +++ b/src/engine/SCons/Tool/yacc.xml @@ -0,0 +1,115 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="yacc"> +<summary> +Sets construction variables for the &yacc; parse generator. +</summary> +<sets> +YACC +YACCFLAGS +YACCCOM +YACCHFILESUFFIX +YACCHXXFILESUFFIX +YACCVCGFILESUFFIX +</sets> +<uses> +YACCCOMSTR +</uses> +</tool> + +<cvar name="YACC"> +<summary> +The parser generator. +</summary> +</cvar> + +<cvar name="YACCCOM"> +<summary> +The command line used to call the parser generator +to generate a source file. +</summary> +</cvar> + +<cvar name="YACCCOMSTR"> +<summary> +The string displayed when generating a source file +using the parser generator. +If this is not set, then &cv-link-YACCCOM; (the command line) is displayed. + +<example> +env = Environment(YACCCOMSTR = "Yacc'ing $TARGET from $SOURCES") +</example> +</summary> +</cvar> + +<cvar name="YACCFLAGS"> +<summary> +General options passed to the parser generator. +If &cv-link-YACCFLAGS; contains a <option>-d</option> option, +SCons assumes that the call will also create a .h file +(if the yacc source file ends in a .y suffix) +or a .hpp file +(if the yacc source file ends in a .yy suffix) +</summary> +</cvar> + +<cvar name="YACCHFILESUFFIX"> +<summary> +The suffix of the C +header file generated by the parser generator +when the +<option>-d</option> +option is used. +Note that setting this variable does not cause +the parser generator to generate a header +file with the specified suffix, +it exists to allow you to specify +what suffix the parser generator will use of its own accord. +The default value is +<filename>.h</filename>. +</summary> +</cvar> + +<cvar name="YACCHXXFILESUFFIX"> +<summary> +The suffix of the C++ +header file generated by the parser generator +when the +<option>-d</option> +option is used. +Note that setting this variable does not cause +the parser generator to generate a header +file with the specified suffix, +it exists to allow you to specify +what suffix the parser generator will use of its own accord. +The default value is +<filename>.hpp</filename>, +except on Mac OS X, +where the default is +<filename>${TARGET.suffix}.h</filename>. +because the default &bison; parser generator just +appends <filename>.h</filename> +to the name of the generated C++ file. +</summary> +</cvar> + +<cvar name="YACCVCGFILESUFFIX"> +<summary> +The suffix of the file +containing the VCG grammar automaton definition +when the +<option>--graph=</option> +option is used. +Note that setting this variable does not cause +the parser generator to generate a VCG +file with the specified suffix, +it exists to allow you to specify +what suffix the parser generator will use of its own accord. +The default value is +<filename>.vcg</filename>. +</summary> +</cvar> diff --git a/src/engine/SCons/Tool/zip.py b/src/engine/SCons/Tool/zip.py new file mode 100644 index 0000000..1b31ad9 --- /dev/null +++ b/src/engine/SCons/Tool/zip.py @@ -0,0 +1,100 @@ +"""SCons.Tool.zip + +Tool-specific initialization for zip. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/zip.py 4577 2009/12/27 19:44:43 scons" + +import os.path + +import SCons.Builder +import SCons.Defaults +import SCons.Node.FS +import SCons.Util + +try: + import zipfile + internal_zip = 1 +except ImportError: + internal_zip = 0 + +if internal_zip: + zipcompression = zipfile.ZIP_DEFLATED + def zip(target, source, env): + def visit(arg, dirname, names): + for name in names: + path = os.path.join(dirname, name) + if os.path.isfile(path): + arg.write(path) + compression = env.get('ZIPCOMPRESSION', 0) + zf = zipfile.ZipFile(str(target[0]), 'w', compression) + for s in source: + if s.isdir(): + os.path.walk(str(s), visit, zf) + else: + zf.write(str(s)) + zf.close() +else: + zipcompression = 0 + zip = "$ZIP $ZIPFLAGS ${TARGET.abspath} $SOURCES" + + +zipAction = SCons.Action.Action(zip, varlist=['ZIPCOMPRESSION']) + +ZipBuilder = SCons.Builder.Builder(action = SCons.Action.Action('$ZIPCOM', '$ZIPCOMSTR'), + source_factory = SCons.Node.FS.Entry, + source_scanner = SCons.Defaults.DirScanner, + suffix = '$ZIPSUFFIX', + multi = 1) + + +def generate(env): + """Add Builders and construction variables for zip to an Environment.""" + try: + bld = env['BUILDERS']['Zip'] + except KeyError: + bld = ZipBuilder + env['BUILDERS']['Zip'] = bld + + env['ZIP'] = 'zip' + env['ZIPFLAGS'] = SCons.Util.CLVar('') + env['ZIPCOM'] = zipAction + env['ZIPCOMPRESSION'] = zipcompression + env['ZIPSUFFIX'] = '.zip' + +def exists(env): + return internal_zip or env.Detect('zip') + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/zip.xml b/src/engine/SCons/Tool/zip.xml new file mode 100644 index 0000000..b08b5f6 --- /dev/null +++ b/src/engine/SCons/Tool/zip.xml @@ -0,0 +1,110 @@ +<!-- +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="zip"> +<summary> +Sets construction variables for the &zip; archiver. +</summary> +<sets> +ZIP +ZIPFLAGS +ZIPCOM +ZIPCOMPRESSION +ZIPSUFFIX +</sets> +<uses> +ZIPCOMSTR +</uses> +</tool> + +<builder name="Zip"> +<summary> +Builds a zip archive of the specified files +and/or directories. +Unlike most builder methods, +the +&b-Zip; +builder method may be called multiple times +for a given target; +each additional call +adds to the list of entries +that will be built into the archive. +Any source directories will +be scanned for changes to +any on-disk files, +regardless of whether or not +&scons; +knows about them from other Builder or function calls. + +<example> +env.Zip('src.zip', 'src') + +# Create the stuff.zip file. +env.Zip('stuff', ['subdir1', 'subdir2']) +# Also add "another" to the stuff.tar file. +env.Zip('stuff', 'another') +</example> +</summary> +</builder> + +<cvar name="ZIP"> +<summary> +The zip compression and file packaging utility. +</summary> +</cvar> + +<cvar name="ZIPCOM"> +<summary> +The command line used to call the zip utility, +or the internal Python function used to create a +zip archive. +</summary> +</cvar> + +<cvar name="ZIPCOMSTR"> +<summary> +The string displayed when archiving files +using the zip utility. +If this is not set, then &cv-link-ZIPCOM; +(the command line or internal Python function) is displayed. + +<example> +env = Environment(ZIPCOMSTR = "Zipping $TARGET") +</example> +</summary> +</cvar> + +<cvar name="ZIPCOMPRESSION"> +<summary> +The +<varname>compression</varname> +flag +from the Python +<filename>zipfile</filename> +module used by the internal Python function +to control whether the zip archive +is compressed or not. +The default value is +<literal>zipfile.ZIP_DEFLATED</literal>, +which creates a compressed zip archive. +This value has no effect when using Python 1.5.2 +or if the +<literal>zipfile</literal> +module is otherwise unavailable. +</summary> +</cvar> + +<cvar name="ZIPFLAGS"> +<summary> +General options passed to the zip utility. +</summary> +</cvar> + +<cvar name="ZIPSUFFIX"> +<summary> +The suffix used for zip file names. +</summary> +</cvar> |