summaryrefslogtreecommitdiff
path: root/engine/SCons/Tool
diff options
context:
space:
mode:
Diffstat (limited to 'engine/SCons/Tool')
-rw-r--r--engine/SCons/Tool/386asm.py61
-rw-r--r--engine/SCons/Tool/BitKeeper.py67
-rw-r--r--engine/SCons/Tool/CVS.py73
-rw-r--r--engine/SCons/Tool/DCommon.py56
-rw-r--r--engine/SCons/Tool/FortranCommon.py263
-rw-r--r--engine/SCons/Tool/GettextCommon.py430
-rw-r--r--engine/SCons/Tool/JavaCommon.py324
-rw-r--r--engine/SCons/Tool/MSCommon/__init__.py56
-rw-r--r--engine/SCons/Tool/MSCommon/arch.py61
-rw-r--r--engine/SCons/Tool/MSCommon/common.py260
-rw-r--r--engine/SCons/Tool/MSCommon/netframework.py82
-rw-r--r--engine/SCons/Tool/MSCommon/sdk.py391
-rw-r--r--engine/SCons/Tool/MSCommon/vc.py501
-rw-r--r--engine/SCons/Tool/MSCommon/vs.py544
-rw-r--r--engine/SCons/Tool/Perforce.py103
-rw-r--r--engine/SCons/Tool/PharLapCommon.py137
-rw-r--r--engine/SCons/Tool/RCS.py64
-rw-r--r--engine/SCons/Tool/SCCS.py64
-rw-r--r--engine/SCons/Tool/Subversion.py71
-rw-r--r--engine/SCons/Tool/__init__.py836
-rw-r--r--engine/SCons/Tool/aixc++.py75
-rw-r--r--engine/SCons/Tool/aixcc.py74
-rw-r--r--engine/SCons/Tool/aixf77.py80
-rw-r--r--engine/SCons/Tool/aixlink.py77
-rw-r--r--engine/SCons/Tool/applelink.py71
-rw-r--r--engine/SCons/Tool/ar.py63
-rw-r--r--engine/SCons/Tool/as.py78
-rw-r--r--engine/SCons/Tool/bcc32.py81
-rw-r--r--engine/SCons/Tool/c++.py100
-rw-r--r--engine/SCons/Tool/cc.py105
-rw-r--r--engine/SCons/Tool/cvf.py58
-rw-r--r--engine/SCons/Tool/cyglink.py94
-rw-r--r--engine/SCons/Tool/default.py50
-rw-r--r--engine/SCons/Tool/dmd.py152
-rw-r--r--engine/SCons/Tool/docbook/__init__.py882
-rw-r--r--engine/SCons/Tool/dvi.py64
-rw-r--r--engine/SCons/Tool/dvipdf.py125
-rw-r--r--engine/SCons/Tool/dvips.py95
-rw-r--r--engine/SCons/Tool/f03.py63
-rw-r--r--engine/SCons/Tool/f77.py62
-rw-r--r--engine/SCons/Tool/f90.py62
-rw-r--r--engine/SCons/Tool/f95.py63
-rw-r--r--engine/SCons/Tool/filesystem.py98
-rw-r--r--engine/SCons/Tool/fortran.py62
-rw-r--r--engine/SCons/Tool/g++.py80
-rw-r--r--engine/SCons/Tool/g77.py73
-rw-r--r--engine/SCons/Tool/gas.py53
-rw-r--r--engine/SCons/Tool/gcc.py100
-rw-r--r--engine/SCons/Tool/gdc.py128
-rw-r--r--engine/SCons/Tool/gettext.py48
-rw-r--r--engine/SCons/Tool/gfortran.py64
-rw-r--r--engine/SCons/Tool/gnulink.py67
-rw-r--r--engine/SCons/Tool/gs.py91
-rw-r--r--engine/SCons/Tool/hpc++.py84
-rw-r--r--engine/SCons/Tool/hpcc.py53
-rw-r--r--engine/SCons/Tool/hplink.py77
-rw-r--r--engine/SCons/Tool/icc.py59
-rw-r--r--engine/SCons/Tool/icl.py52
-rw-r--r--engine/SCons/Tool/ifl.py72
-rw-r--r--engine/SCons/Tool/ifort.py88
-rw-r--r--engine/SCons/Tool/ilink.py59
-rw-r--r--engine/SCons/Tool/ilink32.py60
-rw-r--r--engine/SCons/Tool/install.py493
-rw-r--r--engine/SCons/Tool/intelc.py608
-rw-r--r--engine/SCons/Tool/ipkg.py67
-rw-r--r--engine/SCons/Tool/jar.py116
-rw-r--r--engine/SCons/Tool/javac.py232
-rw-r--r--engine/SCons/Tool/javah.py137
-rw-r--r--engine/SCons/Tool/latex.py80
-rw-r--r--engine/SCons/Tool/ldc.py141
-rw-r--r--engine/SCons/Tool/lex.py97
-rw-r--r--engine/SCons/Tool/link.py204
-rw-r--r--engine/SCons/Tool/linkloc.py112
-rw-r--r--engine/SCons/Tool/m4.py63
-rw-r--r--engine/SCons/Tool/masm.py77
-rw-r--r--engine/SCons/Tool/midl.py88
-rw-r--r--engine/SCons/Tool/mingw.py180
-rw-r--r--engine/SCons/Tool/msgfmt.py108
-rw-r--r--engine/SCons/Tool/msginit.py120
-rw-r--r--engine/SCons/Tool/msgmerge.py104
-rw-r--r--engine/SCons/Tool/mslib.py64
-rw-r--r--engine/SCons/Tool/mslink.py327
-rw-r--r--engine/SCons/Tool/mssdk.py50
-rw-r--r--engine/SCons/Tool/msvc.py278
-rw-r--r--engine/SCons/Tool/msvs.py1803
-rw-r--r--engine/SCons/Tool/mwcc.py207
-rw-r--r--engine/SCons/Tool/mwld.py107
-rw-r--r--engine/SCons/Tool/nasm.py72
-rw-r--r--engine/SCons/Tool/packaging/__init__.py312
-rw-r--r--engine/SCons/Tool/packaging/ipk.py185
-rw-r--r--engine/SCons/Tool/packaging/msi.py527
-rw-r--r--engine/SCons/Tool/packaging/rpm.py357
-rw-r--r--engine/SCons/Tool/packaging/src_tarbz2.py43
-rw-r--r--engine/SCons/Tool/packaging/src_targz.py43
-rw-r--r--engine/SCons/Tool/packaging/src_zip.py43
-rw-r--r--engine/SCons/Tool/packaging/tarbz2.py44
-rw-r--r--engine/SCons/Tool/packaging/targz.py44
-rw-r--r--engine/SCons/Tool/packaging/zip.py44
-rw-r--r--engine/SCons/Tool/pdf.py78
-rw-r--r--engine/SCons/Tool/pdflatex.py84
-rw-r--r--engine/SCons/Tool/pdftex.py109
-rw-r--r--engine/SCons/Tool/qt.py336
-rw-r--r--engine/SCons/Tool/rmic.py126
-rw-r--r--engine/SCons/Tool/rpcgen.py70
-rw-r--r--engine/SCons/Tool/rpm.py132
-rw-r--r--engine/SCons/Tool/rpmutils.py543
-rw-r--r--engine/SCons/Tool/sgiar.py68
-rw-r--r--engine/SCons/Tool/sgic++.py58
-rw-r--r--engine/SCons/Tool/sgicc.py53
-rw-r--r--engine/SCons/Tool/sgilink.py62
-rw-r--r--engine/SCons/Tool/sunar.py67
-rw-r--r--engine/SCons/Tool/sunc++.py142
-rw-r--r--engine/SCons/Tool/suncc.py58
-rw-r--r--engine/SCons/Tool/sunf77.py63
-rw-r--r--engine/SCons/Tool/sunf90.py64
-rw-r--r--engine/SCons/Tool/sunf95.py64
-rw-r--r--engine/SCons/Tool/sunlink.py76
-rw-r--r--engine/SCons/Tool/swig.py184
-rw-r--r--engine/SCons/Tool/tar.py73
-rw-r--r--engine/SCons/Tool/tex.py992
-rw-r--r--engine/SCons/Tool/textfile.py175
-rw-r--r--engine/SCons/Tool/tlib.py53
-rw-r--r--engine/SCons/Tool/wix.py104
-rw-r--r--engine/SCons/Tool/xgettext.py339
-rw-r--r--engine/SCons/Tool/yacc.py140
-rw-r--r--engine/SCons/Tool/zip.py100
126 files changed, 20476 insertions, 0 deletions
diff --git a/engine/SCons/Tool/386asm.py b/engine/SCons/Tool/386asm.py
new file mode 100644
index 0000000..ae45eec
--- /dev/null
+++ b/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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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/engine/SCons/Tool/BitKeeper.py b/engine/SCons/Tool/BitKeeper.py
new file mode 100644
index 0000000..3ca3d2c
--- /dev/null
+++ b/engine/SCons/Tool/BitKeeper.py
@@ -0,0 +1,67 @@
+"""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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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):
+ """ """
+ import SCons.Warnings as W
+ W.warn(W.DeprecatedSourceCodeWarning, """The BitKeeper() factory is deprecated and there is no replacement.""")
+ 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/engine/SCons/Tool/CVS.py b/engine/SCons/Tool/CVS.py
new file mode 100644
index 0000000..2ac30d2
--- /dev/null
+++ b/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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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):
+ """ """
+ import SCons.Warnings as W
+ W.warn(W.DeprecatedSourceCodeWarning, """The CVS() factory is deprecated and there is no replacement.""")
+ # 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/engine/SCons/Tool/DCommon.py b/engine/SCons/Tool/DCommon.py
new file mode 100644
index 0000000..616469e
--- /dev/null
+++ b/engine/SCons/Tool/DCommon.py
@@ -0,0 +1,56 @@
+"""SCons.Tool.DCommon
+
+Common code for the various D tools.
+
+Coded by Russel Winder (russel@winder.org.uk)
+2012-09-06
+"""
+#
+# Copyright (c) 2001 - 2014 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/DCommon.py 2014/09/27 12:51:43 garyo"
+
+import os.path
+
+def isD(env, 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
+
+def addDPATHToEnv(env, executable):
+ dPath = env.WhereIs(executable)
+ if dPath:
+ phobosDir = dPath[:dPath.rindex(executable)] + '/../src/phobos'
+ if os.path.isdir(phobosDir):
+ env.Append(DPATH=[phobosDir])
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/engine/SCons/Tool/FortranCommon.py b/engine/SCons/Tool/FortranCommon.py
new file mode 100644
index 0000000..dcd1166
--- /dev/null
+++ b/engine/SCons/Tool/FortranCommon.py
@@ -0,0 +1,263 @@
+"""SCons.Tool.FortranCommon
+
+Stuff for processing Fortran, common to all fortran dialects.
+
+"""
+
+#
+# Copyright (c) 2001 - 2014 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 2014/09/27 12:51:43 garyo"
+
+import re
+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 = [x.lower() + suffix for x in 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 = s.upper()
+ upper_suffixes = [_.upper() for _ in 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 '%sFLAGS' % dialect not in env:
+ env['%sFLAGS' % dialect] = SCons.Util.CLVar('')
+
+ if 'SH%sFLAGS' % dialect not in env:
+ 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 'INC%sPREFIX' % dialect not in env:
+ env['INC%sPREFIX' % dialect] = '$INCPREFIX'
+
+ if 'INC%sSUFFIX' % dialect not in env:
+ 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_f03_to_env(env):
+ """Add Builders and construction variables for f03 to an Environment."""
+ try:
+ F03Suffixes = env['F03FILESUFFIXES']
+ except KeyError:
+ F03Suffixes = ['.f03']
+
+ #print "Adding %s to f95 suffixes" % F95Suffixes
+ try:
+ F03PPSuffixes = env['F03PPFILESUFFIXES']
+ except KeyError:
+ F03PPSuffixes = []
+
+ DialectAddToEnv(env, "F03", F03Suffixes, F03PPSuffixes,
+ 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)
+ add_f03_to_env(env)
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/engine/SCons/Tool/GettextCommon.py b/engine/SCons/Tool/GettextCommon.py
new file mode 100644
index 0000000..1d1e505
--- /dev/null
+++ b/engine/SCons/Tool/GettextCommon.py
@@ -0,0 +1,430 @@
+"""SCons.Tool.GettextCommon module
+
+Used by several tools of `gettext` toolset.
+"""
+
+# Copyright (c) 2001 - 2014 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/GettextCommon.py 2014/09/27 12:51:43 garyo"
+
+import SCons.Warnings
+import re
+
+#############################################################################
+class XgettextToolWarning(SCons.Warnings.Warning): pass
+class XgettextNotFound(XgettextToolWarning): pass
+class MsginitToolWarning(SCons.Warnings.Warning): pass
+class MsginitNotFound(MsginitToolWarning): pass
+class MsgmergeToolWarning(SCons.Warnings.Warning): pass
+class MsgmergeNotFound(MsgmergeToolWarning): pass
+class MsgfmtToolWarning(SCons.Warnings.Warning): pass
+class MsgfmtNotFound(MsgfmtToolWarning): pass
+#############################################################################
+SCons.Warnings.enableWarningClass(XgettextToolWarning)
+SCons.Warnings.enableWarningClass(XgettextNotFound)
+SCons.Warnings.enableWarningClass(MsginitToolWarning)
+SCons.Warnings.enableWarningClass(MsginitNotFound)
+SCons.Warnings.enableWarningClass(MsgmergeToolWarning)
+SCons.Warnings.enableWarningClass(MsgmergeNotFound)
+SCons.Warnings.enableWarningClass(MsgfmtToolWarning)
+SCons.Warnings.enableWarningClass(MsgfmtNotFound)
+#############################################################################
+
+#############################################################################
+class _POTargetFactory(object):
+ """ A factory of `PO` target files.
+
+ Factory defaults differ from these of `SCons.Node.FS.FS`. We set `precious`
+ (this is required by builders and actions gettext) and `noclean` flags by
+ default for all produced nodes.
+ """
+ def __init__( self, env, nodefault = True, alias = None, precious = True
+ , noclean = True ):
+ """ Object constructor.
+
+ **Arguments**
+
+ - *env* (`SCons.Environment.Environment`)
+ - *nodefault* (`boolean`) - if `True`, produced nodes will be ignored
+ from default target `'.'`
+ - *alias* (`string`) - if provided, produced nodes will be automatically
+ added to this alias, and alias will be set as `AlwaysBuild`
+ - *precious* (`boolean`) - if `True`, the produced nodes will be set as
+ `Precious`.
+ - *noclen* (`boolean`) - if `True`, the produced nodes will be excluded
+ from `Clean`.
+ """
+ self.env = env
+ self.alias = alias
+ self.precious = precious
+ self.noclean = noclean
+ self.nodefault = nodefault
+
+ def _create_node(self, name, factory, directory = None, create = 1):
+ """ Create node, and set it up to factory settings. """
+ import SCons.Util
+ node = factory(name, directory, create)
+ node.set_noclean(self.noclean)
+ node.set_precious(self.precious)
+ if self.nodefault:
+ self.env.Ignore('.', node)
+ if self.alias:
+ self.env.AlwaysBuild(self.env.Alias(self.alias, node))
+ return node
+
+ def Entry(self, name, directory = None, create = 1):
+ """ Create `SCons.Node.FS.Entry` """
+ return self._create_node(name, self.env.fs.Entry, directory, create)
+
+ def File(self, name, directory = None, create = 1):
+ """ Create `SCons.Node.FS.File` """
+ return self._create_node(name, self.env.fs.File, directory, create)
+#############################################################################
+
+#############################################################################
+_re_comment = re.compile(r'(#[^\n\r]+)$', re.M)
+_re_lang = re.compile(r'([a-zA-Z0-9_]+)', re.M)
+#############################################################################
+def _read_linguas_from_files(env, linguas_files = None):
+ """ Parse `LINGUAS` file and return list of extracted languages """
+ import SCons.Util
+ import SCons.Environment
+ global _re_comment
+ global _re_lang
+ if not SCons.Util.is_List(linguas_files) \
+ and not SCons.Util.is_String(linguas_files) \
+ and not isinstance(linguas_files, SCons.Node.FS.Base) \
+ and linguas_files:
+ # If, linguas_files==True or such, then read 'LINGUAS' file.
+ linguas_files = [ 'LINGUAS' ]
+ if linguas_files is None:
+ return []
+ fnodes = env.arg2nodes(linguas_files)
+ linguas = []
+ for fnode in fnodes:
+ contents = _re_comment.sub("", fnode.get_text_contents())
+ ls = [ l for l in _re_lang.findall(contents) if l ]
+ linguas.extend(ls)
+ return linguas
+#############################################################################
+
+#############################################################################
+from SCons.Builder import BuilderBase
+#############################################################################
+class _POFileBuilder(BuilderBase):
+ """ `PO` file builder.
+
+ This is multi-target single-source builder. In typical situation the source
+ is single `POT` file, e.g. `messages.pot`, and there are multiple `PO`
+ targets to be updated from this `POT`. We must run
+ `SCons.Builder.BuilderBase._execute()` separatelly for each target to track
+ dependencies separatelly for each target file.
+
+ **NOTE**: if we call `SCons.Builder.BuilderBase._execute(.., target, ...)`
+ with target being list of all targets, all targets would be rebuilt each time
+ one of the targets from this list is missing. This would happen, for example,
+ when new language `ll` enters `LINGUAS_FILE` (at this moment there is no
+ `ll.po` file yet). To avoid this, we override
+ `SCons.Builder.BuilerBase._execute()` and call it separatelly for each
+ target. Here we also append to the target list the languages read from
+ `LINGUAS_FILE`.
+ """
+ #
+ #* The argument for overriding _execute(): We must use environment with
+ # builder overrides applied (see BuilderBase.__init__(). Here it comes for
+ # free.
+ #* The argument against using 'emitter': The emitter is called too late
+ # by BuilderBase._execute(). If user calls, for example:
+ #
+ # env.POUpdate(LINGUAS_FILE = 'LINGUAS')
+ #
+ # the builder throws error, because it is called with target=None,
+ # source=None and is trying to "generate" sources or target list first.
+ # If user calls
+ #
+ # env.POUpdate(['foo', 'baz'], LINGUAS_FILE = 'LINGUAS')
+ #
+ # the env.BuilderWrapper() calls our builder with target=None,
+ # source=['foo', 'baz']. The BuilderBase._execute() then splits execution
+ # and execute iterativelly (recursion) self._execute(None, source[i]).
+ # After that it calls emitter (which is quite too late). The emitter is
+ # also called in each iteration, what makes things yet worse.
+ def __init__(self, env, **kw):
+ if not 'suffix' in kw:
+ kw['suffix'] = '$POSUFFIX'
+ if not 'src_suffix' in kw:
+ kw['src_suffix'] = '$POTSUFFIX'
+ if not 'src_builder' in kw:
+ kw['src_builder'] = '_POTUpdateBuilder'
+ if not 'single_source' in kw:
+ kw['single_source'] = True
+ alias = None
+ if 'target_alias' in kw:
+ alias = kw['target_alias']
+ del kw['target_alias']
+ if not 'target_factory' in kw:
+ kw['target_factory'] = _POTargetFactory(env, alias=alias).File
+ BuilderBase.__init__(self, **kw)
+
+ def _execute(self, env, target, source, *args, **kw):
+ """ Execute builder's actions.
+
+ Here we append to `target` the languages read from `$LINGUAS_FILE` and
+ apply `SCons.Builder.BuilderBase._execute()` separatelly to each target.
+ The arguments and return value are same as for
+ `SCons.Builder.BuilderBase._execute()`.
+ """
+ import SCons.Util
+ import SCons.Node
+ linguas_files = None
+ if env.has_key('LINGUAS_FILE') and env['LINGUAS_FILE']:
+ linguas_files = env['LINGUAS_FILE']
+ # This prevents endless recursion loop (we'll be invoked once for
+ # each target appended here, we must not extend the list again).
+ env['LINGUAS_FILE'] = None
+ linguas = _read_linguas_from_files(env,linguas_files)
+ if SCons.Util.is_List(target):
+ target.extend(linguas)
+ elif target is not None:
+ target = [target] + linguas
+ else:
+ target = linguas
+ if not target:
+ # Let the SCons.BuilderBase to handle this patologic situation
+ return BuilderBase._execute( self, env, target, source, *args, **kw)
+ # The rest is ours
+ if not SCons.Util.is_List(target):
+ target = [ target ]
+ result = []
+ for tgt in target:
+ r = BuilderBase._execute( self, env, [tgt], source, *args, **kw)
+ result.extend(r)
+ if linguas_files is not None:
+ env['LINGUAS_FILE'] = linguas_files
+ return SCons.Node.NodeList(result)
+#############################################################################
+
+import SCons.Environment
+#############################################################################
+def _translate(env, target=None, source=SCons.Environment._null, *args, **kw):
+ """ Function for `Translate()` pseudo-builder """
+ if target is None: target = []
+ pot = env.POTUpdate(None, source, *args, **kw)
+ po = env.POUpdate(target, pot, *args, **kw)
+ return po
+#############################################################################
+
+#############################################################################
+class RPaths(object):
+ """ Callable object, which returns pathnames relative to SCons current
+ working directory.
+
+ It seems like `SCons.Node.FS.Base.get_path()` returns absolute paths
+ for nodes that are outside of current working directory (`env.fs.getcwd()`).
+ Here, we often have `SConscript`, `POT` and `PO` files within `po/`
+ directory and source files (e.g. `*.c`) outside of it. When generating `POT`
+ template file, references to source files are written to `POT` template, so
+ a translator may later quickly jump to appropriate source file and line from
+ its `PO` editor (e.g. `poedit`). Relative paths in `PO` file are usually
+ interpreted by `PO` editor as paths relative to the place, where `PO` file
+ lives. The absolute paths would make resultant `POT` file nonportable, as
+ the references would be correct only on the machine, where `POT` file was
+ recently re-created. For such reason, we need a function, which always
+ returns relative paths. This is the purpose of `RPaths` callable object.
+
+ The `__call__` method returns paths relative to current woking directory, but
+ we assume, that *xgettext(1)* is run from the directory, where target file is
+ going to be created.
+
+ Note, that this may not work for files distributed over several hosts or
+ across different drives on windows. We assume here, that single local
+ filesystem holds both source files and target `POT` templates.
+
+ Intended use of `RPaths` - in `xgettext.py`::
+
+ def generate(env):
+ from GettextCommon import RPaths
+ ...
+ sources = '$( ${_concat( "", SOURCES, "", __env__, XgettextRPaths, TARGET, SOURCES)} $)'
+ env.Append(
+ ...
+ XGETTEXTCOM = 'XGETTEXT ... ' + sources,
+ ...
+ XgettextRPaths = RPaths(env)
+ )
+ """
+ # NOTE: This callable object returns pathnames of dirs/files relative to
+ # current working directory. The pathname remains relative also for entries
+ # that are outside of current working directory (node, that
+ # SCons.Node.FS.File and siblings return absolute path in such case). For
+ # simplicity we compute path relative to current working directory, this
+ # seems be enough for our purposes (don't need TARGET variable and
+ # SCons.Defaults.Variable_Caller stuff).
+
+ def __init__(self, env):
+ """ Initialize `RPaths` callable object.
+
+ **Arguments**:
+
+ - *env* - a `SCons.Environment.Environment` object, defines *current
+ working dir*.
+ """
+ self.env = env
+
+ # FIXME: I'm not sure, how it should be implemented (what the *args are in
+ # general, what is **kw).
+ def __call__(self, nodes, *args, **kw):
+ """ Return nodes' paths (strings) relative to current working directory.
+
+ **Arguments**:
+
+ - *nodes* ([`SCons.Node.FS.Base`]) - list of nodes.
+ - *args* - currently unused.
+ - *kw* - currently unused.
+
+ **Returns**:
+
+ - Tuple of strings, which represent paths relative to current working
+ directory (for given environment).
+ """
+ # os.path.relpath is available only on python >= 2.6. We use our own
+ # implementation. It's taken from BareNecessities package:
+ # http://jimmyg.org/work/code/barenecessities/index.html
+ from posixpath import curdir
+ def relpath(path, start=curdir):
+ import posixpath
+ """Return a relative version of a path"""
+ if not path:
+ raise ValueError("no path specified")
+ start_list = posixpath.abspath(start).split(posixpath.sep)
+ path_list = posixpath.abspath(path).split(posixpath.sep)
+ # Work out how much of the filepath is shared by start and path.
+ i = len(posixpath.commonprefix([start_list, path_list]))
+ rel_list = [posixpath.pardir] * (len(start_list)-i) + path_list[i:]
+ if not rel_list:
+ return posixpath.curdir
+ return posixpath.join(*rel_list)
+ import os
+ import SCons.Node.FS
+ rpaths = ()
+ cwd = self.env.fs.getcwd().get_abspath()
+ for node in nodes:
+ rpath = None
+ if isinstance(node, SCons.Node.FS.Base):
+ rpath = relpath(node.get_abspath(), cwd)
+ # FIXME: Other types possible here?
+ if rpath is not None:
+ rpaths += (rpath,)
+ return rpaths
+#############################################################################
+
+#############################################################################
+def _init_po_files(target, source, env):
+ """ Action function for `POInit` builder. """
+ nop = lambda target, source, env : 0
+ if env.has_key('POAUTOINIT'):
+ autoinit = env['POAUTOINIT']
+ else:
+ autoinit = False
+ # Well, if everything outside works well, this loop should do single
+ # iteration. Otherwise we are rebuilding all the targets even, if just
+ # one has changed (but is this out fault?).
+ for tgt in target:
+ if not tgt.exists():
+ if autoinit:
+ action = SCons.Action.Action('$MSGINITCOM', '$MSGINITCOMSTR')
+ else:
+ msg = 'File ' + repr(str(tgt)) + ' does not exist. ' \
+ + 'If you are a translator, you can create it through: \n' \
+ + '$MSGINITCOM'
+ action = SCons.Action.Action(nop, msg)
+ status = action([tgt], source, env)
+ if status: return status
+ return 0
+#############################################################################
+
+#############################################################################
+def _detect_xgettext(env):
+ """ Detects *xgettext(1)* binary """
+ if env.has_key('XGETTEXT'):
+ return env['XGETTEXT']
+ xgettext = env.Detect('xgettext');
+ if xgettext:
+ return xgettext
+ raise SCons.Errors.StopError(XgettextNotFound,"Could not detect xgettext")
+ return None
+#############################################################################
+def _xgettext_exists(env):
+ return _detect_xgettext(env)
+#############################################################################
+
+#############################################################################
+def _detect_msginit(env):
+ """ Detects *msginit(1)* program. """
+ if env.has_key('MSGINIT'):
+ return env['MSGINIT']
+ msginit = env.Detect('msginit');
+ if msginit:
+ return msginit
+ raise SCons.Errors.StopError(MsginitNotFound, "Could not detect msginit")
+ return None
+#############################################################################
+def _msginit_exists(env):
+ return _detect_msginit(env)
+#############################################################################
+
+#############################################################################
+def _detect_msgmerge(env):
+ """ Detects *msgmerge(1)* program. """
+ if env.has_key('MSGMERGE'):
+ return env['MSGMERGE']
+ msgmerge = env.Detect('msgmerge');
+ if msgmerge:
+ return msgmerge
+ raise SCons.Errors.StopError(MsgmergeNotFound, "Could not detect msgmerge")
+ return None
+#############################################################################
+def _msgmerge_exists(env):
+ return _detect_msgmerge(env)
+#############################################################################
+
+#############################################################################
+def _detect_msgfmt(env):
+ """ Detects *msgmfmt(1)* program. """
+ if env.has_key('MSGFMT'):
+ return env['MSGFMT']
+ msgfmt = env.Detect('msgfmt');
+ if msgfmt:
+ return msgfmt
+ raise SCons.Errors.StopError(MsgfmtNotFound, "Could not detect msgfmt")
+ return None
+#############################################################################
+def _msgfmt_exists(env):
+ return _detect_msgfmt(env)
+#############################################################################
+
+#############################################################################
+def tool_list(platform, env):
+ """ List tools that shall be generated by top-level `gettext` tool """
+ return [ 'xgettext', 'msginit', 'msgmerge', 'msgfmt' ]
+#############################################################################
+
diff --git a/engine/SCons/Tool/JavaCommon.py b/engine/SCons/Tool/JavaCommon.py
new file mode 100644
index 0000000..13cfc2b
--- /dev/null
+++ b/engine/SCons/Tool/JavaCommon.py
@@ -0,0 +1,324 @@
+"""SCons.Tool.JavaCommon
+
+Stuff for processing Java.
+
+"""
+
+#
+# Copyright (c) 2001 - 2014 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 2014/09/27 12:51:43 garyo"
+
+import os
+import os.path
+import re
+
+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(object):
+ """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', '1.7',
+ '1.8', '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('$'.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', '1.7', '1.8', '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('$'.join(className))
+
+ self.nextAnon = self.nextAnon + 1
+ self.__getAnonStack().append(0)
+
+ def setPackage(self, package):
+ self.package = package
+
+ class AnonClassState(object):
+ """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(object):
+ """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(object):
+ """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'
+ # http://scons.tigris.org/issues/show_bug.cgi?id=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(object):
+ """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(object):
+ """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 = initial.package.replace('.', 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/engine/SCons/Tool/MSCommon/__init__.py b/engine/SCons/Tool/MSCommon/__init__.py
new file mode 100644
index 0000000..7c05452
--- /dev/null
+++ b/engine/SCons/Tool/MSCommon/__init__.py
@@ -0,0 +1,56 @@
+#
+# Copyright (c) 2001 - 2014 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 2014/09/27 12:51:43 garyo"
+
+__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/engine/SCons/Tool/MSCommon/arch.py b/engine/SCons/Tool/MSCommon/arch.py
new file mode 100644
index 0000000..10b4db7
--- /dev/null
+++ b/engine/SCons/Tool/MSCommon/arch.py
@@ -0,0 +1,61 @@
+#
+# Copyright (c) 2001 - 2014 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 2014/09/27 12:51:43 garyo"
+
+__doc__ = """Module to define supported Windows chip architectures.
+"""
+
+import os
+
+class ArchDefinition(object):
+ """
+ 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/engine/SCons/Tool/MSCommon/common.py b/engine/SCons/Tool/MSCommon/common.py
new file mode 100644
index 0000000..0a726ec
--- /dev/null
+++ b/engine/SCons/Tool/MSCommon/common.py
@@ -0,0 +1,260 @@
+#
+# Copyright (c) 2001 - 2014 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 2014/09/27 12:51:43 garyo"
+
+__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.
+
+ # Apparently the best solution is to use env vars that Windows
+ # sets. If PROCESSOR_ARCHITECTURE is not x86, then the python
+ # process is running in 64 bit mode (on a 64-bit OS, 64-bit
+ # hardware, obviously).
+ # If this python is 32-bit but the OS is 64, Windows will set
+ # ProgramW6432 and PROCESSOR_ARCHITEW6432 to non-null.
+ # (Checking for HKLM\Software\Wow6432Node in the registry doesn't
+ # work, because some 32-bit installers create it.)
+ global _is_win64
+ if _is_win64 is None:
+ # I structured these tests to make it easy to add new ones or
+ # add exceptions in the future, because this is a bit fragile.
+ _is_win64 = False
+ if os.environ.get('PROCESSOR_ARCHITECTURE','x86') != 'x86':
+ _is_win64 = True
+ if os.environ.get('PROCESSOR_ARCHITEW6432'):
+ _is_win64 = True
+ if os.environ.get('ProgramW6432'):
+ _is_win64 = True
+ 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, force=False):
+ """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.
+
+ If force=True, then all of the key values that exist are copied
+ into the returned dictionary. If force=false, values are only
+ copied if the key does not already exist in the copied dictionary.
+
+ 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 k in os.environ and (force or not k in normenv):
+ normenv[k] = os.environ[k].encode('mbcs')
+
+ # This shouldn't be necessary, since the default environment should include system32,
+ # but keep this here to be safe, since it's needed to find reg.exe which the MSVC
+ # bat scripts use.
+ sys32_dir = os.path.join(os.environ.get("SystemRoot", os.environ.get("windir",r"C:\Windows\system32")),"System32")
+
+ if sys32_dir not in normenv['PATH']:
+ normenv['PATH'] = normenv['PATH'] + os.pathsep + sys32_dir
+
+ debug("PATH: %s"%normenv['PATH'])
+
+ return normenv
+
+def get_output(vcbat, args = None, env = None):
+ """Parse the output of given bat file, with given args."""
+
+ if env is None:
+ # Create a blank environment, for use in launching the tools
+ env = SCons.Environment.Environment(tools=[])
+
+ # TODO: This is a hard-coded list of the variables that (may) need
+ # to be imported from os.environ[] for v[sc]*vars*.bat file
+ # execution to work. This list should really be either directly
+ # controlled by vc.py, or else derived from the common_tools_var
+ # settings in vs.py.
+ vars = [
+ 'COMSPEC',
+# VS100 and VS110: Still set, but modern MSVC setup scripts will
+# discard these if registry has values. However Intel compiler setup
+# script still requires these as of 2013/2014.
+ 'VS110COMNTOOLS',
+ 'VS100COMNTOOLS',
+ 'VS90COMNTOOLS',
+ 'VS80COMNTOOLS',
+ 'VS71COMNTOOLS',
+ 'VS70COMNTOOLS',
+ 'VS60COMNTOOLS',
+ ]
+ env['ENV'] = normalize_env(env['ENV'], vars, force=False)
+
+ if args:
+ debug("Calling '%s %s'" % (vcbat, args))
+ popen = SCons.Action._subproc(env,
+ '"%s" %s & set' % (vcbat, args),
+ stdin = 'devnull',
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ else:
+ debug("Calling '%s'" % vcbat)
+ popen = SCons.Action._subproc(env,
+ '"%s" & set' % vcbat,
+ stdin = 'devnull',
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+
+ # 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()
+ stderr = popen.stderr.read()
+
+ # Extra debug logic, uncomment if necessar
+# debug('get_output():stdout:%s'%stdout)
+# debug('get_output():stderr:%s'%stderr)
+
+ if stderr:
+ # TODO: find something better to do with stderr;
+ # this at least prevents errors from getting swallowed.
+ import sys
+ sys.stderr.write(stderr)
+ if popen.wait() != 0:
+ raise IOError(stderr.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
+
+ dkeep = dict([(i, []) for i in 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/engine/SCons/Tool/MSCommon/netframework.py b/engine/SCons/Tool/MSCommon/netframework.py
new file mode 100644
index 0000000..6c6dcf6
--- /dev/null
+++ b/engine/SCons/Tool/MSCommon/netframework.py
@@ -0,0 +1,82 @@
+#
+# Copyright (c) 2001 - 2014 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 2014/09/27 12:51:43 garyo"
+
+__doc__ = """
+"""
+
+import os
+import re
+
+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 = [e for e in contents if l.match(e)]
+
+ def versrt(a,b):
+ # since version numbers aren't really floats...
+ aa = a[1:]
+ bb = b[1:]
+ aal = aa.split('.')
+ bbl = bb.split('.')
+ # 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/engine/SCons/Tool/MSCommon/sdk.py b/engine/SCons/Tool/MSCommon/sdk.py
new file mode 100644
index 0000000..d654fc6
--- /dev/null
+++ b/engine/SCons/Tool/MSCommon/sdk.py
@@ -0,0 +1,391 @@
+#
+# Copyright (c) 2001 - 2014 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 2014/09/27 12:51:43 garyo"
+
+__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(object):
+ """
+ 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
+ debug('find_sdk_dir(): checking registry:%s'%hkey)
+
+ try:
+ sdk_dir = common.read_reg(hkey)
+ except WindowsError, e:
+ debug('find_sdk_dir(): no SDK registry key %s' % repr(hkey))
+ return None
+
+ debug('find_sdk_dir(): Trying SDK Dir: %s'%sdk_dir)
+
+ 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
+
+ def get_sdk_vc_script(self,host_arch, target_arch):
+ """ Return the script to initialize the VC compiler installed by SDK
+ """
+
+ if (host_arch == 'amd64' and target_arch == 'x86'):
+ # No cross tools needed compiling 32 bits on 64 bit machine
+ host_arch=target_arch
+
+ arch_string=target_arch
+ if (host_arch != target_arch):
+ arch_string='%s_%s'%(host_arch,target_arch)
+
+ debug("sdk.py: get_sdk_vc_script():arch_string:%s host_arch:%s target_arch:%s"%(arch_string,
+ host_arch,
+ target_arch))
+ file=self.vc_setup_scripts.get(arch_string,None)
+ debug("sdk.py: get_sdk_vc_script():file:%s"%file)
+ return file
+
+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):
+ 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):
+ SDKDefinition.__init__(self, *args, **kw)
+ self.hkey_data = self.uuid
+
+#
+# The list of VC initialization scripts installed by the SDK
+# These should be tried if the vcvarsall.bat TARGET_ARCH fails
+preSDK61VCSetupScripts = { 'x86' : r'bin\vcvars32.bat',
+ 'amd64' : r'bin\vcvarsamd64.bat',
+ 'x86_amd64': r'bin\vcvarsx86_amd64.bat',
+ 'x86_ia64' : r'bin\vcvarsx86_ia64.bat',
+ 'ia64' : r'bin\vcvarsia64.bat'}
+
+SDK61VCSetupScripts = {'x86' : r'bin\vcvars32.bat',
+ 'amd64' : r'bin\amd64\vcvarsamd64.bat',
+ 'x86_amd64': r'bin\x86_amd64\vcvarsx86_amd64.bat',
+ 'x86_ia64' : r'bin\x86_ia64\vcvarsx86_ia64.bat',
+ 'ia64' : r'bin\ia64\vcvarsia64.bat'}
+
+SDK70VCSetupScripts = { 'x86' : r'bin\vcvars32.bat',
+ 'amd64' : r'bin\vcvars64.bat',
+ 'x86_amd64': r'bin\vcvarsx86_amd64.bat',
+ 'x86_ia64' : r'bin\vcvarsx86_ia64.bat',
+ 'ia64' : r'bin\vcvarsia64.bat'}
+
+# 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('7.0',
+ sanity_check_file=r'bin\SetEnv.Cmd',
+ include_subdir='include',
+ lib_subdir={
+ 'x86' : ['lib'],
+ 'x86_64' : [r'lib\x64'],
+ 'ia64' : [r'lib\ia64'],
+ },
+ vc_setup_scripts = SDK70VCSetupScripts,
+ ),
+ 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'],
+ },
+ vc_setup_scripts = SDK61VCSetupScripts,
+ ),
+
+ 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'],
+ },
+ vc_setup_scripts = preSDK61VCSetupScripts,
+ ),
+
+ WindowsSDK('6.0',
+ sanity_check_file=r'bin\gacutil.exe',
+ include_subdir='include',
+ lib_subdir='lib',
+ vc_setup_scripts = preSDK61VCSetupScripts,
+ ),
+
+ PlatformSDK('2003R2',
+ sanity_check_file=r'SetEnv.Cmd',
+ uuid="D2FF9F89-8AA2-4373-8A31-C838BF4DBBE1",
+ vc_setup_scripts = preSDK61VCSetupScripts,
+ ),
+
+ PlatformSDK('2003R1',
+ sanity_check_file=r'SetEnv.Cmd',
+ uuid="8F9E5EF3-A9A5-491B-A889-C58EFFECE8B3",
+ vc_setup_scripts = preSDK61VCSetupScripts,
+ ),
+]
+
+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
+ debug('sdk.py:get_installed_sdks()')
+ if InstalledSDKList is None:
+ InstalledSDKList = []
+ InstalledSDKMap = {}
+ for sdk in SupportedSDKList:
+ debug('MSCommon/sdk.py: trying to find SDK %s' % sdk.version)
+ if sdk.get_sdk_dir():
+ debug('MSCommon/sdk.py: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
+ debug('set_sdk_by_directory: Using dir:%s'%sdk_dir)
+ 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 mssdk not in SupportedSDKMap:
+ 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('sdk.py:mssdk_setup_env()')
+ if 'MSSDK_DIR' in env:
+ sdk_dir = env['MSSDK_DIR']
+ if sdk_dir is None:
+ return
+ sdk_dir = env.subst(sdk_dir)
+ debug('sdk.py:mssdk_setup_env: Using MSSDK_DIR:%s'%sdk_dir)
+ elif 'MSSDK_VERSION' in env:
+ 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()
+ debug('sdk.py:mssdk_setup_env: Using MSSDK_VERSION:%s'%sdk_dir)
+ elif 'MSVS_VERSION' in env:
+ msvs_version = env['MSVS_VERSION']
+ debug('sdk.py:mssdk_setup_env:Getting MSVS_VERSION from env:%s'%msvs_version)
+ if msvs_version is None:
+ debug('sdk.py:mssdk_setup_env thinks msvs_version is None')
+ return
+ msvs_version = env.subst(msvs_version)
+ import vs
+ msvs = vs.get_vs_by_version(msvs_version)
+ debug('sdk.py:mssdk_setup_env:msvs is :%s'%msvs)
+ if not msvs:
+ debug('sdk.py:mssdk_setup_env: no VS version detected, bailingout:%s'%msvs)
+ return
+ sdk_version = msvs.sdk_version
+ debug('sdk.py:msvs.sdk_version is %s'%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()
+ debug('sdk.py:mssdk_setup_env: Using MSVS_VERSION:%s'%sdk_dir)
+ else:
+ mssdk = get_default_sdk()
+ if not mssdk:
+ return
+ sdk_dir = mssdk.get_sdk_dir()
+ debug('sdk.py:mssdk_setup_env: not using any env values. sdk_dir:%s'%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 version in sdks
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/engine/SCons/Tool/MSCommon/vc.py b/engine/SCons/Tool/MSCommon/vc.py
new file mode 100644
index 0000000..e9c8597
--- /dev/null
+++ b/engine/SCons/Tool/MSCommon/vc.py
@@ -0,0 +1,501 @@
+#
+# Copyright (c) 2001 - 2014 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 2014/09/27 12:51:43 garyo"
+
+__doc__ = """Module for Visual C/C++ detection and configuration.
+"""
+import SCons.compat
+
+import os
+import platform
+from string import digits as string_digits
+
+import SCons.Warnings
+
+import common
+
+debug = common.debug
+
+import sdk
+
+get_installed_sdks = sdk.get_installed_sdks
+
+
+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 = {
+ "amd64" : "amd64",
+ "emt64" : "amd64",
+ "i386" : "x86",
+ "i486" : "x86",
+ "i586" : "x86",
+ "i686" : "x86",
+ "ia64" : "ia64",
+ "itanium" : "ia64",
+ "x86" : "x86",
+ "x86_64" : "amd64",
+ "x86_amd64" : "x86_amd64", # Cross compile to 64 bit from 32bits
+}
+
+# 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",
+ ("x86", "x86_amd64"): "x86_amd64",
+ ("amd64", "x86_amd64"): "x86_amd64", # This is present in (at least) VS2012 express
+ ("amd64", "amd64"): "amd64",
+ ("amd64", "x86"): "x86",
+ ("x86", "ia64"): "x86_ia64"
+}
+
+def get_host_target(env):
+ debug('vc.py:get_host_target()')
+
+ 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', '')
+
+ # Retain user requested TARGET_ARCH
+ req_target_platform = env.get('TARGET_ARCH')
+ debug('vc.py:get_host_target() req_target_platform:%s'%req_target_platform)
+
+ if req_target_platform:
+ # If user requested a specific platform then only try that one.
+ target_platform = req_target_platform
+ else:
+ target_platform = host_platform
+
+ try:
+ host = _ARCH_TO_CANONICAL[host_platform.lower()]
+ except KeyError, e:
+ msg = "Unrecognized host architecture %s"
+ raise ValueError(msg % repr(host_platform))
+
+ try:
+ target = _ARCH_TO_CANONICAL[target_platform.lower()]
+ except KeyError, e:
+ all_archs = str(_ARCH_TO_CANONICAL.keys())
+ raise ValueError("Unrecognized target architecture %s\n\tValid architectures: %s" % (target_platform, all_archs))
+
+ return (host, target,req_target_platform)
+
+# If you update this, update SupportedVSList in Tool/MSCommon/vs.py, and the
+# MSVC_VERSION documentation in Tool/msvc.xml.
+_VCVER = ["12.0", "12.0Exp", "11.0", "11.0Exp", "10.0", "10.0Exp", "9.0", "9.0Exp","8.0", "8.0Exp","7.1", "7.0", "6.0"]
+
+_VCVER_TO_PRODUCT_DIR = {
+ '12.0' : [
+ r'Microsoft\VisualStudio\12.0\Setup\VC\ProductDir'],
+ '12.0Exp' : [
+ r'Microsoft\VCExpress\12.0\Setup\VC\ProductDir'],
+ '11.0': [
+ r'Microsoft\VisualStudio\11.0\Setup\VC\ProductDir'],
+ '11.0Exp' : [
+ r'Microsoft\VCExpress\11.0\Setup\VC\ProductDir'],
+ '10.0': [
+ r'Microsoft\VisualStudio\10.0\Setup\VC\ProductDir'],
+ '10.0Exp' : [
+ r'Microsoft\VCExpress\10.0\Setup\VC\ProductDir'],
+ '9.0': [
+ r'Microsoft\VisualStudio\9.0\Setup\VC\ProductDir'],
+ '9.0Exp' : [
+ r'Microsoft\VCExpress\9.0\Setup\VC\ProductDir'],
+ '8.0': [
+ r'Microsoft\VisualStudio\8.0\Setup\VC\ProductDir'],
+ '8.0Exp': [
+ 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):
+ msvc_version_numeric = ''.join([x for x in msvc_version if x in string_digits + '.'])
+
+ t = msvc_version_numeric.split(".")
+ if not len(t) == 2:
+ raise ValueError("Unrecognized version %s (%s)" % (msvc_version,msvc_version_numeric))
+ try:
+ maj = int(t[0])
+ min = int(t[1])
+ return maj, min
+ except ValueError, e:
+ raise ValueError("Unrecognized version %s (%s)" % (msvc_version,msvc_version_numeric))
+
+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(env,msvc_version,host_arch,target_arch):
+ """
+ Find the location of the batch script which should set up the compiler
+ for any TARGET_ARCH whose compilers were installed by Visual Studio/VCExpress
+ """
+ pdir = find_vc_pdir(msvc_version)
+ if pdir is None:
+ raise NoVersionFound("No version of Visual Studio found")
+
+ debug('vc.py: find_batch_file() pdir:%s'%pdir)
+
+ # filter out e.g. "Exp" from the version name
+ msvc_ver_numeric = ''.join([x for x in msvc_version if x in string_digits + "."])
+ vernum = float(msvc_ver_numeric)
+ 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 not os.path.exists(batfilename):
+ debug("Not found: %s" % batfilename)
+ batfilename = None
+
+ installed_sdks=get_installed_sdks()
+ for _sdk in installed_sdks:
+ sdk_bat_file = _sdk.get_sdk_vc_script(host_arch,target_arch)
+ if not sdk_bat_file:
+ debug("vc.py:find_batch_file() not found:%s"%_sdk)
+ else:
+ sdk_bat_file_path = os.path.join(pdir,sdk_bat_file)
+ if os.path.exists(sdk_bat_file_path):
+ debug('vc.py:find_batch_file() sdk_bat_file_path:%s'%sdk_bat_file_path)
+ return (batfilename,sdk_bat_file_path)
+ return (batfilename,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
+
+# Running these batch files isn't cheap: most of the time spent in
+# msvs.generate() is due to vcvars*.bat. In a build that uses "tools='msvs'"
+# in multiple environments, for example:
+# env1 = Environment(tools='msvs')
+# env2 = Environment(tools='msvs')
+# we can greatly improve the speed of the second and subsequent Environment
+# (or Clone) calls by memoizing the environment variables set by vcvars*.bat.
+script_env_stdout_cache = {}
+def script_env(script, args=None):
+ cache_key = (script, args)
+ stdout = script_env_stdout_cache.get(cache_key, None)
+ if stdout is None:
+ stdout = common.get_output(script, args)
+ script_env_stdout_cache[cache_key] = stdout
+
+ # 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')
+
+ debug('get_default_version(): msvc_version:%s msvs_version:%s'%(msvc_version,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)
+ debug('msvc_setup_env: No installed VCs')
+ 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_find_valid_batch_script(env,version):
+ debug('vc.py:msvc_find_valid_batch_script()')
+ # Find the host platform, target platform, and if present the requested
+ # target platform
+ (host_platform, target_platform,req_target_platform) = get_host_target(env)
+
+ try_target_archs = [target_platform]
+ debug("msvs_find_valid_batch_script(): req_target_platform %s target_platform:%s"%(req_target_platform,target_platform))
+
+ # VS2012 has a "cross compile" environment to build 64 bit
+ # with x86_amd64 as the argument to the batch setup script
+ if req_target_platform in ('amd64','x86_64'):
+ try_target_archs.append('x86_amd64')
+ elif not req_target_platform and target_platform in ['amd64','x86_64']:
+ # There may not be "native" amd64, but maybe "cross" x86_amd64 tools
+ try_target_archs.append('x86_amd64')
+ # If the user hasn't specifically requested a TARGET_ARCH, and
+ # The TARGET_ARCH is amd64 then also try 32 bits if there are no viable
+ # 64 bit tools installed
+ try_target_archs.append('x86')
+
+ debug("msvs_find_valid_batch_script(): host_platform: %s try_target_archs:%s"%(host_platform, try_target_archs))
+
+ d = None
+ for tp in try_target_archs:
+ # Set to current arch.
+ env['TARGET_ARCH']=tp
+
+ debug("vc.py:msvc_find_valid_batch_script() trying target_platform:%s"%tp)
+ host_target = (host_platform, tp)
+ 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]
+
+ # Try to locate a batch file for this host/target platform combo
+ try:
+ (vc_script,sdk_script) = find_batch_file(env,version,host_platform,tp)
+ debug('vc.py:msvc_find_valid_batch_script() vc_script:%s sdk_script:%s'%(vc_script,sdk_script))
+ 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)
+ continue
+
+ # Try to use the located batch file for this host/target platform combo
+ debug('vc.py:msvc_find_valid_batch_script() use_script 2 %s, args:%s\n' % (repr(vc_script), arg))
+ if vc_script:
+ try:
+ d = script_env(vc_script, args=arg)
+ except BatchFileExecutionError, e:
+ debug('vc.py:msvc_find_valid_batch_script() use_script 3: failed running VC script %s: %s: Error:%s'%(repr(vc_script),arg,e))
+ vc_script=None
+ continue
+ if not vc_script and sdk_script:
+ debug('vc.py:msvc_find_valid_batch_script() use_script 4: trying sdk script: %s'%(sdk_script))
+ try:
+ d = script_env(sdk_script)
+ except BatchFileExecutionError,e:
+ debug('vc.py:msvc_find_valid_batch_script() use_script 5: failed running SDK script %s: Error:%s'%(repr(sdk_script),e))
+ continue
+ elif not vc_script and not sdk_script:
+ debug('vc.py:msvc_find_valid_batch_script() use_script 6: Neither VC script nor SDK script found')
+ continue
+
+ debug("vc.py:msvc_find_valid_batch_script() Found a working script/target: %s %s"%(repr(sdk_script),arg))
+ break # We've found a working target_platform, so stop looking
+
+ # If we cannot find a viable installed compiler, reset the TARGET_ARCH
+ # To it's initial value
+ if not d:
+ env['TARGET_ARCH']=req_target_platform
+
+ return d
+
+
+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'] = {}
+
+
+ use_script = env.get('MSVC_USE_SCRIPT', True)
+ if SCons.Util.is_String(use_script):
+ debug('vc.py:msvc_setup_env() use_script 1 %s\n' % repr(use_script))
+ d = script_env(use_script)
+ elif use_script:
+ d = msvc_find_valid_batch_script(env,version)
+ debug('vc.py:msvc_setup_env() use_script 2 %s\n' % d)
+ if not d:
+ return d
+ 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():
+ debug('vc.py:msvc_setup_env() env:%s -> %s'%(k,v))
+ 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/engine/SCons/Tool/MSCommon/vs.py b/engine/SCons/Tool/MSCommon/vs.py
new file mode 100644
index 0000000..858ac20
--- /dev/null
+++ b/engine/SCons/Tool/MSCommon/vs.py
@@ -0,0 +1,544 @@
+#
+# Copyright (c) 2001 - 2014 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 2014/09/27 12:51:43 garyo"
+
+__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(object):
+ """
+ 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 _VCVER and _VCVER_TO_PRODUCT_DIR in
+# Tool/MSCommon/vc.py, and the MSVC_VERSION documentation in Tool/msvc.xml.
+
+SupportedVSList = [
+ # Visual Studio 2013
+ VisualStudio('12.0',
+ vc_version='12.0',
+ sdk_version='8.1A',
+ hkeys=[r'Microsoft\VisualStudio\12.0\Setup\VS\ProductDir'],
+ common_tools_var='VS120COMNTOOLS',
+ executable_path=r'Common7\IDE\devenv.com',
+ batch_file_path=r'Common7\Tools\vsvars32.bat',
+ supported_arch=['x86', 'amd64'],
+ ),
+
+ # Visual C++ 2013 Express Edition (for Desktop)
+ VisualStudio('12.0Exp',
+ vc_version='12.0',
+ sdk_version='8.1A',
+ hkeys=[r'Microsoft\VisualStudio\12.0\Setup\VS\ProductDir'],
+ common_tools_var='VS120COMNTOOLS',
+ executable_path=r'Common7\IDE\WDExpress.exe',
+ batch_file_path=r'Common7\Tools\vsvars32.bat',
+ supported_arch=['x86', 'amd64'],
+ ),
+
+ # Visual Studio 2012
+ VisualStudio('11.0',
+ sdk_version='8.0A',
+ hkeys=[r'Microsoft\VisualStudio\11.0\Setup\VS\ProductDir'],
+ common_tools_var='VS110COMNTOOLS',
+ executable_path=r'Common7\IDE\devenv.com',
+ batch_file_path=r'Common7\Tools\vsvars32.bat',
+ supported_arch=['x86', 'amd64'],
+ ),
+
+ # Visual C++ 2012 Express Edition (for Desktop)
+ VisualStudio('11.0Exp',
+ vc_version='11.0',
+ sdk_version='8.0A',
+ hkeys=[r'Microsoft\VisualStudio\11.0\Setup\VS\ProductDir'],
+ common_tools_var='VS110COMNTOOLS',
+ executable_path=r'Common7\IDE\WDExpress.exe',
+ batch_file_path=r'Common7\Tools\vsvars32.bat',
+ supported_arch=['x86', 'amd64'],
+ ),
+
+ # Visual Studio 2010
+ VisualStudio('10.0',
+ sdk_version='7.0A',
+ hkeys=[r'Microsoft\VisualStudio\10.0\Setup\VS\ProductDir'],
+ common_tools_var='VS100COMNTOOLS',
+ executable_path=r'Common7\IDE\devenv.com',
+ batch_file_path=r'Common7\Tools\vsvars32.bat',
+ supported_arch=['x86', 'amd64'],
+ ),
+
+ # Visual C++ 2010 Express Edition
+ VisualStudio('10.0Exp',
+ vc_version='10.0',
+ sdk_version='7.0A',
+ hkeys=[r'Microsoft\VCExpress\10.0\Setup\VS\ProductDir'],
+ common_tools_var='VS100COMNTOOLS',
+ executable_path=r'Common7\IDE\VCExpress.exe',
+ batch_file_path=r'Common7\Tools\vsvars32.bat',
+ supported_arch=['x86'],
+ ),
+
+ # Visual Studio 2008
+ VisualStudio('9.0',
+ sdk_version='6.0A',
+ 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',
+ supported_arch=['x86', 'amd64'],
+ ),
+
+ # Visual C++ 2008 Express Edition
+ VisualStudio('9.0Exp',
+ vc_version='9.0',
+ sdk_version='6.0A',
+ 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',
+ supported_arch=['x86'],
+ ),
+
+ # Visual Studio 2005
+ 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
+ VisualStudio('8.0Exp',
+ vc_version='8.0Exp',
+ 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
+ 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
+ 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
+
+ debug('vs.py:get_vs_by_version()')
+ if msvs not in SupportedVSMap:
+ 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)
+ debug('vs.py:get_vs_by_version: found vs:%s'%vs)
+ # 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
+ get_installed_visual_studios, and take the highest one.
+
+ Return
+ ------
+ version: str
+ the default version.
+ """
+ if 'MSVS' not in env or not SCons.Util.is_Dict(env['MSVS']):
+ # get all versions, and remember them for speed later
+ versions = [vs.version for vs in get_installed_visual_studios()]
+ env['MSVS'] = {'VERSIONS' : versions}
+ else:
+ versions = env['MSVS'].get('VERSIONS', [])
+
+ if 'MSVS_VERSION' not in env:
+ if versions:
+ env['MSVS_VERSION'] = versions[0] #use highest version by default
+ else:
+ debug('get_default_version: WARNING: no installed versions found, '
+ 'using first in SupportedVSList (%s)'%SupportedVSList[0].version)
+ 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()
+ vscommonvarnames = [vs.common_tools_var for vs in msvs_list]
+ save_ENV = env['ENV']
+ nenv = normalize_env(env['ENV'],
+ ['COMSPEC'] + vscommonvarnames,
+ force=True)
+ try:
+ output = get_output(batfilename, arch, env=nenv)
+ finally:
+ env['ENV'] = save_ENV
+ 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()
+ versions = [msvs.version for msvs in msvs_list]
+ return versions
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/engine/SCons/Tool/Perforce.py b/engine/SCons/Tool/Perforce.py
new file mode 100644
index 0000000..7306545
--- /dev/null
+++ b/engine/SCons/Tool/Perforce.py
@@ -0,0 +1,103 @@
+"""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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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):
+ """ """
+ import SCons.Warnings as W
+ W.warn(W.DeprecatedSourceCodeWarning, """The Perforce() factory is deprecated and there is no replacement.""")
+ 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/engine/SCons/Tool/PharLapCommon.py b/engine/SCons/Tool/PharLapCommon.py
new file mode 100644
index 0000000..e7de04d
--- /dev/null
+++ b/engine/SCons/Tool/PharLapCommon.py
@@ -0,0 +1,137 @@
+"""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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+import os
+import os.path
+import SCons.Errors
+import SCons.Util
+import re
+
+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 = paths.split(sep)
+ is_list = 0
+ if os.path.normcase(path) not in list(map(os.path.normcase, paths)):
+ paths = [ path ] + paths
+ if is_list:
+ env_dict[key] = paths
+ else:
+ env_dict[key] = sep.join(paths)
+ 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/engine/SCons/Tool/RCS.py b/engine/SCons/Tool/RCS.py
new file mode 100644
index 0000000..402cc59
--- /dev/null
+++ b/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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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):
+ """ """
+ import SCons.Warnings as W
+ W.warn(W.DeprecatedSourceCodeWarning, """The RCS() factory is deprecated and there is no replacement.""")
+ 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/engine/SCons/Tool/SCCS.py b/engine/SCons/Tool/SCCS.py
new file mode 100644
index 0000000..bc697d1
--- /dev/null
+++ b/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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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):
+ """ """
+ import SCons.Warnings as W
+ W.warn(W.DeprecatedSourceCodeWarning, """The SCCS() factory is deprecated and there is no replacement.""")
+ 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/engine/SCons/Tool/Subversion.py b/engine/SCons/Tool/Subversion.py
new file mode 100644
index 0000000..5c9f4ea
--- /dev/null
+++ b/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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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?
+ import SCons.Warnings as W
+ W.warn(W.DeprecatedSourceCodeWarning, """The Subversion() factory is deprecated and there is no replacement.""")
+ 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/engine/SCons/Tool/__init__.py b/engine/SCons/Tool/__init__.py
new file mode 100644
index 0000000..56a7d80
--- /dev/null
+++ b/engine/SCons/Tool/__init__.py
@@ -0,0 +1,836 @@
+"""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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+import imp
+import sys
+import re
+import os
+import shutil
+
+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", ".sx"]
+
+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(object):
+ 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 'options' not in env:
+ from SCons.Script import ARGUMENTS
+ env['options']=SCons.Variables.Variables(args=ARGUMENTS)
+ opts=env['options']
+
+ self.options(opts)
+ opts.Update(env)
+
+ 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 VersionShLibLinkNames(version, libname, env):
+ """Generate names of symlinks to the versioned shared library"""
+ Verbose = False
+ platform = env.subst('$PLATFORM')
+ shlib_suffix = env.subst('$SHLIBSUFFIX')
+ shlink_flags = SCons.Util.CLVar(env.subst('$SHLINKFLAGS'))
+
+ linknames = []
+ if version.count(".") != 2:
+ # We need a version string of the form x.y.z to proceed
+ # Several changes need to be made to support versions like x.y
+ raise ValueError
+
+ if platform == 'darwin':
+ # For libfoo.x.y.z.dylib, linknames libfoo.so
+ suffix_re = re.escape('.' + version + shlib_suffix)
+ linkname = re.sub(suffix_re, shlib_suffix, libname)
+ if Verbose:
+ print "VersionShLibLinkNames: linkname = ",linkname
+ linknames.append(linkname)
+ elif platform == 'posix':
+ if sys.platform.startswith('openbsd'):
+ # OpenBSD uses x.y shared library versioning numbering convention
+ # and doesn't use symlinks to backwards-compatible libraries
+ return []
+ # For libfoo.so.x.y.z, linknames libfoo.so libfoo.so.x.y libfoo.so.x
+ suffix_re = re.escape(shlib_suffix + '.' + version)
+ # First linkname has no version number
+ linkname = re.sub(suffix_re, shlib_suffix, libname)
+ if Verbose:
+ print "VersionShLibLinkNames: linkname = ",linkname
+ linknames.append(linkname)
+ versionparts = version.split('.')
+ major_name = linkname + "." + versionparts[0]
+ minor_name = major_name + "." + versionparts[1]
+ #Only add link for major_name
+ #for linkname in [major_name, minor_name]:
+ for linkname in [major_name, ]:
+ if Verbose:
+ print "VersionShLibLinkNames: linkname ",linkname, ", target ",libname
+ linknames.append(linkname)
+ # note: no Windows case here (win32 or cygwin);
+ # MSVC doesn't support this type of versioned shared libs.
+ # (could probably do something for MinGW though)
+ return linknames
+
+def VersionedSharedLibrary(target = None, source= None, env=None):
+ """Build a shared library. If the environment has SHLIBVERSION
+defined make a versioned shared library and create the appropriate
+symlinks for the platform we are on"""
+ Verbose = False
+ try:
+ version = env.subst('$SHLIBVERSION')
+ except KeyError:
+ version = None
+
+ # libname includes the version number if one was given
+ libname = target[0].name
+ platform = env.subst('$PLATFORM')
+ shlib_suffix = env.subst('$SHLIBSUFFIX')
+ shlink_flags = SCons.Util.CLVar(env.subst('$SHLINKFLAGS'))
+ if Verbose:
+ print "VersionShLib: libname = ",libname
+ print "VersionShLib: platform = ",platform
+ print "VersionShLib: shlib_suffix = ",shlib_suffix
+ print "VersionShLib: target = ",str(target[0])
+
+ if version:
+ # set the shared library link flags
+ if platform == 'posix':
+ shlink_flags += [ '-Wl,-Bsymbolic' ]
+ # OpenBSD doesn't usually use SONAME for libraries
+ if not sys.platform.startswith('openbsd'):
+ # continue setup of shlink flags for all other POSIX systems
+ suffix_re = re.escape(shlib_suffix + '.' + version)
+ (major, age, revision) = version.split(".")
+ # soname will have only the major version number in it
+ soname = re.sub(suffix_re, shlib_suffix, libname) + '.' + major
+ shlink_flags += [ '-Wl,-soname=%s' % soname ]
+ if Verbose:
+ print " soname ",soname,", shlink_flags ",shlink_flags
+ elif platform == 'cygwin':
+ shlink_flags += [ '-Wl,-Bsymbolic',
+ '-Wl,--out-implib,${TARGET.base}.a' ]
+ elif platform == 'darwin':
+ shlink_flags += [ '-current_version', '%s' % version,
+ '-compatibility_version', '%s' % version,
+ '-undefined', 'dynamic_lookup' ]
+ if Verbose:
+ print "VersionShLib: shlink_flags = ",shlink_flags
+ envlink = env.Clone()
+ envlink['SHLINKFLAGS'] = shlink_flags
+ else:
+ envlink = env
+
+ result = SCons.Defaults.ShLinkAction(target, source, envlink)
+
+ if version:
+ # here we need the full pathname so the links end up in the right directory
+ libname = target[0].path
+ linknames = VersionShLibLinkNames(version, libname, env)
+ if Verbose:
+ print "VerShLib: linknames ",linknames
+ # Here we just need the file name w/o path as the target of the link
+ lib_ver = target[0].name
+ # make symlink of adjacent names in linknames
+ for count in range(len(linknames)):
+ linkname = linknames[count]
+ if count > 0:
+ try:
+ os.remove(lastlinkname)
+ except:
+ pass
+ os.symlink(os.path.basename(linkname),lastlinkname)
+ if Verbose:
+ print "VerShLib: made sym link of %s -> %s" % (lastlinkname,linkname)
+ lastlinkname = linkname
+ # finish chain of sym links with link to the actual library
+ if len(linknames)>0:
+ try:
+ os.remove(lastlinkname)
+ except:
+ pass
+ os.symlink(lib_ver,lastlinkname)
+ if Verbose:
+ print "VerShLib: made sym link of %s -> %s" % (linkname, lib_ver)
+ return result
+
+# Fix http://scons.tigris.org/issues/show_bug.cgi?id=2903 :
+# Ensure we still depend on SCons.Defaults.ShLinkAction command line which is $SHLINKCOM.
+# This was tricky because we don't want changing LIBPATH to cause a rebuild, but
+# changing other link args should. LIBPATH has $( ... $) around it but until this
+# fix, when the varlist was added to the build sig those ignored parts weren't getting
+# ignored.
+ShLibAction = SCons.Action.Action(VersionedSharedLibrary, None, varlist=['SHLINKCOM'])
+
+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,
+ ShLibAction ]
+ 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(object):
+ """
+ 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 builder(*args, **kw)
+
+class ToolInitializer(object):
+ """
+ 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', '_InternalInstallVersionedLib'])
+ def Install(self, *args, **kw):
+ return self._InternalInstall(*args, **kw)
+ def InstallAs(self, *args, **kw):
+ return self._InternalInstallAs(*args, **kw)
+ def InstallVersionedLib(self, *args, **kw):
+ return self._InternalInstallVersionedLib(*args, **kw)
+ env.AddMethod(Install)
+ env.AddMethod(InstallAs)
+ env.AddMethod(InstallVersionedLib)
+
+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 list(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']
+ elif str(platform) == 'cygwin':
+ "prefer GNU tools on Cygwin, except for a platform-specific linker"
+ linkers = ['cyglink', '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']
+ 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']
+
+ if not str(platform) == 'win32':
+ other_plat_tools += ['m4', 'rpm']
+
+ 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]
+
+ d_compilers = ['dmd', 'gdc', 'ldc']
+ d_compiler = FindTool(d_compilers, env) or d_compilers[0]
+
+ other_tools = FindAllTools(other_plat_tools + [
+ #TODO: merge 'install' into 'filesystem' and
+ # make 'filesystem' the default
+ 'filesystem',
+ 'wix', #'midl', 'msvs',
+ # Parser generators
+ 'lex', 'yacc',
+ # Foreign function interface
+ 'rpcgen', 'swig',
+ # Java
+ 'jar', 'javac', 'javah', 'rmic',
+ # TeX
+ 'dvipdf', 'dvips', 'gs',
+ 'tex', 'latex', 'pdflatex', 'pdftex',
+ # Archivers
+ 'tar', 'zip',
+ # SourceCode factories
+ 'BitKeeper', 'CVS', 'Perforce',
+ 'RCS', 'SCCS', # 'Subversion',
+ ], env)
+
+ tools = ([linker, c_compiler, cxx_compiler,
+ fortran_compiler, assembler, ar, d_compiler]
+ + other_tools)
+
+ return [x for x in tools if x]
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
+
diff --git a/engine/SCons/Tool/aixc++.py b/engine/SCons/Tool/aixc++.py
new file mode 100644
index 0000000..b70bfd0
--- /dev/null
+++ b/engine/SCons/Tool/aixc++.py
@@ -0,0 +1,75 @@
+"""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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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')
+ return SCons.Platform.aix.get_xlc(env, xlc, packages)
+
+def generate(env):
+ """Add Builders and construction variables for xlC / Visual Age
+ suite to an Environment."""
+ path, _cxx, version = get_xlc(env)
+ if path and _cxx:
+ _cxx = os.path.join(path, _cxx)
+
+ if 'CXX' not in env:
+ env['CXX'] = _cxx
+
+ cplusplus.generate(env)
+
+ if version:
+ env['CXXVERSION'] = version
+
+def exists(env):
+ path, _cxx, 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/engine/SCons/Tool/aixcc.py b/engine/SCons/Tool/aixcc.py
new file mode 100644
index 0000000..586edcd
--- /dev/null
+++ b/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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+import os.path
+
+import SCons.Platform.aix
+
+import cc
+
+packages = ['vac.C', 'ibmcxx.cmp']
+
+def get_xlc(env):
+ xlc = env.get('CC', 'xlc')
+ return SCons.Platform.aix.get_xlc(env, xlc, packages)
+
+def generate(env):
+ """Add Builders and construction variables for xlc / Visual Age
+ suite to an Environment."""
+ path, _cc, version = get_xlc(env)
+ if path and _cc:
+ _cc = os.path.join(path, _cc)
+
+ if 'CC' not in env:
+ env['CC'] = _cc
+
+ cc.generate(env)
+
+ if version:
+ env['CCVERSION'] = version
+
+def exists(env):
+ path, _cc, 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/engine/SCons/Tool/aixf77.py b/engine/SCons/Tool/aixf77.py
new file mode 100644
index 0000000..74f2194
--- /dev/null
+++ b/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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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/engine/SCons/Tool/aixlink.py b/engine/SCons/Tool/aixlink.py
new file mode 100644
index 0000000..451844c
--- /dev/null
+++ b/engine/SCons/Tool/aixlink.py
@@ -0,0 +1,77 @@
+"""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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+import os
+import os.path
+
+import SCons.Util
+
+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):
+ # TODO: sync with link.smart_link() to choose a linker
+ linkers = { 'CXX': ['aixc++'], 'CC': ['aixcc'] }
+ alltools = []
+ for langvar, linktools in linkers.items():
+ if langvar in env: # use CC over CXX when user specified CC but not CXX
+ return SCons.Tool.FindTool(linktools, env)
+ alltools.extend(linktools)
+ return SCons.Tool.FindTool(alltools, env)
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/engine/SCons/Tool/applelink.py b/engine/SCons/Tool/applelink.py
new file mode 100644
index 0000000..b9861d5
--- /dev/null
+++ b/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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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/engine/SCons/Tool/ar.py b/engine/SCons/Tool/ar.py
new file mode 100644
index 0000000..534c7ad
--- /dev/null
+++ b/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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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/engine/SCons/Tool/as.py b/engine/SCons/Tool/as.py
new file mode 100644
index 0000000..b7e545a
--- /dev/null
+++ b/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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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/engine/SCons/Tool/bcc32.py b/engine/SCons/Tool/bcc32.py
new file mode 100644
index 0000000..e8e373f
--- /dev/null
+++ b/engine/SCons/Tool/bcc32.py
@@ -0,0 +1,81 @@
+"""SCons.Tool.bcc32
+
+XXX
+
+"""
+
+#
+# Copyright (c) 2001 - 2014 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 2014/09/27 12:51:43 garyo"
+
+import os
+import os.path
+
+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/engine/SCons/Tool/c++.py b/engine/SCons/Tool/c++.py
new file mode 100644
index 0000000..179ab84
--- /dev/null
+++ b/engine/SCons/Tool/c++.py
@@ -0,0 +1,100 @@
+"""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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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)
+
+ if 'CXX' not in env:
+ env['CXX'] = env.Detect(compilers) or compilers[0]
+ 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(env.get('CXX', compilers))
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/engine/SCons/Tool/cc.py b/engine/SCons/Tool/cc.py
new file mode 100644
index 0000000..12838cb
--- /dev/null
+++ b/engine/SCons/Tool/cc.py
@@ -0,0 +1,105 @@
+"""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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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 '_CCCOMCOM' not in env:
+ 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 'CCFLAGS' not in env:
+ env['CCFLAGS'] = SCons.Util.CLVar('')
+
+ if 'SHCCFLAGS' not in env:
+ env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS')
+
+compilers = ['cc']
+
+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)
+
+ add_common_cc_variables(env)
+
+ if 'CC' not in env:
+ env['CC'] = env.Detect(compilers) or compilers[0]
+ 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(env.get('CC', compilers))
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/engine/SCons/Tool/cvf.py b/engine/SCons/Tool/cvf.py
new file mode 100644
index 0000000..731a66e
--- /dev/null
+++ b/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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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/engine/SCons/Tool/cyglink.py b/engine/SCons/Tool/cyglink.py
new file mode 100644
index 0000000..87716cf
--- /dev/null
+++ b/engine/SCons/Tool/cyglink.py
@@ -0,0 +1,94 @@
+"""SCons.Tool.cyglink
+
+Customization of gnulink for Cygwin (http://www.cygwin.com/)
+
+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.
+
+"""
+
+import SCons.Action
+import SCons.Util
+
+import gnulink
+
+def shlib_generator(target, source, env, for_signature):
+ cmd = SCons.Util.CLVar(['$SHLINK'])
+
+ dll = env.FindIxes(target, 'SHLIBPREFIX', 'SHLIBSUFFIX')
+ if dll: cmd.extend(['-o', dll])
+
+ cmd.extend(['$SHLINKFLAGS', '$__RPATH'])
+
+ implib = env.FindIxes(target, 'IMPLIBPREFIX', 'IMPLIBSUFFIX')
+ if implib:
+ cmd.extend([
+ '-Wl,--out-implib='+implib.get_string(for_signature),
+ '-Wl,--export-all-symbols',
+ '-Wl,--enable-auto-import',
+ '-Wl,--whole-archive', '$SOURCES',
+ '-Wl,--no-whole-archive', '$_LIBDIRFLAGS', '$_LIBFLAGS'
+ ])
+ else:
+ 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 or len(target) > 1:
+ raise SCons.Errors.UserError("A shared library should have exactly one target with the suffix: %s" % env.subst("$SHLIBSUFFIX"))
+
+ # Remove any "lib" after the prefix
+ pre = env.subst('$SHLIBPREFIX')
+ if dll.name[len(pre):len(pre)+3] == 'lib':
+ dll.name = pre + dll.name[len(pre)+3:]
+
+ orig_target = target
+ target = [env.fs.File(dll)]
+ target[0].attributes.shared = 1
+
+ # Append an import lib target
+ if not no_import_lib:
+ # Create list of target libraries as strings
+ target_strings = env.ReplaceIxes(orig_target[0],
+ 'SHLIBPREFIX', 'SHLIBSUFFIX',
+ 'IMPLIBPREFIX', 'IMPLIBSUFFIX')
+
+ implib_target = env.fs.File(target_strings)
+ implib_target.attributes.shared = 1
+ target.append(implib_target)
+
+ return (target, source)
+
+
+shlib_action = SCons.Action.Action(shlib_generator, generator=1)
+
+def generate(env):
+ """Add Builders and construction variables for cyglink to an Environment."""
+ gnulink.generate(env)
+
+ env['LINKFLAGS'] = SCons.Util.CLVar('-Wl,-no-undefined')
+
+ env['SHLINKCOM'] = shlib_action
+ env['LDMODULECOM'] = shlib_action
+ env.Append(SHLIBEMITTER = [shlib_emitter])
+
+ env['SHLIBPREFIX'] = 'cyg'
+ env['SHLIBSUFFIX'] = '.dll'
+
+ env['IMPLIBPREFIX'] = 'lib'
+ env['IMPLIBSUFFIX'] = '.dll.a'
+
+def exists(env):
+ return gnulink.exists(env)
+
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/engine/SCons/Tool/default.py b/engine/SCons/Tool/default.py
new file mode 100644
index 0000000..0680347
--- /dev/null
+++ b/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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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/engine/SCons/Tool/dmd.py b/engine/SCons/Tool/dmd.py
new file mode 100644
index 0000000..d7b7974
--- /dev/null
+++ b/engine/SCons/Tool/dmd.py
@@ -0,0 +1,152 @@
+"""SCons.Tool.dmd
+
+Tool-specific initialization for the Digital Mars D compiler.
+(http://digitalmars.com/d)
+
+Originally coded by Andy Friesen (andy@ikagames.com)
+15 November 2003
+
+Evolved by Russel Winder (russel@winder.org.uk)
+2010-02-07 onwards
+
+There are a number of problems with this script at this point in time.
+The one that irritates 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,
+ whichever is found.
+ 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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+import os
+import subprocess
+
+import SCons.Action
+import SCons.Builder
+import SCons.Defaults
+import SCons.Scanner.D
+import SCons.Tool
+
+import SCons.Tool.DCommon
+
+
+def generate(env):
+ static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
+
+ static_obj.add_action('.d', SCons.Defaults.DAction)
+ shared_obj.add_action('.d', SCons.Defaults.ShDAction)
+ static_obj.add_emitter('.d', SCons.Defaults.StaticObjectEmitter)
+ shared_obj.add_emitter('.d', SCons.Defaults.SharedObjectEmitter)
+
+ env['DC'] = env.Detect(['dmd', 'gdmd'])
+ 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['SHDC'] = '$DC'
+ env['SHDCOM'] = '$DC $_DINCFLAGS $_DVERFLAGS $_DDEBUGFLAGS $_DFLAGS -c -fPIC -of$TARGET $SOURCES'
+
+ env['DPATH'] = ['#/']
+ env['DFLAGS'] = []
+ env['DVERSIONS'] = []
+ env['DDEBUG'] = []
+
+ if env['DC']:
+ SCons.Tool.DCommon.addDPATHToEnv(env, env['DC'])
+
+ env['DINCPREFIX'] = '-I'
+ env['DINCSUFFIX'] = ''
+ env['DVERPREFIX'] = '-version='
+ env['DVERSUFFIX'] = ''
+ env['DDEBUGPREFIX'] = '-debug='
+ env['DDEBUGSUFFIX'] = ''
+ env['DFLAGPREFIX'] = '-'
+ env['DFLAGSUFFIX'] = ''
+ env['DFILESUFFIX'] = '.d'
+
+ env['DLINK'] = '$DC'
+ env['DLINKFLAGS'] = SCons.Util.CLVar('')
+ env['DLINKCOM'] = '$DLINK -of$TARGET $DLINKFLAGS $__DRPATH $SOURCES $_DLIBDIRFLAGS $_DLIBFLAGS'
+
+ env['DSHLINK'] = '$DC'
+ env['DSHLINKFLAGS'] = SCons.Util.CLVar('$DLINKFLAGS -shared -defaultlib=libphobos2.so')
+ env['SHDLINKCOM'] = '$DLINK -of$TARGET $DSHLINKFLAGS $__DRPATH $SOURCES $_DLIBDIRFLAGS $_DLIBFLAGS'
+
+ env['DLIBLINKPREFIX'] = '' if env['PLATFORM'] == 'win32' else '-L-l'
+ env['DLIBLINKSUFFIX'] = '.lib' if env['PLATFORM'] == 'win32' else ''
+ env['_DLIBFLAGS'] = '${_stripixes(DLIBLINKPREFIX, LIBS, DLIBLINKSUFFIX, LIBPREFIXES, LIBSUFFIXES, __env__)}'
+
+ env['DLIBDIRPREFIX'] = '-L-L'
+ env['DLIBDIRSUFFIX'] = ''
+ env['_DLIBDIRFLAGS'] = '$( ${_concat(DLIBDIRPREFIX, LIBPATH, DLIBDIRSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)'
+
+
+ env['DLIB'] = 'lib' if env['PLATFORM'] == 'win32' else 'ar cr'
+ env['DLIBCOM'] = '$DLIB $_DLIBFLAGS {0}$TARGET $SOURCES $_DLIBFLAGS'.format('-c ' if env['PLATFORM'] == 'win32' else '')
+
+ #env['_DLIBFLAGS'] = '$( ${_concat(DLIBFLAGPREFIX, DLIBFLAGS, DLIBFLAGSUFFIX, __env__)} $)'
+
+ env['DLIBFLAGPREFIX'] = '-'
+ env['DLIBFLAGSUFFIX'] = ''
+
+ # __RPATH is set to $_RPATH in the platform specification if that
+ # platform supports it.
+ env['DRPATHPREFIX'] = '-L-rpath='
+ env['DRPATHSUFFIX'] = ''
+ env['_DRPATH'] = '${_concat(DRPATHPREFIX, RPATH, DRPATHSUFFIX, __env__)}'
+
+ SCons.Tool.createStaticLibBuilder(env)
+
+
+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/engine/SCons/Tool/docbook/__init__.py b/engine/SCons/Tool/docbook/__init__.py
new file mode 100644
index 0000000..26a1a95
--- /dev/null
+++ b/engine/SCons/Tool/docbook/__init__.py
@@ -0,0 +1,882 @@
+
+"""SCons.Tool.docbook
+
+Tool-specific initialization for Docbook.
+
+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-7,2010 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.
+#
+
+import os
+import glob
+import re
+
+import SCons.Action
+import SCons.Builder
+import SCons.Defaults
+import SCons.Script
+import SCons.Tool
+import SCons.Util
+
+# Get full path to this script
+scriptpath = os.path.dirname(os.path.realpath(__file__))
+
+# Local folder for the collection of DocBook XSLs
+db_xsl_folder = 'docbook-xsl-1.76.1'
+
+# Do we have libxml2/libxslt/lxml?
+has_libxml2 = True
+has_lxml = True
+try:
+ import libxml2
+ import libxslt
+except:
+ has_libxml2 = False
+try:
+ import lxml
+except:
+ has_lxml = False
+
+# Set this to True, to prefer xsltproc over libxml2 and lxml
+prefer_xsltproc = False
+
+# Regexs for parsing Docbook XML sources of MAN pages
+re_manvolnum = re.compile("<manvolnum>([^<]*)</manvolnum>")
+re_refname = re.compile("<refname>([^<]*)</refname>")
+
+#
+# Helper functions
+#
+def __extend_targets_sources(target, source):
+ """ Prepare the lists of target and source files. """
+ if not SCons.Util.is_List(target):
+ target = [target]
+ if not source:
+ source = target[:]
+ elif not SCons.Util.is_List(source):
+ source = [source]
+ if len(target) < len(source):
+ target.extend(source[len(target):])
+
+ return target, source
+
+def __init_xsl_stylesheet(kw, env, user_xsl_var, default_path):
+ if kw.get('DOCBOOK_XSL','') == '':
+ xsl_style = kw.get('xsl', env.subst(user_xsl_var))
+ if xsl_style == '':
+ path_args = [scriptpath, db_xsl_folder] + default_path
+ xsl_style = os.path.join(*path_args)
+ kw['DOCBOOK_XSL'] = xsl_style
+
+def __select_builder(lxml_builder, libxml2_builder, cmdline_builder):
+ """ Selects a builder, based on which Python modules are present. """
+ if prefer_xsltproc:
+ return cmdline_builder
+
+ if not has_libxml2:
+ # At the moment we prefer libxml2 over lxml, the latter can lead
+ # to conflicts when installed together with libxml2.
+ if has_lxml:
+ return lxml_builder
+ else:
+ return cmdline_builder
+
+ return libxml2_builder
+
+def __ensure_suffix(t, suffix):
+ """ Ensure that the target t has the given suffix. """
+ tpath = str(t)
+ if not tpath.endswith(suffix):
+ return tpath+suffix
+
+ return t
+
+def __ensure_suffix_stem(t, suffix):
+ """ Ensure that the target t has the given suffix, and return the file's stem. """
+ tpath = str(t)
+ if not tpath.endswith(suffix):
+ stem = tpath
+ tpath += suffix
+
+ return tpath, stem
+ else:
+ stem, ext = os.path.splitext(tpath)
+
+ return t, stem
+
+def __get_xml_text(root):
+ """ Return the text for the given root node (xml.dom.minidom). """
+ txt = ""
+ for e in root.childNodes:
+ if (e.nodeType == e.TEXT_NODE):
+ txt += e.data
+ return txt
+
+def __create_output_dir(base_dir):
+ """ Ensure that the output directory base_dir exists. """
+ root, tail = os.path.split(base_dir)
+ dir = None
+ if tail:
+ if base_dir.endswith('/'):
+ dir = base_dir
+ else:
+ dir = root
+ else:
+ if base_dir.endswith('/'):
+ dir = base_dir
+
+ if dir and not os.path.isdir(dir):
+ os.makedirs(dir)
+
+
+#
+# Supported command line tools and their call "signature"
+#
+xsltproc_com = {'xsltproc' : '$DOCBOOK_XSLTPROC $DOCBOOK_XSLTPROCFLAGS -o $TARGET $DOCBOOK_XSL $SOURCE',
+ 'saxon' : '$DOCBOOK_XSLTPROC $DOCBOOK_XSLTPROCFLAGS -o $TARGET $DOCBOOK_XSL $SOURCE $DOCBOOK_XSLTPROCPARAMS',
+ 'saxon-xslt' : '$DOCBOOK_XSLTPROC $DOCBOOK_XSLTPROCFLAGS -o $TARGET $DOCBOOK_XSL $SOURCE $DOCBOOK_XSLTPROCPARAMS',
+ 'xalan' : '$DOCBOOK_XSLTPROC $DOCBOOK_XSLTPROCFLAGS -q -out $TARGET -xsl $DOCBOOK_XSL -in $SOURCE'}
+xmllint_com = {'xmllint' : '$DOCBOOK_XMLLINT $DOCBOOK_XMLLINTFLAGS --xinclude $SOURCE > $TARGET'}
+fop_com = {'fop' : '$DOCBOOK_FOP $DOCBOOK_FOPFLAGS -fo $SOURCE -pdf $TARGET',
+ 'xep' : '$DOCBOOK_FOP $DOCBOOK_FOPFLAGS -valid -fo $SOURCE -pdf $TARGET',
+ 'jw' : '$DOCBOOK_FOP $DOCBOOK_FOPFLAGS -f docbook -b pdf $SOURCE -o $TARGET'}
+
+def __detect_cl_tool(env, chainkey, cdict):
+ """
+ Helper function, picks a command line tool from the list
+ and initializes its environment variables.
+ """
+ if env.get(chainkey,'') == '':
+ clpath = ''
+ for cltool in cdict:
+ clpath = env.WhereIs(cltool)
+ if clpath:
+ env[chainkey] = clpath
+ if not env[chainkey + 'COM']:
+ env[chainkey + 'COM'] = cdict[cltool]
+
+def _detect(env):
+ """
+ Detect all the command line tools that we might need for creating
+ the requested output formats.
+ """
+ global prefer_xsltproc
+
+ if env.get('DOCBOOK_PREFER_XSLTPROC',''):
+ prefer_xsltproc = True
+
+ if ((not has_libxml2 and not has_lxml) or (prefer_xsltproc)):
+ # Try to find the XSLT processors
+ __detect_cl_tool(env, 'DOCBOOK_XSLTPROC', xsltproc_com)
+ __detect_cl_tool(env, 'DOCBOOK_XMLLINT', xmllint_com)
+
+ __detect_cl_tool(env, 'DOCBOOK_FOP', fop_com)
+
+#
+# Scanners
+#
+include_re = re.compile('fileref\\s*=\\s*["|\']([^\\n]*)["|\']')
+sentity_re = re.compile('<!ENTITY\\s+%*\\s*[^\\s]+\\s+SYSTEM\\s+["|\']([^\\n]*)["|\']>')
+
+def __xml_scan(node, env, path, arg):
+ """ Simple XML file scanner, detecting local images and XIncludes as implicit dependencies. """
+ # Does the node exist yet?
+ if not os.path.isfile(str(node)):
+ return []
+
+ if env.get('DOCBOOK_SCANENT',''):
+ # Use simple pattern matching for system entities..., no support
+ # for recursion yet.
+ contents = node.get_text_contents()
+ return sentity_re.findall(contents)
+
+ xsl_file = os.path.join(scriptpath,'utils','xmldepend.xsl')
+ if not has_libxml2 or prefer_xsltproc:
+ if has_lxml and not prefer_xsltproc:
+
+ from lxml import etree
+
+ xsl_tree = etree.parse(xsl_file)
+ doc = etree.parse(str(node))
+ result = doc.xslt(xsl_tree)
+
+ depfiles = [x.strip() for x in str(result).splitlines() if x.strip() != "" and not x.startswith("<?xml ")]
+ return depfiles
+ else:
+ # Try to call xsltproc
+ xsltproc = env.subst("$DOCBOOK_XSLTPROC")
+ if xsltproc and xsltproc.endswith('xsltproc'):
+ result = env.backtick(' '.join([xsltproc, xsl_file, str(node)]))
+ depfiles = [x.strip() for x in str(result).splitlines() if x.strip() != "" and not x.startswith("<?xml ")]
+ return depfiles
+ else:
+ # Use simple pattern matching, there is currently no support
+ # for xi:includes...
+ contents = node.get_text_contents()
+ return include_re.findall(contents)
+
+ styledoc = libxml2.parseFile(xsl_file)
+ style = libxslt.parseStylesheetDoc(styledoc)
+ doc = libxml2.readFile(str(node), None, libxml2.XML_PARSE_NOENT)
+ result = style.applyStylesheet(doc, None)
+
+ depfiles = []
+ for x in str(result).splitlines():
+ if x.strip() != "" and not x.startswith("<?xml "):
+ depfiles.extend(x.strip().split())
+
+ style.freeStylesheet()
+ doc.freeDoc()
+ result.freeDoc()
+
+ return depfiles
+
+# Creating the instance of our XML dependency scanner
+docbook_xml_scanner = SCons.Script.Scanner(function = __xml_scan,
+ argument = None)
+
+
+#
+# Action generators
+#
+def __generate_xsltproc_action(source, target, env, for_signature):
+ cmd = env['DOCBOOK_XSLTPROCCOM']
+ # Does the environment have a base_dir defined?
+ base_dir = env.subst('$base_dir')
+ if base_dir:
+ # Yes, so replace target path by its filename
+ return cmd.replace('$TARGET','${TARGET.file}')
+ return cmd
+
+
+#
+# Emitters
+#
+def __emit_xsl_basedir(target, source, env):
+ # Does the environment have a base_dir defined?
+ base_dir = env.subst('$base_dir')
+ if base_dir:
+ # Yes, so prepend it to each target
+ return [os.path.join(base_dir, str(t)) for t in target], source
+
+ # No, so simply pass target and source names through
+ return target, source
+
+
+#
+# Builders
+#
+def __build_libxml2(target, source, env):
+ """
+ General XSLT builder (HTML/FO), using the libxml2 module.
+ """
+ xsl_style = env.subst('$DOCBOOK_XSL')
+ styledoc = libxml2.parseFile(xsl_style)
+ style = libxslt.parseStylesheetDoc(styledoc)
+ doc = libxml2.readFile(str(source[0]),None,libxml2.XML_PARSE_NOENT)
+ # Support for additional parameters
+ parampass = {}
+ if parampass:
+ result = style.applyStylesheet(doc, parampass)
+ else:
+ result = style.applyStylesheet(doc, None)
+ style.saveResultToFilename(str(target[0]), result, 0)
+ style.freeStylesheet()
+ doc.freeDoc()
+ result.freeDoc()
+
+ return None
+
+def __build_lxml(target, source, env):
+ """
+ General XSLT builder (HTML/FO), using the lxml module.
+ """
+ from lxml import etree
+
+ xslt_ac = etree.XSLTAccessControl(read_file=True,
+ write_file=True,
+ create_dir=True,
+ read_network=False,
+ write_network=False)
+ xsl_style = env.subst('$DOCBOOK_XSL')
+ xsl_tree = etree.parse(xsl_style)
+ transform = etree.XSLT(xsl_tree, access_control=xslt_ac)
+ doc = etree.parse(str(source[0]))
+ # Support for additional parameters
+ parampass = {}
+ if parampass:
+ result = transform(doc, **parampass)
+ else:
+ result = transform(doc)
+
+ try:
+ of = open(str(target[0]), "w")
+ of.write(of.write(etree.tostring(result, pretty_print=True)))
+ of.close()
+ except:
+ pass
+
+ return None
+
+def __xinclude_libxml2(target, source, env):
+ """
+ Resolving XIncludes, using the libxml2 module.
+ """
+ doc = libxml2.readFile(str(source[0]), None, libxml2.XML_PARSE_NOENT)
+ doc.xincludeProcessFlags(libxml2.XML_PARSE_NOENT)
+ doc.saveFile(str(target[0]))
+ doc.freeDoc()
+
+ return None
+
+def __xinclude_lxml(target, source, env):
+ """
+ Resolving XIncludes, using the lxml module.
+ """
+ from lxml import etree
+
+ doc = etree.parse(str(source[0]))
+ doc.xinclude()
+ try:
+ doc.write(str(target[0]), xml_declaration=True,
+ encoding="UTF-8", pretty_print=True)
+ except:
+ pass
+
+ return None
+
+__libxml2_builder = SCons.Builder.Builder(
+ action = __build_libxml2,
+ src_suffix = '.xml',
+ source_scanner = docbook_xml_scanner,
+ emitter = __emit_xsl_basedir)
+__lxml_builder = SCons.Builder.Builder(
+ action = __build_lxml,
+ src_suffix = '.xml',
+ source_scanner = docbook_xml_scanner,
+ emitter = __emit_xsl_basedir)
+
+__xinclude_libxml2_builder = SCons.Builder.Builder(
+ action = __xinclude_libxml2,
+ suffix = '.xml',
+ src_suffix = '.xml',
+ source_scanner = docbook_xml_scanner)
+__xinclude_lxml_builder = SCons.Builder.Builder(
+ action = __xinclude_lxml,
+ suffix = '.xml',
+ src_suffix = '.xml',
+ source_scanner = docbook_xml_scanner)
+
+__xsltproc_builder = SCons.Builder.Builder(
+ action = SCons.Action.CommandGeneratorAction(__generate_xsltproc_action,
+ {'cmdstr' : '$DOCBOOK_XSLTPROCCOMSTR'}),
+ src_suffix = '.xml',
+ source_scanner = docbook_xml_scanner,
+ emitter = __emit_xsl_basedir)
+__xmllint_builder = SCons.Builder.Builder(
+ action = SCons.Action.Action('$DOCBOOK_XMLLINTCOM','$DOCBOOK_XMLLINTCOMSTR'),
+ suffix = '.xml',
+ src_suffix = '.xml',
+ source_scanner = docbook_xml_scanner)
+__fop_builder = SCons.Builder.Builder(
+ action = SCons.Action.Action('$DOCBOOK_FOPCOM','$DOCBOOK_FOPCOMSTR'),
+ suffix = '.pdf',
+ src_suffix = '.fo',
+ ensure_suffix=1)
+
+def DocbookEpub(env, target, source=None, *args, **kw):
+ """
+ A pseudo-Builder, providing a Docbook toolchain for ePub output.
+ """
+ import zipfile
+ import shutil
+
+ def build_open_container(target, source, env):
+ """Generate the *.epub file from intermediate outputs
+
+ Constructs the epub file according to the Open Container Format. This
+ function could be replaced by a call to the SCons Zip builder if support
+ was added for different compression formats for separate source nodes.
+ """
+ zf = zipfile.ZipFile(str(target[0]), 'w')
+ mime_file = open('mimetype', 'w')
+ mime_file.write('application/epub+zip')
+ mime_file.close()
+ zf.write(mime_file.name, compress_type = zipfile.ZIP_STORED)
+ for s in source:
+ if os.path.isfile(str(s)):
+ head, tail = os.path.split(str(s))
+ if not head:
+ continue
+ s = head
+ for dirpath, dirnames, filenames in os.walk(str(s)):
+ for fname in filenames:
+ path = os.path.join(dirpath, fname)
+ if os.path.isfile(path):
+ zf.write(path, os.path.relpath(path, str(env.get('ZIPROOT', ''))),
+ zipfile.ZIP_DEFLATED)
+ zf.close()
+
+ def add_resources(target, source, env):
+ """Add missing resources to the OEBPS directory
+
+ Ensure all the resources in the manifest are present in the OEBPS directory.
+ """
+ hrefs = []
+ content_file = os.path.join(source[0].abspath, 'content.opf')
+ if not os.path.isfile(content_file):
+ return
+
+ hrefs = []
+ if has_libxml2:
+ nsmap = {'opf' : 'http://www.idpf.org/2007/opf'}
+ # Read file and resolve entities
+ doc = libxml2.readFile(content_file, None, 0)
+ opf = doc.getRootElement()
+ # Create xpath context
+ xpath_context = doc.xpathNewContext()
+ # Register namespaces
+ for key, val in nsmap.iteritems():
+ xpath_context.xpathRegisterNs(key, val)
+
+ if hasattr(opf, 'xpathEval') and xpath_context:
+ # Use the xpath context
+ xpath_context.setContextNode(opf)
+ items = xpath_context.xpathEval(".//opf:item")
+ else:
+ items = opf.findall(".//{'http://www.idpf.org/2007/opf'}item")
+
+ for item in items:
+ if hasattr(item, 'prop'):
+ hrefs.append(item.prop('href'))
+ else:
+ hrefs.append(item.attrib['href'])
+
+ doc.freeDoc()
+ xpath_context.xpathFreeContext()
+ elif has_lxml:
+ from lxml import etree
+
+ opf = etree.parse(content_file)
+ # All the opf:item elements are resources
+ for item in opf.xpath('//opf:item',
+ namespaces= { 'opf': 'http://www.idpf.org/2007/opf' }):
+ hrefs.append(item.attrib['href'])
+
+ for href in hrefs:
+ # If the resource was not already created by DocBook XSL itself,
+ # copy it into the OEBPS folder
+ referenced_file = os.path.join(source[0].abspath, href)
+ if not os.path.exists(referenced_file):
+ shutil.copy(href, os.path.join(source[0].abspath, href))
+
+ # Init list of targets/sources
+ target, source = __extend_targets_sources(target, source)
+
+ # Init XSL stylesheet
+ __init_xsl_stylesheet(kw, env, '$DOCBOOK_DEFAULT_XSL_EPUB', ['epub','docbook.xsl'])
+
+ # Setup builder
+ __builder = __select_builder(__lxml_builder, __libxml2_builder, __xsltproc_builder)
+
+ # Create targets
+ result = []
+ if not env.GetOption('clean'):
+ # Ensure that the folders OEBPS and META-INF exist
+ __create_output_dir('OEBPS/')
+ __create_output_dir('META-INF/')
+ dirs = env.Dir(['OEBPS', 'META-INF'])
+
+ # Set the fixed base_dir
+ kw['base_dir'] = 'OEBPS/'
+ tocncx = __builder.__call__(env, 'toc.ncx', source[0], **kw)
+ cxml = env.File('META-INF/container.xml')
+ env.SideEffect(cxml, tocncx)
+
+ env.Depends(tocncx, kw['DOCBOOK_XSL'])
+ result.extend(tocncx+[cxml])
+
+ container = env.Command(__ensure_suffix(str(target[0]), '.epub'),
+ tocncx+[cxml], [add_resources, build_open_container])
+ mimetype = env.File('mimetype')
+ env.SideEffect(mimetype, container)
+
+ result.extend(container)
+ # Add supporting files for cleanup
+ env.Clean(tocncx, dirs)
+
+ return result
+
+def DocbookHtml(env, target, source=None, *args, **kw):
+ """
+ A pseudo-Builder, providing a Docbook toolchain for HTML output.
+ """
+ # Init list of targets/sources
+ target, source = __extend_targets_sources(target, source)
+
+ # Init XSL stylesheet
+ __init_xsl_stylesheet(kw, env, '$DOCBOOK_DEFAULT_XSL_HTML', ['html','docbook.xsl'])
+
+ # Setup builder
+ __builder = __select_builder(__lxml_builder, __libxml2_builder, __xsltproc_builder)
+
+ # Create targets
+ result = []
+ for t,s in zip(target,source):
+ r = __builder.__call__(env, __ensure_suffix(t,'.html'), s, **kw)
+ env.Depends(r, kw['DOCBOOK_XSL'])
+ result.extend(r)
+
+ return result
+
+def DocbookHtmlChunked(env, target, source=None, *args, **kw):
+ """
+ A pseudo-Builder, providing a Docbook toolchain for chunked HTML output.
+ """
+ # Init target/source
+ if not SCons.Util.is_List(target):
+ target = [target]
+ if not source:
+ source = target
+ target = ['index.html']
+ elif not SCons.Util.is_List(source):
+ source = [source]
+
+ # Init XSL stylesheet
+ __init_xsl_stylesheet(kw, env, '$DOCBOOK_DEFAULT_XSL_HTMLCHUNKED', ['html','chunkfast.xsl'])
+
+ # Setup builder
+ __builder = __select_builder(__lxml_builder, __libxml2_builder, __xsltproc_builder)
+
+ # Detect base dir
+ base_dir = kw.get('base_dir', '')
+ if base_dir:
+ __create_output_dir(base_dir)
+
+ # Create targets
+ result = []
+ r = __builder.__call__(env, __ensure_suffix(str(target[0]), '.html'), source[0], **kw)
+ env.Depends(r, kw['DOCBOOK_XSL'])
+ result.extend(r)
+ # Add supporting files for cleanup
+ env.Clean(r, glob.glob(os.path.join(base_dir, '*.html')))
+
+ return result
+
+
+def DocbookHtmlhelp(env, target, source=None, *args, **kw):
+ """
+ A pseudo-Builder, providing a Docbook toolchain for HTMLHELP output.
+ """
+ # Init target/source
+ if not SCons.Util.is_List(target):
+ target = [target]
+ if not source:
+ source = target
+ target = ['index.html']
+ elif not SCons.Util.is_List(source):
+ source = [source]
+
+ # Init XSL stylesheet
+ __init_xsl_stylesheet(kw, env, '$DOCBOOK_DEFAULT_XSL_HTMLHELP', ['htmlhelp','htmlhelp.xsl'])
+
+ # Setup builder
+ __builder = __select_builder(__lxml_builder, __libxml2_builder, __xsltproc_builder)
+
+ # Detect base dir
+ base_dir = kw.get('base_dir', '')
+ if base_dir:
+ __create_output_dir(base_dir)
+
+ # Create targets
+ result = []
+ r = __builder.__call__(env, __ensure_suffix(str(target[0]), '.html'), source[0], **kw)
+ env.Depends(r, kw['DOCBOOK_XSL'])
+ result.extend(r)
+ # Add supporting files for cleanup
+ env.Clean(r, ['toc.hhc', 'htmlhelp.hhp', 'index.hhk'] +
+ glob.glob(os.path.join(base_dir, '[ar|bk|ch]*.html')))
+
+ return result
+
+def DocbookPdf(env, target, source=None, *args, **kw):
+ """
+ A pseudo-Builder, providing a Docbook toolchain for PDF output.
+ """
+ # Init list of targets/sources
+ target, source = __extend_targets_sources(target, source)
+
+ # Init XSL stylesheet
+ __init_xsl_stylesheet(kw, env, '$DOCBOOK_DEFAULT_XSL_PDF', ['fo','docbook.xsl'])
+
+ # Setup builder
+ __builder = __select_builder(__lxml_builder, __libxml2_builder, __xsltproc_builder)
+
+ # Create targets
+ result = []
+ for t,s in zip(target,source):
+ t, stem = __ensure_suffix_stem(t, '.pdf')
+ xsl = __builder.__call__(env, stem+'.fo', s, **kw)
+ result.extend(xsl)
+ env.Depends(xsl, kw['DOCBOOK_XSL'])
+ result.extend(__fop_builder.__call__(env, t, xsl, **kw))
+
+ return result
+
+def DocbookMan(env, target, source=None, *args, **kw):
+ """
+ A pseudo-Builder, providing a Docbook toolchain for Man page output.
+ """
+ # Init list of targets/sources
+ target, source = __extend_targets_sources(target, source)
+
+ # Init XSL stylesheet
+ __init_xsl_stylesheet(kw, env, '$DOCBOOK_DEFAULT_XSL_MAN', ['manpages','docbook.xsl'])
+
+ # Setup builder
+ __builder = __select_builder(__lxml_builder, __libxml2_builder, __xsltproc_builder)
+
+ # Create targets
+ result = []
+ for t,s in zip(target,source):
+ volnum = "1"
+ outfiles = []
+ srcfile = __ensure_suffix(str(s),'.xml')
+ if os.path.isfile(srcfile):
+ try:
+ import xml.dom.minidom
+
+ dom = xml.dom.minidom.parse(__ensure_suffix(str(s),'.xml'))
+ # Extract volume number, default is 1
+ for node in dom.getElementsByTagName('refmeta'):
+ for vol in node.getElementsByTagName('manvolnum'):
+ volnum = __get_xml_text(vol)
+
+ # Extract output filenames
+ for node in dom.getElementsByTagName('refnamediv'):
+ for ref in node.getElementsByTagName('refname'):
+ outfiles.append(__get_xml_text(ref)+'.'+volnum)
+
+ except:
+ # Use simple regex parsing
+ f = open(__ensure_suffix(str(s),'.xml'), 'r')
+ content = f.read()
+ f.close()
+
+ for m in re_manvolnum.finditer(content):
+ volnum = m.group(1)
+
+ for m in re_refname.finditer(content):
+ outfiles.append(m.group(1)+'.'+volnum)
+
+ if not outfiles:
+ # Use stem of the source file
+ spath = str(s)
+ if not spath.endswith('.xml'):
+ outfiles.append(spath+'.'+volnum)
+ else:
+ stem, ext = os.path.splitext(spath)
+ outfiles.append(stem+'.'+volnum)
+ else:
+ # We have to completely rely on the given target name
+ outfiles.append(t)
+
+ __builder.__call__(env, outfiles[0], s, **kw)
+ env.Depends(outfiles[0], kw['DOCBOOK_XSL'])
+ result.append(outfiles[0])
+ if len(outfiles) > 1:
+ env.Clean(outfiles[0], outfiles[1:])
+
+
+ return result
+
+def DocbookSlidesPdf(env, target, source=None, *args, **kw):
+ """
+ A pseudo-Builder, providing a Docbook toolchain for PDF slides output.
+ """
+ # Init list of targets/sources
+ target, source = __extend_targets_sources(target, source)
+
+ # Init XSL stylesheet
+ __init_xsl_stylesheet(kw, env, '$DOCBOOK_DEFAULT_XSL_SLIDESPDF', ['slides','fo','plain.xsl'])
+
+ # Setup builder
+ __builder = __select_builder(__lxml_builder, __libxml2_builder, __xsltproc_builder)
+
+ # Create targets
+ result = []
+ for t,s in zip(target,source):
+ t, stem = __ensure_suffix_stem(t, '.pdf')
+ xsl = __builder.__call__(env, stem+'.fo', s, **kw)
+ env.Depends(xsl, kw['DOCBOOK_XSL'])
+ result.extend(xsl)
+ result.extend(__fop_builder.__call__(env, t, xsl, **kw))
+
+ return result
+
+def DocbookSlidesHtml(env, target, source=None, *args, **kw):
+ """
+ A pseudo-Builder, providing a Docbook toolchain for HTML slides output.
+ """
+ # Init list of targets/sources
+ if not SCons.Util.is_List(target):
+ target = [target]
+ if not source:
+ source = target
+ target = ['index.html']
+ elif not SCons.Util.is_List(source):
+ source = [source]
+
+ # Init XSL stylesheet
+ __init_xsl_stylesheet(kw, env, '$DOCBOOK_DEFAULT_XSL_SLIDESHTML', ['slides','html','plain.xsl'])
+
+ # Setup builder
+ __builder = __select_builder(__lxml_builder, __libxml2_builder, __xsltproc_builder)
+
+ # Detect base dir
+ base_dir = kw.get('base_dir', '')
+ if base_dir:
+ __create_output_dir(base_dir)
+
+ # Create targets
+ result = []
+ r = __builder.__call__(env, __ensure_suffix(str(target[0]), '.html'), source[0], **kw)
+ env.Depends(r, kw['DOCBOOK_XSL'])
+ result.extend(r)
+ # Add supporting files for cleanup
+ env.Clean(r, [os.path.join(base_dir, 'toc.html')] +
+ glob.glob(os.path.join(base_dir, 'foil*.html')))
+
+ return result
+
+def DocbookXInclude(env, target, source, *args, **kw):
+ """
+ A pseudo-Builder, for resolving XIncludes in a separate processing step.
+ """
+ # Init list of targets/sources
+ target, source = __extend_targets_sources(target, source)
+
+ # Setup builder
+ __builder = __select_builder(__xinclude_lxml_builder,__xinclude_libxml2_builder,__xmllint_builder)
+
+ # Create targets
+ result = []
+ for t,s in zip(target,source):
+ result.extend(__builder.__call__(env, t, s, **kw))
+
+ return result
+
+def DocbookXslt(env, target, source=None, *args, **kw):
+ """
+ A pseudo-Builder, applying a simple XSL transformation to the input file.
+ """
+ # Init list of targets/sources
+ target, source = __extend_targets_sources(target, source)
+
+ # Init XSL stylesheet
+ kw['DOCBOOK_XSL'] = kw.get('xsl', 'transform.xsl')
+
+ # Setup builder
+ __builder = __select_builder(__lxml_builder, __libxml2_builder, __xsltproc_builder)
+
+ # Create targets
+ result = []
+ for t,s in zip(target,source):
+ r = __builder.__call__(env, t, s, **kw)
+ env.Depends(r, kw['DOCBOOK_XSL'])
+ result.extend(r)
+
+ return result
+
+
+def generate(env):
+ """Add Builders and construction variables for docbook to an Environment."""
+
+ env.SetDefault(
+ # Default names for customized XSL stylesheets
+ DOCBOOK_DEFAULT_XSL_EPUB = '',
+ DOCBOOK_DEFAULT_XSL_HTML = '',
+ DOCBOOK_DEFAULT_XSL_HTMLCHUNKED = '',
+ DOCBOOK_DEFAULT_XSL_HTMLHELP = '',
+ DOCBOOK_DEFAULT_XSL_PDF = '',
+ DOCBOOK_DEFAULT_XSL_MAN = '',
+ DOCBOOK_DEFAULT_XSL_SLIDESPDF = '',
+ DOCBOOK_DEFAULT_XSL_SLIDESHTML = '',
+
+ # Paths to the detected executables
+ DOCBOOK_XSLTPROC = '',
+ DOCBOOK_XMLLINT = '',
+ DOCBOOK_FOP = '',
+
+ # Additional flags for the text processors
+ DOCBOOK_XSLTPROCFLAGS = SCons.Util.CLVar(''),
+ DOCBOOK_XMLLINTFLAGS = SCons.Util.CLVar(''),
+ DOCBOOK_FOPFLAGS = SCons.Util.CLVar(''),
+ DOCBOOK_XSLTPROCPARAMS = SCons.Util.CLVar(''),
+
+ # Default command lines for the detected executables
+ DOCBOOK_XSLTPROCCOM = xsltproc_com['xsltproc'],
+ DOCBOOK_XMLLINTCOM = xmllint_com['xmllint'],
+ DOCBOOK_FOPCOM = fop_com['fop'],
+
+ # Screen output for the text processors
+ DOCBOOK_XSLTPROCCOMSTR = None,
+ DOCBOOK_XMLLINTCOMSTR = None,
+ DOCBOOK_FOPCOMSTR = None,
+
+ )
+ _detect(env)
+
+ try:
+ env.AddMethod(DocbookEpub, "DocbookEpub")
+ env.AddMethod(DocbookHtml, "DocbookHtml")
+ env.AddMethod(DocbookHtmlChunked, "DocbookHtmlChunked")
+ env.AddMethod(DocbookHtmlhelp, "DocbookHtmlhelp")
+ env.AddMethod(DocbookPdf, "DocbookPdf")
+ env.AddMethod(DocbookMan, "DocbookMan")
+ env.AddMethod(DocbookSlidesPdf, "DocbookSlidesPdf")
+ env.AddMethod(DocbookSlidesHtml, "DocbookSlidesHtml")
+ env.AddMethod(DocbookXInclude, "DocbookXInclude")
+ env.AddMethod(DocbookXslt, "DocbookXslt")
+ except AttributeError:
+ # Looks like we use a pre-0.98 version of SCons...
+ from SCons.Script.SConscript import SConsEnvironment
+ SConsEnvironment.DocbookEpub = DocbookEpub
+ SConsEnvironment.DocbookHtml = DocbookHtml
+ SConsEnvironment.DocbookHtmlChunked = DocbookHtmlChunked
+ SConsEnvironment.DocbookHtmlhelp = DocbookHtmlhelp
+ SConsEnvironment.DocbookPdf = DocbookPdf
+ SConsEnvironment.DocbookMan = DocbookMan
+ SConsEnvironment.DocbookSlidesPdf = DocbookSlidesPdf
+ SConsEnvironment.DocbookSlidesHtml = DocbookSlidesHtml
+ SConsEnvironment.DocbookXInclude = DocbookXInclude
+ SConsEnvironment.DocbookXslt = DocbookXslt
+
+
+def exists(env):
+ return 1
diff --git a/engine/SCons/Tool/dvi.py b/engine/SCons/Tool/dvi.py
new file mode 100644
index 0000000..e058196
--- /dev/null
+++ b/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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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/engine/SCons/Tool/dvipdf.py b/engine/SCons/Tool/dvipdf.py
new file mode 100644
index 0000000..d4bdfae
--- /dev/null
+++ b/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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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 = list(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):
+ SCons.Tool.tex.generate_darwin(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/engine/SCons/Tool/dvips.py b/engine/SCons/Tool/dvips.py
new file mode 100644
index 0000000..c838170
--- /dev/null
+++ b/engine/SCons/Tool/dvips.py
@@ -0,0 +1,95 @@
+"""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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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):
+ SCons.Tool.tex.generate_darwin(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/engine/SCons/Tool/f03.py b/engine/SCons/Tool/f03.py
new file mode 100644
index 0000000..a40ec41
--- /dev/null
+++ b/engine/SCons/Tool/f03.py
@@ -0,0 +1,63 @@
+"""engine.SCons.Tool.f03
+
+Tool-specific initialization for the generic Posix f03 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 - 2014 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/f03.py 2014/09/27 12:51:43 garyo"
+
+import SCons.Defaults
+import SCons.Tool
+import SCons.Util
+import fortran
+from SCons.Tool.FortranCommon import add_all_to_env, add_f03_to_env
+
+compilers = ['f03']
+
+def generate(env):
+ add_all_to_env(env)
+ add_f03_to_env(env)
+
+ fcomp = env.Detect(compilers) or 'f03'
+ env['F03'] = fcomp
+ env['SHF03'] = 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/engine/SCons/Tool/f77.py b/engine/SCons/Tool/f77.py
new file mode 100644
index 0000000..bcedb87
--- /dev/null
+++ b/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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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/engine/SCons/Tool/f90.py b/engine/SCons/Tool/f90.py
new file mode 100644
index 0000000..93faab9
--- /dev/null
+++ b/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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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/engine/SCons/Tool/f95.py b/engine/SCons/Tool/f95.py
new file mode 100644
index 0000000..f8ccb25
--- /dev/null
+++ b/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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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/engine/SCons/Tool/filesystem.py b/engine/SCons/Tool/filesystem.py
new file mode 100644
index 0000000..00b47e6
--- /dev/null
+++ b/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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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 + [t.File( str( s ) ) for s in source]
+
+ return (n_target, source)
+
+def copy_action_func(target, source, env):
+ assert( len(target) == len(source) ), "\ntarget: %s\nsource: %s" %(list(map(str, target)),list(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/engine/SCons/Tool/fortran.py b/engine/SCons/Tool/fortran.py
new file mode 100644
index 0000000..4fea600
--- /dev/null
+++ b/engine/SCons/Tool/fortran.py
@@ -0,0 +1,62 @@
+"""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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+import re
+
+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/engine/SCons/Tool/g++.py b/engine/SCons/Tool/g++.py
new file mode 100644
index 0000000..3b4e383
--- /dev/null
+++ b/engine/SCons/Tool/g++.py
@@ -0,0 +1,80 @@
+"""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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+import os.path
+import re
+import subprocess
+
+import SCons.Tool
+import SCons.Util
+
+import gcc
+
+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)
+
+ if 'CXX' not in env:
+ env['CXX'] = env.Detect(compilers) or compilers[0]
+
+ cplusplus.generate(env)
+
+ # 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
+ version = gcc.detect_version(env, env['CXX'])
+ if version:
+ env['CXXVERSION'] = version
+
+def exists(env):
+ # is executable, and is a GNU compiler (or accepts '--version' at least)
+ return gcc.detect_version(env, env.Detect(env.get('CXX', compilers)))
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/engine/SCons/Tool/g77.py b/engine/SCons/Tool/g77.py
new file mode 100644
index 0000000..8f9dc1e
--- /dev/null
+++ b/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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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/engine/SCons/Tool/gas.py b/engine/SCons/Tool/gas.py
new file mode 100644
index 0000000..11274e3
--- /dev/null
+++ b/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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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/engine/SCons/Tool/gcc.py b/engine/SCons/Tool/gcc.py
new file mode 100644
index 0000000..d52201b
--- /dev/null
+++ b/engine/SCons/Tool/gcc.py
@@ -0,0 +1,100 @@
+"""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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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."""
+
+ if 'CC' not in env:
+ env['CC'] = env.Detect(compilers) or compilers[0]
+
+ cc.generate(env)
+
+ if env['PLATFORM'] in ['cygwin', 'win32']:
+ env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS')
+ else:
+ env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS -fPIC')
+ # determine compiler version
+ version = detect_version(env, env['CC'])
+ if version:
+ env['CCVERSION'] = version
+
+def exists(env):
+ # is executable, and is a GNU compiler (or accepts '--version' at least)
+ return detect_version(env, env.Detect(env.get('CC', compilers)))
+
+def detect_version(env, cc):
+ """Return the version of the GNU compiler, or None if it is not a GNU compiler."""
+ cc = env.subst(cc)
+ if not cc:
+ return None
+ version = None
+ #pipe = SCons.Action._subproc(env, SCons.Util.CLVar(cc) + ['-dumpversion'],
+ pipe = SCons.Action._subproc(env, SCons.Util.CLVar(cc) + ['--version'],
+ stdin = 'devnull',
+ stderr = 'devnull',
+ stdout = subprocess.PIPE)
+ # -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:
+ # version = line
+ line = pipe.stdout.readline()
+ match = re.search(r'[0-9]+(\.[0-9]+)+', line)
+ if match:
+ version = match.group(0)
+ # Non-GNU compiler's output (like AIX xlc's) may exceed the stdout buffer:
+ # So continue with reading to let the child process actually terminate.
+ while pipe.stdout.readline():
+ pass
+ ret = pipe.wait()
+ if ret != 0:
+ return None
+ return version
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/engine/SCons/Tool/gdc.py b/engine/SCons/Tool/gdc.py
new file mode 100644
index 0000000..52bfb9b
--- /dev/null
+++ b/engine/SCons/Tool/gdc.py
@@ -0,0 +1,128 @@
+"""SCons.Tool.gdc
+
+Tool-specific initialization for the GDC compiler.
+(https://github.com/D-Programming-GDC/GDC)
+
+Developed by Russel Winder (russel@winder.org.uk)
+2012-05-09 onwards
+
+Compiler variables:
+ DC - The name of the D compiler to use. Defaults to gdc.
+ 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 gdc.
+ 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 - 2014 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/gdc.py 2014/09/27 12:51:43 garyo"
+
+import SCons.Action
+import SCons.Defaults
+import SCons.Tool
+
+import SCons.Tool.DCommon
+
+
+def generate(env):
+ static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
+
+ static_obj.add_action('.d', SCons.Defaults.DAction)
+ shared_obj.add_action('.d', SCons.Defaults.ShDAction)
+ static_obj.add_emitter('.d', SCons.Defaults.StaticObjectEmitter)
+ shared_obj.add_emitter('.d', SCons.Defaults.SharedObjectEmitter)
+
+ env['DC'] = env.Detect('gdc')
+ env['DCOM'] = '$DC $_DINCFLAGS $_DVERFLAGS $_DDEBUGFLAGS $_DFLAGS -c -o $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['SHDC'] = '$DC'
+ env['SHDCOM'] = '$SHDC $_DINCFLAGS $_DVERFLAGS $_DDEBUGFLAGS $_DFLAGS -fPIC -c -o $TARGET $SOURCES'
+
+ env['DPATH'] = ['#/']
+ env['DFLAGS'] = []
+ env['DVERSIONS'] = []
+ env['DDEBUG'] = []
+
+ if env['DC']:
+ SCons.Tool.DCommon.addDPATHToEnv(env, env['DC'])
+
+ env['DINCPREFIX'] = '-I'
+ env['DINCSUFFIX'] = ''
+ env['DVERPREFIX'] = '-version='
+ env['DVERSUFFIX'] = ''
+ env['DDEBUGPREFIX'] = '-debug='
+ env['DDEBUGSUFFIX'] = ''
+ env['DFLAGPREFIX'] = '-'
+ env['DFLAGSUFFIX'] = ''
+ env['DFILESUFFIX'] = '.d'
+
+ env['DLINK'] = '$DC'
+ env['DLINKFLAGS'] = SCons.Util.CLVar('')
+ env['DLINKCOM'] = '$DLINK -o $TARGET $DLINKFLAGS $__RPATH $SOURCES $_LIBDIRFLAGS $_LIBFLAGS'
+
+ env['DSHLINK'] = '$DC'
+ env['DSHLINKFLAGS'] = SCons.Util.CLVar('$DLINKFLAGS -shared')
+ env['SHDLINKCOM'] = '$DLINK -o $TARGET $DSHLINKFLAGS $__RPATH $SOURCES $_LIBDIRFLAGS $_LIBFLAGS'
+
+ env['DLIB'] = 'lib' if env['PLATFORM'] == 'win32' else 'ar cr'
+ env['DLIBCOM'] = '$DLIB $_DLIBFLAGS {0}$TARGET $SOURCES $_DLINKLIBFLAGS'.format('-c ' if env['PLATFORM'] == 'win32' else '')
+
+ env['_DLIBFLAGS'] = '$( ${_concat(DLIBFLAGPREFIX, DLIBFLAGS, DLIBFLAGSUFFIX, __env__)} $)'
+
+ env['DLIBFLAGPREFIX'] = '-'
+ env['DLIBFLAGSUFFIX'] = ''
+ env['DLINKFLAGPREFIX'] = '-'
+ env['DLINKFLAGSUFFIX'] = ''
+
+ # __RPATH is set to $_RPATH in the platform specification if that
+ # platform supports it.
+ env['RPATHPREFIX'] = '-Wl,-rpath='
+ env['RPATHSUFFIX'] = ''
+ env['_RPATH'] = '${_concat(RPATHPREFIX, RPATH, RPATHSUFFIX, __env__)}'
+
+ SCons.Tool.createStaticLibBuilder(env)
+
+
+def exists(env):
+ return env.Detect('gdc')
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/engine/SCons/Tool/gettext.py b/engine/SCons/Tool/gettext.py
new file mode 100644
index 0000000..6a7f681
--- /dev/null
+++ b/engine/SCons/Tool/gettext.py
@@ -0,0 +1,48 @@
+"""gettext tool
+"""
+
+
+# Copyright (c) 2001 - 2014 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/gettext.py 2014/09/27 12:51:43 garyo"
+
+#############################################################################
+def generate(env,**kw):
+ import SCons.Tool
+ from SCons.Tool.GettextCommon \
+ import _translate, tool_list
+ for t in tool_list(env['PLATFORM'], env):
+ env.Tool(t)
+ env.AddMethod(_translate, 'Translate')
+#############################################################################
+
+#############################################################################
+def exists(env):
+ from SCons.Tool.GettextCommon \
+ import _xgettext_exists, _msginit_exists, \
+ _msgmerge_exists, _msgfmt_exists
+ try:
+ return _xgettext_exists(env) and _msginit_exists(env) \
+ and _msgmerge_exists(env) and _msgfmt_exists(env)
+ except:
+ return False
+#############################################################################
diff --git a/engine/SCons/Tool/gfortran.py b/engine/SCons/Tool/gfortran.py
new file mode 100644
index 0000000..53a2104
--- /dev/null
+++ b/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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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', 'F03']:
+ 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/engine/SCons/Tool/gnulink.py b/engine/SCons/Tool/gnulink.py
new file mode 100644
index 0000000..8dc6491
--- /dev/null
+++ b/engine/SCons/Tool/gnulink.py
@@ -0,0 +1,67 @@
+"""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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+import SCons.Util
+
+import link
+
+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['RPATHPREFIX'] = '-Wl,-rpath='
+ env['RPATHSUFFIX'] = ''
+ env['_RPATH'] = '${_concat(RPATHPREFIX, RPATH, RPATHSUFFIX, __env__)}'
+
+def exists(env):
+ # TODO: sync with link.smart_link() to choose a linker
+ linkers = { 'CXX': ['g++'], 'CC': ['gcc'] }
+ alltools = []
+ for langvar, linktools in linkers.items():
+ if langvar in env: # use CC over CXX when user specified CC but not CXX
+ return SCons.Tool.FindTool(linktools, env)
+ alltools.extend(linktools)
+ return SCons.Tool.FindTool(alltools, env) # find CXX or CC
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/engine/SCons/Tool/gs.py b/engine/SCons/Tool/gs.py
new file mode 100644
index 0000000..0cb4c5d
--- /dev/null
+++ b/engine/SCons/Tool/gs.py
@@ -0,0 +1,91 @@
+"""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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+import SCons.Action
+import SCons.Builder
+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
+ # The following try-except block enables us to use the Tool
+ # in standalone mode (without the accompanying pdf.py),
+ # whenever we need an explicit call of gs via the Gs()
+ # Builder ...
+ try:
+ if GhostscriptAction is None:
+ GhostscriptAction = SCons.Action.Action('$GSCOM', '$GSCOMSTR')
+
+ import pdf
+ pdf.generate(env)
+
+ bld = env['BUILDERS']['PDF']
+ bld.add_action('.ps', GhostscriptAction)
+ except ImportError, e:
+ pass
+
+ gsbuilder = SCons.Builder.Builder(action = SCons.Action.Action('$GSCOM', '$GSCOMSTR'))
+ env['BUILDERS']['Gs'] = gsbuilder
+
+ env['GS'] = gs
+ env['GSFLAGS'] = SCons.Util.CLVar('-dNOPAUSE -dBATCH -sDEVICE=pdfwrite')
+ env['GSCOM'] = '$GS $GSFLAGS -sOutputFile=$TARGET $SOURCES'
+
+
+def exists(env):
+ if 'PS2PDF' in env:
+ 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/engine/SCons/Tool/hpc++.py b/engine/SCons/Tool/hpc++.py
new file mode 100644
index 0000000..2ec4e82
--- /dev/null
+++ b/engine/SCons/Tool/hpc++.py
@@ -0,0 +1,84 @@
+"""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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+import os.path
+
+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 line.find('aCC: HP ANSI C++') == 0:
+ env['CXXVERSION'] = line.split()[-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/engine/SCons/Tool/hpcc.py b/engine/SCons/Tool/hpcc.py
new file mode 100644
index 0000000..cce0517
--- /dev/null
+++ b/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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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/engine/SCons/Tool/hplink.py b/engine/SCons/Tool/hplink.py
new file mode 100644
index 0000000..9f7221b
--- /dev/null
+++ b/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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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/engine/SCons/Tool/icc.py b/engine/SCons/Tool/icc.py
new file mode 100644
index 0000000..2591756
--- /dev/null
+++ b/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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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/engine/SCons/Tool/icl.py b/engine/SCons/Tool/icl.py
new file mode 100644
index 0000000..66b1e20
--- /dev/null
+++ b/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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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 SCons.Tool.intelc.generate(*args, **kw)
+
+def exists(*args, **kw):
+ return 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/engine/SCons/Tool/ifl.py b/engine/SCons/Tool/ifl.py
new file mode 100644
index 0000000..d4453bd
--- /dev/null
+++ b/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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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 'FORTRANFILESUFFIXES' not in env:
+ env['FORTRANFILESUFFIXES'] = ['.i']
+ else:
+ env['FORTRANFILESUFFIXES'].append('.i')
+
+ if 'F90FILESUFFIXES' not in env:
+ 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/engine/SCons/Tool/ifort.py b/engine/SCons/Tool/ifort.py
new file mode 100644
index 0000000..c28fd00
--- /dev/null
+++ b/engine/SCons/Tool/ifort.py
@@ -0,0 +1,88 @@
+"""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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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 'FORTRANFILESUFFIXES' not in env:
+ env['FORTRANFILESUFFIXES'] = ['.i']
+ else:
+ env['FORTRANFILESUFFIXES'].append('.i')
+
+ if 'F90FILESUFFIXES' not in env:
+ 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] = env[var].replace('-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/engine/SCons/Tool/ilink.py b/engine/SCons/Tool/ilink.py
new file mode 100644
index 0000000..4ba870f
--- /dev/null
+++ b/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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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/engine/SCons/Tool/ilink32.py b/engine/SCons/Tool/ilink32.py
new file mode 100644
index 0000000..c915276
--- /dev/null
+++ b/engine/SCons/Tool/ilink32.py
@@ -0,0 +1,60 @@
+"""SCons.Tool.ilink32
+
+XXX
+
+"""
+
+#
+# Copyright (c) 2001 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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/engine/SCons/Tool/install.py b/engine/SCons/Tool/install.py
new file mode 100644
index 0000000..5aff9a8
--- /dev/null
+++ b/engine/SCons/Tool/install.py
@@ -0,0 +1,493 @@
+"""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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+import os
+import re
+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
+
+class CopytreeError(EnvironmentError):
+ pass
+
+# This is a patched version of shutil.copytree from python 2.5. It
+# doesn't fail if the dir exists, which regular copytree does
+# (annoyingly). Note the XXX comment in the docstring.
+def scons_copytree(src, dst, symlinks=False):
+ """Recursively copy a directory tree using copy2().
+
+ The destination directory must not already exist.
+ If exception(s) occur, an CopytreeError is raised with a list of reasons.
+
+ If the optional symlinks flag is true, symbolic links in the
+ source tree result in symbolic links in the destination tree; if
+ it is false, the contents of the files pointed to by symbolic
+ links are copied.
+
+ XXX Consider this example code rather than the ultimate tool.
+
+ """
+ names = os.listdir(src)
+ # garyo@genarts.com fix: check for dir before making dirs.
+ if not os.path.exists(dst):
+ os.makedirs(dst)
+ errors = []
+ for name in names:
+ srcname = os.path.join(src, name)
+ dstname = os.path.join(dst, name)
+ try:
+ if symlinks and os.path.islink(srcname):
+ linkto = os.readlink(srcname)
+ os.symlink(linkto, dstname)
+ elif os.path.isdir(srcname):
+ scons_copytree(srcname, dstname, symlinks)
+ else:
+ shutil.copy2(srcname, dstname)
+ # XXX What about devices, sockets etc.?
+ except (IOError, os.error), why:
+ errors.append((srcname, dstname, str(why)))
+ # catch the CopytreeError from the recursive copytree so that we can
+ # continue with other files
+ except CopytreeError, err:
+ errors.extend(err.args[0])
+ try:
+ shutil.copystat(src, dst)
+ except WindowsError:
+ # can't copy file access times on Windows
+ pass
+ except OSError, why:
+ errors.extend((src, dst, str(why)))
+ if errors:
+ raise CopytreeError, errors
+
+
+#
+# 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)
+ scons_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
+
+#
+# Functions doing the actual work of the InstallVersionedLib Builder.
+#
+def copyFuncVersionedLib(dest, source, env):
+ """Install a versioned library into a destination by copying,
+ (including copying permission/mode bits) and then creating
+ required symlinks."""
+
+ if os.path.isdir(source):
+ raise SCons.Errors.UserError("cannot install directory `%s' as a version library" % str(source) )
+ else:
+ # remove the link if it is already there
+ try:
+ os.remove(dest)
+ except:
+ pass
+ shutil.copy2(source, dest)
+ st = os.stat(source)
+ os.chmod(dest, stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE)
+ versionedLibLinks(dest, source, env)
+
+ return 0
+
+def versionedLibVersion(dest, env):
+ """Check if dest is a version shared library name. Return version, libname, & install_dir if it is."""
+ Verbose = False
+ platform = env.subst('$PLATFORM')
+ if not (platform == 'posix' or platform == 'darwin'):
+ return (None, None, None)
+
+ libname = os.path.basename(dest)
+ install_dir = os.path.dirname(dest)
+ shlib_suffix = env.subst('$SHLIBSUFFIX')
+ # See if the source name is a versioned shared library, get the version number
+ result = False
+
+ version_re = re.compile("[0-9]+\\.[0-9]+\\.[0-9a-zA-Z]+")
+ version_File = None
+ if platform == 'posix':
+ # handle unix names
+ versioned_re = re.compile(re.escape(shlib_suffix + '.') + "[0-9]+\\.[0-9]+\\.[0-9a-zA-Z]+")
+ result = versioned_re.findall(libname)
+ if result:
+ version_File = version_re.findall(versioned_re.findall(libname)[-1])[-1]
+ elif platform == 'darwin':
+ # handle OSX names
+ versioned_re = re.compile("\\.[0-9]+\\.[0-9]+\\.[0-9a-zA-Z]+" + re.escape(shlib_suffix) )
+ result = versioned_re.findall(libname)
+ if result:
+ version_File = version_re.findall(versioned_re.findall(libname)[-1])[-1]
+
+ if Verbose:
+ print "install: version_File ", version_File
+ # result is False if we did not find a versioned shared library name, so return and empty list
+ if not result:
+ return (None, libname, install_dir)
+
+ version = None
+ # get version number from the environment
+ try:
+ version = env.subst('$SHLIBVERSION')
+ except KeyError:
+ version = None
+
+ if version != version_File:
+ #raise SCons.Errors.UserError("SHLIBVERSION '%s' does not match the version # '%s' in the filename" % (version, version_File) )
+ print "SHLIBVERSION '%s' does not match the version # '%s' in the filename, proceeding based on file name" % (version, version_File)
+ version = version_File
+ return (version, libname, install_dir)
+
+def versionedLibLinks(dest, source, env):
+ """If we are installing a versioned shared library create the required links."""
+ Verbose = False
+ linknames = []
+ version, libname, install_dir = versionedLibVersion(dest, env)
+
+ if version != None:
+ # libname includes the version number if one was given
+ linknames = SCons.Tool.VersionShLibLinkNames(version,libname,env)
+ if Verbose:
+ print "versionedLibLinks: linknames ",linknames
+ # Here we just need the file name w/o path as the target of the link
+ lib_ver = libname
+ # make symlink of adjacent names in linknames
+ for count in range(len(linknames)):
+ linkname = linknames[count]
+ fulllinkname = os.path.join(install_dir, linkname)
+ if Verbose:
+ print "full link name ",fulllinkname
+ if count > 0:
+ try:
+ os.remove(lastlinkname)
+ except:
+ pass
+ os.symlink(os.path.basename(fulllinkname),lastlinkname)
+ if Verbose:
+ print "versionedLibLinks: made sym link of %s -> %s" % (lastlinkname,os.path.basename(fulllinkname))
+ lastlinkname = fulllinkname
+ # finish chain of sym links with link to the actual library
+ if len(linknames)>0:
+ try:
+ os.remove(lastlinkname)
+ except:
+ pass
+ os.symlink(lib_ver,lastlinkname)
+ if Verbose:
+ print "versionedLibLinks: made sym link of %s -> %s" % (lib_ver,lastlinkname)
+ return
+
+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."%(list(map(str, source)), list(map(str, target)))
+ for t,s in zip(target,source):
+ if install(t.get_path(),s.get_path(),env):
+ return 1
+
+ return 0
+
+def installFuncVersionedLib(target, source, env):
+ """Install a versioned library into a target using the function specified
+ as the INSTALLVERSIONEDLIB construction variable."""
+ try:
+ install = env['INSTALLVERSIONEDLIB']
+ except KeyError:
+ raise SCons.Errors.UserError('Missing INSTALLVERSIONEDLIB construction variable.')
+
+ assert len(target)==len(source), \
+ "Installing source %s into target %s: target and source lists must have same length."%(list(map(str, source)), list(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)
+
+def add_versioned_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
+ Verbose = False
+ _INSTALLED_FILES.extend(target)
+ if Verbose:
+ print "ver lib emitter ",repr(target)
+
+ # see if we have a versioned shared library, if so generate side effects
+ version, libname, install_dir = versionedLibVersion(target[0].path, env)
+ if version != None:
+ # generate list of link names
+ linknames = SCons.Tool.VersionShLibLinkNames(version,libname,env)
+ for linkname in linknames:
+ if Verbose:
+ print "make side effect of %s" % os.path.join(install_dir, linkname)
+ fulllinkname = os.path.join(install_dir, linkname)
+ env.SideEffect(fulllinkname,target[0])
+ env.Clean(target[0],fulllinkname)
+ _INSTALLED_FILES.append(fulllinkname)
+ if Verbose:
+ print "installed list ", _INSTALLED_FILES
+
+ _UNIQUE_INSTALLED_FILES = None
+ return (target, source)
+
+class DESTDIR_factory(object):
+ """ 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)
+installVerLib_action = SCons.Action.Action(installFuncVersionedLib, 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(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(BaseInstallBuilder(env, tgt, src, **kw))
+ return result
+
+BaseVersionedInstallBuilder = None
+
+def InstallVersionedBuilderWrapper(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(BaseVersionedInstallBuilder(env, target, src, **kw))
+ return tgt
+
+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')
+
+ global BaseVersionedInstallBuilder
+ if BaseVersionedInstallBuilder is None:
+ install_sandbox = GetOption('install_sandbox')
+ if install_sandbox:
+ target_factory = DESTDIR_factory(env, install_sandbox)
+ else:
+ target_factory = env.fs
+
+ BaseVersionedInstallBuilder = SCons.Builder.Builder(
+ action = installVerLib_action,
+ target_factory = target_factory.Entry,
+ source_factory = env.fs.Entry,
+ multi = 1,
+ emitter = [ add_versioned_targets_to_INSTALLED_FILES, ],
+ name = 'InstallVersionedBuilder')
+
+ env['BUILDERS']['_InternalInstall'] = InstallBuilderWrapper
+ env['BUILDERS']['_InternalInstallAs'] = InstallAsBuilderWrapper
+ env['BUILDERS']['_InternalInstallVersionedLib'] = InstallVersionedBuilderWrapper
+
+ # 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
+
+ try:
+ env['INSTALLVERSIONEDLIB']
+ except KeyError:
+ env['INSTALLVERSIONEDLIB'] = copyFuncVersionedLib
+
+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/engine/SCons/Tool/intelc.py b/engine/SCons/Tool/intelc.py
new file mode 100644
index 0000000..20af1c5
--- /dev/null
+++ b/engine/SCons/Tool/intelc.py
@@ -0,0 +1,608 @@
+"""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 - 2014 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.
+from __future__ import division
+
+__revision__ = "src/engine/SCons/Tool/intelc.py 2014/09/27 12:51:43 garyo"
+
+import math, sys, os.path, glob, string, re
+
+is_windows = sys.platform == 'win32'
+is_win64 = is_windows and (os.environ['PROCESSOR_ARCHITECTURE'] == 'AMD64' or
+ ('PROCESSOR_ARCHITEW6432' in os.environ and
+ os.environ['PROCESSOR_ARCHITEW6432'] == 'AMD64'))
+is_linux = sys.platform.startswith('linux')
+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 list(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
+ # XXX needs to be updated for 2011+ versions (like 2011.11.344 which is compiler v12.1.5)
+ 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, list(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:
+ # For version 13 and later, check UUID subkeys for valuename
+ if is_win64:
+ K = 'Software\\Wow6432Node\\Intel\\Suites\\' + version + "\\Defaults\\C++\\" + abi.upper()
+ else:
+ K = 'Software\\Intel\\Suites\\' + version + "\\Defaults\\C++\\" + abi.upper()
+ try:
+ k = SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_LOCAL_MACHINE, K)
+ uuid = SCons.Util.RegQueryValueEx(k, 'SubKey')[0]
+
+ if is_win64:
+ K = 'Software\\Wow6432Node\\Intel\\Suites\\' + version + "\\" + uuid + "\\C++"
+ else:
+ K = 'Software\\Intel\\Suites\\' + version + "\\" + uuid + "\\C++"
+ k = SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_LOCAL_MACHINE, K)
+
+ try:
+ v = SCons.Util.RegQueryValueEx(k, valuename)[0]
+ return v # or v.encode('iso-8859-1', 'replace') to remove unicode?
+ except SCons.Util.RegError:
+ if abi.upper() == 'EM64T':
+ abi = 'em64t_native'
+ if is_win64:
+ K = 'Software\\Wow6432Node\\Intel\\Suites\\' + version + "\\" + uuid + "\\C++\\" + abi.upper()
+ else:
+ K = 'Software\\Intel\\Suites\\' + version + "\\" + uuid + "\\C++\\" + abi.upper()
+ k = SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_LOCAL_MACHINE, K)
+
+ 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 was not found in the registry, for Intel compiler version %s, abi='%s'"%(K, version,abi))
+
+ except SCons.Util.RegError:
+ raise MissingRegistryError("%s was not found in the registry, for Intel compiler version %s, abi='%s'"%(K, version,abi))
+ except WindowsError:
+ 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:
+ # For version 13 or later, check for default instance UUID
+ if is_win64:
+ keyname = 'Software\\WoW6432Node\\Intel\\Suites'
+ else:
+ keyname = 'Software\\Intel\\Suites'
+ 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.
+ if subkey == 'Defaults': # Ignore default instances
+ i = i + 1
+ continue
+ 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 or is_mac:
+ 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][0-9.]*)$', d)
+ if m:
+ versions.append(m.group(1))
+ for d in glob.glob('/opt/intel/Compiler/*'):
+ # Typical dir here is /opt/intel/Compiler/11.1
+ m = re.search(r'([0-9][0-9.]*)$', d)
+ if m:
+ versions.append(m.group(1))
+ for d in glob.glob('/opt/intel/composerxe-*'):
+ # Typical dir here is /opt/intel/composerxe-2011.4.184
+ m = re.search(r'([0-9][0-9.]*)$', d)
+ if m:
+ versions.append(m.group(1))
+ for d in glob.glob('/opt/intel/composer_xe_*'):
+ # Typical dir here is /opt/intel/composer_xe_2011_sp1.11.344
+ # The _sp1 is useless, the installers are named 2011.9.x, 2011.10.x, 2011.11.x
+ m = re.search(r'([0-9]{0,4})(?:_sp\d*)?\.([0-9][0-9.]*)$', d)
+ if m:
+ versions.append("%s.%s"%(m.group(1), m.group(2)))
+ def keyfunc(str):
+ """Given a dot-separated version string, return a tuple of ints representing it."""
+ return [int(x) for x in str.split('.')]
+ # split into ints, sort, then remove dups
+ return sorted(uniquify(versions), key=keyfunc, reverse=True)
+
+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)
+ archdir={'x86_64': 'intel64',
+ 'amd64' : 'intel64',
+ 'em64t' : 'intel64',
+ 'x86' : 'ia32',
+ 'i386' : 'ia32',
+ 'ia32' : 'ia32'
+ }[abi] # for v11 and greater
+ # 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")) \
+ and not os.path.exists(os.path.join(top, "Bin", archdir, "icl.exe")):
+ raise MissingDirError("Can't find Intel compiler in %s"%(top))
+ elif is_mac or is_linux:
+ def find_in_2008style_dir(version):
+ # 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
+ return top
+ def find_in_2010style_dir(version):
+ dirs=('/opt/intel/Compiler/%s/*'%version)
+ # typically /opt/intel/Compiler/11.1/064 (then bin/intel64/icc)
+ dirs=glob.glob(dirs)
+ # find highest sub-version number by reverse sorting and picking first existing one.
+ dirs.sort()
+ dirs.reverse()
+ top=None
+ for d in dirs:
+ if (os.path.exists(os.path.join(d, "bin", "ia32", "icc")) or
+ os.path.exists(os.path.join(d, "bin", "intel64", "icc"))):
+ top = d
+ break
+ return top
+ def find_in_2011style_dir(version):
+ # The 2011 (compiler v12) dirs are inconsistent, so just redo the search from
+ # get_all_compiler_versions and look for a match (search the newest form first)
+ top=None
+ for d in glob.glob('/opt/intel/composer_xe_*'):
+ # Typical dir here is /opt/intel/composer_xe_2011_sp1.11.344
+ # The _sp1 is useless, the installers are named 2011.9.x, 2011.10.x, 2011.11.x
+ m = re.search(r'([0-9]{0,4})(?:_sp\d*)?\.([0-9][0-9.]*)$', d)
+ if m:
+ cur_ver = "%s.%s"%(m.group(1), m.group(2))
+ if cur_ver == version and \
+ (os.path.exists(os.path.join(d, "bin", "ia32", "icc")) or
+ os.path.exists(os.path.join(d, "bin", "intel64", "icc"))):
+ top = d
+ break
+ if not top:
+ for d in glob.glob('/opt/intel/composerxe-*'):
+ # Typical dir here is /opt/intel/composerxe-2011.4.184
+ m = re.search(r'([0-9][0-9.]*)$', d)
+ if m and m.group(1) == version and \
+ (os.path.exists(os.path.join(d, "bin", "ia32", "icc")) or
+ os.path.exists(os.path.join(d, "bin", "intel64", "icc"))):
+ top = d
+ break
+ return top
+ top = find_in_2011style_dir(version) or find_in_2010style_dir(version) or find_in_2008style_dir(version)
+ # print "INTELC: top=",top
+ 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:
+ archdir={'x86_64': 'intel64',
+ 'amd64' : 'intel64',
+ 'em64t' : 'intel64',
+ 'x86' : 'ia32',
+ 'i386' : 'ia32',
+ 'ia32' : 'ia32'
+ }[abi] # for v11 and greater
+ if os.path.exists(os.path.join(topdir, 'bin', archdir)):
+ bindir="bin/%s"%archdir
+ libdir="lib/%s"%archdir
+ else:
+ bindir="bin"
+ libdir="lib"
+ if verbose:
+ print "Intel C compiler: using version %s (%g), abi %s, in '%s/%s'"%\
+ (repr(version), linux_ver_normalize(version),abi,topdir,bindir)
+ if is_linux:
+ # Show the actual compiler version by running the compiler.
+ os.system('%s/%s/icc --version'%(topdir,bindir))
+ if is_mac:
+ # Show the actual compiler version by running the compiler.
+ os.system('%s/%s/icc --version'%(topdir,bindir))
+
+ env['INTEL_C_COMPILER_TOP'] = topdir
+ if is_linux:
+ paths={'INCLUDE' : 'include',
+ 'LIB' : libdir,
+ 'PATH' : bindir,
+ 'LD_LIBRARY_PATH' : libdir}
+ for p in paths.keys():
+ env.PrependENVPath(p, os.path.join(topdir, paths[p]))
+ if is_mac:
+ paths={'INCLUDE' : 'include',
+ 'LIB' : libdir,
+ 'PATH' : bindir,
+ 'LD_LIBRARY_PATH' : libdir}
+ 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], path.split(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 (ld.find('@') != -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/engine/SCons/Tool/ipkg.py b/engine/SCons/Tool/ipkg.py
new file mode 100644
index 0000000..ccfa0e1
--- /dev/null
+++ b/engine/SCons/Tool/ipkg.py
@@ -0,0 +1,67 @@
+"""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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+import os
+
+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}'
+ env['IPKGUSER'] = os.popen('id -un').read().strip()
+ env['IPKGGROUP'] = os.popen('id -gn').read().strip()
+ 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/engine/SCons/Tool/jar.py b/engine/SCons/Tool/jar.py
new file mode 100644
index 0000000..b99aa7f
--- /dev/null
+++ b/engine/SCons/Tool/jar.py
@@ -0,0 +1,116 @@
+"""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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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):
+ # As reported by Jan Nijtmans in issue #2730, the simple
+ # return env.Detect('jar')
+ # doesn't always work during initialization. For now, we
+ # stop trying to detect an executable (analogous to the
+ # javac Builder).
+ # TODO: Come up with a proper detect() routine...and enable it.
+ return 1
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/engine/SCons/Tool/javac.py b/engine/SCons/Tool/javac.py
new file mode 100644
index 0000000..4fa23b1
--- /dev/null
+++ b/engine/SCons/Tool/javac.py
@@ -0,0 +1,232 @@
+"""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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+import os
+import os.path
+
+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 os.path.normpath(path).replace(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)
+ 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()
+ dirnode = entry.rdir()
+ def find_java_files(arg, dirpath, filenames):
+ java_files = sorted([n for n in filenames
+ if _my_normcase(n).endswith(js)])
+ mydir = dirnode.Dir(dirpath)
+ java_paths = [mydir.File(f) for f in java_files]
+ for jp in java_paths:
+ arg[jp] = True
+ for dirpath, dirnames, filenames in os.walk(dirnode.get_abspath()):
+ find_java_files(result, dirpath, filenames)
+ entry.walk(find_java_files, result)
+
+ slist.extend(list(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(object):
+ """
+ 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:
+ default = env[self.default]
+ if default:
+ if not SCons.Util.is_List(default):
+ default = [default]
+ path = path + default
+ if path:
+ return [self.opt, os.pathsep.join(map(str, path))]
+ else:
+ 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(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/engine/SCons/Tool/javah.py b/engine/SCons/Tool/javah.py
new file mode 100644
index 0000000..3deb78a
--- /dev/null
+++ b/engine/SCons/Tool/javah.py
@@ -0,0 +1,137 @@
+"""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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+import os.path
+
+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 = s.attributes.java_classname.replace('.', '_') + '.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 'JAVACLASSPATH' in env 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/engine/SCons/Tool/latex.py b/engine/SCons/Tool/latex.py
new file mode 100644
index 0000000..b837735
--- /dev/null
+++ b/engine/SCons/Tool/latex.py
@@ -0,0 +1,80 @@
+"""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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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:
+ SCons.Tool.tex.check_file_error_message(env['LATEX'])
+ 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):
+ SCons.Tool.tex.generate_darwin(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/engine/SCons/Tool/ldc.py b/engine/SCons/Tool/ldc.py
new file mode 100644
index 0000000..a32c5ab
--- /dev/null
+++ b/engine/SCons/Tool/ldc.py
@@ -0,0 +1,141 @@
+"""SCons.Tool.ldc
+
+Tool-specific initialization for the LDC compiler.
+(http://www.dsource.org/projects/ldc)
+
+Developed by Russel Winder (russel@winder.org.uk)
+2012-05-09 onwards
+
+Compiler variables:
+ DC - The name of the D compiler to use. Defaults to ldc2.
+ 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 ldc2.
+ 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 - 2014 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/ldc.py 2014/09/27 12:51:43 garyo"
+
+import os
+import subprocess
+
+import SCons.Action
+import SCons.Builder
+import SCons.Defaults
+import SCons.Scanner.D
+import SCons.Tool
+
+import SCons.Tool.DCommon
+
+
+def generate(env):
+ static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
+
+ static_obj.add_action('.d', SCons.Defaults.DAction)
+ shared_obj.add_action('.d', SCons.Defaults.ShDAction)
+ static_obj.add_emitter('.d', SCons.Defaults.StaticObjectEmitter)
+ shared_obj.add_emitter('.d', SCons.Defaults.SharedObjectEmitter)
+
+ env['DC'] = env.Detect('ldc2')
+ 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['SHDC'] = '$DC'
+ env['SHDCOM'] = '$DC $_DINCFLAGS $_DVERFLAGS $_DDEBUGFLAGS $_DFLAGS -c -relocation-model=pic -of=$TARGET $SOURCES'
+
+ env['DPATH'] = ['#/']
+ env['DFLAGS'] = []
+ env['DVERSIONS'] = []
+ env['DDEBUG'] = []
+
+ if env['DC']:
+ SCons.Tool.DCommon.addDPATHToEnv(env, env['DC'])
+
+ env['DINCPREFIX'] = '-I='
+ env['DINCSUFFIX'] = ''
+ env['DVERPREFIX'] = '-version='
+ env['DVERSUFFIX'] = ''
+ env['DDEBUGPREFIX'] = '-debug='
+ env['DDEBUGSUFFIX'] = ''
+ env['DFLAGPREFIX'] = '-'
+ env['DFLAGSUFFIX'] = ''
+ env['DFILESUFFIX'] = '.d'
+
+ env['DLINK'] = '$DC'
+ env['DLINKFLAGS'] = SCons.Util.CLVar('')
+ env['DLINKCOM'] = '$DLINK -of=$TARGET $DLINKFLAGS $__DRPATH $SOURCES $_DLIBDIRFLAGS $_DLIBFLAGS'
+
+ env['DSHLINK'] = '$DC'
+ env['DSHLINKFLAGS'] = SCons.Util.CLVar('$DLINKFLAGS -shared -defaultlib=phobos2')
+ env['SHDLINKCOM'] = '$DLINK -of=$TARGET $DSHLINKFLAGS $__DRPATH $SOURCES $_DLIBDIRFLAGS $_DLIBFLAGS'
+
+ env['DLIBLINKPREFIX'] = '' if env['PLATFORM'] == 'win32' else '-L-l'
+ env['DLIBLINKSUFFIX'] = '.lib' if env['PLATFORM'] == 'win32' else ''
+ #env['_DLIBFLAGS'] = '$( ${_concat(DLIBLINKPREFIX, LIBS, DLIBLINKSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)'
+ env['_DLIBFLAGS'] = '${_stripixes(DLIBLINKPREFIX, LIBS, DLIBLINKSUFFIX, LIBPREFIXES, LIBSUFFIXES, __env__)}'
+
+ env['DLIBDIRPREFIX'] = '-L-L'
+ env['DLIBDIRSUFFIX'] = ''
+ env['_DLIBDIRFLAGS'] = '$( ${_concat(DLIBDIRPREFIX, LIBPATH, DLIBDIRSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)'
+
+
+ env['DLIB'] = 'lib' if env['PLATFORM'] == 'win32' else 'ar cr'
+ env['DLIBCOM'] = '$DLIB $_DLIBFLAGS {0}$TARGET $SOURCES $_DLIBFLAGS'.format('-c ' if env['PLATFORM'] == 'win32' else '')
+
+ #env['_DLIBFLAGS'] = '$( ${_concat(DLIBFLAGPREFIX, DLIBFLAGS, DLIBFLAGSUFFIX, __env__)} $)'
+
+ env['DLIBFLAGPREFIX'] = '-'
+ env['DLIBFLAGSUFFIX'] = ''
+
+ # __RPATH is set to $_RPATH in the platform specification if that
+ # platform supports it.
+ env['DRPATHPREFIX'] = '-L-rpath='
+ env['DRPATHSUFFIX'] = ''
+ env['_DRPATH'] = '${_concat(DRPATHPREFIX, RPATH, DRPATHSUFFIX, __env__)}'
+
+ SCons.Tool.createStaticLibBuilder(env)
+
+
+def exists(env):
+ return env.Detect('ldc2')
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/engine/SCons/Tool/lex.py b/engine/SCons/Tool/lex.py
new file mode 100644
index 0000000..501c6a1
--- /dev/null
+++ b/engine/SCons/Tool/lex.py
@@ -0,0 +1,97 @@
+"""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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+import os.path
+
+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 = option[l:].strip()
+ 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/engine/SCons/Tool/link.py b/engine/SCons/Tool/link.py
new file mode 100644
index 0000000..3871e8d
--- /dev/null
+++ b/engine/SCons/Tool/link.py
@@ -0,0 +1,204 @@
+"""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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+import re
+
+import SCons.Defaults
+import SCons.Tool
+import SCons.Util
+import SCons.Warnings
+
+from SCons.Tool.FortranCommon import isfortran
+
+from SCons.Tool.DCommon import isD
+
+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)
+ has_d = isD(env, source)
+ if has_cplusplus and has_fortran and not has_d:
+ 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_d:
+ env['LINKCOM'] = env['DLINKCOM']
+ env['SHLINKCOM'] = env['SHDLINKCOM']
+ return '$DC'
+ elif has_fortran:
+ return '$FORTRAN'
+ elif has_cplusplus:
+ return '$CXX'
+ return '$CC'
+
+def shlib_emitter(target, source, env):
+ Verbose = False
+ platform = env.subst('$PLATFORM')
+ for tgt in target:
+ tgt.attributes.shared = 1
+ try:
+ # target[0] comes in as libtest.so. Add the version extensions
+ version = env.subst('$SHLIBVERSION')
+ if version:
+ version_names = shlib_emitter_names(target, source, env)
+ # change the name of the target to include the version number
+ target[0].name = version_names[0]
+ for name in version_names:
+ env.SideEffect(name, target[0])
+ env.Clean(target[0], name)
+ if Verbose:
+ print "shlib_emitter: add side effect - ",name
+ except KeyError:
+ version = None
+ return (target, source)
+
+def shlib_emitter_names(target, source, env):
+ """Return list of file names that are side effects for a versioned library build. The first name in the list is the new name for the target"""
+ Verbose = False
+ platform = env.subst('$PLATFORM')
+ version_names = []
+ try:
+ # target[0] comes in as libtest.so. Add the version extensions
+ version = env.subst('$SHLIBVERSION')
+ if version.count(".") != 2:
+ # We need a version of the form x.y.z to proceed
+ raise ValueError
+ if version:
+ if platform == 'posix':
+ versionparts = version.split('.')
+ name = target[0].name
+ # generate library name with the version number
+ version_name = target[0].name + '.' + version
+ if Verbose:
+ print "shlib_emitter_names: target is ", version_name
+ print "shlib_emitter_names: side effect: ", name
+ # add version_name to list of names to be a Side effect
+ version_names.append(version_name)
+ if Verbose:
+ print "shlib_emitter_names: versionparts ",versionparts
+ for ver in versionparts[0:-1]:
+ name = name + '.' + ver
+ if Verbose:
+ print "shlib_emitter_names: side effect: ", name
+ # add name to list of names to be a Side effect
+ version_names.append(name)
+ elif platform == 'darwin':
+ shlib_suffix = env.subst('$SHLIBSUFFIX')
+ name = target[0].name
+ # generate library name with the version number
+ suffix_re = re.escape(shlib_suffix)
+ version_name = re.sub(suffix_re, '.' + version + shlib_suffix, name)
+ if Verbose:
+ print "shlib_emitter_names: target is ", version_name
+ print "shlib_emitter_names: side effect: ", name
+ # add version_name to list of names to be a Side effect
+ version_names.append(version_name)
+ elif platform == 'cygwin':
+ shlib_suffix = env.subst('$SHLIBSUFFIX')
+ name = target[0].name
+ # generate library name with the version number
+ suffix_re = re.escape(shlib_suffix)
+ version_name = re.sub(suffix_re, '-' + re.sub('\.', '-', version) + shlib_suffix, name)
+ if Verbose:
+ print "shlib_emitter_names: target is ", version_name
+ print "shlib_emitter_names: side effect: ", name
+ # add version_name to list of names to be a Side effect
+ version_names.append(version_name)
+
+ except KeyError:
+ version = None
+ return version_names
+
+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 $__RPATH $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('')
+ # __RPATH is only set to something ($_RPATH typically) on platforms that support it.
+ env['LINKCOM'] = '$LINK -o $TARGET $LINKFLAGS $__RPATH $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 $__RPATH $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/engine/SCons/Tool/linkloc.py b/engine/SCons/Tool/linkloc.py
new file mode 100644
index 0000000..e1c67ed
--- /dev/null
+++ b/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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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(object):
+ 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/engine/SCons/Tool/m4.py b/engine/SCons/Tool/m4.py
new file mode 100644
index 0000000..9c28871
--- /dev/null
+++ b/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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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/engine/SCons/Tool/masm.py b/engine/SCons/Tool/masm.py
new file mode 100644
index 0000000..6006ed4
--- /dev/null
+++ b/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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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/engine/SCons/Tool/midl.py b/engine/SCons/Tool/midl.py
new file mode 100644
index 0000000..6b170d5
--- /dev/null
+++ b/engine/SCons/Tool/midl.py
@@ -0,0 +1,88 @@
+"""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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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 midlcom.find('/proxy') != -1:
+ proxy = base + '_p.c'
+ t.append(proxy)
+ if midlcom.find('/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/engine/SCons/Tool/mingw.py b/engine/SCons/Tool/mingw.py
new file mode 100644
index 0000000..bf26a06
--- /dev/null
+++ b/engine/SCons/Tool/mingw.py
@@ -0,0 +1,180 @@
+"""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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+import os
+import os.path
+
+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
+ path=env.WhereIs(key_program)
+ if (path):
+ return path
+ # then the OS path:
+ path=SCons.Util.WhereIs(key_program)
+ if (path):
+ return path
+
+ # If that doesn't work try default location for mingw
+ save_path=env['ENV']['PATH']
+ env.AppendENVPath('PATH',r'c:\MinGW\bin')
+ path =env.WhereIs(key_program)
+ if not path:
+ env['ENV']['PATH']=save_path
+ return path
+
+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'):
+
+ # Create list of target libraries as strings
+ targetStrings=env.ReplaceIxes(dll,
+ 'SHLIBPREFIX', 'SHLIBSUFFIX',
+ 'LIBPREFIX', 'LIBSUFFIX')
+
+ # Now add file nodes to target list
+ target.append(env.fs.File(targetStrings))
+
+ # Append a def file target if there isn't already a def file target
+ # or a def file source or the user has explicitly asked for the target
+ # to be emitted.
+ def_source = env.FindIxes(source, 'WINDOWSDEFPREFIX', 'WINDOWSDEFSUFFIX')
+ def_target = env.FindIxes(target, 'WINDOWSDEFPREFIX', 'WINDOWSDEFSUFFIX')
+ skip_def_insert = env.subst("$WINDOWS_INSERT_DEF") in ['', '0', 0]
+ if not def_source and not def_target and not skip_def_insert:
+ # Create list of target libraries and def files as strings
+ targetStrings=env.ReplaceIxes(dll,
+ 'SHLIBPREFIX', 'SHLIBSUFFIX',
+ 'WINDOWSDEFPREFIX', 'WINDOWSDEFSUFFIX')
+
+ # Now add file nodes to target list
+ target.append(env.fs.File(targetStrings))
+
+ 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', 'gfortran', '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'
+ env['PROGSUFFIX'] = '.exe'
+
+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/engine/SCons/Tool/msgfmt.py b/engine/SCons/Tool/msgfmt.py
new file mode 100644
index 0000000..84d3bec
--- /dev/null
+++ b/engine/SCons/Tool/msgfmt.py
@@ -0,0 +1,108 @@
+""" msgfmt tool """
+
+# Copyright (c) 2001 - 2014 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/msgfmt.py 2014/09/27 12:51:43 garyo"
+
+from SCons.Builder import BuilderBase
+#############################################################################
+class _MOFileBuilder(BuilderBase):
+ """ The builder class for `MO` files.
+
+ The reason for this builder to exists and its purpose is quite simillar
+ as for `_POFileBuilder`. This time, we extend list of sources, not targets,
+ and call `BuilderBase._execute()` only once (as we assume single-target
+ here).
+ """
+
+ def _execute(self, env, target, source, *args, **kw):
+ # Here we add support for 'LINGUAS_FILE' keyword. Emitter is not suitable
+ # in this case, as it is called too late (after multiple sources
+ # are handled single_source builder.
+ import SCons.Util
+ from SCons.Tool.GettextCommon import _read_linguas_from_files
+ linguas_files = None
+ if env.has_key('LINGUAS_FILE') and env['LINGUAS_FILE'] is not None:
+ linguas_files = env['LINGUAS_FILE']
+ # This should prevent from endless recursion.
+ env['LINGUAS_FILE'] = None
+ # We read only languages. Suffixes shall be added automatically.
+ linguas = _read_linguas_from_files(env, linguas_files)
+ if SCons.Util.is_List(source):
+ source.extend(linguas)
+ elif source is not None:
+ source = [source] + linguas
+ else:
+ source = linguas
+ result = BuilderBase._execute(self,env,target,source,*args, **kw)
+ if linguas_files is not None:
+ env['LINGUAS_FILE'] = linguas_files
+ return result
+#############################################################################
+
+#############################################################################
+def _create_mo_file_builder(env, **kw):
+ """ Create builder object for `MOFiles` builder """
+ import SCons.Action
+ # FIXME: What factory use for source? Ours or their?
+ kw['action'] = SCons.Action.Action('$MSGFMTCOM','$MSGFMTCOMSTR')
+ kw['suffix'] = '$MOSUFFIX'
+ kw['src_suffix'] = '$POSUFFIX'
+ kw['src_builder'] = '_POUpdateBuilder'
+ kw['single_source'] = True
+ return _MOFileBuilder(**kw)
+#############################################################################
+
+#############################################################################
+def generate(env,**kw):
+ """ Generate `msgfmt` tool """
+ import SCons.Util
+ from SCons.Tool.GettextCommon import _detect_msgfmt
+ try:
+ env['MSGFMT'] = _detect_msgfmt(env)
+ except:
+ env['MSGFMT'] = 'msgfmt'
+ env.SetDefault(
+ MSGFMTFLAGS = [ SCons.Util.CLVar('-c') ],
+ MSGFMTCOM = '$MSGFMT $MSGFMTFLAGS -o $TARGET $SOURCE',
+ MSGFMTCOMSTR = '',
+ MOSUFFIX = ['.mo'],
+ POSUFFIX = ['.po']
+ )
+ env.Append( BUILDERS = { 'MOFiles' : _create_mo_file_builder(env) } )
+#############################################################################
+
+#############################################################################
+def exists(env):
+ """ Check if the tool exists """
+ from SCons.Tool.GettextCommon import _msgfmt_exists
+ try:
+ return _msgfmt_exists(env)
+ except:
+ return False
+#############################################################################
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/engine/SCons/Tool/msginit.py b/engine/SCons/Tool/msginit.py
new file mode 100644
index 0000000..e594230
--- /dev/null
+++ b/engine/SCons/Tool/msginit.py
@@ -0,0 +1,120 @@
+""" msginit tool
+
+Tool specific initialization of msginit tool.
+"""
+
+# Copyright (c) 2001 - 2014 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/msginit.py 2014/09/27 12:51:43 garyo"
+
+import SCons.Warnings
+import SCons.Builder
+import re
+
+#############################################################################
+def _optional_no_translator_flag(env):
+ """ Return '--no-translator' flag if we run *msginit(1)* in non-interactive
+ mode."""
+ import SCons.Util
+ if env.has_key('POAUTOINIT'):
+ autoinit = env['POAUTOINIT']
+ else:
+ autoinit = False
+ if autoinit:
+ return [SCons.Util.CLVar('--no-translator')]
+ else:
+ return [SCons.Util.CLVar('')]
+#############################################################################
+
+#############################################################################
+def _POInitBuilder(env, **kw):
+ """ Create builder object for `POInit` builder. """
+ import SCons.Action
+ from SCons.Tool.GettextCommon import _init_po_files, _POFileBuilder
+ action = SCons.Action.Action(_init_po_files, None)
+ return _POFileBuilder(env, action=action, target_alias='$POCREATE_ALIAS')
+#############################################################################
+
+#############################################################################
+from SCons.Environment import _null
+#############################################################################
+def _POInitBuilderWrapper(env, target=None, source=_null, **kw):
+ """ Wrapper for _POFileBuilder. We use it to make user's life easier.
+
+ This wrapper checks for `$POTDOMAIN` construction variable (or override in
+ `**kw`) and treats it appropriatelly.
+ """
+ if source is _null:
+ if 'POTDOMAIN' in kw:
+ domain = kw['POTDOMAIN']
+ elif env.has_key('POTDOMAIN'):
+ domain = env['POTDOMAIN']
+ else:
+ domain = 'messages'
+ source = [ domain ] # NOTE: Suffix shall be appended automatically
+ return env._POInitBuilder(target, source, **kw)
+#############################################################################
+
+#############################################################################
+def generate(env,**kw):
+ """ Generate the `msginit` tool """
+ import SCons.Util
+ from SCons.Tool.GettextCommon import _detect_msginit
+ try:
+ env['MSGINIT'] = _detect_msginit(env)
+ except:
+ env['MSGINIT'] = 'msginit'
+ msginitcom = '$MSGINIT ${_MSGNoTranslator(__env__)} -l ${_MSGINITLOCALE}' \
+ + ' $MSGINITFLAGS -i $SOURCE -o $TARGET'
+ # NOTE: We set POTSUFFIX here, in case the 'xgettext' is not loaded
+ # (sometimes we really don't need it)
+ env.SetDefault(
+ POSUFFIX = ['.po'],
+ POTSUFFIX = ['.pot'],
+ _MSGINITLOCALE = '${TARGET.filebase}',
+ _MSGNoTranslator = _optional_no_translator_flag,
+ MSGINITCOM = msginitcom,
+ MSGINITCOMSTR = '',
+ MSGINITFLAGS = [ ],
+ POAUTOINIT = False,
+ POCREATE_ALIAS = 'po-create'
+ )
+ env.Append( BUILDERS = { '_POInitBuilder' : _POInitBuilder(env) } )
+ env.AddMethod(_POInitBuilderWrapper, 'POInit')
+ env.AlwaysBuild(env.Alias('$POCREATE_ALIAS'))
+#############################################################################
+
+#############################################################################
+def exists(env):
+ """ Check if the tool exists """
+ from SCons.Tool.GettextCommon import _msginit_exists
+ try:
+ return _msginit_exists(env)
+ except:
+ return False
+#############################################################################
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/engine/SCons/Tool/msgmerge.py b/engine/SCons/Tool/msgmerge.py
new file mode 100644
index 0000000..644be85
--- /dev/null
+++ b/engine/SCons/Tool/msgmerge.py
@@ -0,0 +1,104 @@
+""" msgmerget tool
+
+Tool specific initialization for `msgmerge` tool.
+"""
+
+# Copyright (c) 2001 - 2014 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/msgmerge.py 2014/09/27 12:51:43 garyo"
+
+#############################################################################
+def _update_or_init_po_files(target, source, env):
+ """ Action function for `POUpdate` builder """
+ import SCons.Action
+ from SCons.Tool.GettextCommon import _init_po_files
+ for tgt in target:
+ if tgt.rexists():
+ action = SCons.Action.Action('$MSGMERGECOM', '$MSGMERGECOMSTR')
+ else:
+ action = _init_po_files
+ status = action([tgt], source, env)
+ if status : return status
+ return 0
+#############################################################################
+
+#############################################################################
+def _POUpdateBuilder(env, **kw):
+ """ Create an object of `POUpdate` builder """
+ import SCons.Action
+ from SCons.Tool.GettextCommon import _POFileBuilder
+ action = SCons.Action.Action(_update_or_init_po_files, None)
+ return _POFileBuilder(env, action=action, target_alias='$POUPDATE_ALIAS')
+#############################################################################
+
+#############################################################################
+from SCons.Environment import _null
+#############################################################################
+def _POUpdateBuilderWrapper(env, target=None, source=_null, **kw):
+ """ Wrapper for `POUpdate` builder - make user's life easier """
+ if source is _null:
+ if 'POTDOMAIN' in kw:
+ domain = kw['POTDOMAIN']
+ elif env.has_key('POTDOMAIN') and env['POTDOMAIN']:
+ domain = env['POTDOMAIN']
+ else:
+ domain = 'messages'
+ source = [ domain ] # NOTE: Suffix shall be appended automatically
+ return env._POUpdateBuilder(target, source, **kw)
+#############################################################################
+
+#############################################################################
+def generate(env,**kw):
+ """ Generate the `xgettext` tool """
+ from SCons.Tool.GettextCommon import _detect_msgmerge
+ try:
+ env['MSGMERGE'] = _detect_msgmerge(env)
+ except:
+ env['MSGMERGE'] = 'msgmerge'
+ env.SetDefault(
+ POTSUFFIX = ['.pot'],
+ POSUFFIX = ['.po'],
+ MSGMERGECOM = '$MSGMERGE $MSGMERGEFLAGS --update $TARGET $SOURCE',
+ MSGMERGECOMSTR = '',
+ MSGMERGEFLAGS = [ ],
+ POUPDATE_ALIAS = 'po-update'
+ )
+ env.Append(BUILDERS = { '_POUpdateBuilder':_POUpdateBuilder(env) })
+ env.AddMethod(_POUpdateBuilderWrapper, 'POUpdate')
+ env.AlwaysBuild(env.Alias('$POUPDATE_ALIAS'))
+#############################################################################
+
+#############################################################################
+def exists(env):
+ """ Check if the tool exists """
+ from SCons.Tool.GettextCommon import _msgmerge_exists
+ try:
+ return _msgmerge_exists(env)
+ except:
+ return False
+#############################################################################
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/engine/SCons/Tool/mslib.py b/engine/SCons/Tool/mslib.py
new file mode 100644
index 0000000..f51b957
--- /dev/null
+++ b/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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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/engine/SCons/Tool/mslink.py b/engine/SCons/Tool/mslink.py
new file mode 100644
index 0000000..e10662b
--- /dev/null
+++ b/engine/SCons/Tool/mslink.py
@@ -0,0 +1,327 @@
+"""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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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) or env.get('WINDOWS_EMBED_MANIFEST', 0)):
+ # MSVC 8 and above automatically generate .manifest files that must be installed
+ extratargets.append(
+ env.ReplaceIxes(dll,
+ '%sPREFIX' % paramtp, '%sSUFFIX' % paramtp,
+ "WINDOWSSHLIBMANIFESTPREFIX", "WINDOWSSHLIBMANIFESTSUFFIX"))
+
+ if 'PDB' in env 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 = []
+ extrasources = []
+
+ 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) or env.get('WINDOWS_EMBED_MANIFEST', 0)):
+ # MSVC 8 and above automatically generate .manifest files that have to be installed
+ extratargets.append(
+ env.ReplaceIxes(exe,
+ "PROGPREFIX", "PROGSUFFIX",
+ "WINDOWSPROGMANIFESTPREFIX", "WINDOWSPROGMANIFESTSUFFIX"))
+
+ if 'PDB' in env and env['PDB']:
+ pdb = env.arg2nodes('$PDB', target=target, source=source)[0]
+ extratargets.append(pdb)
+ target[0].attributes.pdb = pdb
+
+ if version_num >= 11.0 and env.get('PCH', 0):
+ # MSVC 11 and above need the PCH object file to be added to the link line,
+ # otherwise you get link error LNK2011.
+ pchobj = SCons.Util.splitext(str(env['PCH']))[0] + '.obj'
+ # print "prog_emitter, version %s, appending pchobj %s"%(version_num, pchobj)
+ if pchobj not in extrasources:
+ extrasources.append(pchobj)
+
+ return (target+extratargets,source+extrasources)
+
+def RegServerFunc(target, source, env):
+ if 'register' in env 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
+
+# These are the actual actions run to embed the manifest.
+# They are only called from the Check versions below.
+embedManifestExeAction = SCons.Action.Action('$MTEXECOM')
+embedManifestDllAction = SCons.Action.Action('$MTSHLIBCOM')
+
+def embedManifestDllCheck(target, source, env):
+ """Function run by embedManifestDllCheckAction to check for existence of manifest
+ and other conditions, and embed the manifest by calling embedManifestDllAction if so."""
+ if env.get('WINDOWS_EMBED_MANIFEST', 0):
+ manifestSrc = target[0].abspath + '.manifest'
+ if os.path.exists(manifestSrc):
+ ret = (embedManifestDllAction) ([target[0]],None,env)
+ if ret:
+ raise SCons.Errors.UserError, "Unable to embed manifest into %s" % (target[0])
+ return ret
+ else:
+ print '(embed: no %s.manifest found; not embedding.)'%str(target[0])
+ return 0
+
+def embedManifestExeCheck(target, source, env):
+ """Function run by embedManifestExeCheckAction to check for existence of manifest
+ and other conditions, and embed the manifest by calling embedManifestExeAction if so."""
+ if env.get('WINDOWS_EMBED_MANIFEST', 0):
+ manifestSrc = target[0].abspath + '.manifest'
+ if os.path.exists(manifestSrc):
+ ret = (embedManifestExeAction) ([target[0]],None,env)
+ if ret:
+ raise SCons.Errors.UserError, "Unable to embed manifest into %s" % (target[0])
+ return ret
+ else:
+ print '(embed: no %s.manifest found; not embedding.)'%str(target[0])
+ return 0
+
+embedManifestDllCheckAction = SCons.Action.Action(embedManifestDllCheck, None)
+embedManifestExeCheckAction = SCons.Action.Action(embedManifestExeCheck, None)
+
+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")}', '$SHLINKCOMSTR')
+compositeShLinkAction = shlibLinkAction + regServerCheck + embedManifestDllCheckAction
+ldmodLinkAction = SCons.Action.Action('${TEMPFILE("$LDMODULE $LDMODULEFLAGS $_LDMODULE_TARGETS $_LIBDIRFLAGS $_LIBFLAGS $_PDB $_LDMODULE_SOURCES")}', '$LDMODULECOMSTR')
+compositeLdmodAction = ldmodLinkAction + regServerCheck + embedManifestDllCheckAction
+exeLinkAction = SCons.Action.Action('${TEMPFILE("$LINK $LINKFLAGS /OUT:$TARGET.windows $_LIBDIRFLAGS $_LIBFLAGS $_PDB $SOURCES.windows")}', '$LINKCOMSTR')
+compositeLinkAction = exeLinkAction + embedManifestExeCheckAction
+
+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'] = compositeLinkAction
+ 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}'
+
+ env['WINDOWS_EMBED_MANIFEST'] = 0
+ env['MT'] = 'mt'
+ #env['MTFLAGS'] = ['-hashupdate']
+ env['MTFLAGS'] = SCons.Util.CLVar('/nologo')
+ # Note: use - here to prevent build failure if no manifest produced.
+ # This seems much simpler than a fancy system using a function action to see
+ # if the manifest actually exists before trying to run mt with it.
+ env['MTEXECOM'] = '-$MT $MTFLAGS -manifest ${TARGET}.manifest $_MANIFEST_SOURCES -outputresource:$TARGET;1'
+ env['MTSHLIBCOM'] = '-$MT $MTFLAGS -manifest ${TARGET}.manifest $_MANIFEST_SOURCES -outputresource:$TARGET;2'
+ # Future work garyo 27-Feb-11
+ env['_MANIFEST_SOURCES'] = None # _windowsManifestSources
+
+ # 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/engine/SCons/Tool/mssdk.py b/engine/SCons/Tool/mssdk.py
new file mode 100644
index 0000000..c70e788
--- /dev/null
+++ b/engine/SCons/Tool/mssdk.py
@@ -0,0 +1,50 @@
+#
+# Copyright (c) 2001 - 2014 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 2014/09/27 12:51:43 garyo"
+
+"""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/engine/SCons/Tool/msvc.py b/engine/SCons/Tool/msvc.py
new file mode 100644
index 0000000..d93bfa7
--- /dev/null
+++ b/engine/SCons/Tool/msvc.py
@@ -0,0 +1,278 @@
+"""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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+import os.path
+import re
+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 'PCH' in env and env['PCH']:
+ if 'PCHSTOP' not in env:
+ 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)
+
+ # Add a dependency, but only if the target (e.g. 'Source1.obj')
+ # doesn't correspond to the pre-compiled header ('Source1.pch').
+ # If the basenames match, then this was most likely caused by
+ # someone adding the source file to both the env.PCH() and the
+ # env.Program() calls, and adding the explicit dependency would
+ # cause a cycle on the .pch file itself.
+ #
+ # See issue #2505 for a discussion of what to do if it turns
+ # out this assumption causes trouble in the wild:
+ # http://scons.tigris.org/issues/show_bug.cgi?id=2505
+ if 'PCH' in env:
+ pch = env['PCH']
+ if str(target[0]) != SCons.Util.splitext(str(pch))[0] + '.obj':
+ env.Depends(target, 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.
+ """
+
+ # Fixing MSVC_BATCH mode. Previous if did not work when MSVC_BATCH
+ # was set to False. This new version should work better.
+ # Note we need to do the env.subst so $MSVC_BATCH can be a reference to
+ # another construction variable, which is why we test for False and 0
+ # as strings.
+ if not 'MSVC_BATCH' in env or env.subst('$MSVC_BATCH') in ('0', 'False', '', None):
+ # 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).
+ """
+
+ # Fixing MSVC_BATCH mode. Previous if did not work when MSVC_BATCH
+ # was set to False. This new version should work better. Removed
+ # len(source)==1 as batch mode can compile only one file
+ # (and it also fixed problem with compiling only one changed file
+ # with batch mode enabled)
+ if not 'MSVC_BATCH' in env or env.subst('$MSVC_BATCH') in ('0', 'False', '', None):
+ 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'] = '${TEMPFILE("$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'] = '${TEMPFILE("$SHCC $_MSVC_OUTPUT_FLAG /c $CHANGED_SOURCES $SHCFLAGS $SHCCFLAGS $_CCCOMCOM")}'
+ env['CXX'] = '$CC'
+ env['CXXFLAGS'] = SCons.Util.CLVar('$( /TP $)')
+ env['CXXCOM'] = '${TEMPFILE("$CXX $_MSVC_OUTPUT_FLAG /c $CHANGED_SOURCES $CXXFLAGS $CCFLAGS $_CCCOMCOM")}'
+ env['SHCXX'] = '$CXX'
+ env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS')
+ env['SHCXXCOM'] = '${TEMPFILE("$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 'ENV' not in env:
+ env['ENV'] = {}
+ if 'SystemRoot' not in env['ENV']: # 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/engine/SCons/Tool/msvs.py b/engine/SCons/Tool/msvs.py
new file mode 100644
index 0000000..ce4d834
--- /dev/null
+++ b/engine/SCons/Tool/msvs.py
@@ -0,0 +1,1803 @@
+"""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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+import SCons.compat
+
+import base64
+import hashlib
+import ntpath
+import os
+# compat layer imports "cPickle" for us if it's available.
+import pickle
+import re
+import sys
+
+import SCons.Builder
+import SCons.Node.FS
+import SCons.Platform.win32
+import SCons.Script.SConscript
+import SCons.PathList
+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 xmlify(s):
+ s = s.replace("&", "&amp;") # do this first
+ s = s.replace("'", "&apos;")
+ s = s.replace('"', "&quot;")
+ return s
+
+# Process a CPPPATH list in includes, given the env, target and source.
+# Returns a tuple of nodes.
+def processIncludes(includes, env, target, source):
+ return SCons.PathList.PathList(includes).subst_path(env, target, source)
+
+
+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))
+ solution = m.hexdigest().upper()
+ # 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
+
+# os.path.relpath has been introduced in Python 2.6
+# We define it locally for earlier versions of Python
+def relpath(path, start=os.path.curdir):
+ """Return a relative version of a path"""
+ import sys
+ if not path:
+ raise ValueError("no path specified")
+ start_list = os.path.abspath(start).split(os.sep)
+ path_list = os.path.abspath(path).split(os.sep)
+ if 'posix' in sys.builtin_module_names:
+ # Work out how much of the filepath is shared by start and path.
+ i = len(os.path.commonprefix([start_list, path_list]))
+ else:
+ if start_list[0].lower() != path_list[0].lower():
+ unc_path, rest = os.path.splitunc(path)
+ unc_start, rest = os.path.splitunc(start)
+ if bool(unc_path) ^ bool(unc_start):
+ raise ValueError("Cannot mix UNC and non-UNC paths (%s and %s)"
+ % (path, start))
+ else:
+ raise ValueError("path is on drive %s, start on drive %s"
+ % (path_list[0], start_list[0]))
+ # Work out how much of the filepath is shared by start and path.
+ for i in range(min(len(start_list), len(path_list))):
+ if start_list[i].lower() != path_list[i].lower():
+ break
+ else:
+ i += 1
+ rel_list = [os.pardir] * (len(start_list)-i) + path_list[i:]
+ if not rel_list:
+ return os.path.curdir
+ return os.path.join(*rel_list)
+
+if not "relpath" in os.path.__all__:
+ os.path.relpath = relpath
+
+# 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 'SCONS_LIB_DIR' in os.environ:
+ 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(object):
+ 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 part not in dict:
+ dict[part] = {}
+ dict = dict[part]
+ dict[path[-1]] = file
+ #else:
+ # print 'Warning: failed to decompose path for '+str(file)
+ return hierarchy
+
+class _DSPGenerator(object):
+ """ 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 'variant' not in env:
+ 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 'buildtarget' not in env 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 'outdir' not in env 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 'runfile' not in env 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 'name' in self.env:
+ 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 'nokeep' in env 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 t[1] in self.env:
+ 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 2.4: compat layer supports sorted(key=) but not sort(key=)
+ #TODO 2.4: self.sources[n].sort(key=lambda a: a.lower())
+ self.sources[n] = sorted(self.sources[n], key=lambda a: a.lower())
+
+ 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 = sorted(self.configs.keys())
+
+ 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 = sorted(self.configs.keys())
+ 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 = 'MSVSBUILDTARGET' in self.env
+ 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))
+ if kind.lower().find('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': ''}
+
+ for kind in sorted(categories.keys(), key=lambda a: a.lower()):
+ if not self.sources[kind]:
+ continue # skip empty groups
+
+ self.file.write('# Begin Group "' + kind + '"\n\n')
+ typelist = categories[kind].replace('|', ';')
+ 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:
+ if line.find("# 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"
+\tProjectGUID="%(project_guid)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\tReBuildCommandLine="%(rebuildcmd)s"
+\t\t\t\tCleanCommandLine="%(cleancmd)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"
+\tProjectGUID="%(project_guid)s"
+\tRootNamespace="%(name)s"
+%(scc_attrs)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 >= 9.0:
+ self.versionstr = '9.00'
+ self.dspheader = V8DSPHeader
+ self.dspconfiguration = V8DSPConfiguration
+ elif 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', '')
+ # MSVS_SCC_LOCAL_PATH is kept for backwards compatibility purpose and should
+ # be deprecated as soon as possible.
+ scc_local_path_legacy = env.get('MSVS_SCC_LOCAL_PATH', '')
+ scc_connection_root = env.get('MSVS_SCC_CONNECTION_ROOT', os.curdir)
+ scc_local_path = os.path.relpath(scc_connection_root, os.path.dirname(self.dspabs))
+ project_guid = env.get('MSVS_PROJECT_GUID', '')
+ if not project_guid:
+ project_guid = _generateGUID(self.dspfile, '')
+ if scc_provider != '':
+ scc_attrs = '\tSccProjectName="%s"\n' % scc_project_name
+ if scc_aux_path != '':
+ scc_attrs += '\tSccAuxPath="%s"\n' % scc_aux_path
+ scc_attrs += ('\tSccLocalPath="%s"\n'
+ '\tSccProvider="%s"' % (scc_local_path, scc_provider))
+ elif scc_local_path_legacy != '':
+ # This case is kept for backwards compatibility purpose and should
+ # be deprecated as soon as possible.
+ scc_attrs = ('\tSccProjectName="%s"\n'
+ '\tSccLocalPath="%s"' % (scc_project_name, scc_local_path_legacy))
+ else:
+ self.dspheader = self.dspheader.replace('%(scc_attrs)s\n', '')
+
+ 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 = sorted(self.configs.keys())
+ 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 = 'MSVSBUILDTARGET' in self.env
+ 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)
+
+ # This isn't perfect; CPPDEFINES and CPPPATH can contain $TARGET and $SOURCE,
+ # so they could vary depending on the command being generated. This code
+ # assumes they don't.
+ preprocdefs = xmlify(';'.join(processDefines(self.env.get('CPPDEFINES', []))))
+ includepath_Dirs = processIncludes(self.env.get('CPPPATH', []), self.env, None, None)
+ includepath = xmlify(';'.join([str(x) for x in includepath_Dirs]))
+
+ 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 = sorted(hierarchy.items(), key=lambda a: a[0].lower())
+
+ # 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 = sorted([k for k in categories.keys() if self.sources[k]],
+ key=lambda a: a.lower())
+ 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
+ s = list(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 = [s[len(cp)+1:] for s in sources]
+ commonprefix = cp
+
+ 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:
+ if line.find('<!-- 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()
+
+V10DSPHeader = """\
+<?xml version="1.0" encoding="%(encoding)s"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+"""
+
+V10DSPProjectConfiguration = """\
+\t\t<ProjectConfiguration Include="%(variant)s|%(platform)s">
+\t\t\t<Configuration>%(variant)s</Configuration>
+\t\t\t<Platform>%(platform)s</Platform>
+\t\t</ProjectConfiguration>
+"""
+
+V10DSPGlobals = """\
+\t<PropertyGroup Label="Globals">
+\t\t<ProjectGuid>%(project_guid)s</ProjectGuid>
+%(scc_attrs)s\t\t<RootNamespace>%(name)s</RootNamespace>
+\t\t<Keyword>MakeFileProj</Keyword>
+\t</PropertyGroup>
+"""
+
+V10DSPPropertyGroupCondition = """\
+\t<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='%(variant)s|%(platform)s'" Label="Configuration">
+\t\t<ConfigurationType>Makefile</ConfigurationType>
+\t\t<UseOfMfc>false</UseOfMfc>
+\t</PropertyGroup>
+"""
+
+V10DSPImportGroupCondition = """\
+\t<ImportGroup Condition="'$(Configuration)|$(Platform)'=='%(variant)s|%(platform)s'" Label="PropertySheets">
+\t\t<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+\t</ImportGroup>
+"""
+
+V10DSPCommandLine = """\
+\t\t<NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='%(variant)s|%(platform)s'">%(buildcmd)s</NMakeBuildCommandLine>
+\t\t<NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='%(variant)s|%(platform)s'">%(rebuildcmd)s</NMakeReBuildCommandLine>
+\t\t<NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='%(variant)s|%(platform)s'">%(cleancmd)s</NMakeCleanCommandLine>
+\t\t<NMakeOutput Condition="'$(Configuration)|$(Platform)'=='%(variant)s|%(platform)s'">%(runfile)s</NMakeOutput>
+\t\t<NMakePreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='%(variant)s|%(platform)s'">%(preprocdefs)s</NMakePreprocessorDefinitions>
+\t\t<NMakeIncludeSearchPath Condition="'$(Configuration)|$(Platform)'=='%(variant)s|%(platform)s'">%(includepath)s</NMakeIncludeSearchPath>
+\t\t<NMakeForcedIncludes Condition="'$(Configuration)|$(Platform)'=='%(variant)s|%(platform)s'">$(NMakeForcedIncludes)</NMakeForcedIncludes>
+\t\t<NMakeAssemblySearchPath Condition="'$(Configuration)|$(Platform)'=='%(variant)s|%(platform)s'">$(NMakeAssemblySearchPath)</NMakeAssemblySearchPath>
+\t\t<NMakeForcedUsingAssemblies Condition="'$(Configuration)|$(Platform)'=='%(variant)s|%(platform)s'">$(NMakeForcedUsingAssemblies)</NMakeForcedUsingAssemblies>
+"""
+
+class _GenerateV10DSP(_DSPGenerator):
+ """Generates a Project file for MSVS 2010"""
+
+ def __init__(self, dspfile, source, env):
+ _DSPGenerator.__init__(self, dspfile, source, env)
+
+ self.dspheader = V10DSPHeader
+ self.dspconfiguration = V10DSPProjectConfiguration
+ self.dspglobals = V10DSPGlobals
+
+ def PrintHeader(self):
+ env = self.env
+ name = self.name
+ encoding = env.subst('$MSVSENCODING')
+ project_guid = env.get('MSVS_PROJECT_GUID', '')
+ 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', '')
+ # MSVS_SCC_LOCAL_PATH is kept for backwards compatibility purpose and should
+ # be deprecated as soon as possible.
+ scc_local_path_legacy = env.get('MSVS_SCC_LOCAL_PATH', '')
+ scc_connection_root = env.get('MSVS_SCC_CONNECTION_ROOT', os.curdir)
+ scc_local_path = os.path.relpath(scc_connection_root, os.path.dirname(self.dspabs))
+ if not project_guid:
+ project_guid = _generateGUID(self.dspfile, '')
+ if scc_provider != '':
+ scc_attrs = '\t\t<SccProjectName>%s</SccProjectName>\n' % scc_project_name
+ if scc_aux_path != '':
+ scc_attrs += '\t\t<SccAuxPath>%s</SccAuxPath>\n' % scc_aux_path
+ scc_attrs += ('\t\t<SccLocalPath>%s</SccLocalPath>\n'
+ '\t\t<SccProvider>%s</SccProvider>\n' % (scc_local_path, scc_provider))
+ elif scc_local_path_legacy != '':
+ # This case is kept for backwards compatibility purpose and should
+ # be deprecated as soon as possible.
+ scc_attrs = ('\t\t<SccProjectName>%s</SccProjectName>\n'
+ '\t\t<SccLocalPath>%s</SccLocalPath>\n' % (scc_project_name, scc_local_path_legacy))
+ else:
+ self.dspglobals = self.dspglobals.replace('%(scc_attrs)s', '')
+
+ self.file.write(self.dspheader % locals())
+
+ self.file.write('\t<ItemGroup Label="ProjectConfigurations">\n')
+
+ confkeys = sorted(self.configs.keys())
+ for kind in confkeys:
+ variant = self.configs[kind].variant
+ platform = self.configs[kind].platform
+ self.file.write(self.dspconfiguration % locals())
+
+ self.file.write('\t</ItemGroup>\n')
+
+ self.file.write(self.dspglobals % locals())
+
+ def PrintProject(self):
+ name = self.name
+ confkeys = sorted(self.configs.keys())
+
+ self.file.write('\t<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />\n')
+
+ for kind in confkeys:
+ variant = self.configs[kind].variant
+ platform = self.configs[kind].platform
+ self.file.write(V10DSPPropertyGroupCondition % locals())
+
+ self.file.write('\t<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />\n')
+ self.file.write('\t<ImportGroup Label="ExtensionSettings">\n')
+ self.file.write('\t</ImportGroup>\n')
+
+ for kind in confkeys:
+ variant = self.configs[kind].variant
+ platform = self.configs[kind].platform
+ self.file.write(V10DSPImportGroupCondition % locals())
+
+ self.file.write('\t<PropertyGroup Label="UserMacros" />\n')
+ self.file.write('\t<PropertyGroup>\n')
+ self.file.write('\t<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>\n')
+
+ 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 = 'MSVSBUILDTARGET' in self.env
+ 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)
+
+ # This isn't perfect; CPPDEFINES and CPPPATH can contain $TARGET and $SOURCE,
+ # so they could vary depending on the command being generated. This code
+ # assumes they don't.
+ preprocdefs = xmlify(';'.join(processDefines(self.env.get('CPPDEFINES', []))))
+ includepath_Dirs = processIncludes(self.env.get('CPPPATH', []), self.env, None, None)
+ includepath = xmlify(';'.join([str(x) for x in includepath_Dirs]))
+
+ if not env_has_buildtarget:
+ del self.env['MSVSBUILDTARGET']
+
+ self.file.write(V10DSPCommandLine % locals())
+
+ self.file.write('\t</PropertyGroup>\n')
+
+ #filter settings in MSVS 2010 are stored in separate file
+ self.filtersabs = self.dspabs + '.filters'
+ try:
+ self.filters_file = open(self.filtersabs, 'w')
+ except IOError, detail:
+ raise SCons.Errors.InternalError('Unable to open "' + self.filtersabs + '" for writing:' + str(detail))
+
+ self.filters_file.write('<?xml version="1.0" encoding="utf-8"?>\n'
+ '<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\n')
+
+ self.PrintSourceFiles()
+
+ self.filters_file.write('</Project>')
+ self.filters_file.close()
+
+ self.file.write('\t<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\n'
+ '\t<ImportGroup Label="ExtensionTargets">\n'
+ '\t</ImportGroup>\n'
+ '</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('<!-- SCons Data:\n' + pdata + '\n')
+ pdata = pickle.dumps(self.sources,1)
+ pdata = base64.encodestring(pdata)
+ self.file.write(pdata + '-->\n')
+
+ def printFilters(self, hierarchy, name):
+ sorteditems = sorted(hierarchy.items(), key = lambda a: a[0].lower())
+
+ for key, value in sorteditems:
+ if SCons.Util.is_Dict(value):
+ filter_name = name + '\\' + key
+ self.filters_file.write('\t\t<Filter Include="%s">\n'
+ '\t\t\t<UniqueIdentifier>%s</UniqueIdentifier>\n'
+ '\t\t</Filter>\n' % (filter_name, _generateGUID(self.dspabs, filter_name)))
+ self.printFilters(value, filter_name)
+
+ def printSources(self, hierarchy, kind, commonprefix, filter_name):
+ keywords = {'Source Files': 'ClCompile',
+ 'Header Files': 'ClInclude',
+ 'Local Headers': 'ClInclude',
+ 'Resource Files': 'None',
+ 'Other Files': 'None'}
+
+ sorteditems = sorted(hierarchy.items(), key = lambda a: a[0].lower())
+
+ # First folders, then files
+ for key, value in sorteditems:
+ if SCons.Util.is_Dict(value):
+ self.printSources(value, kind, commonprefix, filter_name + '\\' + key)
+
+ 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<%s Include="%s" />\n' % (keywords[kind], file))
+ self.filters_file.write('\t\t<%s Include="%s">\n'
+ '\t\t\t<Filter>%s</Filter>\n'
+ '\t\t</%s>\n' % (keywords[kind], file, filter_name, keywords[kind]))
+
+ 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 = sorted([k for k in categories.keys() if self.sources[k]],
+ key = lambda a: a.lower())
+
+ # print vcxproj.filters file first
+ self.filters_file.write('\t<ItemGroup>\n')
+ for kind in cats:
+ self.filters_file.write('\t\t<Filter Include="%s">\n'
+ '\t\t\t<UniqueIdentifier>{7b42d31d-d53c-4868-8b92-ca2bc9fc052f}</UniqueIdentifier>\n'
+ '\t\t\t<Extensions>%s</Extensions>\n'
+ '\t\t</Filter>\n' % (kind, categories[kind]))
+
+ # First remove any common prefix
+ sources = self.sources[kind]
+ commonprefix = None
+ s = list(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 = [s[len(cp)+1:] for s in sources]
+ commonprefix = cp
+
+ hierarchy = makeHierarchy(sources)
+ self.printFilters(hierarchy, kind)
+
+ self.filters_file.write('\t</ItemGroup>\n')
+
+ # then print files and filters
+ for kind in cats:
+ self.file.write('\t<ItemGroup>\n')
+ self.filters_file.write('\t<ItemGroup>\n')
+
+ # First remove any common prefix
+ sources = self.sources[kind]
+ commonprefix = None
+ s = list(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 = [s[len(cp)+1:] for s in sources]
+ commonprefix = cp
+
+ hierarchy = makeHierarchy(sources)
+ self.printSources(hierarchy, kind, commonprefix, kind)
+
+ self.file.write('\t</ItemGroup>\n')
+ self.filters_file.write('\t</ItemGroup>\n')
+
+ # add the SConscript file outside of the groups
+ self.file.write('\t<ItemGroup>\n'
+ '\t\t<None Include="%s" />\n'
+ #'\t\t<None Include="SConstruct" />\n'
+ '\t</ItemGroup>\n' % str(self.sconscript))
+
+ def Parse(self):
+ print "_GenerateV10DSP.Parse()"
+
+ 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(object):
+ """ Base class for DSW generators """
+ def __init__(self, dswfile, source, env):
+ self.dswfile = os.path.normpath(str(dswfile))
+ self.dsw_folder_path = os.path.dirname(os.path.abspath(self.dswfile))
+ self.env = env
+
+ if 'projects' not in env:
+ 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 = list(map(str, projects))
+
+ if 'name' in self.env:
+ 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 >= 11.0:
+ self.versionstr = '12.00'
+ elif self.version_num >= 10.0:
+ self.versionstr = '11.00'
+ elif self.version_num >= 9.0:
+ self.versionstr = '10.00'
+ elif self.version_num >= 8.0:
+ self.versionstr = '9.00'
+ elif self.version_num >= 7.1:
+ self.versionstr = '8.00'
+
+ if 'slnguid' in env and env['slnguid']:
+ self.slnguid = env['slnguid']
+ else:
+ self.slnguid = _generateGUID(dswfile, self.name)
+
+ self.configs = {}
+
+ self.nokeep = 0
+ if 'nokeep' in env 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 'variant' not in env:
+ 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 GenerateProjectFilesInfo(self):
+ for dspfile in self.dspfiles:
+ dsp_folder_path, name = os.path.split(dspfile)
+ dsp_folder_path = os.path.abspath(dsp_folder_path)
+ dsp_relative_folder_path = os.path.relpath(dsp_folder_path, self.dsw_folder_path)
+ if dsp_relative_folder_path == os.curdir:
+ dsp_relative_file_path = name
+ else:
+ dsp_relative_file_path = os.path.join(dsp_relative_folder_path, name)
+ dspfile_info = {'NAME': name,
+ 'GUID': _generateGUID(dspfile, ''),
+ 'FOLDER_PATH': dsp_folder_path,
+ 'FILE_PATH': dspfile,
+ 'SLN_RELATIVE_FOLDER_PATH': dsp_relative_folder_path,
+ 'SLN_RELATIVE_FILE_PATH': dsp_relative_file_path}
+ self.dspfiles_info.append(dspfile_info)
+
+ self.dspfiles_info = []
+ GenerateProjectFilesInfo(self)
+
+ 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 >= 11.0:
+ self.file.write('# Visual Studio 11\n')
+ elif self.version_num >= 10.0:
+ self.file.write('# Visual Studio 2010\n')
+ elif self.version_num >= 9.0:
+ self.file.write('# Visual Studio 2008\n')
+ elif self.version_num >= 8.0:
+ self.file.write('# Visual Studio 2005\n')
+
+ for dspinfo in self.dspfiles_info:
+ name = dspinfo['NAME']
+ base, suffix = SCons.Util.splitext(name)
+ if suffix == '.vcproj':
+ name = base
+ self.file.write('Project("%s") = "%s", "%s", "%s"\n'
+ % (external_makefile_guid, name, dspinfo['SLN_RELATIVE_FILE_PATH'], dspinfo['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 'MSVS_SCC_PROVIDER' in env:
+ scc_number_of_projects = len(self.dspfiles) + 1
+ slnguid = self.slnguid
+ scc_provider = env.get('MSVS_SCC_PROVIDER', '').replace(' ', r'\u0020')
+ scc_project_name = env.get('MSVS_SCC_PROJECT_NAME', '').replace(' ', r'\u0020')
+ scc_connection_root = env.get('MSVS_SCC_CONNECTION_ROOT', os.curdir)
+ scc_local_path = os.path.relpath(scc_connection_root, self.dsw_folder_path).replace('\\', '\\\\')
+ self.file.write('\tGlobalSection(SourceCodeControl) = preSolution\n'
+ '\t\tSccNumberOfProjects = %(scc_number_of_projects)d\n'
+ '\t\tSccProjectName0 = %(scc_project_name)s\n'
+ '\t\tSccLocalPath0 = %(scc_local_path)s\n'
+ '\t\tSccProvider0 = %(scc_provider)s\n'
+ '\t\tCanCheckoutShared = true\n' % locals())
+ sln_relative_path_from_scc = os.path.relpath(self.dsw_folder_path, scc_connection_root)
+ if sln_relative_path_from_scc != os.curdir:
+ self.file.write('\t\tSccProjectFilePathRelativizedFromConnection0 = %s\\\\\n'
+ % sln_relative_path_from_scc.replace('\\', '\\\\'))
+ if self.version_num < 8.0:
+ # When present, SolutionUniqueID is automatically removed by VS 2005
+ # TODO: check for Visual Studio versions newer than 2005
+ self.file.write('\t\tSolutionUniqueID = %s\n' % slnguid)
+ for dspinfo in self.dspfiles_info:
+ i = self.dspfiles_info.index(dspinfo) + 1
+ dsp_relative_file_path = dspinfo['SLN_RELATIVE_FILE_PATH'].replace('\\', '\\\\')
+ dsp_scc_relative_folder_path = os.path.relpath(dspinfo['FOLDER_PATH'], scc_connection_root).replace('\\', '\\\\')
+ self.file.write('\t\tSccProjectUniqueName%(i)s = %(dsp_relative_file_path)s\n'
+ '\t\tSccLocalPath%(i)d = %(scc_local_path)s\n'
+ '\t\tCanCheckoutShared = true\n'
+ '\t\tSccProjectFilePathRelativizedFromConnection%(i)s = %(dsp_scc_relative_folder_path)s\\\\\n'
+ % locals())
+ self.file.write('\tEndGlobalSection\n')
+ if self.version_num >= 8.0:
+ self.file.write('\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n')
+ else:
+ self.file.write('\tGlobalSection(SolutionConfiguration) = preSolution\n')
+
+ confkeys = sorted(self.configs.keys())
+ 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 dspinfo in self.dspfiles_info:
+ guid = dspinfo['GUID']
+ 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 dspinfo in self.dspfiles_info:
+ guid = dspinfo['GUID']
+ 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 = os.path.relpath(self.dspfiles[0], self.dsw_folder_path)
+ 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 'MSVS_VERSION' in env:
+ version_num, suite = msvs_parse_version(env['MSVS_VERSION'])
+ if version_num >= 10.0:
+ g = _GenerateV10DSP(dspfile, source, env)
+ g.Build()
+ elif 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 'MSVS_VERSION' in env:
+ 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)
+
+ # Project file depends on CPPDEFINES and CPPPATH
+ preprocdefs = xmlify(';'.join(processDefines(env.get('CPPDEFINES', []))))
+ includepath_Dirs = processIncludes(env.get('CPPPATH', []), env, None, None)
+ includepath = xmlify(';'.join([str(x) for x in includepath_Dirs]))
+ source = source + "; ppdefs:%s incpath:%s"%(preprocdefs, includepath)
+
+ if 'buildtarget' in env 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 'outdir' in env 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 'name' in env:
+ if SCons.Util.is_String(env['name']):
+ source = source + ' "%s"' % env['name']
+ else:
+ raise SCons.Errors.InternalError("name must be a string")
+
+ if 'variant' in env:
+ 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 s in env:
+ 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'] = [env.File(t).srcnode() for t in targetlist]
+ t, s = solutionEmitter(target, target, env)
+ targetlist = targetlist + t
+
+ # Beginning with Visual Studio 2010 for each project file (.vcxproj) we have additional file (.vcxproj.filters)
+ if float(env['MSVS_VERSION']) >= 10.0:
+ targetlist.append(targetlist[0] + '.filters')
+
+ 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 'name' in env:
+ if SCons.Util.is_String(env['name']):
+ source = source + ' "%s"' % env['name']
+ else:
+ raise SCons.Errors.InternalError("name must be a string")
+
+ if 'variant' in env:
+ 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 'slnguid' in env:
+ if SCons.Util.is_String(env['slnguid']):
+ source = source + ' "%s"' % env['slnguid']
+ else:
+ raise SCons.Errors.InternalError("slnguid must be a string")
+
+ if 'projects' in env:
+ 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"'
+
+ # Set-up ms tools paths for default version
+ msvc_setup_env_once(env)
+
+ if 'MSVS_VERSION' in env:
+ version_num, suite = msvs_parse_version(env['MSVS_VERSION'])
+ else:
+ (version_num, suite) = (7.0, None) # guess at a default
+ if 'MSVS' not in env:
+ env['MSVS'] = {}
+ if (version_num < 7.0):
+ env['MSVS']['PROJECTSUFFIX'] = '.dsp'
+ env['MSVS']['SOLUTIONSUFFIX'] = '.dsw'
+ elif (version_num < 10.0):
+ env['MSVS']['PROJECTSUFFIX'] = '.vcproj'
+ env['MSVS']['SOLUTIONSUFFIX'] = '.sln'
+ else:
+ env['MSVS']['PROJECTSUFFIX'] = '.vcxproj'
+ env['MSVS']['SOLUTIONSUFFIX'] = '.sln'
+
+ if (version_num >= 10.0):
+ env['MSVSENCODING'] = 'utf-8'
+ else:
+ env['MSVSENCODING'] = 'Windows-1252'
+
+ 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/engine/SCons/Tool/mwcc.py b/engine/SCons/Tool/mwcc.py
new file mode 100644
index 0000000..ae0d030
--- /dev/null
+++ b/engine/SCons/Tool/mwcc.py
@@ -0,0 +1,207 @@
+"""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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+import os
+import os.path
+
+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'] = os.pathsep.join(map(plus, version.includes))
+ ENV['MWLibraries'] = os.pathsep.join(map(plus, version.libs))
+ 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 True:
+ 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(object):
+ 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/engine/SCons/Tool/mwld.py b/engine/SCons/Tool/mwld.py
new file mode 100644
index 0000000..5309ea2
--- /dev/null
+++ b/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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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/engine/SCons/Tool/nasm.py b/engine/SCons/Tool/nasm.py
new file mode 100644
index 0000000..0636247
--- /dev/null
+++ b/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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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/engine/SCons/Tool/packaging/__init__.py b/engine/SCons/Tool/packaging/__init__.py
new file mode 100644
index 0000000..4249925
--- /dev/null
+++ b/engine/SCons/Tool/packaging/__init__.py
@@ -0,0 +1,312 @@
+"""SCons.Tool.Packaging
+
+SCons Packaging Tool.
+"""
+
+#
+# Copyright (c) 2001 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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 'Tar' in env['BUILDERS']:
+ kw['PACKAGETYPE']='targz'
+ elif 'Zip' in env['BUILDERS']:
+ kw['PACKAGETYPE']='zip'
+ else:
+ raise UserError("No type for Package() given")
+
+ PACKAGETYPE=kw['PACKAGETYPE']
+ if not is_List(PACKAGETYPE):
+ PACKAGETYPE=PACKAGETYPE.split(',')
+
+ # 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=list(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 'PACKAGEROOT' not in kw:
+ 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=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 x not in kw]
+
+ 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=list(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: not hasattr(f2, x) and x[:10] == 'PACKAGING_'
+ pattrs = list(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(list(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/engine/SCons/Tool/packaging/ipk.py b/engine/SCons/Tool/packaging/ipk.py
new file mode 100644
index 0000000..f8cb3f7
--- /dev/null
+++ b/engine/SCons/Tool/packaging/ipk.py
@@ -0,0 +1,185 @@
+"""SCons.Tool.Packaging.ipk
+"""
+
+#
+# Copyright (c) 2001 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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 'ARCHITECTURE' in kw:
+ 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 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
+ 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 'X_IPK_DESCRIPTION' not in env:
+ 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 'CHANGE_SPECFILE' in env:
+ 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/engine/SCons/Tool/packaging/msi.py b/engine/SCons/Tool/packaging/msi.py
new file mode 100644
index 0000000..9611af4
--- /dev/null
+++ b/engine/SCons/Tool/packaging/msi.py
@@ -0,0 +1,527 @@
+"""SCons.Tool.packaging.msi
+
+The msi packager.
+"""
+
+#
+# Copyright (c) 2001 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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 = [c for c in s if c in charset]
+
+ # 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 id not in id_set: 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 = [c for c in fname if c not in forbidden]
+
+ # 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 f not in dict:
+ 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 'CHANGE_SPECFILE' in env:
+ 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 = [d for d in dir_parts if d != '']
+ for d in dir_parts[:]:
+ already_created = [c for c in Directory.childNodes
+ if c.nodeName == 'Directory'
+ and c.attributes['LongName'].value == escape(d)]
+
+ 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 'X_MSI_LANGUAGE' not in spec:
+ 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 'DESCRIPTION' in spec:
+ Package.attributes['Comments'] = escape( spec['DESCRIPTION'] )
+
+ if 'X_MSI_UPGRADE_CODE' in spec:
+ 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 = 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/engine/SCons/Tool/packaging/rpm.py b/engine/SCons/Tool/packaging/rpm.py
new file mode 100644
index 0000000..39f2b5e
--- /dev/null
+++ b/engine/SCons/Tool/packaging/rpm.py
@@ -0,0 +1,357 @@
+"""SCons.Tool.Packaging.rpm
+
+The rpm packager.
+"""
+
+#
+# Copyright (c) 2001 - 2014 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 2014/09/27 12:51:43 garyo"
+
+import os
+
+import SCons.Builder
+import SCons.Tool.rpmutils
+
+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=.
+ buildarchitecture = SCons.Tool.rpmutils.defaultMachine()
+
+ if 'ARCHITECTURE' in kw:
+ 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 'SOURCE_URL' not in kw:
+ #kw['SOURCE_URL']=(str(target[0])+".tar.gz").replace('.rpm', '')
+ kw['SOURCE_URL']=(str(target[0])+".tar.gz").replace('.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 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 = [s for s in sources if s not in target]
+
+ # 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: str(s).rfind('.spec') != -1
+ sources.extend( list(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 = (str(target[0])+".tar.gz").replace('.rpm', '')
+ try:
+ #tarball = env['SOURCE_URL'].split('/')[-1]
+ tarball = env['SOURCE_URL'].split('/')[-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 'CHANGE_SPECFILE' in env:
+ 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 'X_RPM_PREP' not in spec:
+ spec['X_RPM_PREP'] = '[ -n "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ] && rm -rf "$RPM_BUILD_ROOT"' + '\n%setup -q'
+
+ if 'X_RPM_BUILD' not in spec:
+ spec['X_RPM_BUILD'] = '[ ! -e "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ] && mkdir "$RPM_BUILD_ROOT"'
+
+ if 'X_RPM_INSTALL' not in spec:
+ spec['X_RPM_INSTALL'] = 'scons --install-sandbox="$RPM_BUILD_ROOT" "$RPM_BUILD_ROOT"'
+
+ if 'X_RPM_CLEAN' not in spec:
+ 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 'X_RPM_BUILDROOT' not in spec:
+ 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 'X_RPM_DEFATTR' not in spec:
+ 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(object):
+ """ 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 = list(self.tagset.items())
+
+ str = ""
+ #domestic = [ (k,v) for k,v in replacements if not is_international(k) ]
+ domestic = [t for t in replacements if not is_international(t[0])]
+ 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 = [t for t in replacements if is_international(t[0])]
+ 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 = [t for t in values.items() if strip_country_code(t[0]) == key]
+ int_values_for_key = [(get_country_code(t[0]),t[1]) for t in 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/engine/SCons/Tool/packaging/src_tarbz2.py b/engine/SCons/Tool/packaging/src_tarbz2.py
new file mode 100644
index 0000000..bb243cf
--- /dev/null
+++ b/engine/SCons/Tool/packaging/src_tarbz2.py
@@ -0,0 +1,43 @@
+"""SCons.Tool.Packaging.tarbz2
+
+The tarbz2 SRC packager.
+"""
+
+#
+# Copyright (c) 2001 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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/engine/SCons/Tool/packaging/src_targz.py b/engine/SCons/Tool/packaging/src_targz.py
new file mode 100644
index 0000000..1b80433
--- /dev/null
+++ b/engine/SCons/Tool/packaging/src_targz.py
@@ -0,0 +1,43 @@
+"""SCons.Tool.Packaging.targz
+
+The targz SRC packager.
+"""
+
+#
+# Copyright (c) 2001 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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/engine/SCons/Tool/packaging/src_zip.py b/engine/SCons/Tool/packaging/src_zip.py
new file mode 100644
index 0000000..d6d3a5d
--- /dev/null
+++ b/engine/SCons/Tool/packaging/src_zip.py
@@ -0,0 +1,43 @@
+"""SCons.Tool.Packaging.zip
+
+The zip SRC packager.
+"""
+
+#
+# Copyright (c) 2001 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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/engine/SCons/Tool/packaging/tarbz2.py b/engine/SCons/Tool/packaging/tarbz2.py
new file mode 100644
index 0000000..f1ff223
--- /dev/null
+++ b/engine/SCons/Tool/packaging/tarbz2.py
@@ -0,0 +1,44 @@
+"""SCons.Tool.Packaging.tarbz2
+
+The tarbz2 SRC packager.
+"""
+
+#
+# Copyright (c) 2001 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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/engine/SCons/Tool/packaging/targz.py b/engine/SCons/Tool/packaging/targz.py
new file mode 100644
index 0000000..8b31768
--- /dev/null
+++ b/engine/SCons/Tool/packaging/targz.py
@@ -0,0 +1,44 @@
+"""SCons.Tool.Packaging.targz
+
+The targz SRC packager.
+"""
+
+#
+# Copyright (c) 2001 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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/engine/SCons/Tool/packaging/zip.py b/engine/SCons/Tool/packaging/zip.py
new file mode 100644
index 0000000..09a320d
--- /dev/null
+++ b/engine/SCons/Tool/packaging/zip.py
@@ -0,0 +1,44 @@
+"""SCons.Tool.Packaging.zip
+
+The zip SRC packager.
+"""
+
+#
+# Copyright (c) 2001 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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/engine/SCons/Tool/pdf.py b/engine/SCons/Tool/pdf.py
new file mode 100644
index 0000000..f38cdbf
--- /dev/null
+++ b/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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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/engine/SCons/Tool/pdflatex.py b/engine/SCons/Tool/pdflatex.py
new file mode 100644
index 0000000..1caac91
--- /dev/null
+++ b/engine/SCons/Tool/pdflatex.py
@@ -0,0 +1,84 @@
+"""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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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:
+ SCons.Tool.tex.check_file_error_message(env['PDFLATEX'])
+ 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):
+ SCons.Tool.tex.generate_darwin(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/engine/SCons/Tool/pdftex.py b/engine/SCons/Tool/pdftex.py
new file mode 100644
index 0000000..92b54d0
--- /dev/null
+++ b/engine/SCons/Tool/pdftex.py
@@ -0,0 +1,109 @@
+"""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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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:
+ SCons.Tool.tex.check_file_error_message(env['PDFLATEX'])
+ else:
+ result = PDFTeXAction(target,source,env)
+ if result != 0:
+ SCons.Tool.tex.check_file_error_message(env['PDFTEX'])
+ 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):
+ SCons.Tool.tex.generate_darwin(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/engine/SCons/Tool/qt.py b/engine/SCons/Tool/qt.py
new file mode 100644
index 0000000..004fce7
--- /dev/null
+++ b/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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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(object):
+ """
+ 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/engine/SCons/Tool/rmic.py b/engine/SCons/Tool/rmic.py
new file mode 100644
index 0000000..2e684d4
--- /dev/null
+++ b/engine/SCons/Tool/rmic.py
@@ -0,0 +1,126 @@
+"""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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+import os.path
+
+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 = s.attributes.java_classname.replace('.', 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):
+ # As reported by Jan Nijtmans in issue #2730, the simple
+ # return env.Detect('rmic')
+ # doesn't always work during initialization. For now, we
+ # stop trying to detect an executable (analogous to the
+ # javac Builder).
+ # TODO: Come up with a proper detect() routine...and enable it.
+ return 1
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/engine/SCons/Tool/rpcgen.py b/engine/SCons/Tool/rpcgen.py
new file mode 100644
index 0000000..24895e9
--- /dev/null
+++ b/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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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/engine/SCons/Tool/rpm.py b/engine/SCons/Tool/rpm.py
new file mode 100644
index 0000000..20156d4
--- /dev/null
+++ b/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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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/engine/SCons/Tool/rpmutils.py b/engine/SCons/Tool/rpmutils.py
new file mode 100644
index 0000000..91c95a1
--- /dev/null
+++ b/engine/SCons/Tool/rpmutils.py
@@ -0,0 +1,543 @@
+"""SCons.Tool.rpmutils.py
+
+RPM specific helper routines for general usage in the test framework
+and SCons core modules.
+
+Since we check for the RPM package target name in several places,
+we have to know which machine/system name RPM will use for the current
+hardware setup. The following dictionaries and functions try to
+mimic the exact naming rules of the RPM source code.
+They were directly derived from the file "rpmrc.in" of the version
+rpm-4.9.1.3. For updating to a more recent version of RPM, this Python
+script can be used standalone. The usage() function below shows the
+exact syntax.
+
+"""
+
+# Copyright (c) 2001 - 2014 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/rpmutils.py 2014/09/27 12:51:43 garyo"
+
+
+import platform
+import subprocess
+
+# Start of rpmrc dictionaries (Marker, don't change or remove!)
+os_canon = {
+ 'AIX' : ['AIX','5'],
+ 'AmigaOS' : ['AmigaOS','5'],
+ 'BSD_OS' : ['bsdi','12'],
+ 'CYGWIN32_95' : ['cygwin32','15'],
+ 'CYGWIN32_NT' : ['cygwin32','14'],
+ 'Darwin' : ['darwin','21'],
+ 'FreeBSD' : ['FreeBSD','8'],
+ 'HP-UX' : ['hpux10','6'],
+ 'IRIX' : ['Irix','2'],
+ 'IRIX64' : ['Irix64','10'],
+ 'Linux' : ['Linux','1'],
+ 'Linux/390' : ['OS/390','20'],
+ 'Linux/ESA' : ['VM/ESA','20'],
+ 'MacOSX' : ['macosx','21'],
+ 'MiNT' : ['FreeMiNT','17'],
+ 'NEXTSTEP' : ['NextStep','11'],
+ 'OS/390' : ['OS/390','18'],
+ 'OSF1' : ['osf1','7'],
+ 'SCO_SV' : ['SCO_SV3.2v5.0.2','9'],
+ 'SunOS4' : ['SunOS','4'],
+ 'SunOS5' : ['solaris','3'],
+ 'UNIX_SV' : ['MP_RAS','16'],
+ 'VM/ESA' : ['VM/ESA','19'],
+ 'machten' : ['machten','13'],
+ 'osf3.2' : ['osf1','7'],
+ 'osf4.0' : ['osf1','7'],
+}
+
+buildarch_compat = {
+ 'alpha' : ['noarch'],
+ 'alphaev5' : ['alpha'],
+ 'alphaev56' : ['alphaev5'],
+ 'alphaev6' : ['alphapca56'],
+ 'alphaev67' : ['alphaev6'],
+ 'alphapca56' : ['alphaev56'],
+ 'amd64' : ['x86_64'],
+ 'armv3l' : ['noarch'],
+ 'armv4b' : ['noarch'],
+ 'armv4l' : ['armv3l'],
+ 'armv4tl' : ['armv4l'],
+ 'armv5tejl' : ['armv5tel'],
+ 'armv5tel' : ['armv4tl'],
+ 'armv6l' : ['armv5tejl'],
+ 'armv7l' : ['armv6l'],
+ 'atariclone' : ['m68kmint','noarch'],
+ 'atarist' : ['m68kmint','noarch'],
+ 'atariste' : ['m68kmint','noarch'],
+ 'ataritt' : ['m68kmint','noarch'],
+ 'athlon' : ['i686'],
+ 'falcon' : ['m68kmint','noarch'],
+ 'geode' : ['i586'],
+ 'hades' : ['m68kmint','noarch'],
+ 'hppa1.0' : ['parisc'],
+ 'hppa1.1' : ['hppa1.0'],
+ 'hppa1.2' : ['hppa1.1'],
+ 'hppa2.0' : ['hppa1.2'],
+ 'i386' : ['noarch','fat'],
+ 'i486' : ['i386'],
+ 'i586' : ['i486'],
+ 'i686' : ['i586'],
+ 'ia32e' : ['x86_64'],
+ 'ia64' : ['noarch'],
+ 'm68k' : ['noarch'],
+ 'milan' : ['m68kmint','noarch'],
+ 'mips' : ['noarch'],
+ 'mipsel' : ['noarch'],
+ 'parisc' : ['noarch'],
+ 'pentium3' : ['i686'],
+ 'pentium4' : ['pentium3'],
+ 'ppc' : ['noarch','fat'],
+ 'ppc32dy4' : ['noarch'],
+ 'ppc64' : ['noarch','fat'],
+ 'ppc64iseries' : ['ppc64'],
+ 'ppc64pseries' : ['ppc64'],
+ 'ppc8260' : ['noarch'],
+ 'ppc8560' : ['noarch'],
+ 'ppciseries' : ['noarch'],
+ 'ppcpseries' : ['noarch'],
+ 's390' : ['noarch'],
+ 's390x' : ['noarch'],
+ 'sh3' : ['noarch'],
+ 'sh4' : ['noarch'],
+ 'sh4a' : ['sh4'],
+ 'sparc' : ['noarch'],
+ 'sparc64' : ['sparcv9v'],
+ 'sparc64v' : ['sparc64'],
+ 'sparcv8' : ['sparc'],
+ 'sparcv9' : ['sparcv8'],
+ 'sparcv9v' : ['sparcv9'],
+ 'sun4c' : ['noarch'],
+ 'sun4d' : ['noarch'],
+ 'sun4m' : ['noarch'],
+ 'sun4u' : ['noarch'],
+ 'x86_64' : ['noarch'],
+}
+
+os_compat = {
+ 'BSD_OS' : ['bsdi'],
+ 'Darwin' : ['MacOSX'],
+ 'FreeMiNT' : ['mint','MiNT','TOS'],
+ 'IRIX64' : ['IRIX'],
+ 'MiNT' : ['FreeMiNT','mint','TOS'],
+ 'TOS' : ['FreeMiNT','MiNT','mint'],
+ 'bsdi4.0' : ['bsdi'],
+ 'hpux10.00' : ['hpux9.07'],
+ 'hpux10.01' : ['hpux10.00'],
+ 'hpux10.10' : ['hpux10.01'],
+ 'hpux10.20' : ['hpux10.10'],
+ 'hpux10.30' : ['hpux10.20'],
+ 'hpux11.00' : ['hpux10.30'],
+ 'hpux9.05' : ['hpux9.04'],
+ 'hpux9.07' : ['hpux9.05'],
+ 'mint' : ['FreeMiNT','MiNT','TOS'],
+ 'ncr-sysv4.3' : ['ncr-sysv4.2'],
+ 'osf4.0' : ['osf3.2','osf1'],
+ 'solaris2.4' : ['solaris2.3'],
+ 'solaris2.5' : ['solaris2.3','solaris2.4'],
+ 'solaris2.6' : ['solaris2.3','solaris2.4','solaris2.5'],
+ 'solaris2.7' : ['solaris2.3','solaris2.4','solaris2.5','solaris2.6'],
+}
+
+arch_compat = {
+ 'alpha' : ['axp','noarch'],
+ 'alphaev5' : ['alpha'],
+ 'alphaev56' : ['alphaev5'],
+ 'alphaev6' : ['alphapca56'],
+ 'alphaev67' : ['alphaev6'],
+ 'alphapca56' : ['alphaev56'],
+ 'amd64' : ['x86_64','athlon','noarch'],
+ 'armv3l' : ['noarch'],
+ 'armv4b' : ['noarch'],
+ 'armv4l' : ['armv3l'],
+ 'armv4tl' : ['armv4l'],
+ 'armv5tejl' : ['armv5tel'],
+ 'armv5tel' : ['armv4tl'],
+ 'armv6l' : ['armv5tejl'],
+ 'armv7l' : ['armv6l'],
+ 'atariclone' : ['m68kmint','noarch'],
+ 'atarist' : ['m68kmint','noarch'],
+ 'atariste' : ['m68kmint','noarch'],
+ 'ataritt' : ['m68kmint','noarch'],
+ 'athlon' : ['i686'],
+ 'falcon' : ['m68kmint','noarch'],
+ 'geode' : ['i586'],
+ 'hades' : ['m68kmint','noarch'],
+ 'hppa1.0' : ['parisc'],
+ 'hppa1.1' : ['hppa1.0'],
+ 'hppa1.2' : ['hppa1.1'],
+ 'hppa2.0' : ['hppa1.2'],
+ 'i370' : ['noarch'],
+ 'i386' : ['noarch','fat'],
+ 'i486' : ['i386'],
+ 'i586' : ['i486'],
+ 'i686' : ['i586'],
+ 'ia32e' : ['x86_64','athlon','noarch'],
+ 'ia64' : ['noarch'],
+ 'milan' : ['m68kmint','noarch'],
+ 'mips' : ['noarch'],
+ 'mipsel' : ['noarch'],
+ 'osfmach3_i386' : ['i486'],
+ 'osfmach3_i486' : ['i486','osfmach3_i386'],
+ 'osfmach3_i586' : ['i586','osfmach3_i486'],
+ 'osfmach3_i686' : ['i686','osfmach3_i586'],
+ 'osfmach3_ppc' : ['ppc'],
+ 'parisc' : ['noarch'],
+ 'pentium3' : ['i686'],
+ 'pentium4' : ['pentium3'],
+ 'powerpc' : ['ppc'],
+ 'powerppc' : ['ppc'],
+ 'ppc' : ['rs6000'],
+ 'ppc32dy4' : ['ppc'],
+ 'ppc64' : ['ppc'],
+ 'ppc64iseries' : ['ppc64'],
+ 'ppc64pseries' : ['ppc64'],
+ 'ppc8260' : ['ppc'],
+ 'ppc8560' : ['ppc'],
+ 'ppciseries' : ['ppc'],
+ 'ppcpseries' : ['ppc'],
+ 'rs6000' : ['noarch','fat'],
+ 's390' : ['noarch'],
+ 's390x' : ['s390','noarch'],
+ 'sh3' : ['noarch'],
+ 'sh4' : ['noarch'],
+ 'sh4a' : ['sh4'],
+ 'sparc' : ['noarch'],
+ 'sparc64' : ['sparcv9'],
+ 'sparc64v' : ['sparc64'],
+ 'sparcv8' : ['sparc'],
+ 'sparcv9' : ['sparcv8'],
+ 'sparcv9v' : ['sparcv9'],
+ 'sun4c' : ['sparc'],
+ 'sun4d' : ['sparc'],
+ 'sun4m' : ['sparc'],
+ 'sun4u' : ['sparc64'],
+ 'x86_64' : ['amd64','athlon','noarch'],
+}
+
+buildarchtranslate = {
+ 'alphaev5' : ['alpha'],
+ 'alphaev56' : ['alpha'],
+ 'alphaev6' : ['alpha'],
+ 'alphaev67' : ['alpha'],
+ 'alphapca56' : ['alpha'],
+ 'amd64' : ['x86_64'],
+ 'armv3l' : ['armv3l'],
+ 'armv4b' : ['armv4b'],
+ 'armv4l' : ['armv4l'],
+ 'armv4tl' : ['armv4tl'],
+ 'armv5tejl' : ['armv5tejl'],
+ 'armv5tel' : ['armv5tel'],
+ 'armv6l' : ['armv6l'],
+ 'armv7l' : ['armv7l'],
+ 'atariclone' : ['m68kmint'],
+ 'atarist' : ['m68kmint'],
+ 'atariste' : ['m68kmint'],
+ 'ataritt' : ['m68kmint'],
+ 'athlon' : ['i386'],
+ 'falcon' : ['m68kmint'],
+ 'geode' : ['i386'],
+ 'hades' : ['m68kmint'],
+ 'i386' : ['i386'],
+ 'i486' : ['i386'],
+ 'i586' : ['i386'],
+ 'i686' : ['i386'],
+ 'ia32e' : ['x86_64'],
+ 'ia64' : ['ia64'],
+ 'milan' : ['m68kmint'],
+ 'osfmach3_i386' : ['i386'],
+ 'osfmach3_i486' : ['i386'],
+ 'osfmach3_i586' : ['i386'],
+ 'osfmach3_i686' : ['i386'],
+ 'osfmach3_ppc' : ['ppc'],
+ 'pentium3' : ['i386'],
+ 'pentium4' : ['i386'],
+ 'powerpc' : ['ppc'],
+ 'powerppc' : ['ppc'],
+ 'ppc32dy4' : ['ppc'],
+ 'ppc64iseries' : ['ppc64'],
+ 'ppc64pseries' : ['ppc64'],
+ 'ppc8260' : ['ppc'],
+ 'ppc8560' : ['ppc'],
+ 'ppciseries' : ['ppc'],
+ 'ppcpseries' : ['ppc'],
+ 's390' : ['s390'],
+ 's390x' : ['s390x'],
+ 'sh3' : ['sh3'],
+ 'sh4' : ['sh4'],
+ 'sh4a' : ['sh4'],
+ 'sparc64v' : ['sparc64'],
+ 'sparcv8' : ['sparc'],
+ 'sparcv9' : ['sparc'],
+ 'sparcv9v' : ['sparc'],
+ 'sun4c' : ['sparc'],
+ 'sun4d' : ['sparc'],
+ 'sun4m' : ['sparc'],
+ 'sun4u' : ['sparc64'],
+ 'x86_64' : ['x86_64'],
+}
+
+optflags = {
+ 'alpha' : ['-O2','-g','-mieee'],
+ 'alphaev5' : ['-O2','-g','-mieee','-mtune=ev5'],
+ 'alphaev56' : ['-O2','-g','-mieee','-mtune=ev56'],
+ 'alphaev6' : ['-O2','-g','-mieee','-mtune=ev6'],
+ 'alphaev67' : ['-O2','-g','-mieee','-mtune=ev67'],
+ 'alphapca56' : ['-O2','-g','-mieee','-mtune=pca56'],
+ 'amd64' : ['-O2','-g'],
+ 'armv3l' : ['-O2','-g','-march=armv3'],
+ 'armv4b' : ['-O2','-g','-march=armv4'],
+ 'armv4l' : ['-O2','-g','-march=armv4'],
+ 'armv4tl' : ['-O2','-g','-march=armv4t'],
+ 'armv5tejl' : ['-O2','-g','-march=armv5te'],
+ 'armv5tel' : ['-O2','-g','-march=armv5te'],
+ 'armv6l' : ['-O2','-g','-march=armv6'],
+ 'armv7l' : ['-O2','-g','-march=armv7'],
+ 'atariclone' : ['-O2','-g','-fomit-frame-pointer'],
+ 'atarist' : ['-O2','-g','-fomit-frame-pointer'],
+ 'atariste' : ['-O2','-g','-fomit-frame-pointer'],
+ 'ataritt' : ['-O2','-g','-fomit-frame-pointer'],
+ 'athlon' : ['-O2','-g','-march=athlon'],
+ 'falcon' : ['-O2','-g','-fomit-frame-pointer'],
+ 'fat' : ['-O2','-g','-arch','i386','-arch','ppc'],
+ 'geode' : ['-Os','-g','-m32','-march=geode'],
+ 'hades' : ['-O2','-g','-fomit-frame-pointer'],
+ 'hppa1.0' : ['-O2','-g','-mpa-risc-1-0'],
+ 'hppa1.1' : ['-O2','-g','-mpa-risc-1-0'],
+ 'hppa1.2' : ['-O2','-g','-mpa-risc-1-0'],
+ 'hppa2.0' : ['-O2','-g','-mpa-risc-1-0'],
+ 'i386' : ['-O2','-g','-march=i386','-mtune=i686'],
+ 'i486' : ['-O2','-g','-march=i486'],
+ 'i586' : ['-O2','-g','-march=i586'],
+ 'i686' : ['-O2','-g','-march=i686'],
+ 'ia32e' : ['-O2','-g'],
+ 'ia64' : ['-O2','-g'],
+ 'm68k' : ['-O2','-g','-fomit-frame-pointer'],
+ 'milan' : ['-O2','-g','-fomit-frame-pointer'],
+ 'mips' : ['-O2','-g'],
+ 'mipsel' : ['-O2','-g'],
+ 'parisc' : ['-O2','-g','-mpa-risc-1-0'],
+ 'pentium3' : ['-O2','-g','-march=pentium3'],
+ 'pentium4' : ['-O2','-g','-march=pentium4'],
+ 'ppc' : ['-O2','-g','-fsigned-char'],
+ 'ppc32dy4' : ['-O2','-g','-fsigned-char'],
+ 'ppc64' : ['-O2','-g','-fsigned-char'],
+ 'ppc8260' : ['-O2','-g','-fsigned-char'],
+ 'ppc8560' : ['-O2','-g','-fsigned-char'],
+ 'ppciseries' : ['-O2','-g','-fsigned-char'],
+ 'ppcpseries' : ['-O2','-g','-fsigned-char'],
+ 's390' : ['-O2','-g'],
+ 's390x' : ['-O2','-g'],
+ 'sh3' : ['-O2','-g'],
+ 'sh4' : ['-O2','-g','-mieee'],
+ 'sh4a' : ['-O2','-g','-mieee'],
+ 'sparc' : ['-O2','-g','-m32','-mtune=ultrasparc'],
+ 'sparc64' : ['-O2','-g','-m64','-mtune=ultrasparc'],
+ 'sparc64v' : ['-O2','-g','-m64','-mtune=niagara'],
+ 'sparcv8' : ['-O2','-g','-m32','-mtune=ultrasparc','-mv8'],
+ 'sparcv9' : ['-O2','-g','-m32','-mtune=ultrasparc'],
+ 'sparcv9v' : ['-O2','-g','-m32','-mtune=niagara'],
+ 'x86_64' : ['-O2','-g'],
+}
+
+arch_canon = {
+ 'IP' : ['sgi','7'],
+ 'alpha' : ['alpha','2'],
+ 'alphaev5' : ['alphaev5','2'],
+ 'alphaev56' : ['alphaev56','2'],
+ 'alphaev6' : ['alphaev6','2'],
+ 'alphaev67' : ['alphaev67','2'],
+ 'alphapca56' : ['alphapca56','2'],
+ 'amd64' : ['amd64','1'],
+ 'armv3l' : ['armv3l','12'],
+ 'armv4b' : ['armv4b','12'],
+ 'armv4l' : ['armv4l','12'],
+ 'armv5tejl' : ['armv5tejl','12'],
+ 'armv5tel' : ['armv5tel','12'],
+ 'armv6l' : ['armv6l','12'],
+ 'armv7l' : ['armv7l','12'],
+ 'atariclone' : ['m68kmint','13'],
+ 'atarist' : ['m68kmint','13'],
+ 'atariste' : ['m68kmint','13'],
+ 'ataritt' : ['m68kmint','13'],
+ 'athlon' : ['athlon','1'],
+ 'falcon' : ['m68kmint','13'],
+ 'geode' : ['geode','1'],
+ 'hades' : ['m68kmint','13'],
+ 'i370' : ['i370','14'],
+ 'i386' : ['i386','1'],
+ 'i486' : ['i486','1'],
+ 'i586' : ['i586','1'],
+ 'i686' : ['i686','1'],
+ 'ia32e' : ['ia32e','1'],
+ 'ia64' : ['ia64','9'],
+ 'm68k' : ['m68k','6'],
+ 'm68kmint' : ['m68kmint','13'],
+ 'milan' : ['m68kmint','13'],
+ 'mips' : ['mips','4'],
+ 'mipsel' : ['mipsel','11'],
+ 'pentium3' : ['pentium3','1'],
+ 'pentium4' : ['pentium4','1'],
+ 'ppc' : ['ppc','5'],
+ 'ppc32dy4' : ['ppc32dy4','5'],
+ 'ppc64' : ['ppc64','16'],
+ 'ppc64iseries' : ['ppc64iseries','16'],
+ 'ppc64pseries' : ['ppc64pseries','16'],
+ 'ppc8260' : ['ppc8260','5'],
+ 'ppc8560' : ['ppc8560','5'],
+ 'ppciseries' : ['ppciseries','5'],
+ 'ppcpseries' : ['ppcpseries','5'],
+ 'rs6000' : ['rs6000','8'],
+ 's390' : ['s390','14'],
+ 's390x' : ['s390x','15'],
+ 'sh' : ['sh','17'],
+ 'sh3' : ['sh3','17'],
+ 'sh4' : ['sh4','17'],
+ 'sh4a' : ['sh4a','17'],
+ 'sparc' : ['sparc','3'],
+ 'sparc64' : ['sparc64','2'],
+ 'sparc64v' : ['sparc64v','2'],
+ 'sparcv8' : ['sparcv8','3'],
+ 'sparcv9' : ['sparcv9','3'],
+ 'sparcv9v' : ['sparcv9v','3'],
+ 'sun4' : ['sparc','3'],
+ 'sun4c' : ['sparc','3'],
+ 'sun4d' : ['sparc','3'],
+ 'sun4m' : ['sparc','3'],
+ 'sun4u' : ['sparc64','2'],
+ 'x86_64' : ['x86_64','1'],
+ 'xtensa' : ['xtensa','18'],
+}
+
+# End of rpmrc dictionaries (Marker, don't change or remove!)
+
+def defaultMachine(use_rpm_default=True):
+ """ Return the canonicalized machine name. """
+
+ if use_rpm_default:
+ try:
+ # This should be the most reliable way to get the default arch
+ rmachine = subprocess.check_output(['rpm', '--eval=%_target_cpu'], shell=False).rstrip()
+ except Exception as e:
+ # Something went wrong, try again by looking up platform.machine()
+ return defaultMachine(False)
+ else:
+ rmachine = platform.machine()
+
+ # Try to lookup the string in the canon table
+ if rmachine in arch_canon:
+ rmachine = arch_canon[rmachine][0]
+
+ return rmachine
+
+def defaultSystem():
+ """ Return the canonicalized system name. """
+ rsystem = platform.system()
+
+ # Try to lookup the string in the canon tables
+ if rsystem in os_canon:
+ rsystem = os_canon[rsystem][0]
+
+ return rsystem
+
+def defaultNames():
+ """ Return the canonicalized machine and system name. """
+ return defaultMachine(), defaultSystem()
+
+def updateRpmDicts(rpmrc, pyfile):
+ """ Read the given rpmrc file with RPM definitions and update the
+ info dictionaries in the file pyfile with it.
+ The arguments will usually be 'rpmrc.in' from a recent RPM source
+ tree, and 'rpmutils.py' referring to this script itself.
+ See also usage() below.
+ """
+ try:
+ # Read old rpmutils.py file
+ oldpy = open(pyfile,"r").readlines()
+ # Read current rpmrc.in file
+ rpm = open(rpmrc,"r").readlines()
+ # Parse for data
+ data = {}
+ # Allowed section names that get parsed
+ sections = ['optflags',
+ 'arch_canon',
+ 'os_canon',
+ 'buildarchtranslate',
+ 'arch_compat',
+ 'os_compat',
+ 'buildarch_compat']
+ for l in rpm:
+ l = l.rstrip('\n').replace(':',' ')
+ # Skip comments
+ if l.lstrip().startswith('#'):
+ continue
+ tokens = l.strip().split()
+ if len(tokens):
+ key = tokens[0]
+ if key in sections:
+ # Have we met this section before?
+ if not data.has_key(tokens[0]):
+ # No, so insert it
+ data[key] = {}
+ # Insert data
+ data[key][tokens[1]] = tokens[2:]
+ # Write new rpmutils.py file
+ out = open(pyfile,"w")
+ pm = 0
+ for l in oldpy:
+ if pm:
+ if l.startswith('# End of rpmrc dictionaries'):
+ pm = 0
+ out.write(l)
+ else:
+ out.write(l)
+ if l.startswith('# Start of rpmrc dictionaries'):
+ pm = 1
+ # Write data sections to single dictionaries
+ for key, entries in data.iteritems():
+ out.write("%s = {\n" % key)
+ for arch in sorted(entries.keys()):
+ out.write(" '%s' : ['%s'],\n" % (arch, "','".join(entries[arch])))
+ out.write("}\n\n")
+ out.close()
+ except:
+ pass
+
+def usage():
+ print "rpmutils.py rpmrc.in rpmutils.py"
+
+def main():
+ import sys
+
+ if len(sys.argv) < 3:
+ usage()
+ sys.exit(0)
+ updateRpmDicts(sys.argv[1], sys.argv[2])
+
+if __name__ == "__main__":
+ main()
diff --git a/engine/SCons/Tool/sgiar.py b/engine/SCons/Tool/sgiar.py
new file mode 100644
index 0000000..7012bb7
--- /dev/null
+++ b/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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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/engine/SCons/Tool/sgic++.py b/engine/SCons/Tool/sgic++.py
new file mode 100644
index 0000000..b4f4e51
--- /dev/null
+++ b/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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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/engine/SCons/Tool/sgicc.py b/engine/SCons/Tool/sgicc.py
new file mode 100644
index 0000000..c8dd66e
--- /dev/null
+++ b/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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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/engine/SCons/Tool/sgilink.py b/engine/SCons/Tool/sgilink.py
new file mode 100644
index 0000000..8f46558
--- /dev/null
+++ b/engine/SCons/Tool/sgilink.py
@@ -0,0 +1,62 @@
+"""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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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['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/engine/SCons/Tool/sunar.py b/engine/SCons/Tool/sunar.py
new file mode 100644
index 0000000..6ef5b63
--- /dev/null
+++ b/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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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/engine/SCons/Tool/sunc++.py b/engine/SCons/Tool/sunc++.py
new file mode 100644
index 0000000..e563056
--- /dev/null
+++ b/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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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/engine/SCons/Tool/suncc.py b/engine/SCons/Tool/suncc.py
new file mode 100644
index 0000000..42fcf52
--- /dev/null
+++ b/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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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/engine/SCons/Tool/sunf77.py b/engine/SCons/Tool/sunf77.py
new file mode 100644
index 0000000..b3c764f
--- /dev/null
+++ b/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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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/engine/SCons/Tool/sunf90.py b/engine/SCons/Tool/sunf90.py
new file mode 100644
index 0000000..999aed8
--- /dev/null
+++ b/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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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/engine/SCons/Tool/sunf95.py b/engine/SCons/Tool/sunf95.py
new file mode 100644
index 0000000..329b10b
--- /dev/null
+++ b/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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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/engine/SCons/Tool/sunlink.py b/engine/SCons/Tool/sunlink.py
new file mode 100644
index 0000000..ecd0ce7
--- /dev/null
+++ b/engine/SCons/Tool/sunlink.py
@@ -0,0 +1,76 @@
+"""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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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['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/engine/SCons/Tool/swig.py b/engine/SCons/Tool/swig.py
new file mode 100644
index 0000000..572c83e
--- /dev/null
+++ b/engine/SCons/Tool/swig.py
@@ -0,0 +1,184 @@
+"""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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+import os.path
+import re
+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)
+# Also allow for the line to have spaces after test if not quoted
+_reModule = re.compile(r'%module(\s*\(.*\))?\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 file stem
+ matches = []
+ mnames.append(os.path.splitext(os.path.basename(src))[0])
+
+ for m in matches:
+ mnames.append(m[2])
+ directors = directors or m[0].find('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 = [m + ".py" for m in 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 = [env.fs.File(os.path.join(outdir, j)) for j in python_files]
+ else:
+ python_files = [target[0].dir.File(m) for m in 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 = [[m + ".java", m + "JNI.java"] for m in mnames]
+ java_files = SCons.Util.flatten(java_files)
+ outdir = env.subst('$SWIGOUTDIR', target=target, source=source)
+ if outdir:
+ java_files = [os.path.join(outdir, j) for j in java_files]
+ java_files = list(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):
+ swig = env.get('SWIG') or env.Detect(['swig'])
+ return swig
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/engine/SCons/Tool/tar.py b/engine/SCons/Tool/tar.py
new file mode 100644
index 0000000..ae054a3
--- /dev/null
+++ b/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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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/engine/SCons/Tool/tex.py b/engine/SCons/Tool/tex.py
new file mode 100644
index 0000000..28d0773
--- /dev/null
+++ b/engine/SCons/Tool/tex.py
@@ -0,0 +1,992 @@
+"""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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+import os.path
+import re
+import shutil
+import sys
+import platform
+import glob
+
+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', '.bcf']
+
+#
+# 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"OUTPUT *(.*\.aux)")
+
+# search for all .bcf files opened by latex (recorded in the .fls file)
+# for use by biber
+openout_bcf_re = re.compile(r"OUTPUT *(.*\.bcf)")
+
+#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)
+bibunit_re = re.compile(r"^[^%\n]*\\begin\{bibunit\}", re.MULTILINE)
+multibib_re = re.compile(r"^[^%\n]*\\newcites\{([^\}]*)\}", re.MULTILINE)
+addbibresource_re = re.compile(r"^[^%\n]*\\(addbibresource|addglobalbib|addsectionbib)", 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)
+regex = r'^[^%\n]*\\newglossary\s*\[([^\]]+)\]?\s*\{([^}]*)\}\s*\{([^}]*)\}\s*\{([^}]*)\}\s*\{([^}]*)\}'
+newglossary_re = re.compile(regex, re.MULTILINE)
+biblatex_re = re.compile(r"^[^%\n]*\\usepackage.*\{biblatex\}", re.MULTILINE)
+
+newglossary_suffix = []
+
+# search to find all files included by Latex
+include_re = re.compile(r'^[^%\n]*\\(?:include|input){([^}]*)}', re.MULTILINE)
+includeOnly_re = re.compile(r'^[^%\n]*\\(?:include){([^}]*)}', 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 Biber on a file.
+BiberAction = 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
+
+# An action to run MakeIndex (for newglossary commands) on a file.
+MakeNewGlossaryAction = 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 check_file_error_message(utility, filename='log'):
+ msg = '%s returned an error, check the %s file\n' % (utility, filename)
+ sys.stdout.write(msg)
+
+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.isfile(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.isfile(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, nomenclature, and acronyms
+ src_content = source[0].get_text_contents()
+ run_makeindex = makeindex_re.search(src_content) and not os.path.isfile(targetbase + '.idx')
+ run_nomenclature = makenomenclature_re.search(src_content) and not os.path.isfile(targetbase + '.nlo')
+ run_glossary = makeglossary_re.search(src_content) and not os.path.isfile(targetbase + '.glo')
+ run_glossaries = makeglossaries_re.search(src_content) and not os.path.isfile(targetbase + '.glo')
+ run_acronyms = makeacronyms_re.search(src_content) and not os.path.isfile(targetbase + '.acn')
+
+ saved_hashes = {}
+ suffix_nodes = {}
+
+
+ for suffix in all_suffixes+sum(newglossary_suffix, []):
+ 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
+
+ # .aux files already processed by BibTex
+ already_bibtexed = []
+
+ #
+ # routine to update MD5 hash and compare
+ #
+ def check_MD5(filenode, suffix):
+ 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.isfile(logfilename):
+ logContent = open(logfilename, "rb").read()
+
+
+ # Read the fls file to find all .aux files
+ flsfilename = targetbase + '.fls'
+ flsContent = ''
+ auxfiles = []
+ if os.path.isfile(flsfilename):
+ flsContent = open(flsfilename, "rb").read()
+ auxfiles = openout_aux_re.findall(flsContent)
+ # remove duplicates
+ dups = {}
+ for x in auxfiles:
+ dups[x] = 1
+ auxfiles = list(dups.keys())
+
+ bcffiles = []
+ if os.path.isfile(flsfilename):
+ flsContent = open(flsfilename, "rb").read()
+ bcffiles = openout_bcf_re.findall(flsContent)
+ # remove duplicates
+ dups = {}
+ for x in bcffiles:
+ dups[x] = 1
+ bcffiles = list(dups.keys())
+
+ if Verbose:
+ print "auxfiles ",auxfiles
+ print "bcffiles ",bcffiles
+
+ # 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 once
+ # Go through all .aux files and remember the files already done.
+ for auxfilename in auxfiles:
+ if auxfilename not in already_bibtexed:
+ already_bibtexed.append(auxfilename)
+ target_aux = os.path.join(targetdir, auxfilename)
+ if os.path.isfile(target_aux):
+ content = open(target_aux, "rb").read()
+ if content.find("bibdata") != -1:
+ if Verbose:
+ print "Need to run bibtex on ",auxfilename
+ bibfile = env.fs.File(SCons.Util.splitext(target_aux)[0])
+ result = BibTeXAction(bibfile, bibfile, env)
+ if result != 0:
+ check_file_error_message(env['BIBTEX'], 'blg')
+ must_rerun_latex = True
+
+ # Now decide if biber will need to be run.
+ # When the backend for biblatex is biber (by choice or default) the
+ # citation information is put in the .bcf file.
+ # The information that biber reads from the .bcf 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 once
+ # Go through all .bcf files and remember the files already done.
+ for bcffilename in bcffiles:
+ if bcffilename not in already_bibtexed:
+ already_bibtexed.append(bcffilename)
+ target_bcf = os.path.join(targetdir, bcffilename)
+ if os.path.isfile(target_bcf):
+ content = open(target_bcf, "rb").read()
+ if content.find("bibdata") != -1:
+ if Verbose:
+ print "Need to run biber on ",bcffilename
+ bibfile = env.fs.File(SCons.Util.splitext(target_bcf)[0])
+ result = BiberAction(bibfile, bibfile, env)
+ if result != 0:
+ check_file_error_message(env['BIBER'], 'blg')
+ must_rerun_latex = True
+
+ # 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:
+ check_file_error_message(env['MAKEINDEX'], 'ilg')
+ 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:
+ check_file_error_message('%s (nomenclature)' % env['MAKENCL'],
+ 'nlg')
+ #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:
+ check_file_error_message('%s (glossary)' % env['MAKEGLOSSARY'],
+ 'glg')
+ #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:
+ check_file_error_message('%s (acronyms)' % env['MAKEACRONYMS'],
+ 'alg')
+ return result
+
+ # Now decide if latex will need to be run again due to newglossary command.
+ for ig in range(len(newglossary_suffix)):
+ if check_MD5(suffix_nodes[newglossary_suffix[ig][2]],newglossary_suffix[ig][2]) or (count == 1):
+ # We must run makeindex
+ if Verbose:
+ print "Need to run makeindex for newglossary"
+ newglfile = suffix_nodes[newglossary_suffix[ig][2]]
+ MakeNewGlossaryAction = SCons.Action.Action("$MAKENEWGLOSSARYCOM ${SOURCE.filebase}%s -s ${SOURCE.filebase}.ist -t ${SOURCE.filebase}%s -o ${SOURCE.filebase}%s" % (newglossary_suffix[ig][2],newglossary_suffix[ig][0],newglossary_suffix[ig][1]), "$MAKENEWGLOSSARYCOMSTR")
+
+ result = MakeNewGlossaryAction(newglfile, newglfile, env)
+ if result != 0:
+ check_file_error_message('%s (newglossary)' % env['MAKENEWGLOSSARY'],
+ newglossary_suffix[ig][0])
+ 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.isfile(resultfilename)):
+ if os.path.isfile(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
+ paths = paths.split(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:
+ check_file_error_message(env['LATEX'])
+ else:
+ result = TeXAction(target,source,env)
+ if result != 0:
+ check_file_error_message(env['TEX'])
+ 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, aux_files):
+ """ 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:
+ if Verbose:
+ print "scan i ",i," files_tests[i] ",file_tests[i], file_tests[i][1]
+ file_tests[i][0] = file_tests_search[i].search(content)
+ if Verbose and file_tests[i][0]:
+ print " found match for ",file_tests[i][1][-1]
+ # for newglossary insert the suffixes in file_tests[i]
+ if file_tests[i][0] and file_tests[i][1][-1] == 'newglossary':
+ findresult = file_tests_search[i].findall(content)
+ for l in range(len(findresult)) :
+ (file_tests[i][1]).insert(0,'.'+findresult[l][3])
+ (file_tests[i][1]).insert(0,'.'+findresult[l][2])
+ (file_tests[i][1]).insert(0,'.'+findresult[l][0])
+ suffix_list = ['.'+findresult[l][0],'.'+findresult[l][2],'.'+findresult[l][3] ]
+ newglossary_suffix.append(suffix_list)
+ if Verbose:
+ print " new suffixes for newglossary ",newglossary_suffix
+
+
+ incResult = includeOnly_re.search(content)
+ if incResult:
+ aux_files.append(os.path.join(targetdir, incResult.group(1)))
+ if Verbose:
+ print "\include file names : ", aux_files
+ # 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, aux_files)
+ 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'
+ syncfilename = targetbase + '.synctex.gz'
+
+ env.SideEffect(auxfilename,target[0])
+ env.SideEffect(logfilename,target[0])
+ env.SideEffect(flsfilename,target[0])
+ env.SideEffect(syncfilename,target[0])
+ if Verbose:
+ print "side effect :",auxfilename,logfilename,flsfilename,syncfilename
+ env.Clean(target[0],auxfilename)
+ env.Clean(target[0],logfilename)
+ env.Clean(target[0],flsfilename)
+ env.Clean(target[0],syncfilename)
+
+ content = source[0].get_text_contents()
+
+ # These variables are no longer used.
+ #idx_exists = os.path.isfile(targetbase + '.idx')
+ #nlo_exists = os.path.isfile(targetbase + '.nlo')
+ #glo_exists = os.path.isfile(targetbase + '.glo')
+ #acr_exists = os.path.isfile(targetbase + '.acn')
+
+ # set up list with the regular expressions
+ # we use to find features used
+ file_tests_search = [auxfile_re,
+ makeindex_re,
+ bibliography_re,
+ bibunit_re,
+ multibib_re,
+ addbibresource_re,
+ tableofcontents_re,
+ listoffigures_re,
+ listoftables_re,
+ hyperref_re,
+ makenomenclature_re,
+ makeglossary_re,
+ makeglossaries_re,
+ makeacronyms_re,
+ beamer_re,
+ newglossary_re,
+ biblatex_re ]
+ # set up list with the file suffixes that need emitting
+ # when a feature is found
+ file_tests_suff = [['.aux','aux_file'],
+ ['.idx', '.ind', '.ilg','makeindex'],
+ ['.bbl', '.blg','bibliography'],
+ ['.bbl', '.blg','bibunit'],
+ ['.bbl', '.blg','multibib'],
+ ['.bbl', '.blg','.bcf','addbibresource'],
+ ['.toc','contents'],
+ ['.lof','figures'],
+ ['.lot','tables'],
+ ['.out','hyperref'],
+ ['.nlo', '.nls', '.nlg','nomenclature'],
+ ['.glo', '.gls', '.glg','glossary'],
+ ['.glo', '.gls', '.glg','glossaries'],
+ ['.acn', '.acr', '.alg','acronyms'],
+ ['.nav', '.snm', '.out', '.toc','beamer'],
+ ['newglossary',],
+ ['.bcf', '.blg','biblatex'] ]
+ # for newglossary the suffixes are added as we find the command
+ # 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
+ paths = paths.split(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
+
+ # scan all sources for side effect files
+ aux_files = []
+ file_tests = ScanFiles(source[0], target, paths, file_tests, file_tests_search, env, graphics_extensions, targetdir, aux_files)
+
+ for (theSearch,suffix_list) in file_tests:
+ # add side effects if feature is present.If file is to be generated,add all side effects
+ if Verbose and theSearch:
+ print "check side effects for ",suffix_list[-1]
+ if (theSearch != None) or (not source[0].exists() ):
+ file_list = [targetbase,]
+ # for bibunit we need a list of files
+ if suffix_list[-1] == 'bibunit':
+ file_basename = os.path.join(targetdir, 'bu*.aux')
+ file_list = glob.glob(file_basename)
+ # remove the suffix '.aux'
+ for i in range(len(file_list)):
+ file_list.append(SCons.Util.splitext(file_list[i])[0])
+ # for multibib we need a list of files
+ if suffix_list[-1] == 'multibib':
+ for multibibmatch in multibib_re.finditer(content):
+ if Verbose:
+ print "multibib match ",multibibmatch.group(1)
+ if multibibmatch != None:
+ baselist = multibibmatch.group(1).split(',')
+ if Verbose:
+ print "multibib list ", baselist
+ for i in range(len(baselist)):
+ file_list.append(os.path.join(targetdir, baselist[i]))
+ # now define the side effects
+ for file_name in file_list:
+ for suffix in suffix_list[:-1]:
+ env.SideEffect(file_name + suffix,target[0])
+ if Verbose:
+ print "side effect tst :",file_name + suffix, " target is ",str(target[0])
+ env.Clean(target[0],file_name + suffix)
+
+ for aFile in aux_files:
+ aFile_base = SCons.Util.splitext(aFile)[0]
+ env.SideEffect(aFile_base + '.aux',target[0])
+ if Verbose:
+ print "side effect aux :",aFile_base + '.aux'
+ env.Clean(target[0],aFile_base + '.aux')
+ # 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.isfile(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 fls :",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_darwin(env):
+ try:
+ environ = env['ENV']
+ except KeyError:
+ environ = {}
+ env['ENV'] = environ
+
+ if (platform.system() == 'Darwin'):
+ try:
+ ospath = env['ENV']['PATHOSX']
+ except:
+ ospath = None
+ if ospath:
+ env.AppendENVPath('PATH', ospath)
+
+def generate_common(env):
+ """Add internal Builders and construction variables for LaTeX to an Environment."""
+
+ # Add OSX system paths so TeX tools can be found
+ # when a list of tools is given the exists() method is not called
+ generate_darwin(env)
+
+ # 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 Biber on a file.
+ global BiberAction
+ if BiberAction is None:
+ BiberAction = SCons.Action.Action("$BIBERCOM", "$BIBERCOMSTR")
+
+ # 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")
+
+ try:
+ environ = env['ENV']
+ except KeyError:
+ environ = {}
+ env['ENV'] = environ
+
+ # Some Linux platforms have pdflatex set up in a way
+ # that requires that the HOME environment variable be set.
+ # Add it here if defined.
+ v = os.environ.get('HOME')
+ if v:
+ environ['HOME'] = v
+
+ CDCOM = 'cd '
+ if platform.system() == 'Windows':
+ # allow cd command to change drives on Windows
+ CDCOM = 'cd /D '
+
+ env['TEX'] = 'tex'
+ env['TEXFLAGS'] = SCons.Util.CLVar('-interaction=nonstopmode -recorder')
+ env['TEXCOM'] = CDCOM + '${TARGET.dir} && $TEX $TEXFLAGS ${SOURCE.file}'
+
+ env['PDFTEX'] = 'pdftex'
+ env['PDFTEXFLAGS'] = SCons.Util.CLVar('-interaction=nonstopmode -recorder')
+ env['PDFTEXCOM'] = CDCOM + '${TARGET.dir} && $PDFTEX $PDFTEXFLAGS ${SOURCE.file}'
+
+ env['LATEX'] = 'latex'
+ env['LATEXFLAGS'] = SCons.Util.CLVar('-interaction=nonstopmode -recorder')
+ env['LATEXCOM'] = CDCOM + '${TARGET.dir} && $LATEX $LATEXFLAGS ${SOURCE.file}'
+ env['LATEXRETRIES'] = 4
+
+ env['PDFLATEX'] = 'pdflatex'
+ env['PDFLATEXFLAGS'] = SCons.Util.CLVar('-interaction=nonstopmode -recorder')
+ env['PDFLATEXCOM'] = CDCOM + '${TARGET.dir} && $PDFLATEX $PDFLATEXFLAGS ${SOURCE.file}'
+
+ env['BIBTEX'] = 'bibtex'
+ env['BIBTEXFLAGS'] = SCons.Util.CLVar('')
+ env['BIBTEXCOM'] = CDCOM + '${TARGET.dir} && $BIBTEX $BIBTEXFLAGS ${SOURCE.filebase}'
+
+ env['BIBER'] = 'biber'
+ env['BIBERFLAGS'] = SCons.Util.CLVar('')
+ env['BIBERCOM'] = CDCOM + '${TARGET.dir} && $BIBER $BIBERFLAGS ${SOURCE.filebase}'
+
+ env['MAKEINDEX'] = 'makeindex'
+ env['MAKEINDEXFLAGS'] = SCons.Util.CLVar('')
+ env['MAKEINDEXCOM'] = CDCOM + '${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'] = CDCOM + '${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'] = CDCOM + '${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'] = CDCOM + '${TARGET.dir} && $MAKENCL ${SOURCE.filebase}.nlo $MAKENCLFLAGS -o ${SOURCE.filebase}.nls'
+
+ env['MAKENEWGLOSSARY'] = 'makeindex'
+ env['MAKENEWGLOSSARYCOM'] = CDCOM + '${TARGET.dir} && $MAKENEWGLOSSARY '
+
+def exists(env):
+ generate_darwin(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/engine/SCons/Tool/textfile.py b/engine/SCons/Tool/textfile.py
new file mode 100644
index 0000000..3851ef1
--- /dev/null
+++ b/engine/SCons/Tool/textfile.py
@@ -0,0 +1,175 @@
+# -*- python -*-
+#
+# Copyright (c) 2001 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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 'SUBST_DICT' not in env:
+ subs = None # no substitutions
+ else:
+ d = env['SUBST_DICT']
+ if is_Dict(d):
+ d = list(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/engine/SCons/Tool/tlib.py b/engine/SCons/Tool/tlib.py
new file mode 100644
index 0000000..7eedee8
--- /dev/null
+++ b/engine/SCons/Tool/tlib.py
@@ -0,0 +1,53 @@
+"""SCons.Tool.tlib
+
+XXX
+
+"""
+
+#
+# Copyright (c) 2001 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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/engine/SCons/Tool/wix.py b/engine/SCons/Tool/wix.py
new file mode 100644
index 0000000..ca2495a
--- /dev/null
+++ b/engine/SCons/Tool/wix.py
@@ -0,0 +1,104 @@
+"""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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+import SCons.Builder
+import SCons.Action
+import os
+
+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}"
+ env['WIXSRCSUF'] = '.wxs'
+ env['WIXOBJSUF'] = '.wixobj'
+
+ object_builder = SCons.Builder.Builder(
+ action = '$WIXCANDLECOM',
+ suffix = '$WIXOBJSUF',
+ src_suffix = '$WIXSRCSUF')
+
+ linker_builder = SCons.Builder.Builder(
+ action = '$WIXLIGHTCOM',
+ src_suffix = '$WIXOBJSUF',
+ 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):
+ 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:
+ files = os.listdir(path)
+ if env['WIXCANDLE'] in files and env['WIXLIGHT'] in files:
+ env.PrependENVPath('PATH', path)
+ # include appropriate flags if running WiX 2.0
+ if 'wixui.wixlib' in files and 'WixUI_en-us.wxl' in files:
+ env['WIXLIGHTFLAGS'] = [ os.path.join( path, 'wixui.wixlib' ),
+ '-loc',
+ os.path.join( path, 'WixUI_en-us.wxl' ) ]
+ else:
+ env['WIXLIGHTFLAGS'] = []
+ 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/engine/SCons/Tool/xgettext.py b/engine/SCons/Tool/xgettext.py
new file mode 100644
index 0000000..d5db451
--- /dev/null
+++ b/engine/SCons/Tool/xgettext.py
@@ -0,0 +1,339 @@
+""" xgettext tool
+
+Tool specific initialization of `xgettext` tool.
+"""
+
+# Copyright (c) 2001 - 2014 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/xgettext.py 2014/09/27 12:51:43 garyo"
+
+#############################################################################
+class _CmdRunner(object):
+ """ Callabe object, which runs shell command storing its stdout and stderr to
+ variables. It also provides `strfunction()` method, which shall be used by
+ scons Action objects to print command string. """
+
+ def __init__( self, command, commandstr = None):
+ self.out = None
+ self.err = None
+ self.status = None
+ self.command = command
+ self.commandstr = commandstr
+
+ def __call__(self, target, source, env):
+ import SCons.Action
+ import subprocess
+ import os
+ import sys
+ kw = {
+ 'stdin' : 'devnull',
+ 'stdout' : subprocess.PIPE,
+ 'stderr' : subprocess.PIPE,
+ 'universal_newlines' : True,
+ 'shell' : True
+ }
+ command = env.subst(self.command, target = target, source = source)
+ proc = SCons.Action._subproc(env, command, **kw)
+ self.out, self.err = proc.communicate()
+ self.status = proc.wait()
+ if self.err: sys.stderr.write(unicode(self.err))
+ return self.status
+
+ def strfunction(self, target, source, env):
+ import os
+ comstr = self.commandstr
+ if env.subst(comstr, target = target, source = source) == "":
+ comstr = self.command
+ s = env.subst(comstr, target = target, source = source)
+ return s
+#############################################################################
+
+#############################################################################
+def _update_pot_file(target, source, env):
+ """ Action function for `POTUpdate` builder """
+ import re
+ import os
+ import SCons.Action
+ nop = lambda target, source, env : 0
+
+ # Save scons cwd and os cwd (NOTE: they may be different. After the job, we
+ # revert ech one to its original state).
+ save_cwd = env.fs.getcwd()
+ save_os_cwd = os.getcwd()
+ chdir = target[0].dir
+ chdir_str = repr(chdir.get_abspath())
+ # Print chdir message (employ SCons.Action.Action for that. It knows better
+ # than me how to to this correctly).
+ env.Execute(SCons.Action.Action(nop, "Entering " + chdir_str))
+ # Go to target's directory and do our job
+ env.fs.chdir(chdir, 1) # Go into target's directory
+ try:
+ cmd = _CmdRunner('$XGETTEXTCOM', '$XGETTEXTCOMSTR')
+ action = SCons.Action.Action(cmd, strfunction=cmd.strfunction)
+ status = action([ target[0] ], source, env)
+ except:
+ # Something went wrong.
+ env.Execute(SCons.Action.Action(nop, "Leaving " + chdir_str))
+ # Revert working dirs to previous state and re-throw exception.
+ env.fs.chdir(save_cwd, 0)
+ os.chdir(save_os_cwd)
+ raise
+ # Print chdir message.
+ env.Execute(SCons.Action.Action(nop, "Leaving " + chdir_str))
+ # Revert working dirs to previous state.
+ env.fs.chdir(save_cwd, 0)
+ os.chdir(save_os_cwd)
+ # If the command was not successfull, return error code.
+ if status: return status
+
+ new_content = cmd.out
+
+ if not new_content:
+ # When xgettext finds no internationalized messages, no *.pot is created
+ # (because we don't want to bother translators with empty POT files).
+ needs_update = False
+ explain = "no internationalized messages encountered"
+ else:
+ if target[0].exists():
+ # If the file already exists, it's left unaltered unless its messages
+ # are outdated (w.r.t. to these recovered by xgettext from sources).
+ old_content = target[0].get_text_contents()
+ re_cdate = re.compile(r'^"POT-Creation-Date: .*"$[\r\n]?', re.M)
+ old_content_nocdate = re.sub(re_cdate,"",old_content)
+ new_content_nocdate = re.sub(re_cdate,"",new_content)
+ if(old_content_nocdate == new_content_nocdate):
+ # Messages are up-to-date
+ needs_update = False
+ explain = "messages in file found to be up-to-date"
+ else:
+ # Messages are outdated
+ needs_update = True
+ explain = "messages in file were outdated"
+ else:
+ # No POT file found, create new one
+ needs_update = True
+ explain = "new file"
+ if needs_update:
+ # Print message employing SCons.Action.Action for that.
+ msg = "Writting " + repr(str(target[0])) + " (" + explain + ")"
+ env.Execute(SCons.Action.Action(nop, msg))
+ f = open(str(target[0]),"w")
+ f.write(new_content)
+ f.close()
+ return 0
+ else:
+ # Print message employing SCons.Action.Action for that.
+ msg = "Not writting " + repr(str(target[0])) + " (" + explain + ")"
+ env.Execute(SCons.Action.Action(nop, msg))
+ return 0
+#############################################################################
+
+#############################################################################
+from SCons.Builder import BuilderBase
+#############################################################################
+class _POTBuilder(BuilderBase):
+ def _execute(self, env, target, source, *args):
+ if not target:
+ if env.has_key('POTDOMAIN') and env['POTDOMAIN']:
+ domain = env['POTDOMAIN']
+ else:
+ domain = 'messages'
+ target = [ domain ]
+ return BuilderBase._execute(self, env, target, source, *args)
+#############################################################################
+
+#############################################################################
+def _scan_xgettext_from_files(target, source, env, files = None, path = None):
+ """ Parses `POTFILES.in`-like file and returns list of extracted file names.
+ """
+ import re
+ import SCons.Util
+ import SCons.Node.FS
+
+ if files is None:
+ return 0
+ if not SCons.Util.is_List(files):
+ files = [ files ]
+
+ if path is None:
+ if env.has_key('XGETTEXTPATH'):
+ path = env['XGETTEXTPATH']
+ else:
+ path = []
+ if not SCons.Util.is_List(path):
+ path = [ path ]
+
+ path = SCons.Util.flatten(path)
+
+ dirs = ()
+ for p in path:
+ if not isinstance(p, SCons.Node.FS.Base):
+ if SCons.Util.is_String(p):
+ p = env.subst(p, source = source, target = target)
+ p = env.arg2nodes(p, env.fs.Dir)
+ dirs += tuple(p)
+ # cwd is the default search path (when no path is defined by user)
+ if not dirs:
+ dirs = (env.fs.getcwd(),)
+
+ # Parse 'POTFILE.in' files.
+ re_comment = re.compile(r'^#[^\n\r]*$\r?\n?', re.M)
+ re_emptyln = re.compile(r'^[ \t\r]*$\r?\n?', re.M)
+ re_trailws = re.compile(r'[ \t\r]+$')
+ for f in files:
+ # Find files in search path $XGETTEXTPATH
+ if isinstance(f, SCons.Node.FS.Base) and f.rexists():
+ contents = f.get_text_contents()
+ contents = re_comment.sub("", contents)
+ contents = re_emptyln.sub("", contents)
+ contents = re_trailws.sub("", contents)
+ depnames = contents.splitlines()
+ for depname in depnames:
+ depfile = SCons.Node.FS.find_file(depname, dirs)
+ if not depfile:
+ depfile = env.arg2nodes(depname, dirs[0].File)
+ env.Depends(target, depfile)
+ return 0
+#############################################################################
+
+#############################################################################
+def _pot_update_emitter(target, source, env):
+ """ Emitter function for `POTUpdate` builder """
+ from SCons.Tool.GettextCommon import _POTargetFactory
+ import SCons.Util
+ import SCons.Node.FS
+
+ if env.has_key('XGETTEXTFROM'):
+ xfrom = env['XGETTEXTFROM']
+ else:
+ return target, source
+ if not SCons.Util.is_List(xfrom):
+ xfrom = [ xfrom ]
+
+ xfrom = SCons.Util.flatten(xfrom)
+
+ # Prepare list of 'POTFILE.in' files.
+ files = []
+ for xf in xfrom:
+ if not isinstance(xf, SCons.Node.FS.Base):
+ if SCons.Util.is_String(xf):
+ # Interpolate variables in strings
+ xf = env.subst(xf, source = source, target = target)
+ xf = env.arg2nodes(xf)
+ files.extend(xf)
+ if files:
+ env.Depends(target, files)
+ _scan_xgettext_from_files(target, source, env, files)
+ return target, source
+#############################################################################
+
+#############################################################################
+from SCons.Environment import _null
+#############################################################################
+def _POTUpdateBuilderWrapper(env, target=None, source=_null, **kw):
+ return env._POTUpdateBuilder(target, source, **kw)
+#############################################################################
+
+#############################################################################
+def _POTUpdateBuilder(env, **kw):
+ """ Creates `POTUpdate` builder object """
+ import SCons.Action
+ from SCons.Tool.GettextCommon import _POTargetFactory
+ kw['action'] = SCons.Action.Action(_update_pot_file, None)
+ kw['suffix'] = '$POTSUFFIX'
+ kw['target_factory'] = _POTargetFactory(env, alias='$POTUPDATE_ALIAS').File
+ kw['emitter'] = _pot_update_emitter
+ return _POTBuilder(**kw)
+#############################################################################
+
+#############################################################################
+def generate(env,**kw):
+ """ Generate `xgettext` tool """
+ import SCons.Util
+ from SCons.Tool.GettextCommon import RPaths, _detect_xgettext
+
+ try:
+ env['XGETTEXT'] = _detect_xgettext(env)
+ except:
+ env['XGETTEXT'] = 'xgettext'
+ # NOTE: sources="$SOURCES" would work as well. However, we use following
+ # construction to convert absolute paths provided by scons onto paths
+ # relative to current working dir. Note, that scons expands $SOURCE(S) to
+ # absolute paths for sources $SOURCE(s) outside of current subtree (e.g. in
+ # "../"). With source=$SOURCE these absolute paths would be written to the
+ # resultant *.pot file (and its derived *.po files) as references to lines in
+ # source code (e.g. referring lines in *.c files). Such references would be
+ # correct (e.g. in poedit) only on machine on which *.pot was generated and
+ # would be of no use on other hosts (having a copy of source code located
+ # in different place in filesystem).
+ sources = '$( ${_concat( "", SOURCES, "", __env__, XgettextRPaths, TARGET' \
+ + ', SOURCES)} $)'
+
+ # NOTE: the output from $XGETTEXTCOM command must go to stdout, not to a file.
+ # This is required by the POTUpdate builder's action.
+ xgettextcom = '$XGETTEXT $XGETTEXTFLAGS $_XGETTEXTPATHFLAGS' \
+ + ' $_XGETTEXTFROMFLAGS -o - ' + sources
+
+ xgettextpathflags = '$( ${_concat( XGETTEXTPATHPREFIX, XGETTEXTPATH' \
+ + ', XGETTEXTPATHSUFFIX, __env__, RDirs, TARGET, SOURCES)} $)'
+ xgettextfromflags = '$( ${_concat( XGETTEXTFROMPREFIX, XGETTEXTFROM' \
+ + ', XGETTEXTFROMSUFFIX, __env__, target=TARGET, source=SOURCES)} $)'
+
+ env.SetDefault(
+ _XGETTEXTDOMAIN = '${TARGET.filebase}',
+ XGETTEXTFLAGS = [ ],
+ XGETTEXTCOM = xgettextcom,
+ XGETTEXTCOMSTR = '',
+ XGETTEXTPATH = [ ],
+ XGETTEXTPATHPREFIX = '-D',
+ XGETTEXTPATHSUFFIX = '',
+ XGETTEXTFROM = None,
+ XGETTEXTFROMPREFIX = '-f',
+ XGETTEXTFROMSUFFIX = '',
+ _XGETTEXTPATHFLAGS = xgettextpathflags,
+ _XGETTEXTFROMFLAGS = xgettextfromflags,
+ POTSUFFIX = ['.pot'],
+ POTUPDATE_ALIAS = 'pot-update',
+ XgettextRPaths = RPaths(env)
+ )
+ env.Append( BUILDERS = {
+ '_POTUpdateBuilder' : _POTUpdateBuilder(env)
+ } )
+ env.AddMethod(_POTUpdateBuilderWrapper, 'POTUpdate')
+ env.AlwaysBuild(env.Alias('$POTUPDATE_ALIAS'))
+#############################################################################
+
+#############################################################################
+def exists(env):
+ """ Check, whether the tool exists """
+ from SCons.Tool.GettextCommon import _xgettext_exists
+ try:
+ return _xgettext_exists(env)
+ except:
+ return False
+#############################################################################
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/engine/SCons/Tool/yacc.py b/engine/SCons/Tool/yacc.py
new file mode 100644
index 0000000..e8bfc8c
--- /dev/null
+++ b/engine/SCons/Tool/yacc.py
@@ -0,0 +1,140 @@
+"""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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+import os.path
+
+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"))
+
+ # If -v is specirfied yacc will create the output debug file
+ # which is not really source for any process, but should
+ # be noted and also be cleaned
+ # Bug #2558
+ if "-v" in flags:
+ env.SideEffect(targetBase+'.output',target[0])
+ env.Clean(target[0],targetBase+'.output')
+
+
+
+ # 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 = option[l:].strip()
+ 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/engine/SCons/Tool/zip.py b/engine/SCons/Tool/zip.py
new file mode 100644
index 0000000..86513c1
--- /dev/null
+++ b/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 - 2014 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 2014/09/27 12:51:43 garyo"
+
+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):
+ compression = env.get('ZIPCOMPRESSION', 0)
+ zf = zipfile.ZipFile(str(target[0]), 'w', compression)
+ for s in source:
+ if s.isdir():
+ for dirpath, dirnames, filenames in os.walk(str(s)):
+ for fname in filenames:
+ path = os.path.join(dirpath, fname)
+ if os.path.isfile(path):
+ zf.write(path, os.path.relpath(path, str(env.get('ZIPROOT', ''))))
+ else:
+ zf.write(str(s), os.path.relpath(str(s), str(env.get('ZIPROOT', ''))))
+ 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'
+ env['ZIPROOT'] = SCons.Util.CLVar('')
+
+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: