From 78a8b1cdcfa5d0fb290cf4569e5b18a4d04c73cf Mon Sep 17 00:00:00 2001 From: Dirk Baechle Date: Thu, 21 Aug 2014 23:18:20 +0200 Subject: - fix for issue #2970, false line length calculation in TempFileMunge class --- src/CHANGES.txt | 3 ++ src/engine/SCons/Platform/PlatformTests.py | 50 +++++++++++++++++++++++++++++- src/engine/SCons/Platform/__init__.py | 3 +- 3 files changed, 54 insertions(+), 2 deletions(-) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index cf4264a..0011463 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -6,6 +6,9 @@ RELEASE 2.3.2.alpha.yyyymmdd - NEW DATE WILL BE INSERTED HERE + From Roland Stark: + - Fixed false line length calculation in the TempFileMunge class (#2970). + From Anatoly Techtonik: - Do not fail on EnsureSConsVersion when running from checkout diff --git a/src/engine/SCons/Platform/PlatformTests.py b/src/engine/SCons/Platform/PlatformTests.py index 515382a..a507e4e 100644 --- a/src/engine/SCons/Platform/PlatformTests.py +++ b/src/engine/SCons/Platform/PlatformTests.py @@ -33,10 +33,13 @@ import TestUnit import SCons.Errors import SCons.Platform +import SCons.Environment +import SCons.Action class Environment(collections.UserDict): def Detect(self, cmd): return cmd + def AppendENVPath(self, key, value): pass @@ -117,9 +120,54 @@ class PlatformTestCase(unittest.TestCase): SCons.Platform.Platform()(env) assert env != {}, env +class TempFileMungeTestCase(unittest.TestCase): + def test_TempFileMunge(self): + """Test the TempFileMunge() class, more specifically the + MAXLINELENGTH setting. + We try setting different maximum line lengths for a + fixed command string and ensure that the tempfile mechanism + kicks in at MAXLINELENGTH+1. + """ + # Init class with cmd, such that the fully expanded + # string reads "a test command line". + # Note, how we're using a command string here that is + # actually longer than the substituted one. This is to ensure + # that the TempFileMunge class internally really takes the + # length of the expanded string into account. + defined_cmd = "a $VERY $OVERSIMPLIFIED line" + t = SCons.Platform.TempFileMunge(defined_cmd) + env = SCons.Environment.SubstitutionEnvironment(tools=[]) + # Setting the line length high enough... + env['MAXLINELENGTH'] = 1024 + env['VERY'] = 'test' + env['OVERSIMPLIFIED'] = 'command' + expanded_cmd = env.subst(defined_cmd) + # Call the tempfile munger + cmd = t(None,None,env,0) + assert cmd == defined_cmd, cmd + # Let MAXLINELENGTH equal the string's length + env['MAXLINELENGTH'] = len(expanded_cmd) + cmd = t(None,None,env,0) + assert cmd == defined_cmd, cmd + # Finally, let the actual tempfile mechanism kick in + # Disable printing of actions... + old_actions = SCons.Action.print_actions + SCons.Action.print_actions = 0 + env['MAXLINELENGTH'] = len(expanded_cmd)-1 + cmd = t(None,None,env,0) + # ...and restoring its setting. + SCons.Action.print_actions = old_actions + assert cmd != defined_cmd, cmd if __name__ == "__main__": - suite = unittest.makeSuite(PlatformTestCase, 'test_') + suite = unittest.TestSuite() + + tclasses = [ PlatformTestCase, + TempFileMungeTestCase ] + for tclass in tclasses: + names = unittest.getTestCaseNames(tclass, 'test_') + suite.addTests(list(map(tclass, names))) + TestUnit.run(suite) # Local Variables: diff --git a/src/engine/SCons/Platform/__init__.py b/src/engine/SCons/Platform/__init__.py index 81a49e7..a9c8076 100644 --- a/src/engine/SCons/Platform/__init__.py +++ b/src/engine/SCons/Platform/__init__.py @@ -173,6 +173,7 @@ class TempFileMunge(object): length = 0 for c in cmd: length += len(c) + length += len(cmd) - 1 if length <= maxline: return self.cmd @@ -187,7 +188,7 @@ class TempFileMunge(object): (fd, tmp) = tempfile.mkstemp('.lnk', text=True) native_tmp = SCons.Util.get_native_path(os.path.normpath(tmp)) - if env['SHELL'] and env['SHELL'] == 'sh': + if env.get('SHELL',None) and env['SHELL'] == 'sh': # The sh shell will try to escape the backslashes in the # path, so unescape them. native_tmp = native_tmp.replace('\\', r'\\\\') -- cgit v0.12 From af7ae3e0489ca6f58a2581add0ceb7da4e7ccf0d Mon Sep 17 00:00:00 2001 From: Gary Oberbrunner Date: Thu, 21 Aug 2014 20:59:35 -0400 Subject: Fixed or skipped tests that fail on Windows. Mostly just per-test changes, but also made match_re strip out CR (\r) chars at end of lines to make Windows match properly. --- QMTest/TestCmd.py | 5 +++-- test/CC/CCVERSION.py | 3 ++- test/CXX/CXXVERSION.py | 2 ++ test/Configure/custom-tests.py | 2 +- test/Copy-Symlinks.py | 3 +++ test/FindSourceFiles.py | 3 ++- 6 files changed, 13 insertions(+), 5 deletions(-) diff --git a/QMTest/TestCmd.py b/QMTest/TestCmd.py index b51d90f..3048973 100644 --- a/QMTest/TestCmd.py +++ b/QMTest/TestCmd.py @@ -486,7 +486,8 @@ def match_re(lines = None, res = None): """ """ if not is_List(lines): - lines = lines.split("\n") + # CRs mess up matching (Windows) so split carefully + lines = re.split('\r?\n', lines) if not is_List(res): res = res.split("\n") if len(lines) != len(res): @@ -683,7 +684,7 @@ if subprocess.mswindows: assert ol is None lpBuffer = ctypes.create_string_buffer(bufSize) bytesRead = DWORD() - bErr = ctypes.windll.kernel32.ReadFile( + bErr = ctypes.windll.kernel32.ReadFile( hFile, lpBuffer, bufSize, ctypes.byref(bytesRead), ol) if not bErr: raise ctypes.WinError() return (0, ctypes.string_at(lpBuffer, bytesRead.value)) diff --git a/test/CC/CCVERSION.py b/test/CC/CCVERSION.py index ac28e38..f785ddc 100644 --- a/test/CC/CCVERSION.py +++ b/test/CC/CCVERSION.py @@ -33,7 +33,8 @@ _exe = TestSCons._exe test = TestSCons.TestSCons() - +if sys.platform == 'win32': + test.skip_test('CCVERSION not set with MSVC, skipping test.') test.write("versioned.py", """import os diff --git a/test/CXX/CXXVERSION.py b/test/CXX/CXXVERSION.py index 8433aa6..6017001 100644 --- a/test/CXX/CXXVERSION.py +++ b/test/CXX/CXXVERSION.py @@ -33,6 +33,8 @@ _exe = TestSCons._exe test = TestSCons.TestSCons() +if sys.platform == 'win32': + test.skip_test('CXXVERSION not set with MSVC, skipping test.') test.write("versioned.py", diff --git a/test/Configure/custom-tests.py b/test/Configure/custom-tests.py index f79ea0d..687ba48 100644 --- a/test/Configure/custom-tests.py +++ b/test/Configure/custom-tests.py @@ -180,7 +180,7 @@ scons: Configure: Display of random string ... scons: Configure: \(cached\) a random string scons: Configure: Display of empty string ... -scons: Configure: \(cached\). +scons: Configure: \(cached\) * scons: Configure: Display of dictionary ... scons: Configure: \(cached\) yes diff --git a/test/Copy-Symlinks.py b/test/Copy-Symlinks.py index f8f92d7..31b2a71 100644 --- a/test/Copy-Symlinks.py +++ b/test/Copy-Symlinks.py @@ -38,6 +38,9 @@ SCons.Defaults.DefaultEnvironment( tools = [] ) test = TestSCons.TestSCons() +if sys.platform == 'win32': + test.skip_test('No symlink-copying (yet) on Windows, skipping test.') + filelinkToCopy = 'filelinkToCopy' fileToLink = 'file.in' fileContents = 'stuff n things\n' diff --git a/test/FindSourceFiles.py b/test/FindSourceFiles.py index 3ba542b..88b9d7e 100644 --- a/test/FindSourceFiles.py +++ b/test/FindSourceFiles.py @@ -28,12 +28,13 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" Test Environment's FindSourceFiles method. """ +import sys import TestSCons test = TestSCons.TestSCons() package_format = "src_tarbz2" -if not test.where_is('tar'): +if not test.where_is('tar') or sys.platform == 'win32': if not test.where_is('zip'): test.skip_test("neither 'tar' nor 'zip' found; skipping test\n") package_format = "src_zip" -- cgit v0.12 From c4eed1ab36078a84bad08c13da1c754fbb63f942 Mon Sep 17 00:00:00 2001 From: anatoly techtonik Date: Sat, 23 Aug 2014 13:31:44 +0300 Subject: taprunner 0.2 - remove unused import that failed Python 2.6 Crash evidence: http://buildbot.scons.org/builders/ubuntu-python-2.6/builds/118/steps/shell/logs/stdio --- testing/framework/TestUnit/taprunner.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/testing/framework/TestUnit/taprunner.py b/testing/framework/TestUnit/taprunner.py index 01e0e81..31eb963 100644 --- a/testing/framework/TestUnit/taprunner.py +++ b/testing/framework/TestUnit/taprunner.py @@ -5,12 +5,14 @@ http://testanything.org/tap-version-13-specification.html Public domain work by: anatoly techtonik +Changes: + 0.2 - removed unused import that failed on Python 2.6 + 0.1 - initial release """ -from unittest import suite from unittest.runner import TextTestRunner, TextTestResult -__version__ = "0.1" +__version__ = "0.2" class TAPTestResult(TextTestResult): -- cgit v0.12 From 1f5b82c89db82ce36896933cf0104f6821742cba Mon Sep 17 00:00:00 2001 From: Gary Oberbrunner Date: Sat, 23 Aug 2014 19:09:54 -0400 Subject: Don't skip Copy-Symlinks test on Windows; it should be made to work instead. --- test/Copy-Symlinks.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/Copy-Symlinks.py b/test/Copy-Symlinks.py index 31b2a71..f8f92d7 100644 --- a/test/Copy-Symlinks.py +++ b/test/Copy-Symlinks.py @@ -38,9 +38,6 @@ SCons.Defaults.DefaultEnvironment( tools = [] ) test = TestSCons.TestSCons() -if sys.platform == 'win32': - test.skip_test('No symlink-copying (yet) on Windows, skipping test.') - filelinkToCopy = 'filelinkToCopy' fileToLink = 'file.in' fileContents = 'stuff n things\n' -- cgit v0.12 From 61edca4165343ae6361160d05dc2e5d022e9d780 Mon Sep 17 00:00:00 2001 From: Gary Oberbrunner Date: Sat, 23 Aug 2014 20:19:34 -0400 Subject: Update doc, change python floor from 2.4 to 2.7. --- doc/man/scons.xml | 2 +- doc/python10/process.xml | 4 ++-- doc/user/build-install.xml | 16 ++++++++-------- doc/user/misc.xml | 9 ++++----- 4 files changed, 15 insertions(+), 16 deletions(-) diff --git a/doc/man/scons.xml b/doc/man/scons.xml index 8d52c1e..55f2d63 100644 --- a/doc/man/scons.xml +++ b/doc/man/scons.xml @@ -425,7 +425,7 @@ try to access a list member that does not exist. scons -requires Python version 2.4 or later. +requires Python version 2.7 or later. There should be no other dependencies or requirements to run scons. diff --git a/doc/python10/process.xml b/doc/python10/process.xml index 24645e6..6c790d0 100644 --- a/doc/python10/process.xml +++ b/doc/python10/process.xml @@ -50,7 +50,7 @@ - &SCons; will be written to Python version 2.4 (to ensure + &SCons; will be written to Python version 2.7 (to ensure usability by a wide install base). @@ -296,7 +296,7 @@ - + In practice, simple tests only need to initialize a test object, use the object to write some input files, run &SCons;, and then check whatever criteria diff --git a/doc/user/build-install.xml b/doc/user/build-install.xml index ca40b04..d107b4a 100644 --- a/doc/user/build-install.xml +++ b/doc/user/build-install.xml @@ -6,7 +6,7 @@ %scons; - + %builders-mod; @@ -15,7 +15,7 @@ %tools-mod; %variables-mod; - + ]> @@ -147,7 +147,7 @@ Python 2.5.1 - &SCons; will work with any 2.x version of Python from 2.4 on; + &SCons; will work with any 2.x version of Python from 2.7 on; 3.0 and later are not yet supported. If you need to install Python and have a choice, we recommend using the most recent 2.x Python version available. @@ -209,7 +209,7 @@ Python 2.5.1 a specific &SCons; RPM file, you can download and install from the generic RPM provided by the &SCons; project. - This will install the + This will install the SCons script(s) in /usr/bin, and the SCons library modules in /usr/lib/scons. @@ -530,7 +530,7 @@ Python 2.5.1 This would install the scons script in /opt/scons/bin - and the build engine in + and the build engine in /opt/scons/lib/scons, @@ -566,7 +566,7 @@ Python 2.5.1 relative to the user's $HOME directory, the &scons; script in $HOME/bin - and the build engine in + and the build engine in $HOME/lib/scons, simply type: @@ -719,7 +719,7 @@ $ python setup.py install --prefix=$HOME while: statements look like break statements look like - + continue statements look like diff --git a/doc/user/misc.xml b/doc/user/misc.xml index a71663f..286963d 100644 --- a/doc/user/misc.xml +++ b/doc/user/misc.xml @@ -2,7 +2,7 @@ %scons; - + %builders-mod; @@ -56,11 +56,10 @@ - Although the &SCons; code itself will run - on any 2.x Python version 2.4 or later, + Although the &SCons; code itself will run + on any 2.x Python version 2.7 or later, you are perfectly free to make use of - Python syntax and modules from more modern versions - (for example, Python 2.5 or 2.6) + Python syntax and modules from later versions when writing your &SConscript; files or your own local modules. If you do this, it's usually helpful to -- cgit v0.12 From 1930f1b34740e1b12220c46483d3fb5f9e125aef Mon Sep 17 00:00:00 2001 From: Dirk Baechle Date: Sun, 24 Aug 2014 12:04:48 +0200 Subject: - updated doc string and simplified a comparison, based on PR review comments --- src/engine/SCons/Platform/PlatformTests.py | 11 ++++------- src/engine/SCons/Platform/__init__.py | 2 +- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/engine/SCons/Platform/PlatformTests.py b/src/engine/SCons/Platform/PlatformTests.py index a507e4e..ca3080e 100644 --- a/src/engine/SCons/Platform/PlatformTests.py +++ b/src/engine/SCons/Platform/PlatformTests.py @@ -26,7 +26,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import SCons.compat import collections -import sys import unittest import TestUnit @@ -121,12 +120,10 @@ class PlatformTestCase(unittest.TestCase): assert env != {}, env class TempFileMungeTestCase(unittest.TestCase): - def test_TempFileMunge(self): - """Test the TempFileMunge() class, more specifically the - MAXLINELENGTH setting. - We try setting different maximum line lengths for a - fixed command string and ensure that the tempfile mechanism - kicks in at MAXLINELENGTH+1. + def test_MAXLINELENGTH(self): + """ Test different values for MAXLINELENGTH with the same + size command string to ensure that the temp file mechanism + kicks in only at MAXLINELENGTH+1, or higher """ # Init class with cmd, such that the fully expanded # string reads "a test command line". diff --git a/src/engine/SCons/Platform/__init__.py b/src/engine/SCons/Platform/__init__.py index a9c8076..fa6df61 100644 --- a/src/engine/SCons/Platform/__init__.py +++ b/src/engine/SCons/Platform/__init__.py @@ -188,7 +188,7 @@ class TempFileMunge(object): (fd, tmp) = tempfile.mkstemp('.lnk', text=True) native_tmp = SCons.Util.get_native_path(os.path.normpath(tmp)) - if env.get('SHELL',None) and env['SHELL'] == 'sh': + if env.get('SHELL',None) == 'sh': # The sh shell will try to escape the backslashes in the # path, so unescape them. native_tmp = native_tmp.replace('\\', r'\\\\') -- cgit v0.12 From b6ff759ffe7188104be3fe53d0a7c0a8a1cd0b17 Mon Sep 17 00:00:00 2001 From: Gary Oberbrunner Date: Sat, 23 Aug 2014 20:42:24 -0400 Subject: Updated generated docs for 2.3.3 release --- doc/generated/examples/caching_ex-random_1.xml | 4 +- doc/generated/examples/troubleshoot_explain1_3.xml | 2 +- doc/generated/tools.gen | 12 ++--- doc/generated/tools.mod | 4 +- doc/generated/variables.gen | 52 +++++++++++----------- doc/generated/variables.mod | 4 +- 6 files changed, 39 insertions(+), 39 deletions(-) diff --git a/doc/generated/examples/caching_ex-random_1.xml b/doc/generated/examples/caching_ex-random_1.xml index 2ed1a8f..b864ef4 100644 --- a/doc/generated/examples/caching_ex-random_1.xml +++ b/doc/generated/examples/caching_ex-random_1.xml @@ -1,9 +1,9 @@ % scons -Q cc -o f1.o -c f1.c -cc -o f2.o -c f2.c cc -o f3.o -c f3.c -cc -o f5.o -c f5.c cc -o f4.o -c f4.c +cc -o f2.o -c f2.c +cc -o f5.o -c f5.c cc -o prog f1.o f2.o f3.o f4.o f5.o diff --git a/doc/generated/examples/troubleshoot_explain1_3.xml b/doc/generated/examples/troubleshoot_explain1_3.xml index 0bdaace..0a5299b 100644 --- a/doc/generated/examples/troubleshoot_explain1_3.xml +++ b/doc/generated/examples/troubleshoot_explain1_3.xml @@ -3,5 +3,5 @@ cp file.in file.oout scons: warning: Cannot find target file.out after building -File "/home/garyo/src/scons-scons/bootstrap/src/script/scons.py", line 199, in <module> +File "/home/garyo/src/scons-scons/src/script/scons.py", line 199, in <module> diff --git a/doc/generated/tools.gen b/doc/generated/tools.gen index dc9b50d..539c5e6 100644 --- a/doc/generated/tools.gen +++ b/doc/generated/tools.gen @@ -767,19 +767,19 @@ Sets construction variables for the Sets: &cv-link-AS;, &cv-link-ASCOM;, &cv-link-ASFLAGS;, &cv-link-ASPPCOM;, &cv-link-ASPPFLAGS;.Uses: &cv-link-ASCOMSTR;, &cv-link-ASPPCOMSTR;. - - packaging + + Packaging -A framework for building binary and source packages. +Sets construction variables for the Package Builder. - - Packaging + + packaging -Sets construction variables for the Package Builder. +A framework for building binary and source packages. diff --git a/doc/generated/tools.mod b/doc/generated/tools.mod index 3c6f71c..13072bf 100644 --- a/doc/generated/tools.mod +++ b/doc/generated/tools.mod @@ -76,8 +76,8 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. mwcc"> mwld"> nasm"> -packaging"> Packaging"> +packaging"> pdf"> pdflatex"> pdftex"> @@ -185,8 +185,8 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. mwcc"> mwld"> nasm"> -packaging"> Packaging"> +packaging"> pdf"> pdflatex"> pdftex"> diff --git a/doc/generated/variables.gen b/doc/generated/variables.gen index d21b417..34b9017 100644 --- a/doc/generated/variables.gen +++ b/doc/generated/variables.gen @@ -950,19 +950,19 @@ DFLAGPREFIX. - - DFLAGS + + _DFLAGS -DFLAGS. +_DFLAGS. - - _DFLAGS + + DFLAGS -_DFLAGS. +DFLAGS. @@ -2642,6 +2642,15 @@ is -dNOPAUSE -dBATCH -sDEVICE=pdfwrite HOST_ARCH + The name of the host hardware architecture used to create the Environment. + If a platform is specified when creating the Environment, then + that Platform's logic will handle setting this value. + This value is immutable, and should not be changed by the user after + the Environment is initialized. + Currently only set for Win32. + + + Sets the host architecture for Visual Studio compiler. If not set, default to the detected host architecture: note that this may depend on the python you are using. @@ -2657,16 +2666,7 @@ Valid values are the same as for This is currently only used on Windows, but in the future it will be used on other OSes as well. - - - The name of the host hardware architecture used to create the Environment. - If a platform is specified when creating the Environment, then - that Platform's logic will handle setting this value. - This value is immutable, and should not be changed by the user after - the Environment is initialized. - Currently only set for Win32. - - + HOST_OS @@ -2862,7 +2862,7 @@ The command line used to call the Java archive tool. The string displayed when the Java archive tool is called -If this is not set, then $JARCOM (the command line) is displayed. +If this is not set, then $JARCOM (the command line) is displayed. @@ -2872,7 +2872,7 @@ env = Environment(JARCOMSTR = "JARchiving $SOURCES into $TARGET") The string displayed when the Java archive tool is called -If this is not set, then $JARCOM (the command line) is displayed. +If this is not set, then $JARCOM (the command line) is displayed. @@ -6713,6 +6713,13 @@ that may not be set or used in a construction environment. TARGET_ARCH + The name of the target hardware architecture for the compiled objects + created by this Environment. + This defaults to the value of HOST_ARCH, and the user can override it. + Currently only set for Win32. + + + Sets the target architecture for Visual Studio compiler (i.e. the arch of the binaries generated by the compiler). If not set, default to $HOST_ARCH, or, if that is unset, to the architecture of the @@ -6737,14 +6744,7 @@ and ia64 (Itanium). For example, if you want to compile 64-bit binaries, you would set TARGET_ARCH='x86_64' in your SCons environment. - - - The name of the target hardware architecture for the compiled objects - created by this Environment. - This defaults to the value of HOST_ARCH, and the user can override it. - Currently only set for Win32. - - + TARGET_OS diff --git a/doc/generated/variables.mod b/doc/generated/variables.mod index 0a59605..473c8a2 100644 --- a/doc/generated/variables.mod +++ b/doc/generated/variables.mod @@ -76,8 +76,8 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. $DESCRIPTION_lang"> $DFILESUFFIX"> $DFLAGPREFIX"> -$DFLAGS"> $_DFLAGS"> +$DFLAGS"> $DFLAGSUFFIX"> $_DINCFLAGS"> $DINCPREFIX"> @@ -698,8 +698,8 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. $DESCRIPTION_lang"> $DFILESUFFIX"> $DFLAGPREFIX"> -$DFLAGS"> $_DFLAGS"> +$DFLAGS"> $DFLAGSUFFIX"> $_DINCFLAGS"> $DINCPREFIX"> -- cgit v0.12 From eb71dba8c06d345f325f1be0d9ba0ec59b53a207 Mon Sep 17 00:00:00 2001 From: Gary Oberbrunner Date: Sat, 23 Aug 2014 21:03:43 -0400 Subject: Update CHANGES, Release and Announce prior to 2.3.3 release. --- src/Announce.txt | 6 ++++++ src/CHANGES.txt | 6 ++++++ src/RELEASE.txt | 37 ++++++++++++++----------------------- 3 files changed, 26 insertions(+), 23 deletions(-) diff --git a/src/Announce.txt b/src/Announce.txt index 83fe421..a749981 100644 --- a/src/Announce.txt +++ b/src/Announce.txt @@ -26,6 +26,12 @@ RELEASE 2.3.2.alpha.yyyymmdd - NEW DATE WILL BE INSERTED HERE since last release. This announcement highlights only the important changes. + Please note the following important changes since release 2.3.2: + + -- On Windows, .def files did not work as sources to shared + libraries or executables, due to a regression which is + corrected in 2.3.3. + Please note the following important changes since release 2.3.0: -- BitKeeper, CVS, Perforce, RCS, SCCS are deprecated from the diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 0011463..7c5372e 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -9,6 +9,12 @@ RELEASE 2.3.2.alpha.yyyymmdd - NEW DATE WILL BE INSERTED HERE From Roland Stark: - Fixed false line length calculation in the TempFileMunge class (#2970). + From Gary Oberbrunner: + - Improve SWIG detection + + From Russel Winder: + - Fix regression on Windows in D language update + From Anatoly Techtonik: - Do not fail on EnsureSConsVersion when running from checkout diff --git a/src/RELEASE.txt b/src/RELEASE.txt index 7249af4..b5f226e 100644 --- a/src/RELEASE.txt +++ b/src/RELEASE.txt @@ -5,52 +5,43 @@ This is a maintenance release, focusing on bug fixes. - Here is a summary of the changes since 2.3.1: + Here is a summary of the changes since 2.3.2: NEW FUNCTIONALITY - - Support for Visual Studio 12.0Exp and 2013 (12.0). + - Added Copy Action symlink soft-copy support (#2395). DEPRECATED FUNCTIONALITY - - RPM and m4 are no longer in the default toolset on Windows. - - BitKeeper, CVS, Perforce, RCS, SCCS are deprecated from the - default toolset and will be removed from the default toolset - in future SCons versions. - - D language, version 1, is now deprecated. Version 2 is - supported. + - None CHANGED/ENHANCED EXISTING FUNCTIONALITY - - Revamp of D language support. - Tools for DMD, GDC and LDC are provided, and integrated - with the C and C++ linking. - - TeX builder now supports -synctex=1 - - TeX builder cleans auxiliary files correctly with biblatex. + - Improved SWIG detection FIXES - - Fixed handling of nested ifs in CPP scanner PreProcessor class. - - Respect user's CC/CXX values; don't always overwrite in generate() - - Delegate linker Tool.exists() to CC/CXX Tool.exists(). - - Fixed NoClean() for multi-target builders (#2353). - - Fix SConf tests that write output - - get default RPM architecture more robustly when building RPMs - - Allow varlist to be specified as list of strings for Actions (#2754) - - Fixes to Docbook tool + - Fix regression on Windows in D language update + - Fixed the newglossary action to work with VariantDir (LaTeX). + - Added a default for the BUILDERS environment variable, + to prevent not defined exception on a Clone(). + - Fixed handling of CPPDEFINE var in Append() + for several list-dict combinations (#2900). PACKAGING - - Update XML doc editor configuration + - No changes DEVELOPMENT - - Improvements to running scons.py from the source tree + - Do not fail on EnsureSConsVersion when running from checkout Thanks to: Dirk Baechle, Vincent Beffar, Thomas Berg, + William Blevins, + Kendrick Boyd, Antonio Cavallo, Jean-François Colson, Bauke Conijn, -- cgit v0.12 From 3daacb57d4a2deeeddddb54cb17fa79f8ffb7abf Mon Sep 17 00:00:00 2001 From: Gary Oberbrunner Date: Sun, 24 Aug 2014 12:34:35 -0400 Subject: Apply 2.3.3 release auto changes to default branch --- QMTest/TestSCons.py | 2 +- README.rst | 16 ++++++++-------- ReleaseConfig | 2 +- SConstruct | 4 ++-- debian/changelog | 12 ++++++++++++ src/Announce.txt | 2 +- src/CHANGES.txt | 2 +- 7 files changed, 26 insertions(+), 14 deletions(-) diff --git a/QMTest/TestSCons.py b/QMTest/TestSCons.py index 9434bb1..3c94dcd 100644 --- a/QMTest/TestSCons.py +++ b/QMTest/TestSCons.py @@ -34,7 +34,7 @@ from TestCmd import PIPE # here provides some independent verification that what we packaged # conforms to what we expect. -default_version = '2.3.1.alpha.yyyymmdd' +default_version = '2.3.3' python_version_unsupported = (2, 3, 0) python_version_deprecated = (2, 7, 0) diff --git a/README.rst b/README.rst index 35dc980..56c48e2 100644 --- a/README.rst +++ b/README.rst @@ -480,14 +480,14 @@ following packages will be built:: build/dist/scons-2.0.0-1.noarch.rpm build/dist/scons-2.0.0-1.src.rpm build/dist/scons-2.0.0.linux-i686.tar.gz - build/dist/scons-2.3.1.alpha.yyyymmdd.tar.gz - build/dist/scons-2.3.1.alpha.yyyymmdd.win32.exe - build/dist/scons-2.3.1.alpha.yyyymmdd.zip - build/dist/scons-doc-2.3.1.alpha.yyyymmdd.tar.gz - build/dist/scons-local-2.3.1.alpha.yyyymmdd.tar.gz - build/dist/scons-local-2.3.1.alpha.yyyymmdd.zip - build/dist/scons-src-2.3.1.alpha.yyyymmdd.tar.gz - build/dist/scons-src-2.3.1.alpha.yyyymmdd.zip + build/dist/scons-2.3.3.tar.gz + build/dist/scons-2.3.3.win32.exe + build/dist/scons-2.3.3.zip + build/dist/scons-doc-2.3.3.tar.gz + build/dist/scons-local-2.3.3.tar.gz + build/dist/scons-local-2.3.3.zip + build/dist/scons-src-2.3.3.tar.gz + build/dist/scons-src-2.3.3.zip build/dist/scons_1.3.0-1_all.deb The SConstruct file is supposed to be smart enough to avoid trying to build diff --git a/ReleaseConfig b/ReleaseConfig index 6da53b1..92a016c 100644 --- a/ReleaseConfig +++ b/ReleaseConfig @@ -32,7 +32,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" # 'final', the patchlevel is set to the release date. This value is # mandatory and must be present in this file. #version_tuple = (2, 2, 0, 'final', 0) -version_tuple = (2, 3, 1, 'alpha', 0) +version_tuple = (2, 3, 3) # Python versions prior to unsupported_python_version cause a fatal error # when that version is used. Python versions prior to deprecate_python_version diff --git a/SConstruct b/SConstruct index 3ab4d8c..d07c6cf 100644 --- a/SConstruct +++ b/SConstruct @@ -6,7 +6,7 @@ copyright_years = '2001 - 2014' # This gets inserted into the man pages to reflect the month of release. -month_year = 'MONTH YEAR' +month_year = 'August 2014' # # __COPYRIGHT__ @@ -43,7 +43,7 @@ import tempfile import bootstrap project = 'scons' -default_version = '2.3.1.alpha.yyyymmdd' +default_version = '2.3.3' copyright = "Copyright (c) %s The SCons Foundation" % copyright_years platform = distutils.util.get_platform() diff --git a/debian/changelog b/debian/changelog index ec049e1..5e4bf60 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,15 @@ +scons (2.3.3) unstable; urgency=low + + * Maintenance release. + + -- Gary Oberbrunner Sun, 24 Aug 2014 21:00:00 -0500 + +scons (2.3.2) unstable; urgency=low + + * Maintenance release. + + -- Gary Oberbrunner Fri, 4 July 2014 21:00:00 -0500 + scons (2.3.0) unstable; urgency=low * Maintenance release. diff --git a/src/Announce.txt b/src/Announce.txt index a749981..e741a20 100644 --- a/src/Announce.txt +++ b/src/Announce.txt @@ -19,7 +19,7 @@ effectively, please go to http://scons.org/lists.php#users to sign up for the scons-users mailing list. -RELEASE 2.3.2.alpha.yyyymmdd - NEW DATE WILL BE INSERTED HERE +RELEASE 2.3.3 - Sun, 24 Aug 2014 21:08:33 -0400 Please consult the RELEASE.txt file for a summary of changes since the last release and consult the CHANGES.txt file for complete a list of changes diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 7c5372e..f85e4a2 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -4,7 +4,7 @@ Change Log -RELEASE 2.3.2.alpha.yyyymmdd - NEW DATE WILL BE INSERTED HERE +RELEASE 2.3.3 - Sun, 24 Aug 2014 21:08:33 -0400 From Roland Stark: - Fixed false line length calculation in the TempFileMunge class (#2970). -- cgit v0.12 From bc08d4b6ce7e0d4ab554bcd79aca8627aa3521e8 Mon Sep 17 00:00:00 2001 From: Gary Oberbrunner Date: Sun, 24 Aug 2014 12:39:50 -0400 Subject: Put default branch back into develop mode for next release --- ReleaseConfig | 2 +- src/Announce.txt | 2 +- src/CHANGES.txt | 7 ++++ src/RELEASE.txt | 111 +++++++++++++++++++++++-------------------------------- 4 files changed, 56 insertions(+), 66 deletions(-) diff --git a/ReleaseConfig b/ReleaseConfig index 92a016c..9d06967 100644 --- a/ReleaseConfig +++ b/ReleaseConfig @@ -32,7 +32,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" # 'final', the patchlevel is set to the release date. This value is # mandatory and must be present in this file. #version_tuple = (2, 2, 0, 'final', 0) -version_tuple = (2, 3, 3) +version_tuple = (2, 3, 4, 'alpha', 0) # Python versions prior to unsupported_python_version cause a fatal error # when that version is used. Python versions prior to deprecate_python_version diff --git a/src/Announce.txt b/src/Announce.txt index e741a20..9ca047d 100644 --- a/src/Announce.txt +++ b/src/Announce.txt @@ -19,7 +19,7 @@ effectively, please go to http://scons.org/lists.php#users to sign up for the scons-users mailing list. -RELEASE 2.3.3 - Sun, 24 Aug 2014 21:08:33 -0400 +RELEASE VERSION/DATE TO BE FILLED IN LATER Please consult the RELEASE.txt file for a summary of changes since the last release and consult the CHANGES.txt file for complete a list of changes diff --git a/src/CHANGES.txt b/src/CHANGES.txt index f85e4a2..d516131 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -4,6 +4,13 @@ Change Log +RELEASE VERSION/DATE TO BE FILLED IN LATER + + From John Doe: + + - Whatever John Doe did. + + RELEASE 2.3.3 - Sun, 24 Aug 2014 21:08:33 -0400 From Roland Stark: diff --git a/src/RELEASE.txt b/src/RELEASE.txt index b5f226e..31c9590 100644 --- a/src/RELEASE.txt +++ b/src/RELEASE.txt @@ -1,90 +1,73 @@ - A new SCons release, 2.3.2, is now available + A new SCons checkpoint release, 2.3.4.alpha.yyyymmdd, is now available on the SCons download page: http://www.scons.org/download.php - This is a maintenance release, focusing on bug fixes. + XXX The primary purpose of this release ... XXX - Here is a summary of the changes since 2.3.2: + A SCons "checkpoint release" is intended to provide early access to + new features so they can be tested in the field before being released + for adoption by other software distributions. + + Note that a checkpoint release is developed using the same test-driven + development methodology as all SCons releases. Existing SCons + functionality should all work as it does in previous releases (except + for any changes identified in the release notes) and early adopters + should be able to use a checkpoint release safely for production work + with existing SConscript files. If not, it represents not only a bug + in SCons but also a hole in the regression test suite, and we want to + hear about it. + + New features may be more lightly tested than in past releases, + especially as concerns their interaction with all of the other + functionality in SCons. We are especially interested in hearing bug + reports about new functionality. + + We do not recommend that downstream distributions (Debian, Fedora, + etc.) package a checkpoint release, mainly to avoid confusing the + "public" release numbering with the long checkpoint release names. + + Here is a summary of the changes since 1.3.0: NEW FUNCTIONALITY - - Added Copy Action symlink soft-copy support (#2395). + - List new features (presumably why a checkpoint is being released) DEPRECATED FUNCTIONALITY - - None + - List anything that's been deprecated since the last release CHANGED/ENHANCED EXISTING FUNCTIONALITY - - Improved SWIG detection + - List modifications to existing features, where the previous behavior + wouldn't actually be considered a bug FIXES - - Fix regression on Windows in D language update - - Fixed the newglossary action to work with VariantDir (LaTeX). - - Added a default for the BUILDERS environment variable, - to prevent not defined exception on a Clone(). - - Fixed handling of CPPDEFINE var in Append() - for several list-dict combinations (#2900). + - List fixes of outright bugs + + IMPROVEMENTS + + - List improvements that wouldn't be visible to the user in the + documentation: performance improvements (describe the circumstances + under which they would be observed), or major code cleanups PACKAGING - - No changes + - List changes in the way SCons is packaged and/or released + + DOCUMENTATION + + - List any significant changes to the documentation (not individual + typo fixes, even if they're mentioned in src/CHANGES.txt to give + the contributor credit) DEVELOPMENT - - Do not fail on EnsureSConsVersion when running from checkout - -Thanks to: - Dirk Baechle, - Vincent Beffar, - Thomas Berg, - William Blevins, - Kendrick Boyd, - Antonio Cavallo, - Jean-François Colson, - Bauke Conijn, - Bill Deegan, - Ken Deeter, - dubcanada on Bitbucket, - Luca Falavigna, - Andrew Featherstone, - Alexandre Feblot, - Shane Gannon, - Alexander Goomenyuk, - Justin Gullingsrud, - Michael Haubenwallner, - Joshua Hughes, - Alexey Klimkin, - Steven Knight, - Arve Knudsen, - Philipp Kraus, - Jean-Baptiste Lab, - Juan Lang, - Rob Managan, - Michael McDougall, - Mortoray, - Manuel Francisco Naranjo, - Gary Oberbrunner, - Alexey Petruchik, - Evgeny Podjachev, - David Rothenberger, - smallbub on Bitbucket, - Sohail Somani, - Stefan Sperling, - Amir Szekely, - Tom Tanner, - Anatoly Techtonik, - Bogdan Tenea, - Paweł Tomulik, - Sye van der Veen, - veon on bitbucket, - Greg Ward, - Allen Weeks, - Russel Winder, - Joe Zuntz - for their contributions to this and prior releases. + - List visible changes in the way SCons is developed + + Thanks to CURLY, LARRY, and MOE for their contributions to this release. + Contributors are listed alphabetically by their last name. __COPYRIGHT__ __FILE__ __REVISION__ __DATE__ __DEVELOPER__ -- cgit v0.12 From b5b79f13edf2c4d7f046a6a373579bb8cf7a873e Mon Sep 17 00:00:00 2001 From: anatoly techtonik Date: Mon, 25 Aug 2014 01:25:28 +0300 Subject: 0.3 - fixed used imports that failed on Python 2.6 Crash evidence: http://buildbot.scons.org/builders/debian6-python-2.6/builds/54/steps/shell/logs/stdio --- testing/framework/TestUnit/taprunner.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/testing/framework/TestUnit/taprunner.py b/testing/framework/TestUnit/taprunner.py index 31eb963..5c2e87c 100644 --- a/testing/framework/TestUnit/taprunner.py +++ b/testing/framework/TestUnit/taprunner.py @@ -6,13 +6,21 @@ Public domain work by: anatoly techtonik Changes: + 0.3 - fixed used imports that failed on Python 2.6 0.2 - removed unused import that failed on Python 2.6 0.1 - initial release """ -from unittest.runner import TextTestRunner, TextTestResult +__version__ = "0.3" + + +from unittest import TextTestRunner +try: + from unittest import TextTestResult +except ImportError: + # Python 2.6 + from unittest import _TextTestResult as TextTestResult -__version__ = "0.2" class TAPTestResult(TextTestResult): -- cgit v0.12 From ade8f8c0aa199049d46d2b19a73964d9fd3c78ef Mon Sep 17 00:00:00 2001 From: William Blevins Date: Wed, 27 Aug 2014 21:14:22 -0400 Subject: Issue 2395: Updated tests to be skipped on systems without os.symlink functionality. Apparently, the SConsTest.symlink behavior doesn't give any success/fail feedback. --- test/Copy-Symlinks.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/test/Copy-Symlinks.py b/test/Copy-Symlinks.py index f8f92d7..35e4aa0 100644 --- a/test/Copy-Symlinks.py +++ b/test/Copy-Symlinks.py @@ -36,6 +36,9 @@ import TestSCons import SCons.Defaults SCons.Defaults.DefaultEnvironment( tools = [] ) +if not hasattr(os, 'symlink'): + test.skip_test('No os.symlink() method, no symlinks to test.\n') + test = TestSCons.TestSCons() filelinkToCopy = 'filelinkToCopy' @@ -48,13 +51,10 @@ treelinkToCopy = 'treelinkToCopy' badToLink = 'None' # do not write this item badlinkToCopy = 'badlinkToCopy' -try: - test.symlink( fileToLink, filelinkToCopy ) - test.symlink( dirToLink, dirlinkToCopy ) - test.symlink( treeToLink, treelinkToCopy ) - test.symlink( badToLink, badlinkToCopy ) -except: - test.no_result() +test.symlink( fileToLink, filelinkToCopy ) +test.symlink( dirToLink, dirlinkToCopy ) +test.symlink( treeToLink, treelinkToCopy ) +test.symlink( badToLink, badlinkToCopy ) test.write( fileToLink, fileContents ) test.subdir( dirToLink ) -- cgit v0.12 From e6451df2f5ac7b86b9a93c787a9ef70e9ffd06f0 Mon Sep 17 00:00:00 2001 From: Dirk Baechle Date: Sun, 31 Aug 2014 20:50:05 +0200 Subject: - added import of libxslt binding to DocBook tests --- doc/SConscript | 1 + test/Docbook/basedir/htmlchunked/htmlchunked.py | 1 + test/Docbook/basedir/htmlhelp/htmlhelp.py | 1 + test/Docbook/basedir/slideshtml/slideshtml.py | 1 + test/Docbook/basic/epub/epub.py | 1 + test/Docbook/basic/html/html.py | 1 + test/Docbook/basic/htmlchunked/htmlchunked.py | 1 + test/Docbook/basic/htmlhelp/htmlhelp.py | 1 + test/Docbook/basic/man/man.py | 1 + test/Docbook/basic/slideshtml/slideshtml.py | 1 + test/Docbook/basic/xinclude/xinclude.py | 1 + test/Docbook/dependencies/xinclude/xinclude.py | 1 + test/Docbook/rootname/htmlchunked/htmlchunked.py | 1 + test/Docbook/rootname/htmlhelp/htmlhelp.py | 1 + test/Docbook/rootname/slideshtml/slideshtml.py | 1 + 15 files changed, 15 insertions(+) diff --git a/doc/SConscript b/doc/SConscript index b82d63b..7880ba3 100644 --- a/doc/SConscript +++ b/doc/SConscript @@ -82,6 +82,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. skip_doc = False try: import libxml2 + import libxslt except: try: import lxml diff --git a/test/Docbook/basedir/htmlchunked/htmlchunked.py b/test/Docbook/basedir/htmlchunked/htmlchunked.py index cf5f3d1..f97555b 100644 --- a/test/Docbook/basedir/htmlchunked/htmlchunked.py +++ b/test/Docbook/basedir/htmlchunked/htmlchunked.py @@ -38,6 +38,7 @@ if not (sys.platform.startswith('linux') and try: import libxml2 + import libxslt except: try: import lxml diff --git a/test/Docbook/basedir/htmlhelp/htmlhelp.py b/test/Docbook/basedir/htmlhelp/htmlhelp.py index 22bbd72..17aba09 100644 --- a/test/Docbook/basedir/htmlhelp/htmlhelp.py +++ b/test/Docbook/basedir/htmlhelp/htmlhelp.py @@ -38,6 +38,7 @@ if not (sys.platform.startswith('linux') and try: import libxml2 + import libxslt except: try: import lxml diff --git a/test/Docbook/basedir/slideshtml/slideshtml.py b/test/Docbook/basedir/slideshtml/slideshtml.py index a2375e4..a89edcd 100644 --- a/test/Docbook/basedir/slideshtml/slideshtml.py +++ b/test/Docbook/basedir/slideshtml/slideshtml.py @@ -39,6 +39,7 @@ if not (sys.platform.startswith('linux') and try: import libxml2 + import libxslt except: try: import lxml diff --git a/test/Docbook/basic/epub/epub.py b/test/Docbook/basic/epub/epub.py index 19e08a0..0a317b6 100644 --- a/test/Docbook/basic/epub/epub.py +++ b/test/Docbook/basic/epub/epub.py @@ -32,6 +32,7 @@ test = TestSCons.TestSCons() try: import libxml2 + import libxslt except: try: import lxml diff --git a/test/Docbook/basic/html/html.py b/test/Docbook/basic/html/html.py index 0cb4fb6..acf38a3 100644 --- a/test/Docbook/basic/html/html.py +++ b/test/Docbook/basic/html/html.py @@ -32,6 +32,7 @@ test = TestSCons.TestSCons() try: import libxml2 + import libxslt except: try: import lxml diff --git a/test/Docbook/basic/htmlchunked/htmlchunked.py b/test/Docbook/basic/htmlchunked/htmlchunked.py index 46cc8dc..74b8c7a 100644 --- a/test/Docbook/basic/htmlchunked/htmlchunked.py +++ b/test/Docbook/basic/htmlchunked/htmlchunked.py @@ -32,6 +32,7 @@ test = TestSCons.TestSCons() try: import libxml2 + import libxslt except: try: import lxml diff --git a/test/Docbook/basic/htmlhelp/htmlhelp.py b/test/Docbook/basic/htmlhelp/htmlhelp.py index 9b00bbd..080ec60 100644 --- a/test/Docbook/basic/htmlhelp/htmlhelp.py +++ b/test/Docbook/basic/htmlhelp/htmlhelp.py @@ -32,6 +32,7 @@ test = TestSCons.TestSCons() try: import libxml2 + import libxslt except: try: import lxml diff --git a/test/Docbook/basic/man/man.py b/test/Docbook/basic/man/man.py index c1f164d..d9b16b3 100644 --- a/test/Docbook/basic/man/man.py +++ b/test/Docbook/basic/man/man.py @@ -32,6 +32,7 @@ test = TestSCons.TestSCons() try: import libxml2 + import libxslt except: try: import lxml diff --git a/test/Docbook/basic/slideshtml/slideshtml.py b/test/Docbook/basic/slideshtml/slideshtml.py index 37c2be0..8251b3e 100644 --- a/test/Docbook/basic/slideshtml/slideshtml.py +++ b/test/Docbook/basic/slideshtml/slideshtml.py @@ -39,6 +39,7 @@ if not (sys.platform.startswith('linux') and try: import libxml2 + import libxslt except: try: import lxml diff --git a/test/Docbook/basic/xinclude/xinclude.py b/test/Docbook/basic/xinclude/xinclude.py index 2d87713..302c777 100644 --- a/test/Docbook/basic/xinclude/xinclude.py +++ b/test/Docbook/basic/xinclude/xinclude.py @@ -32,6 +32,7 @@ test = TestSCons.TestSCons() try: import libxml2 + import libxslt except: try: import lxml diff --git a/test/Docbook/dependencies/xinclude/xinclude.py b/test/Docbook/dependencies/xinclude/xinclude.py index 84d9ce7..115163c 100644 --- a/test/Docbook/dependencies/xinclude/xinclude.py +++ b/test/Docbook/dependencies/xinclude/xinclude.py @@ -32,6 +32,7 @@ test = TestSCons.TestSCons() try: import libxml2 + import libxslt except: try: import lxml diff --git a/test/Docbook/rootname/htmlchunked/htmlchunked.py b/test/Docbook/rootname/htmlchunked/htmlchunked.py index 8ab91d2..65b50ef 100644 --- a/test/Docbook/rootname/htmlchunked/htmlchunked.py +++ b/test/Docbook/rootname/htmlchunked/htmlchunked.py @@ -38,6 +38,7 @@ if not (sys.platform.startswith('linux') and try: import libxml2 + import libxslt except: try: import lxml diff --git a/test/Docbook/rootname/htmlhelp/htmlhelp.py b/test/Docbook/rootname/htmlhelp/htmlhelp.py index ee37e1a..9d0b076 100644 --- a/test/Docbook/rootname/htmlhelp/htmlhelp.py +++ b/test/Docbook/rootname/htmlhelp/htmlhelp.py @@ -38,6 +38,7 @@ if not (sys.platform.startswith('linux') and try: import libxml2 + import libxslt except: try: import lxml diff --git a/test/Docbook/rootname/slideshtml/slideshtml.py b/test/Docbook/rootname/slideshtml/slideshtml.py index 4d55035..399764b 100644 --- a/test/Docbook/rootname/slideshtml/slideshtml.py +++ b/test/Docbook/rootname/slideshtml/slideshtml.py @@ -39,6 +39,7 @@ if not (sys.platform.startswith('linux') and try: import libxml2 + import libxslt except: try: import lxml -- cgit v0.12 From 074a3c0d96b7a02284b3c67d837d3753731e68c8 Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Fri, 5 Sep 2014 18:46:26 +0100 Subject: Remove the setting of the ENV property to os.environ. --- src/engine/SCons/Tool/gdc.py | 6 +++--- src/engine/SCons/Tool/ldc.py | 2 +- test/D/CoreScanner/Image/SConstruct_template | 1 - test/D/DMD.py | 2 +- test/D/DMD2.py | 2 +- test/D/DMD2_Alt.py | 2 +- test/D/GDC.py | 2 +- test/D/GDC_Alt.py | 2 +- test/D/HSTeoh/LinkingProblem/SConstruct_template | 3 +-- .../HSTeoh/SingleStringCannotBeMultipleOptions/SConstruct_template | 1 - test/D/HelloWorld/CompileAndLinkOneStep/Image/SConstruct_template | 1 - test/D/HelloWorld/CompileThenLinkTwoSteps/Image/SConstruct_template | 1 - test/D/LDC.py | 2 +- test/D/LDC_Alt.py | 2 +- test/D/MixedDAndC/Image/SConstruct | 1 - 15 files changed, 12 insertions(+), 18 deletions(-) diff --git a/src/engine/SCons/Tool/gdc.py b/src/engine/SCons/Tool/gdc.py index 1178b85..048d736 100644 --- a/src/engine/SCons/Tool/gdc.py +++ b/src/engine/SCons/Tool/gdc.py @@ -95,9 +95,9 @@ def generate(env): env['DLINKFLAGS'] = SCons.Util.CLVar('') env['DLINKCOM'] = '$DLINK -o $TARGET $DLINKFLAGS $__RPATH $SOURCES $_LIBDIRFLAGS $_LIBFLAGS' - env['SHDLINK'] = '$DC' - env['SHDLINKFLAGS'] = SCons.Util.CLVar('$DLINKFLAGS -shared') - env['SHDLINKCOM'] = '$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 '') diff --git a/src/engine/SCons/Tool/ldc.py b/src/engine/SCons/Tool/ldc.py index 6b215e2..6b080e6 100644 --- a/src/engine/SCons/Tool/ldc.py +++ b/src/engine/SCons/Tool/ldc.py @@ -101,7 +101,7 @@ def generate(env): env['DLINKCOM'] = '$DLINK -of=$TARGET $DLINKFLAGS $__DRPATH $SOURCES $_DLIBDIRFLAGS $_DLIBFLAGS' env['DSHLINK'] = '$DC' - env['DSHLINKFLAGS'] = SCons.Util.CLVar('$DLINKFLAGS -shared') + 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' diff --git a/test/D/CoreScanner/Image/SConstruct_template b/test/D/CoreScanner/Image/SConstruct_template index a128c67..e91343b 100644 --- a/test/D/CoreScanner/Image/SConstruct_template +++ b/test/D/CoreScanner/Image/SConstruct_template @@ -3,7 +3,6 @@ import os environment = Environment( - ENV=os.environ, tools=['link', '{}']) environment.Program('test1.d') environment.Program('test2.d') diff --git a/test/D/DMD.py b/test/D/DMD.py index 1bde380..4b1c125 100644 --- a/test/D/DMD.py +++ b/test/D/DMD.py @@ -37,7 +37,7 @@ if not dmd: test.write('SConstruct', """\ import os -env = Environment(ENV=os.environ) +env = Environment() if env['PLATFORM'] == 'cygwin': env['OBJSUFFIX'] = '.obj' # trick DMD env.Program('foo', 'foo.d') """) diff --git a/test/D/DMD2.py b/test/D/DMD2.py index cc8ab93..3634d88 100644 --- a/test/D/DMD2.py +++ b/test/D/DMD2.py @@ -36,7 +36,7 @@ if not test.where_is('dmd') and not test.where_is('gdmd'): test.write('SConstruct', """\ import os -env = Environment(tools=['link', 'dmd'], ENV=os.environ) +env = Environment(tools=['link', 'dmd']) if env['PLATFORM'] == 'cygwin': env['OBJSUFFIX'] = '.obj' # trick DMD env.Program('foo', 'foo.d') """) diff --git a/test/D/DMD2_Alt.py b/test/D/DMD2_Alt.py index fbe2f2b..27b21d0 100644 --- a/test/D/DMD2_Alt.py +++ b/test/D/DMD2_Alt.py @@ -36,7 +36,7 @@ if not test.where_is('dmd') and not test.where_is('gdmd'): test.write('SConstruct', """\ import os -env = Environment(tools=['dmd', 'link'], ENV=os.environ) +env = Environment(tools=['dmd', 'link']) if env['PLATFORM'] == 'cygwin': env['OBJSUFFIX'] = '.obj' # trick DMD env.Program('foo', 'foo.d') """) diff --git a/test/D/GDC.py b/test/D/GDC.py index e24ec43..b548b94 100644 --- a/test/D/GDC.py +++ b/test/D/GDC.py @@ -36,7 +36,7 @@ if not test.where_is('gdc'): test.write('SConstruct', """\ import os -env = Environment(tools=['link', 'gdc'], ENV=os.environ) +env = Environment(tools=['link', 'gdc']) if env['PLATFORM'] == 'cygwin': env['OBJSUFFIX'] = '.obj' # trick DMD env.Program('foo', 'foo.d') """) diff --git a/test/D/GDC_Alt.py b/test/D/GDC_Alt.py index cac7949..27159ee 100644 --- a/test/D/GDC_Alt.py +++ b/test/D/GDC_Alt.py @@ -36,7 +36,7 @@ if not test.where_is('gdc'): test.write('SConstruct', """\ import os -env = Environment(tools=['gdc', 'link'], ENV=os.environ) +env = Environment(tools=['gdc', 'link']) if env['PLATFORM'] == 'cygwin': env['OBJSUFFIX'] = '.obj' # trick DMD env.Program('foo', 'foo.d') """) diff --git a/test/D/HSTeoh/LinkingProblem/SConstruct_template b/test/D/HSTeoh/LinkingProblem/SConstruct_template index 6815cdf..a4aa795 100644 --- a/test/D/HSTeoh/LinkingProblem/SConstruct_template +++ b/test/D/HSTeoh/LinkingProblem/SConstruct_template @@ -3,8 +3,7 @@ import os environment = Environment( - ENV=os.environ, - tools = ['cc', 'link' , '{}'], + tools = ['cc', '{}', 'link'], LIBS = ['ncurses']) environment.Object('ncurs_impl.o', 'ncurs_impl.c') diff --git a/test/D/HSTeoh/SingleStringCannotBeMultipleOptions/SConstruct_template b/test/D/HSTeoh/SingleStringCannotBeMultipleOptions/SConstruct_template index 89c603b..118a7b2 100644 --- a/test/D/HSTeoh/SingleStringCannotBeMultipleOptions/SConstruct_template +++ b/test/D/HSTeoh/SingleStringCannotBeMultipleOptions/SConstruct_template @@ -3,7 +3,6 @@ import os environment = Environment( - ENV=os.environ, tools=['link', '{}'], # It might be thought that a single string can contain multiple options space separated. Actually this # is deemed to be a single option, so leads to an error. diff --git a/test/D/HelloWorld/CompileAndLinkOneStep/Image/SConstruct_template b/test/D/HelloWorld/CompileAndLinkOneStep/Image/SConstruct_template index c688ab7..e2e7439 100644 --- a/test/D/HelloWorld/CompileAndLinkOneStep/Image/SConstruct_template +++ b/test/D/HelloWorld/CompileAndLinkOneStep/Image/SConstruct_template @@ -3,7 +3,6 @@ import os environment = Environment( - ENV=os.environ, tools=['link', '{}']) environment.Program('helloWorld.d') diff --git a/test/D/HelloWorld/CompileThenLinkTwoSteps/Image/SConstruct_template b/test/D/HelloWorld/CompileThenLinkTwoSteps/Image/SConstruct_template index 425970a..b38a9f0 100644 --- a/test/D/HelloWorld/CompileThenLinkTwoSteps/Image/SConstruct_template +++ b/test/D/HelloWorld/CompileThenLinkTwoSteps/Image/SConstruct_template @@ -3,7 +3,6 @@ import os environment = Environment( - ENV=os.environ, tools=['link', '{}']) objects = environment.Object('helloWorld.d') diff --git a/test/D/LDC.py b/test/D/LDC.py index 94acf1c..19070a5 100644 --- a/test/D/LDC.py +++ b/test/D/LDC.py @@ -43,7 +43,7 @@ if not isExecutableOfToolAvailable(test, 'ldc'): test.write('SConstruct', """\ import os -env = Environment(tools=['link', 'ldc'], ENV=os.environ) +env = Environment(tools=['link', 'ldc']) if env['PLATFORM'] == 'cygwin': env['OBJSUFFIX'] = '.obj' # trick DMD env.Program('foo', 'foo.d') """) diff --git a/test/D/LDC_Alt.py b/test/D/LDC_Alt.py index 571b8f0..bca7dd6 100644 --- a/test/D/LDC_Alt.py +++ b/test/D/LDC_Alt.py @@ -43,7 +43,7 @@ if not isExecutableOfToolAvailable(test, 'ldc'): test.write('SConstruct', """\ import os -env = Environment(tools=['ldc', 'link'], ENV=os.environ) +env = Environment(tools=['ldc', 'link']) if env['PLATFORM'] == 'cygwin': env['OBJSUFFIX'] = '.obj' # trick DMD env.Program('foo', 'foo.d') """) diff --git a/test/D/MixedDAndC/Image/SConstruct b/test/D/MixedDAndC/Image/SConstruct index 47870d7..5cf58a3 100644 --- a/test/D/MixedDAndC/Image/SConstruct +++ b/test/D/MixedDAndC/Image/SConstruct @@ -3,7 +3,6 @@ import os environment = Environment( - ENV=os.environ, DFLAGS=['-m64', '-O']) environment.Program('proj', [ -- cgit v0.12 From ea1898b916bbaceab6ecff490b51606ba0b311dc Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Fri, 5 Sep 2014 18:47:51 +0100 Subject: The tests for the changes already commited to the tools for dealing with shared libraries. --- test/D/SharedObjects/Common/__init__.py | 0 test/D/SharedObjects/Common/common.py | 80 ++++++++++++++++++++++++++ test/D/SharedObjects/Common/sconstest.skip | 0 test/D/SharedObjects/Image/SConstruct_template | 8 +++ test/D/SharedObjects/Image/code.d | 3 + test/D/SharedObjects/sconstest-dmd.py | 37 ++++++++++++ test/D/SharedObjects/sconstest-gdc.py | 40 +++++++++++++ test/D/SharedObjects/sconstest-ldc.py | 37 ++++++++++++ 8 files changed, 205 insertions(+) create mode 100644 test/D/SharedObjects/Common/__init__.py create mode 100644 test/D/SharedObjects/Common/common.py create mode 100644 test/D/SharedObjects/Common/sconstest.skip create mode 100644 test/D/SharedObjects/Image/SConstruct_template create mode 100644 test/D/SharedObjects/Image/code.d create mode 100644 test/D/SharedObjects/sconstest-dmd.py create mode 100644 test/D/SharedObjects/sconstest-gdc.py create mode 100644 test/D/SharedObjects/sconstest-ldc.py diff --git a/test/D/SharedObjects/Common/__init__.py b/test/D/SharedObjects/Common/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/test/D/SharedObjects/Common/common.py b/test/D/SharedObjects/Common/common.py new file mode 100644 index 0000000..a5d7b27 --- /dev/null +++ b/test/D/SharedObjects/Common/common.py @@ -0,0 +1,80 @@ +""" +Support functions for all the tests. +""" + +# +# __COPYRIGHT__ +# +# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import TestSCons + +from SCons.Environment import Base + +from os.path import abspath, dirname + +import sys +sys.path.insert(1, abspath(dirname(__file__) + '/../../Support')) + +from executablesSearch import isExecutableOfToolAvailable + +def testForTool(tool): + + test = TestSCons.TestSCons() + + if not isExecutableOfToolAvailable(test, tool) : + test.skip_test("Required executable for tool '{}' not found, skipping test.\n".format(tool)) + + test.dir_fixture('Image') + test.write('SConstruct', open('SConstruct_template', 'r').read().format(tool)) + + if tool == 'dmd': + # The gdmd executable in Debian Unstable as at 2012-05-12, version 4.6.3 puts out messages on stderr + # that cause inappropriate failure of the tests, so simply ignore them. + test.run(stderr=None) + else: + test.run() + + platform = Base()['PLATFORM'] + if platform == 'posix': + filename = 'code.o' + libraryname = 'libanswer.so' + elif platform == 'darwin': + filename = 'code.o' + libraryname = 'libanswer.dylib' + elif platform == 'win32' or platform == 'win64': + filename = 'code.obj' + libraryname = 'answer.dll' + else: + test.fail_test() + + test.must_exist(test.workpath(filename)) + test.must_exist(test.workpath(libraryname)) + + test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/D/SharedObjects/Common/sconstest.skip b/test/D/SharedObjects/Common/sconstest.skip new file mode 100644 index 0000000..e69de29 diff --git a/test/D/SharedObjects/Image/SConstruct_template b/test/D/SharedObjects/Image/SConstruct_template new file mode 100644 index 0000000..213de7e --- /dev/null +++ b/test/D/SharedObjects/Image/SConstruct_template @@ -0,0 +1,8 @@ +# -*- mode:python; coding:utf-8; -*- + +import os + +environment = Environment( + tools=['{}', 'link']) + +environment.SharedLibrary('answer', 'code.d') diff --git a/test/D/SharedObjects/Image/code.d b/test/D/SharedObjects/Image/code.d new file mode 100644 index 0000000..0d9d1d7 --- /dev/null +++ b/test/D/SharedObjects/Image/code.d @@ -0,0 +1,3 @@ +int returnTheAnswer() { + return 42; +} diff --git a/test/D/SharedObjects/sconstest-dmd.py b/test/D/SharedObjects/sconstest-dmd.py new file mode 100644 index 0000000..df6ddeb --- /dev/null +++ b/test/D/SharedObjects/sconstest-dmd.py @@ -0,0 +1,37 @@ +""" +Test compiling and executing using the dmd tool. +""" + +# +# __COPYRIGHT__ +# +# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +from Common.common import testForTool +testForTool('dmd') + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/D/SharedObjects/sconstest-gdc.py b/test/D/SharedObjects/sconstest-gdc.py new file mode 100644 index 0000000..7d0f28c --- /dev/null +++ b/test/D/SharedObjects/sconstest-gdc.py @@ -0,0 +1,40 @@ +""" +Test compiling and executing using the gcd tool. +""" + +# +# __COPYRIGHT__ +# +# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import TestSCons +TestSCons.TestSCons().skip_test('SKIPPED... gdc does not, as at version 4.9.1, support shared libraries.\n') + +from Common.common import testForTool +testForTool('gdc') + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/D/SharedObjects/sconstest-ldc.py b/test/D/SharedObjects/sconstest-ldc.py new file mode 100644 index 0000000..f61efbc --- /dev/null +++ b/test/D/SharedObjects/sconstest-ldc.py @@ -0,0 +1,37 @@ +""" +Test compiling and executing using the ldc tool. +""" + +# +# __COPYRIGHT__ +# +# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +from Common.common import testForTool +testForTool('ldc') + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: -- cgit v0.12 From 87cb9ca579c9e8cc2d972552f8db6590b991cdeb Mon Sep 17 00:00:00 2001 From: Dirk Baechle Date: Sat, 6 Sep 2014 12:27:56 +0200 Subject: - additional fixes to get all tests pass on the Fedora20 box --- src/engine/SCons/Tool/ldc.py | 2 +- test/sconsign/script/Configure.py | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/engine/SCons/Tool/ldc.py b/src/engine/SCons/Tool/ldc.py index 6b215e2..fa50060 100644 --- a/src/engine/SCons/Tool/ldc.py +++ b/src/engine/SCons/Tool/ldc.py @@ -126,7 +126,7 @@ def generate(env): # platform supports it. env['DRPATHPREFIX'] = '-L-rpath=' env['DRPATHSUFFIX'] = '' - env['_RPATH'] = '${_concat(DRPATHPREFIX, RPATH, DRPATHSUFFIX, __env__)}' + env['_DRPATH'] = '${_concat(DRPATHPREFIX, RPATH, DRPATHSUFFIX, __env__)}' SCons.Tool.createStaticLibBuilder(env) diff --git a/test/sconsign/script/Configure.py b/test/sconsign/script/Configure.py index 3b43def..679f084 100644 --- a/test/sconsign/script/Configure.py +++ b/test/sconsign/script/Configure.py @@ -58,9 +58,8 @@ CC_file = re.escape(CC_file) _sconf_temp_conftest_0_c = '.sconf_temp/conftest_0.c' test.write('SConstruct', """ -env = Environment() import os -env.AppendENVPath('PATH', os.environ['PATH']) +env = Environment(ENV={'PATH' : os.environ.get('PATH','')}) conf = Configure(env) r1 = conf.CheckCHeader( 'math.h' ) env = conf.Finish() -- cgit v0.12 From 414cb583cf31b2a8c65704e57dd19cfb865e6582 Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Sat, 6 Sep 2014 15:38:18 +0100 Subject: Amend the executable search support function to use the default SCons path only. --- test/D/Support/executablesSearch.py | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/test/D/Support/executablesSearch.py b/test/D/Support/executablesSearch.py index e0487f6..17d9990 100755 --- a/test/D/Support/executablesSearch.py +++ b/test/D/Support/executablesSearch.py @@ -29,39 +29,60 @@ Support functions for all the tests. __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" +if __name__ == '__main__': + import sys + import os.path + sys.path.append(os.path.abspath('../../../src/engine')) + +from SCons.Environment import Base + +path = Base()['ENV']['PATH'] + def isExecutableOfToolAvailable(test, tool): for executable in { 'dmd': ['dmd', 'gdmd'], 'gdc': ['gdc'], - 'ldc': ['ldc2', 'ldc']}[tool]: - if test.where_is(executable): + 'ldc': ['ldc2', 'ldc'], + }[tool]: + if test.where_is(executable, path): return True return False + if __name__ == '__main__': import unittest - import sys - import os.path sys.path.append(os.path.abspath('../../../QMTest')) - sys.path.append(os.path.abspath('../../../src/engine')) + import TestSCons class VariousTests(unittest.TestCase): + ''' + These tests are somewhat self referential in that + isExecutableOfToolAvailable uses where_is to do most of it's + work and we use the same function in the tests. + ''' def setUp(self): self.test = TestSCons.TestSCons() + + def tearDown(self): + self.test = None + def test_None_tool(self): self.assertRaises(KeyError, isExecutableOfToolAvailable, self.test, None) + def test_dmd_tool(self): self.assertEqual( - self.test.where_is('dmd') is not None or self.test.where_is('gdmd') is not None, + self.test.where_is('dmd', path) is not None or self.test.where_is('gdmd', path) is not None, isExecutableOfToolAvailable(self.test, 'dmd')) + def test_gdc_tool(self): self.assertEqual( - self.test.where_is('gdc') is not None, + self.test.where_is('gdc', path) is not None, isExecutableOfToolAvailable(self.test, 'gdc')) + def test_ldc_tool(self): self.assertEqual( - self.test.where_is('ldc2') is not None or self.test.where_is('ldc') is not None, + self.test.where_is('ldc2', path) is not None or self.test.where_is('ldc', path) is not None, isExecutableOfToolAvailable(self.test, 'ldc')) unittest.main() -- cgit v0.12 From 70a6365e0bcf530819a83edaa3b9d9bbc08b218e Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Sat, 6 Sep 2014 16:25:28 +0100 Subject: Deal better with the discovery of a suitable D compiler executable. --- test/D/DMD.py | 8 ++++++-- test/D/DMD2.py | 9 +++++++-- test/D/DMD2_Alt.py | 9 +++++++-- .../Issues/2939_Ariovistus/Common/correctLinkOptions.py | 16 +++++++++++++++- .../Issues/2940_Ariovistus/Common/correctLinkOptions.py | 16 +++++++++++++++- test/D/Scanner.py | 8 ++++++-- 6 files changed, 56 insertions(+), 10 deletions(-) diff --git a/test/D/DMD.py b/test/D/DMD.py index 4b1c125..2d9333a 100644 --- a/test/D/DMD.py +++ b/test/D/DMD.py @@ -28,11 +28,15 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import TestSCons +import sys +from os.path import abspath, dirname, join +sys.path.append(join(dirname(abspath(__file__)), 'Support')) +from executablesSearch import isExecutableOfToolAvailable + _exe = TestSCons._exe test = TestSCons.TestSCons() -dmd = test.where_is('dmd') -if not dmd: +if not isExecutableOfToolAvailable(test, 'dmd'): test.skip_test("Could not find 'dmd'; skipping test.\n") test.write('SConstruct', """\ diff --git a/test/D/DMD2.py b/test/D/DMD2.py index 3634d88..fc5f79f 100644 --- a/test/D/DMD2.py +++ b/test/D/DMD2.py @@ -28,11 +28,16 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import TestSCons +import sys +from os.path import abspath, dirname, join +sys.path.append(join(dirname(abspath(__file__)), 'Support')) +from executablesSearch import isExecutableOfToolAvailable + _exe = TestSCons._exe test = TestSCons.TestSCons() -if not test.where_is('dmd') and not test.where_is('gdmd'): - test.skip_test("Could not find 'dmd' or 'gdmd', skipping test.\n") +if not isExecutableOfToolAvailable(test, 'dmd'): + test.skip_test("Could not find 'dmd'; skipping test.\n") test.write('SConstruct', """\ import os diff --git a/test/D/DMD2_Alt.py b/test/D/DMD2_Alt.py index 27b21d0..11c061d 100644 --- a/test/D/DMD2_Alt.py +++ b/test/D/DMD2_Alt.py @@ -28,11 +28,16 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import TestSCons +import sys +from os.path import abspath, dirname, join +sys.path.append(join(dirname(abspath(__file__)), 'Support')) +from executablesSearch import isExecutableOfToolAvailable + _exe = TestSCons._exe test = TestSCons.TestSCons() -if not test.where_is('dmd') and not test.where_is('gdmd'): - test.skip_test("Could not find 'dmd' or 'gdmd', skipping test.\n") +if not isExecutableOfToolAvailable(test, 'dmd'): + test.skip_test("Could not find 'dmd'; skipping test.\n") test.write('SConstruct', """\ import os diff --git a/test/D/Issues/2939_Ariovistus/Common/correctLinkOptions.py b/test/D/Issues/2939_Ariovistus/Common/correctLinkOptions.py index 3b178b9..d44c9bd 100644 --- a/test/D/Issues/2939_Ariovistus/Common/correctLinkOptions.py +++ b/test/D/Issues/2939_Ariovistus/Common/correctLinkOptions.py @@ -50,7 +50,21 @@ def testForTool(tool): test.run() - for f in ('libstuff.so', 'stuff.os', 'test1', 'test1.o', 'test2', 'test2.o'): + platform = Base()['PLATFORM'] + + if platform == 'posix': + libraryname = 'libstuff.so' + filename = 'stuff.os' + elif platform == 'darwin': + libraryname = 'libstuff.dylib' + filename = 'stuff.os' + elif platform == 'win32': + libraryname = 'stuff.dll' + filename = 'stuff.obj' + else: + test.fail_test('No information about platform: ' + platform) + + for f in (libraryname, filename, 'test1', 'test1.o', 'test2', 'test2.o'): test.must_exist(test.workpath(join('test', 'test1', f))) test.pass_test() diff --git a/test/D/Issues/2940_Ariovistus/Common/correctLinkOptions.py b/test/D/Issues/2940_Ariovistus/Common/correctLinkOptions.py index 3b178b9..d44c9bd 100644 --- a/test/D/Issues/2940_Ariovistus/Common/correctLinkOptions.py +++ b/test/D/Issues/2940_Ariovistus/Common/correctLinkOptions.py @@ -50,7 +50,21 @@ def testForTool(tool): test.run() - for f in ('libstuff.so', 'stuff.os', 'test1', 'test1.o', 'test2', 'test2.o'): + platform = Base()['PLATFORM'] + + if platform == 'posix': + libraryname = 'libstuff.so' + filename = 'stuff.os' + elif platform == 'darwin': + libraryname = 'libstuff.dylib' + filename = 'stuff.os' + elif platform == 'win32': + libraryname = 'stuff.dll' + filename = 'stuff.obj' + else: + test.fail_test('No information about platform: ' + platform) + + for f in (libraryname, filename, 'test1', 'test1.o', 'test2', 'test2.o'): test.must_exist(test.workpath(join('test', 'test1', f))) test.pass_test() diff --git a/test/D/Scanner.py b/test/D/Scanner.py index 48af057..b005adf 100644 --- a/test/D/Scanner.py +++ b/test/D/Scanner.py @@ -31,12 +31,16 @@ a single statement. import TestSCons +import sys +from os.path import abspath, dirname, join +sys.path.append(join(dirname(abspath(__file__)), 'Support')) +from executablesSearch import isExecutableOfToolAvailable + test = TestSCons.TestSCons() _obj = TestSCons._obj -dmd = test.where_is('dmd') -if not dmd: +if not isExecutableOfToolAvailable(test, 'dmd'): test.skip_test("Could not find 'dmd'; skipping test.\n") test.subdir(['p']) -- cgit v0.12 From a7cd008ff19d54fc63f8a22cbec00d12e743c800 Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Sun, 14 Sep 2014 17:27:51 +0100 Subject: Refactoring and amendment to ensure correct behaviour of D tool shared library tests on OSX. --- .../2940_Ariovistus/Common/correctLinkOptions.py | 14 +++++++----- test/D/SharedObjects/Common/common.py | 26 ++++++++++++++-------- test/D/SharedObjects/sconstest-gdc.py | 3 --- 3 files changed, 25 insertions(+), 18 deletions(-) diff --git a/test/D/Issues/2940_Ariovistus/Common/correctLinkOptions.py b/test/D/Issues/2940_Ariovistus/Common/correctLinkOptions.py index d44c9bd..0aaa283 100644 --- a/test/D/Issues/2940_Ariovistus/Common/correctLinkOptions.py +++ b/test/D/Issues/2940_Ariovistus/Common/correctLinkOptions.py @@ -45,25 +45,27 @@ def testForTool(tool): if not isExecutableOfToolAvailable(test, tool) : test.skip_test("Required executable for tool '{}' not found, skipping test.\n".format(tool)) - test.dir_fixture('Project') - test.write('SConstruct', open('SConstruct_template', 'r').read().format('tools=["{}", "link"]'.format(tool))) - - test.run() - platform = Base()['PLATFORM'] - if platform == 'posix': libraryname = 'libstuff.so' filename = 'stuff.os' elif platform == 'darwin': libraryname = 'libstuff.dylib' filename = 'stuff.os' + # As at 2014-09-14, DMD 2.066, LDC master head, and GDC 4.9.1 do not support + # shared libraries on OSX. + test.skip_test('Dynamic libraries not yet supported on OSX.\n') elif platform == 'win32': libraryname = 'stuff.dll' filename = 'stuff.obj' else: test.fail_test('No information about platform: ' + platform) + test.dir_fixture('Project') + test.write('SConstruct', open('SConstruct_template', 'r').read().format('tools=["{}", "link"]'.format(tool))) + + test.run() + for f in (libraryname, filename, 'test1', 'test1.o', 'test2', 'test2.o'): test.must_exist(test.workpath(join('test', 'test1', f))) diff --git a/test/D/SharedObjects/Common/common.py b/test/D/SharedObjects/Common/common.py index a5d7b27..e608fdb 100644 --- a/test/D/SharedObjects/Common/common.py +++ b/test/D/SharedObjects/Common/common.py @@ -45,15 +45,10 @@ def testForTool(tool): if not isExecutableOfToolAvailable(test, tool) : test.skip_test("Required executable for tool '{}' not found, skipping test.\n".format(tool)) - test.dir_fixture('Image') - test.write('SConstruct', open('SConstruct_template', 'r').read().format(tool)) - if tool == 'dmd': - # The gdmd executable in Debian Unstable as at 2012-05-12, version 4.6.3 puts out messages on stderr - # that cause inappropriate failure of the tests, so simply ignore them. - test.run(stderr=None) - else: - test.run() + if tool == 'gdc': + test.skip_test('gdc does not, as at version 4.9.1, support shared libraries.\n') + platform = Base()['PLATFORM'] if platform == 'posix': @@ -62,12 +57,25 @@ def testForTool(tool): elif platform == 'darwin': filename = 'code.o' libraryname = 'libanswer.dylib' - elif platform == 'win32' or platform == 'win64': + # As at 2014-09-14, DMD 2.066, LDC master head, and GDC 4.9.1 do not support + # shared libraries on OSX. + test.skip_test('Dynamic libraries not yet supported on OSX.\n') + elif platform == 'win32': filename = 'code.obj' libraryname = 'answer.dll' else: test.fail_test() + test.dir_fixture('Image') + test.write('SConstruct', open('SConstruct_template', 'r').read().format(tool)) + + if tool == 'dmd': + # The gdmd executable in Debian Unstable as at 2012-05-12, version 4.6.3 puts out messages on stderr + # that cause inappropriate failure of the tests, so simply ignore them. + test.run(stderr=None) + else: + test.run() + test.must_exist(test.workpath(filename)) test.must_exist(test.workpath(libraryname)) diff --git a/test/D/SharedObjects/sconstest-gdc.py b/test/D/SharedObjects/sconstest-gdc.py index 7d0f28c..43bb8eb 100644 --- a/test/D/SharedObjects/sconstest-gdc.py +++ b/test/D/SharedObjects/sconstest-gdc.py @@ -27,9 +27,6 @@ Test compiling and executing using the gcd tool. __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" -import TestSCons -TestSCons.TestSCons().skip_test('SKIPPED... gdc does not, as at version 4.9.1, support shared libraries.\n') - from Common.common import testForTool testForTool('gdc') -- cgit v0.12 From 2f5f1e802fb142bd4e1ebfc45e1ddc30ac84dfa8 Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Sun, 14 Sep 2014 17:31:35 +0100 Subject: Remove the incorrect Windows type label. --- test/D/SharedObjects/Common/common.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/D/SharedObjects/Common/common.py b/test/D/SharedObjects/Common/common.py index a5d7b27..0362525 100644 --- a/test/D/SharedObjects/Common/common.py +++ b/test/D/SharedObjects/Common/common.py @@ -62,7 +62,7 @@ def testForTool(tool): elif platform == 'darwin': filename = 'code.o' libraryname = 'libanswer.dylib' - elif platform == 'win32' or platform == 'win64': + elif platform == 'win32': filename = 'code.obj' libraryname = 'answer.dll' else: -- cgit v0.12 From f8614aa2d65f2b2484efdaf55a4b8c506157e915 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Sun, 14 Sep 2014 22:21:30 -0400 Subject: Support -isystem in ParseFlags The -isystem flag specifies an include directory that is afforded the same special treatment (e.g., suppression of warnings) as the typical system include directories. --- src/engine/SCons/Environment.py | 5 ++++- src/engine/SCons/EnvironmentTests.py | 10 ++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py index 62d6809..5f2c9ff 100644 --- a/src/engine/SCons/Environment.py +++ b/src/engine/SCons/Environment.py @@ -719,6 +719,9 @@ class SubstitutionEnvironment(object): t = ('-isysroot', arg) dict['CCFLAGS'].append(t) dict['LINKFLAGS'].append(t) + elif append_next_arg_to == '-isystem': + t = ('-isystem', arg) + dict['CCFLAGS'].append(t) elif append_next_arg_to == '-arch': t = ('-arch', arg) dict['CCFLAGS'].append(t) @@ -791,7 +794,7 @@ class SubstitutionEnvironment(object): elif arg[0] == '+': dict['CCFLAGS'].append(arg) dict['LINKFLAGS'].append(arg) - elif arg in ['-include', '-isysroot', '-arch']: + elif arg in ['-include', '-isysroot', '-isystem', '-arch']: append_next_arg_to = arg else: dict['CCFLAGS'].append(arg) diff --git a/src/engine/SCons/EnvironmentTests.py b/src/engine/SCons/EnvironmentTests.py index b9ef3f2..a0869e8 100644 --- a/src/engine/SCons/EnvironmentTests.py +++ b/src/engine/SCons/EnvironmentTests.py @@ -805,7 +805,9 @@ sys.exit(0) "-pthread " + \ "-fopenmp " + \ "-mno-cygwin -mwindows " + \ - "-arch i386 -isysroot /tmp +DD64 " + \ + "-arch i386 -isysroot /tmp " + \ + "-isystem /usr/include/foo " + \ + "+DD64 " + \ "-DFOO -DBAR=value -D BAZ " d = env.ParseFlags(s) @@ -815,6 +817,7 @@ sys.exit(0) assert d['CCFLAGS'] == ['-X', '-Wa,-as', '-pthread', '-fopenmp', '-mno-cygwin', ('-arch', 'i386'), ('-isysroot', '/tmp'), + ('-isystem', '/usr/include/foo'), '+DD64'], repr(d['CCFLAGS']) assert d['CXXFLAGS'] == ['-std=c++0x'], repr(d['CXXFLAGS']) assert d['CPPDEFINES'] == ['FOO', ['BAR', 'value'], 'BAZ'], d['CPPDEFINES'] @@ -2051,7 +2054,9 @@ def generate(env): "-F fwd3 " + \ "-pthread " + \ "-mno-cygwin -mwindows " + \ - "-arch i386 -isysroot /tmp +DD64 " + \ + "-arch i386 -isysroot /tmp " + \ + "-isystem /usr/include/foo " + \ + "+DD64 " + \ "-DFOO -DBAR=value") env.ParseConfig("fake $COMMAND") assert save_command == ['fake command'], save_command @@ -2059,6 +2064,7 @@ def generate(env): assert env['CCFLAGS'] == ['', '-X', '-Wa,-as', '-pthread', '-mno-cygwin', ('-arch', 'i386'), ('-isysroot', '/tmp'), + ('-isystem', '/usr/include/foo'), '+DD64'], env['CCFLAGS'] assert env['CPPDEFINES'] == ['FOO', ['BAR', 'value']], env['CPPDEFINES'] assert env['CPPFLAGS'] == ['', '-Wp,-cpp'], env['CPPFLAGS'] -- cgit v0.12 From 811d3f2115eae697a0132d11d07df54163f3479b Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Mon, 15 Sep 2014 18:47:05 +0100 Subject: Make the format method work on Python 2.6 as well as later versions. --- test/D/HSTeoh/Common/arLibIssue.py | 4 ++-- test/D/HSTeoh/Common/libCompileOptions.py | 4 ++-- test/D/Issues/2939_Ariovistus/Common/correctLinkOptions.py | 4 ++-- test/D/Issues/2940_Ariovistus/Common/correctLinkOptions.py | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/test/D/HSTeoh/Common/arLibIssue.py b/test/D/HSTeoh/Common/arLibIssue.py index fe5902b..9bca3d8 100644 --- a/test/D/HSTeoh/Common/arLibIssue.py +++ b/test/D/HSTeoh/Common/arLibIssue.py @@ -43,10 +43,10 @@ def testForTool(tool): test = TestSCons.TestSCons() if not isExecutableOfToolAvailable(test, tool) : - test.skip_test("Required executable for tool '{}' not found, skipping test.\n".format(tool)) + test.skip_test("Required executable for tool '{0}' not found, skipping test.\n".format(tool)) test.dir_fixture('ArLibIssue') - test.write('SConstruct', open('SConstruct_template', 'r').read().format('tools=["{}", "ar"]'.format(tool))) + test.write('SConstruct', open('SConstruct_template', 'r').read().format('tools=["{0}", "ar"]'.format(tool))) test.run() diff --git a/test/D/HSTeoh/Common/libCompileOptions.py b/test/D/HSTeoh/Common/libCompileOptions.py index dd95fc8..4a21c45 100644 --- a/test/D/HSTeoh/Common/libCompileOptions.py +++ b/test/D/HSTeoh/Common/libCompileOptions.py @@ -43,10 +43,10 @@ def testForTool(tool): test = TestSCons.TestSCons() if not isExecutableOfToolAvailable(test, tool) : - test.skip_test("Required executable for tool '{}' not found, skipping test.\n".format(tool)) + test.skip_test("Required executable for tool '{0}' not found, skipping test.\n".format(tool)) test.dir_fixture('LibCompileOptions') - test.write('SConstruct', open('SConstruct_template', 'r').read().format('tools=["{}", "link", "ar"]'.format(tool))) + test.write('SConstruct', open('SConstruct_template', 'r').read().format('tools=["{0}", "link", "ar"]'.format(tool))) test.run() diff --git a/test/D/Issues/2939_Ariovistus/Common/correctLinkOptions.py b/test/D/Issues/2939_Ariovistus/Common/correctLinkOptions.py index d44c9bd..1b42580 100644 --- a/test/D/Issues/2939_Ariovistus/Common/correctLinkOptions.py +++ b/test/D/Issues/2939_Ariovistus/Common/correctLinkOptions.py @@ -43,10 +43,10 @@ def testForTool(tool): test = TestSCons.TestSCons() if not isExecutableOfToolAvailable(test, tool) : - test.skip_test("Required executable for tool '{}' not found, skipping test.\n".format(tool)) + test.skip_test("Required executable for tool '{0}' not found, skipping test.\n".format(tool)) test.dir_fixture('Project') - test.write('SConstruct', open('SConstruct_template', 'r').read().format('tools=["{}", "link"]'.format(tool))) + test.write('SConstruct', open('SConstruct_template', 'r').read().format('tools=["{0}", "link"]'.format(tool))) test.run() diff --git a/test/D/Issues/2940_Ariovistus/Common/correctLinkOptions.py b/test/D/Issues/2940_Ariovistus/Common/correctLinkOptions.py index 0aaa283..8060add 100644 --- a/test/D/Issues/2940_Ariovistus/Common/correctLinkOptions.py +++ b/test/D/Issues/2940_Ariovistus/Common/correctLinkOptions.py @@ -43,7 +43,7 @@ def testForTool(tool): test = TestSCons.TestSCons() if not isExecutableOfToolAvailable(test, tool) : - test.skip_test("Required executable for tool '{}' not found, skipping test.\n".format(tool)) + test.skip_test("Required executable for tool '{0}' not found, skipping test.\n".format(tool)) platform = Base()['PLATFORM'] if platform == 'posix': @@ -62,7 +62,7 @@ def testForTool(tool): test.fail_test('No information about platform: ' + platform) test.dir_fixture('Project') - test.write('SConstruct', open('SConstruct_template', 'r').read().format('tools=["{}", "link"]'.format(tool))) + test.write('SConstruct', open('SConstruct_template', 'r').read().format('tools=["{0}", "link"]'.format(tool))) test.run() -- cgit v0.12 From 31a6b57a62dcbdfcb4b059feb4a9ea93793c3e70 Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Mon, 15 Sep 2014 18:52:28 +0100 Subject: And all the rest of the {} in format strings made Python 2.6 compatible. --- test/D/CoreScanner/Common/common.py | 2 +- test/D/HSTeoh/Common/linkingProblem.py | 2 +- test/D/HSTeoh/Common/singleStringCannotBeMultipleOptions.py | 2 +- test/D/HelloWorld/CompileAndLinkOneStep/Common/common.py | 2 +- test/D/HelloWorld/CompileThenLinkTwoSteps/Common/common.py | 2 +- test/D/MixedDAndC/Common/common.py | 2 +- test/D/SharedObjects/Common/common.py | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/test/D/CoreScanner/Common/common.py b/test/D/CoreScanner/Common/common.py index 657e83e..1d2fde0 100644 --- a/test/D/CoreScanner/Common/common.py +++ b/test/D/CoreScanner/Common/common.py @@ -44,7 +44,7 @@ def testForTool(tool): _obj = TestSCons._obj if not isExecutableOfToolAvailable(test, tool) : - test.skip_test("Required executable for tool '{}' not found, skipping test.\n".format(tool)) + test.skip_test("Required executable for tool '{0}' not found, skipping test.\n".format(tool)) test.dir_fixture('Image') test.write('SConstruct', open('SConstruct_template', 'r').read().format(tool)) diff --git a/test/D/HSTeoh/Common/linkingProblem.py b/test/D/HSTeoh/Common/linkingProblem.py index 59b409f..46351b3 100644 --- a/test/D/HSTeoh/Common/linkingProblem.py +++ b/test/D/HSTeoh/Common/linkingProblem.py @@ -41,7 +41,7 @@ def testForTool(tool): test = TestSCons.TestSCons() if not isExecutableOfToolAvailable(test, tool) : - test.skip_test("Required executable for tool '{}' not found, skipping test.\n".format(tool)) + test.skip_test("Required executable for tool '{0}' not found, skipping test.\n".format(tool)) test.dir_fixture('LinkingProblem') test.write('SConstruct', open('SConstruct_template', 'r').read().format(tool)) diff --git a/test/D/HSTeoh/Common/singleStringCannotBeMultipleOptions.py b/test/D/HSTeoh/Common/singleStringCannotBeMultipleOptions.py index 4dabf7b..26b477b 100644 --- a/test/D/HSTeoh/Common/singleStringCannotBeMultipleOptions.py +++ b/test/D/HSTeoh/Common/singleStringCannotBeMultipleOptions.py @@ -42,7 +42,7 @@ def testForTool(tool): test = TestSCons.TestSCons() if not isExecutableOfToolAvailable(test, tool) : - test.skip_test("Required executable for tool '{}' not found, skipping test.\n".format(tool)) + test.skip_test("Required executable for tool '{0}' not found, skipping test.\n".format(tool)) test.dir_fixture('SingleStringCannotBeMultipleOptions') test.write('SConstruct', open('SConstruct_template', 'r').read().format(tool)) diff --git a/test/D/HelloWorld/CompileAndLinkOneStep/Common/common.py b/test/D/HelloWorld/CompileAndLinkOneStep/Common/common.py index 618041b..e757d47 100644 --- a/test/D/HelloWorld/CompileAndLinkOneStep/Common/common.py +++ b/test/D/HelloWorld/CompileAndLinkOneStep/Common/common.py @@ -41,7 +41,7 @@ def testForTool(tool): test = TestSCons.TestSCons() if not isExecutableOfToolAvailable(test, tool) : - test.skip_test("Required executable for tool '{}' not found, skipping test.\n".format(tool)) + test.skip_test("Required executable for tool '{0}' not found, skipping test.\n".format(tool)) test.dir_fixture('Image') test.write('SConstruct', open('SConstruct_template', 'r').read().format(tool)) diff --git a/test/D/HelloWorld/CompileThenLinkTwoSteps/Common/common.py b/test/D/HelloWorld/CompileThenLinkTwoSteps/Common/common.py index 618041b..e757d47 100644 --- a/test/D/HelloWorld/CompileThenLinkTwoSteps/Common/common.py +++ b/test/D/HelloWorld/CompileThenLinkTwoSteps/Common/common.py @@ -41,7 +41,7 @@ def testForTool(tool): test = TestSCons.TestSCons() if not isExecutableOfToolAvailable(test, tool) : - test.skip_test("Required executable for tool '{}' not found, skipping test.\n".format(tool)) + test.skip_test("Required executable for tool '{0}' not found, skipping test.\n".format(tool)) test.dir_fixture('Image') test.write('SConstruct', open('SConstruct_template', 'r').read().format(tool)) diff --git a/test/D/MixedDAndC/Common/common.py b/test/D/MixedDAndC/Common/common.py index 66c738f..c9ecb6a 100644 --- a/test/D/MixedDAndC/Common/common.py +++ b/test/D/MixedDAndC/Common/common.py @@ -41,7 +41,7 @@ def testForTool(tool): test = TestSCons.TestSCons() if not isExecutableOfToolAvailable(test, tool) : - test.skip_test("Required executable for tool '{}' not found, skipping test.\n".format(tool)) + test.skip_test("Required executable for tool '{0}' not found, skipping test.\n".format(tool)) test.dir_fixture('Image') diff --git a/test/D/SharedObjects/Common/common.py b/test/D/SharedObjects/Common/common.py index e608fdb..cb1e71b 100644 --- a/test/D/SharedObjects/Common/common.py +++ b/test/D/SharedObjects/Common/common.py @@ -43,7 +43,7 @@ def testForTool(tool): test = TestSCons.TestSCons() if not isExecutableOfToolAvailable(test, tool) : - test.skip_test("Required executable for tool '{}' not found, skipping test.\n".format(tool)) + test.skip_test("Required executable for tool '{0}' not found, skipping test.\n".format(tool)) if tool == 'gdc': -- cgit v0.12 From 3460931829a56a63ee077d126e051032cf5aedef Mon Sep 17 00:00:00 2001 From: Dirk Baechle Date: Thu, 18 Sep 2014 20:27:56 +0200 Subject: - fixed Java test for derived sources problem, now favouring skip() over no_result() --- test/Java/DerivedSourceTest.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/Java/DerivedSourceTest.py b/test/Java/DerivedSourceTest.py index c749cf3..7f80595 100644 --- a/test/Java/DerivedSourceTest.py +++ b/test/Java/DerivedSourceTest.py @@ -45,14 +45,14 @@ SCons.Defaults.DefaultEnvironment(tools = []) test = TestSCons.TestSCons() -# No result if tools not available -test.no_result( condition=(test.where_is( 'javac' ) is None) ) -test.no_result( condition=(test.where_is( 'jar' ) is None) ) - # This test is known to fail as of July 2014; see Tigris issue 1771 and issue 2931. # Once the underlying issue is corrected, this test should be re-enabled. test.skip_test('Skipping derived-source test until issue 1771 is fixed.\n') +# No result if tools not available +test.no_result( condition=(test.where_is( 'javac' ) is None) ) +test.no_result( condition=(test.where_is( 'jar' ) is None) ) + test.write( ['Sample.java'], """ -- cgit v0.12 From c60c51f29fa2044ec13b8a3160e2f26bb3531497 Mon Sep 17 00:00:00 2001 From: Alexandre Feblot Date: Sun, 21 Sep 2014 21:19:42 +0200 Subject: Attempt to fix versionned shared library on Solaris --- src/engine/SCons/Tool/__init__.py | 2 +- src/engine/SCons/Tool/install.py | 4 ++-- src/engine/SCons/Tool/link.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py index 55eb1d3..81c052f 100644 --- a/src/engine/SCons/Tool/__init__.py +++ b/src/engine/SCons/Tool/__init__.py @@ -256,7 +256,7 @@ def VersionShLibLinkNames(version, libname, env): if Verbose: print "VersionShLibLinkNames: linkname = ",linkname linknames.append(linkname) - elif platform == 'posix': + elif platform == 'posix' or platform == 'sunos': if sys.platform.startswith('openbsd'): # OpenBSD uses x.y shared library versioning numbering convention # and doesn't use symlinks to backwards-compatible libraries diff --git a/src/engine/SCons/Tool/install.py b/src/engine/SCons/Tool/install.py index 0c81d05..66869b7 100644 --- a/src/engine/SCons/Tool/install.py +++ b/src/engine/SCons/Tool/install.py @@ -149,7 +149,7 @@ 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'): + if not (platform == 'posix' or platform == 'darwin' or platform == 'sunos'): return (None, None, None) libname = os.path.basename(dest) @@ -160,7 +160,7 @@ def versionedLibVersion(dest, env): version_re = re.compile("[0-9]+\\.[0-9]+\\.[0-9a-zA-Z]+") version_File = None - if platform == 'posix': + if platform == 'posix' or platform == 'sunos': # handle unix names versioned_re = re.compile(re.escape(shlib_suffix + '.') + "[0-9]+\\.[0-9]+\\.[0-9a-zA-Z]+") result = versioned_re.findall(libname) diff --git a/src/engine/SCons/Tool/link.py b/src/engine/SCons/Tool/link.py index baa7407..f70f5b8 100644 --- a/src/engine/SCons/Tool/link.py +++ b/src/engine/SCons/Tool/link.py @@ -105,7 +105,7 @@ def shlib_emitter_names(target, source, env): # We need a version of the form x.y.z to proceed raise ValueError if version: - if platform == 'posix': + if platform == 'posix' or platform == 'sunos': versionparts = version.split('.') name = target[0].name # generate library name with the version number -- cgit v0.12 From 2a2bb65ba5daa067950ea2be8b13ee812db47241 Mon Sep 17 00:00:00 2001 From: Dirk Baechle Date: Sat, 27 Sep 2014 18:23:41 +0200 Subject: - fix for issue #2971 (Interactive build doesn't work anymore) --- src/CHANGES.txt | 6 +-- src/engine/SCons/Script/Main.py | 9 +++- test/Interactive/configure.py | 106 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 117 insertions(+), 4 deletions(-) create mode 100644 test/Interactive/configure.py diff --git a/src/CHANGES.txt b/src/CHANGES.txt index d516131..58071ab 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -6,9 +6,9 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER - From John Doe: - - - Whatever John Doe did. + From Bernhard Walle and Dirk Baechle: + - Fixed the interactive mode, in connection with + Configure contexts (#2971). RELEASE 2.3.3 - Sun, 24 Aug 2014 21:08:33 -0400 diff --git a/src/engine/SCons/Script/Main.py b/src/engine/SCons/Script/Main.py index 439b869..c7a9d27 100644 --- a/src/engine/SCons/Script/Main.py +++ b/src/engine/SCons/Script/Main.py @@ -953,6 +953,14 @@ def _main(parser): if options.include_dir: sys.path = options.include_dir + sys.path + # If we're about to start SCons in the interactive mode, + # inform the FS about this right here. Else, the release_target_info + # method could get called on some nodes, like the used "gcc" compiler, + # when using the Configure methods within the SConscripts. + # This would then cause subtle bugs, as already happened in #2971. + if options.interactive: + SCons.Node.interactive = True + # That should cover (most of) the options. Next, set up the variables # that hold command-line arguments, so the SConscript files that we # read and execute have access to them. @@ -1082,7 +1090,6 @@ def _main(parser): platform = SCons.Platform.platform_module() if options.interactive: - SCons.Node.interactive = True SCons.Script.Interactive.interact(fs, OptionsParser, options, targets, target_top) diff --git a/test/Interactive/configure.py b/test/Interactive/configure.py new file mode 100644 index 0000000..ceb1aea --- /dev/null +++ b/test/Interactive/configure.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Verify basic operation of the --interactive command line option to build +a target, while using a Configure context within the environment. + +Also tests that "b" can be used as a synonym for "build". +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.write('SConstruct', """\ +import sys + +env = Environment() + +conf = Configure(env) +if not conf.CheckCXX(): + sys.exit(1) +conf.Finish() + +env.Program('foo','foo.cpp') +""") + +test.write('foo.cpp', """\ +#include + +int main (int argc, char *argv[]) +{ + printf("Hello, World!"); + return 0; +} +""") + + +scons = test.start(arguments = '-Q --interactive') +# Initial build +scons.send("build foo\n") + +test.wait_for(test.workpath('foo')) +# Update without any changes -> no action +scons.send("build foo\n") +# Changing the source file +test.write('foo.cpp', """\ +#include + +void foo() +{ + ; +} + +int main (int argc, char *argv[]) +{ + printf("Hello, World!"); + return 0; +} +""") + +# Verify that "b" can be used as a synonym for the "build" command. +scons.send("b foo\n") + +scons.send("build foo\n") + +expect_stdout = r"""scons>>> .*foo\.cpp.* +.*foo.* +scons>>> .*foo\.cpp.* +.*foo.* +scons>>> scons: `foo' is up to date. +scons>>> scons: `foo' is up to date. +scons>>>\s* +""" + +test.finish(scons, stdout = expect_stdout, match=TestSCons.match_re) + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: -- cgit v0.12 From 0b806ea5b203f1ef876f5d91294aaeabdc5a639a Mon Sep 17 00:00:00 2001 From: anatoly techtonik Date: Fri, 26 Sep 2014 16:17:38 +0300 Subject: Split __VERSION__ string in EnsureSConsVersion to avoid replacement during package build process. This fixes SCons warning that it runs in development mode. --- src/CHANGES.txt | 5 +++++ src/engine/SCons/Script/SConscript.py | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 58071ab..4fc89b6 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -11,6 +11,11 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER Configure contexts (#2971). +RELEASE 2.3.4 - Sss, DD Mmm yyyy hh:mm:ss -zzzz + + From Anatoly Techtonik: + - Fix EnsureSConsVersion warning when running packaged version + RELEASE 2.3.3 - Sun, 24 Aug 2014 21:08:33 -0400 From Roland Stark: diff --git a/src/engine/SCons/Script/SConscript.py b/src/engine/SCons/Script/SConscript.py index 111d091..f4a7f07 100644 --- a/src/engine/SCons/Script/SConscript.py +++ b/src/engine/SCons/Script/SConscript.py @@ -461,7 +461,8 @@ class SConsEnvironment(SCons.Environment.Base): def EnsureSConsVersion(self, major, minor, revision=0): """Exit abnormally if the SCons version is not late enough.""" - if SCons.__version__ == '__VERSION__': + # split string to avoid replacement during build process + if SCons.__version__ == '__' + 'VERSION__': SCons.Warnings.warn(SCons.Warnings.DevelopmentVersionWarning, "EnsureSConsVersion is ignored for development version") return -- cgit v0.12 From 2db53c86a769e77f7f15db67992ae240bebd86cd Mon Sep 17 00:00:00 2001 From: Gary Oberbrunner Date: Sat, 27 Sep 2014 09:25:42 -0400 Subject: Fix change log from prev commit. --- src/CHANGES.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 4fc89b6..7f7b4ab 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -10,9 +10,6 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER - Fixed the interactive mode, in connection with Configure contexts (#2971). - -RELEASE 2.3.4 - Sss, DD Mmm yyyy hh:mm:ss -zzzz - From Anatoly Techtonik: - Fix EnsureSConsVersion warning when running packaged version -- cgit v0.12 From 5832ea4637bd1ab86b385fffffb482467509a7e6 Mon Sep 17 00:00:00 2001 From: Gary Oberbrunner Date: Sat, 27 Sep 2014 09:51:17 -0400 Subject: Updated CHANGES.txt: recent D tool fixes --- src/CHANGES.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 7f7b4ab..4207390 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -13,6 +13,9 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER From Anatoly Techtonik: - Fix EnsureSConsVersion warning when running packaged version + From Russel Winder: + - Fix D tools for building shared libraries + RELEASE 2.3.3 - Sun, 24 Aug 2014 21:08:33 -0400 From Roland Stark: -- cgit v0.12 From c75d5a163567c2e8e16e24dd73c90b6ee75fc03c Mon Sep 17 00:00:00 2001 From: Gary Oberbrunner Date: Sat, 27 Sep 2014 10:22:16 -0400 Subject: Release fixes: README.rst python version, and some auto version numbering. --- README.rst | 26 +++++++++++++------------- src/Announce.txt | 5 +++++ 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/README.rst b/README.rst index 56c48e2..f80afd7 100644 --- a/README.rst +++ b/README.rst @@ -47,7 +47,7 @@ version at the SCons download page: Execution Requirements ====================== -Running SCons requires Python version 2.4 or later (Python 3 is not +Running SCons requires Python version 2.6 or later (Python 3 is not yet supported). There should be no other dependencies or requirements to run SCons. @@ -156,7 +156,7 @@ Or on Windows:: By default, the above commands will do the following: -- Install the version-numbered "scons-2.0.0" and "sconsign-2.0.0" scripts in +- Install the version-numbered "scons-2.3.3" and "sconsign-2.3.3" scripts in the default system script directory (/usr/bin or C:\\Python\*\\Scripts, for example). This can be disabled by specifying the "--no-version-script" option on the command line. @@ -168,23 +168,23 @@ By default, the above commands will do the following: before making it the default on your system. On UNIX or Linux systems, you can have the "scons" and "sconsign" scripts be - hard links or symbolic links to the "scons-2.0.0" and "sconsign-2.0.0" + hard links or symbolic links to the "scons-2.3.3" and "sconsign-2.3.3" scripts by specifying the "--hardlink-scons" or "--symlink-scons" options on the command line. -- Install "scons-2.0.0.bat" and "scons.bat" wrapper scripts in the Python +- Install "scons-2.3.3.bat" and "scons.bat" wrapper scripts in the Python prefix directory on Windows (C:\\Python\*, for example). This can be disabled by specifying the "--no-install-bat" option on the command line. On UNIX or Linux systems, the "--install-bat" option may be specified to - have "scons-2.0.0.bat" and "scons.bat" files installed in the default system + have "scons-2.3.3.bat" and "scons.bat" files installed in the default system script directory, which is useful if you want to install SCons in a shared file system directory that can be used to execute SCons from both UNIX/Linux and Windows systems. - Install the SCons build engine (a Python module) in an appropriate - version-numbered SCons library directory (/usr/lib/scons-2.0.0 or - C:\\Python\*\\scons-2.0.0, for example). See below for more options related to + version-numbered SCons library directory (/usr/lib/scons-2.3.3 or + C:\\Python\*\\scons-2.3.3, for example). See below for more options related to installing the build engine library. - Install the troff-format man pages in an appropriate directory on UNIX or @@ -462,13 +462,13 @@ running all of "runtest.py -a". Building Packages ================= -We use SCons (version 0.96.93 later) to build its own packages. If you +We use SCons (version 2.3.3 or later) to build its own packages. If you already have an appropriate version of SCons installed on your system, you can build everything by simply running it:: $ scons -If you don't have SCons version 0.96.93 later already installed on your +If you don't have SCons already installed on your system, you can use the supplied bootstrap.py script (see the section above about `Executing SCons Without Installing`_):: @@ -477,9 +477,9 @@ about `Executing SCons Without Installing`_):: Depending on the utilities installed on your system, any or all of the following packages will be built:: - build/dist/scons-2.0.0-1.noarch.rpm - build/dist/scons-2.0.0-1.src.rpm - build/dist/scons-2.0.0.linux-i686.tar.gz + build/dist/scons-2.3.3-1.noarch.rpm + build/dist/scons-2.3.3-1.src.rpm + build/dist/scons-2.3.3.linux-i686.tar.gz build/dist/scons-2.3.3.tar.gz build/dist/scons-2.3.3.win32.exe build/dist/scons-2.3.3.zip @@ -488,7 +488,7 @@ following packages will be built:: build/dist/scons-local-2.3.3.zip build/dist/scons-src-2.3.3.tar.gz build/dist/scons-src-2.3.3.zip - build/dist/scons_1.3.0-1_all.deb + build/dist/scons_2.3.3-1_all.deb The SConstruct file is supposed to be smart enough to avoid trying to build packages for which you don't have the proper utilities installed. For diff --git a/src/Announce.txt b/src/Announce.txt index 9ca047d..6cb69b3 100644 --- a/src/Announce.txt +++ b/src/Announce.txt @@ -26,6 +26,11 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER since last release. This announcement highlights only the important changes. + Please note the following important changes since release 2.3.3: + + -- Fix for EnsureSConsVersion regression in 2.3.3. + -- Fix for interactive mode with Configure contexts + Please note the following important changes since release 2.3.2: -- On Windows, .def files did not work as sources to shared -- cgit v0.12 From fc66ae179da0e407b43f572f45d8656ba6b42a78 Mon Sep 17 00:00:00 2001 From: Gary Oberbrunner Date: Sat, 27 Sep 2014 10:17:02 -0400 Subject: Update CHANGES, Release and Announce prior to 2.3.4 release. --- debian/changelog | 6 +++++ src/Announce.txt | 1 + src/RELEASE.txt | 68 ++++++-------------------------------------------------- 3 files changed, 14 insertions(+), 61 deletions(-) diff --git a/debian/changelog b/debian/changelog index 5e4bf60..a39a73b 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +scons (2.3.4) unstable; urgency=low + + * Maintenance release. + + -- Gary Oberbrunner Sun, 27 Sep 2014 21:00:00 -0500 + scons (2.3.3) unstable; urgency=low * Maintenance release. diff --git a/src/Announce.txt b/src/Announce.txt index 6cb69b3..7c6fdd5 100644 --- a/src/Announce.txt +++ b/src/Announce.txt @@ -29,6 +29,7 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER Please note the following important changes since release 2.3.3: -- Fix for EnsureSConsVersion regression in 2.3.3. + -- Fix for interactive mode with Configure contexts Please note the following important changes since release 2.3.2: diff --git a/src/RELEASE.txt b/src/RELEASE.txt index 31c9590..853456d 100644 --- a/src/RELEASE.txt +++ b/src/RELEASE.txt @@ -1,73 +1,19 @@ - A new SCons checkpoint release, 2.3.4.alpha.yyyymmdd, is now available + A new SCons checkpoint release, 2.3.4, is now available on the SCons download page: http://www.scons.org/download.php - XXX The primary purpose of this release ... XXX + This is a bug fix release to fix a regression in EnsureSConsVersion. - A SCons "checkpoint release" is intended to provide early access to - new features so they can be tested in the field before being released - for adoption by other software distributions. - - Note that a checkpoint release is developed using the same test-driven - development methodology as all SCons releases. Existing SCons - functionality should all work as it does in previous releases (except - for any changes identified in the release notes) and early adopters - should be able to use a checkpoint release safely for production work - with existing SConscript files. If not, it represents not only a bug - in SCons but also a hole in the regression test suite, and we want to - hear about it. - - New features may be more lightly tested than in past releases, - especially as concerns their interaction with all of the other - functionality in SCons. We are especially interested in hearing bug - reports about new functionality. - - We do not recommend that downstream distributions (Debian, Fedora, - etc.) package a checkpoint release, mainly to avoid confusing the - "public" release numbering with the long checkpoint release names. - - Here is a summary of the changes since 1.3.0: - - NEW FUNCTIONALITY - - - List new features (presumably why a checkpoint is being released) - - DEPRECATED FUNCTIONALITY - - - List anything that's been deprecated since the last release - - CHANGED/ENHANCED EXISTING FUNCTIONALITY - - - List modifications to existing features, where the previous behavior - wouldn't actually be considered a bug + Here is a summary of the changes since 2.3.3 FIXES - - List fixes of outright bugs - - IMPROVEMENTS - - - List improvements that wouldn't be visible to the user in the - documentation: performance improvements (describe the circumstances - under which they would be observed), or major code cleanups - - PACKAGING - - - List changes in the way SCons is packaged and/or released - - DOCUMENTATION - - - List any significant changes to the documentation (not individual - typo fixes, even if they're mentioned in src/CHANGES.txt to give - the contributor credit) - - DEVELOPMENT - - - List visible changes in the way SCons is developed + - Fix regression in EnsureSConsVersion - Thanks to CURLY, LARRY, and MOE for their contributions to this release. - Contributors are listed alphabetically by their last name. + Thanks to Anatoly Techtonik and Russel Winder for their + contributions to this release. Contributors are listed + alphabetically by their last name. __COPYRIGHT__ __FILE__ __REVISION__ __DATE__ __DEVELOPER__ -- cgit v0.12 From 03a83a3d4cb16181642bd85b72d70f26d79ee290 Mon Sep 17 00:00:00 2001 From: Gary Oberbrunner Date: Sat, 27 Sep 2014 15:56:46 -0400 Subject: Put default branch back to develop mode, post 2.3.4. --- QMTest/TestSCons.py | 2 +- README.rst | 16 ++++++------- ReleaseConfig | 2 +- SConstruct | 4 ++-- src/CHANGES.txt | 7 ++++++ src/RELEASE.txt | 68 +++++++++++++++++++++++++++++++++++++++++++++++------ 6 files changed, 80 insertions(+), 19 deletions(-) diff --git a/QMTest/TestSCons.py b/QMTest/TestSCons.py index 3c94dcd..8635f8e 100644 --- a/QMTest/TestSCons.py +++ b/QMTest/TestSCons.py @@ -34,7 +34,7 @@ from TestCmd import PIPE # here provides some independent verification that what we packaged # conforms to what we expect. -default_version = '2.3.3' +default_version = '2.3.4' python_version_unsupported = (2, 3, 0) python_version_deprecated = (2, 7, 0) diff --git a/README.rst b/README.rst index f80afd7..599abaf 100644 --- a/README.rst +++ b/README.rst @@ -480,14 +480,14 @@ following packages will be built:: build/dist/scons-2.3.3-1.noarch.rpm build/dist/scons-2.3.3-1.src.rpm build/dist/scons-2.3.3.linux-i686.tar.gz - build/dist/scons-2.3.3.tar.gz - build/dist/scons-2.3.3.win32.exe - build/dist/scons-2.3.3.zip - build/dist/scons-doc-2.3.3.tar.gz - build/dist/scons-local-2.3.3.tar.gz - build/dist/scons-local-2.3.3.zip - build/dist/scons-src-2.3.3.tar.gz - build/dist/scons-src-2.3.3.zip + build/dist/scons-2.3.4.tar.gz + build/dist/scons-2.3.4.win32.exe + build/dist/scons-2.3.4.zip + build/dist/scons-doc-2.3.4.tar.gz + build/dist/scons-local-2.3.4.tar.gz + build/dist/scons-local-2.3.4.zip + build/dist/scons-src-2.3.4.tar.gz + build/dist/scons-src-2.3.4.zip build/dist/scons_2.3.3-1_all.deb The SConstruct file is supposed to be smart enough to avoid trying to build diff --git a/ReleaseConfig b/ReleaseConfig index 9d06967..0735012 100644 --- a/ReleaseConfig +++ b/ReleaseConfig @@ -32,7 +32,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" # 'final', the patchlevel is set to the release date. This value is # mandatory and must be present in this file. #version_tuple = (2, 2, 0, 'final', 0) -version_tuple = (2, 3, 4, 'alpha', 0) +version_tuple = (2, 3, 5, 'alpha', 0) # Python versions prior to unsupported_python_version cause a fatal error # when that version is used. Python versions prior to deprecate_python_version diff --git a/SConstruct b/SConstruct index d07c6cf..27b07f2 100644 --- a/SConstruct +++ b/SConstruct @@ -6,7 +6,7 @@ copyright_years = '2001 - 2014' # This gets inserted into the man pages to reflect the month of release. -month_year = 'August 2014' +month_year = 'September 2014' # # __COPYRIGHT__ @@ -43,7 +43,7 @@ import tempfile import bootstrap project = 'scons' -default_version = '2.3.3' +default_version = '2.3.4' copyright = "Copyright (c) %s The SCons Foundation" % copyright_years platform = distutils.util.get_platform() diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 4207390..1798e36 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -6,6 +6,13 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER + From John Doe: + + - Whatever John Doe did. + + +RELEASE 2.3.4 - Mon, 27 Sep 2014 12:50:35 -0400 + From Bernhard Walle and Dirk Baechle: - Fixed the interactive mode, in connection with Configure contexts (#2971). diff --git a/src/RELEASE.txt b/src/RELEASE.txt index 853456d..1fa033b 100644 --- a/src/RELEASE.txt +++ b/src/RELEASE.txt @@ -1,19 +1,73 @@ - A new SCons checkpoint release, 2.3.4, is now available + A new SCons checkpoint release, 2.3.5.alpha.yyyymmdd, is now available on the SCons download page: http://www.scons.org/download.php - This is a bug fix release to fix a regression in EnsureSConsVersion. + XXX The primary purpose of this release ... XXX - Here is a summary of the changes since 2.3.3 + A SCons "checkpoint release" is intended to provide early access to + new features so they can be tested in the field before being released + for adoption by other software distributions. + + Note that a checkpoint release is developed using the same test-driven + development methodology as all SCons releases. Existing SCons + functionality should all work as it does in previous releases (except + for any changes identified in the release notes) and early adopters + should be able to use a checkpoint release safely for production work + with existing SConscript files. If not, it represents not only a bug + in SCons but also a hole in the regression test suite, and we want to + hear about it. + + New features may be more lightly tested than in past releases, + especially as concerns their interaction with all of the other + functionality in SCons. We are especially interested in hearing bug + reports about new functionality. + + We do not recommend that downstream distributions (Debian, Fedora, + etc.) package a checkpoint release, mainly to avoid confusing the + "public" release numbering with the long checkpoint release names. + + Here is a summary of the changes since 1.3.0: + + NEW FUNCTIONALITY + + - List new features (presumably why a checkpoint is being released) + + DEPRECATED FUNCTIONALITY + + - List anything that's been deprecated since the last release + + CHANGED/ENHANCED EXISTING FUNCTIONALITY + + - List modifications to existing features, where the previous behavior + wouldn't actually be considered a bug FIXES - - Fix regression in EnsureSConsVersion + - List fixes of outright bugs + + IMPROVEMENTS + + - List improvements that wouldn't be visible to the user in the + documentation: performance improvements (describe the circumstances + under which they would be observed), or major code cleanups + + PACKAGING + + - List changes in the way SCons is packaged and/or released + + DOCUMENTATION + + - List any significant changes to the documentation (not individual + typo fixes, even if they're mentioned in src/CHANGES.txt to give + the contributor credit) + + DEVELOPMENT + + - List visible changes in the way SCons is developed - Thanks to Anatoly Techtonik and Russel Winder for their - contributions to this release. Contributors are listed - alphabetically by their last name. + Thanks to CURLY, LARRY, and MOE for their contributions to this release. + Contributors are listed alphabetically by their last name. __COPYRIGHT__ __FILE__ __REVISION__ __DATE__ __DEVELOPER__ -- cgit v0.12 From 072430f48c21dfc9dfa0b26c6aa9a7b1d4ec3fc7 Mon Sep 17 00:00:00 2001 From: Dirk Baechle Date: Sun, 28 Sep 2014 12:27:01 +0200 Subject: - fix: made the test for Interactive/configure self-contained, such that it works on any platform --- test/Interactive/configure.py | 55 ++++++++++++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 17 deletions(-) diff --git a/test/Interactive/configure.py b/test/Interactive/configure.py index ceb1aea..1a92f6c 100644 --- a/test/Interactive/configure.py +++ b/test/Interactive/configure.py @@ -32,20 +32,43 @@ Also tests that "b" can be used as a synonym for "build". import TestSCons +_python_ = TestSCons._python_ + test = TestSCons.TestSCons() -test.write('SConstruct', """\ +test.write('mycc.py', r""" import sys +outfile = open(sys.argv[1], 'wb') +infile = open(sys.argv[2], 'rb') +for l in [l for l in infile.readlines() if l[:7] != '/*c++*/']: + outfile.write(l) +sys.exit(0) +""") -env = Environment() - -conf = Configure(env) -if not conf.CheckCXX(): - sys.exit(1) +test.write('SConstruct', """\ +env = Environment(CXXCOM = r'%(_python_)s mycc.py $TARGET $SOURCE', + OBJSUFFIX='.obj') + +# Ensure that our 'compiler' works... +def CheckMyCC(context): + context.Message('Checking for MyCC compiler...') + result = context.TryBuild(context.env.Object, + 'int main(void) {return 0;}', + '.cpp') + context.Result(result) + return result + +conf = Configure(env, + custom_tests = {'CheckMyCC' : CheckMyCC}) + +if conf.CheckMyCC(): + pass # build succeeded +else: + Exit(1) conf.Finish() -env.Program('foo','foo.cpp') -""") +env.Object('foo.obj','foo.cpp') +""" % locals()) test.write('foo.cpp', """\ #include @@ -60,11 +83,11 @@ int main (int argc, char *argv[]) scons = test.start(arguments = '-Q --interactive') # Initial build -scons.send("build foo\n") +scons.send("build foo.obj\n") -test.wait_for(test.workpath('foo')) +test.wait_for(test.workpath('foo.obj')) # Update without any changes -> no action -scons.send("build foo\n") +scons.send("build foo.obj\n") # Changing the source file test.write('foo.cpp', """\ #include @@ -82,16 +105,14 @@ int main (int argc, char *argv[]) """) # Verify that "b" can be used as a synonym for the "build" command. -scons.send("b foo\n") +scons.send("b foo.obj\n") -scons.send("build foo\n") +scons.send("build foo.obj\n") expect_stdout = r"""scons>>> .*foo\.cpp.* -.*foo.* scons>>> .*foo\.cpp.* -.*foo.* -scons>>> scons: `foo' is up to date. -scons>>> scons: `foo' is up to date. +scons>>> scons: `foo.obj' is up to date. +scons>>> scons: `foo.obj' is up to date. scons>>>\s* """ -- cgit v0.12 From e702acbc201264b28825b600f41c2c351149680a Mon Sep 17 00:00:00 2001 From: Dan Pidcock Date: Wed, 15 Oct 2014 12:52:31 +0100 Subject: Support toolset in VS project files so that displayed version of visual studio matches the one that will be used --- src/engine/SCons/Tool/msvs.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/engine/SCons/Tool/msvs.py b/src/engine/SCons/Tool/msvs.py index 06ce486..2b2ea13 100644 --- a/src/engine/SCons/Tool/msvs.py +++ b/src/engine/SCons/Tool/msvs.py @@ -892,6 +892,7 @@ V10DSPPropertyGroupCondition = """\ \t \t\tMakefile \t\tfalse +\t\t%(toolset)s \t """ @@ -972,6 +973,11 @@ class _GenerateV10DSP(_DSPGenerator): self.file.write('\t\n') + toolset = '' + if 'MSVC_VERSION' in self.env: + version_num, suite = msvs_parse_version(self.env['MSVC_VERSION']) + print version_num + toolset = 'v%d' % (version_num * 10) for kind in confkeys: variant = self.configs[kind].variant platform = self.configs[kind].platform -- cgit v0.12 From c11c5c59c13727c429df1941a5c9574617e1546f Mon Sep 17 00:00:00 2001 From: Dan Pidcock Date: Wed, 15 Oct 2014 14:43:38 +0100 Subject: Issue 2978: Update tests for toolset support in VS project files --- QMTest/TestSConsMSVS.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/QMTest/TestSConsMSVS.py b/QMTest/TestSConsMSVS.py index c78b452..540d24d 100644 --- a/QMTest/TestSConsMSVS.py +++ b/QMTest/TestSConsMSVS.py @@ -709,6 +709,7 @@ expected_vcprojfile_10_0 = """\ \t \t\tMakefile \t\tfalse +\t\tv100 \t \t \t @@ -773,6 +774,7 @@ expected_vcprojfile_11_0 = """\ \t \t\tMakefile \t\tfalse +\t\tv110 \t \t \t -- cgit v0.12 From 6333b00c9c8baa442154291c9beb29f958066b3c Mon Sep 17 00:00:00 2001 From: Dan Pidcock Date: Mon, 20 Oct 2014 10:10:47 +0100 Subject: Issue 2978: remove debug line --- src/engine/SCons/Tool/msvs.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/engine/SCons/Tool/msvs.py b/src/engine/SCons/Tool/msvs.py index 2b2ea13..c9f1f2a 100644 --- a/src/engine/SCons/Tool/msvs.py +++ b/src/engine/SCons/Tool/msvs.py @@ -976,7 +976,6 @@ class _GenerateV10DSP(_DSPGenerator): toolset = '' if 'MSVC_VERSION' in self.env: version_num, suite = msvs_parse_version(self.env['MSVC_VERSION']) - print version_num toolset = 'v%d' % (version_num * 10) for kind in confkeys: variant = self.configs[kind].variant -- cgit v0.12 From 9866a7f445bb30e8cb16cc1f9c0225dfc1061ff5 Mon Sep 17 00:00:00 2001 From: Dirk Baechle Date: Wed, 22 Oct 2014 12:25:22 +0200 Subject: updated CHANGES.txt --- src/CHANGES.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 8c02e14..1372baf 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -6,6 +6,9 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER + From Dan Pidcock: + - Added support for the 'PlatformToolset' tag in VS project files (#2978). + From James McCoy: - Added support for '-isystem' to ParseFlags. -- cgit v0.12 From 8daa5b033c4d7447a36b3f1fb1a119dd8f72b381 Mon Sep 17 00:00:00 2001 From: MorpheusDev Date: Mon, 27 Oct 2014 16:33:16 +0100 Subject: Multiple 'cmdargs' feature added to allow a per variant cmdargs, to be able to insert different parameters between Debug and Release. --- src/engine/SCons/Tool/msvs.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/engine/SCons/Tool/msvs.py b/src/engine/SCons/Tool/msvs.py index c9f1f2a..f54e552 100644 --- a/src/engine/SCons/Tool/msvs.py +++ b/src/engine/SCons/Tool/msvs.py @@ -289,9 +289,17 @@ class _DSPGenerator(object): runfile.append(s) self.sconscript = env['MSVSSCONSCRIPT'] - - cmdargs = env.get('cmdargs', '') - + + if 'cmdargs' not in env or env['cmdargs'] == None: + cmdargs = [''] * len(variants) + elif SCons.Util.is_String(env['cmdargs']): + outdir = [env['cmdargs']] * len(variants) + elif SCons.Util.is_List(env['cmdargs']): + if len(env['cmdargs']) != len(variants): + raise SCons.Errors.InternalError("Sizes of 'cmdargs' and 'variant' lists must be the same.") + else: + cmdargs = env['cmdargs'] + self.env = env if 'name' in self.env: @@ -354,7 +362,7 @@ class _DSPGenerator(object): 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) + AddConfig(self, variants[i], buildtarget[i], outdir[i], runfile[i], cmdargs[i]) self.platforms = [] for key in self.configs.keys(): -- cgit v0.12 From 9ebcb17af2a0cc42e44a35113e345e1eb9e21fb5 Mon Sep 17 00:00:00 2001 From: Laurent Marchelli Date: Wed, 5 Nov 2014 10:19:30 +0100 Subject: Dumb error fixed. --- src/engine/SCons/Tool/msvs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/SCons/Tool/msvs.py b/src/engine/SCons/Tool/msvs.py index f54e552..cb4ca55 100644 --- a/src/engine/SCons/Tool/msvs.py +++ b/src/engine/SCons/Tool/msvs.py @@ -293,7 +293,7 @@ class _DSPGenerator(object): if 'cmdargs' not in env or env['cmdargs'] == None: cmdargs = [''] * len(variants) elif SCons.Util.is_String(env['cmdargs']): - outdir = [env['cmdargs']] * len(variants) + cmdargs = [env['cmdargs']] * len(variants) elif SCons.Util.is_List(env['cmdargs']): if len(env['cmdargs']) != len(variants): raise SCons.Errors.InternalError("Sizes of 'cmdargs' and 'variant' lists must be the same.") -- cgit v0.12 From ad21677e236fb53db18f42402ec7f024f3e58a36 Mon Sep 17 00:00:00 2001 From: Dirk Baechle Date: Wed, 5 Nov 2014 14:56:56 +0100 Subject: - added new method rentry_exists_on_disk (check for physical files/dirs) --- src/engine/SCons/Node/FS.py | 33 +++++++++++++++++++++++++++++++++ src/engine/SCons/Node/FSTests.py | 26 ++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py index 219718c..e73dd92 100644 --- a/src/engine/SCons/Node/FS.py +++ b/src/engine/SCons/Node/FS.py @@ -1830,6 +1830,12 @@ class Dir(Base): return self.tpath + OS_SEP + name def entry_exists_on_disk(self, name): + """ Searches through the file/dir entries of the current + directory, and returns True if a physical entry with the given + name could be found. + + @see rentry_exists_on_disk + """ try: d = self.on_disk_entries except AttributeError: @@ -1854,6 +1860,33 @@ class Dir(Base): else: return name in d + def rentry_exists_on_disk(self, name): + """ Searches through the file/dir entries of the current + *and* all its remote directories (repos), and returns + True if a physical entry with the given name could be found. + The local directory (self) gets searched first, so + repositories take a lower precedence regarding the + searching order. + + @see entry_exists_on_disk + """ + + rentry_exists = self.entry_exists_on_disk(name) + if not rentry_exists: + # Search through the repository folders + norm_name = _my_normcase(name) + for rdir in self.get_all_rdirs(): + try: + node = rdir.entries[norm_name] + if node: + rentry_exists = True + break + except KeyError: + if rdir.entry_exists_on_disk(name): + rentry_exists = True + break + return rentry_exists + memoizer_counters.append(SCons.Memoize.CountValue('srcdir_list')) def srcdir_list(self): diff --git a/src/engine/SCons/Node/FSTests.py b/src/engine/SCons/Node/FSTests.py index c4dc2ce..0326717 100644 --- a/src/engine/SCons/Node/FSTests.py +++ b/src/engine/SCons/Node/FSTests.py @@ -2052,6 +2052,32 @@ class DirTestCase(_tempdirTestCase): if os.path.normcase("TeSt") != os.path.normpath("TeSt") or sys.platform == "cygwin": assert d.entry_exists_on_disk('case-insensitive') + def test_rentry_exists_on_disk(self): + """Test the Dir.rentry_exists_on_disk() method + """ + test = self.test + + does_not_exist = self.fs.Dir('does_not_exist') + assert not does_not_exist.rentry_exists_on_disk('foo') + + test.subdir('d') + test.write(['d', 'exists'], "d/exists\n") + test.write(['d', 'Case-Insensitive'], "d/Case-Insensitive\n") + + test.subdir('r') + test.write(['r', 'rexists'], "r/rexists\n") + + d = self.fs.Dir('d') + r = self.fs.Dir('r') + d.addRepository(r) + + assert d.rentry_exists_on_disk('exists') + assert d.rentry_exists_on_disk('rexists') + assert not d.rentry_exists_on_disk('does_not_exist') + + if os.path.normcase("TeSt") != os.path.normpath("TeSt") or sys.platform == "cygwin": + assert d.rentry_exists_on_disk('case-insensitive') + def test_srcdir_list(self): """Test the Dir.srcdir_list() method """ -- cgit v0.12 From 2d510c98fe10cbdc8328da7baea83b2ea74c0788 Mon Sep 17 00:00:00 2001 From: MorpheusDev Date: Fri, 7 Nov 2014 16:54:35 +0100 Subject: Unary tests ready for review. --- src/engine/SCons/Tool/msvsTests.py | 79 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/src/engine/SCons/Tool/msvsTests.py b/src/engine/SCons/Tool/msvsTests.py index 2f4f302..261dbcc 100644 --- a/src/engine/SCons/Tool/msvsTests.py +++ b/src/engine/SCons/Tool/msvsTests.py @@ -40,6 +40,7 @@ from SCons.Tool.MSCommon.common import debug from SCons.Tool.MSCommon import get_default_version, \ query_versions +from SCons.Tool.msvs import _GenerateV6DSP, _GenerateV7DSP, _GenerateV10DSP regdata_6a = r'''[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio] [HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\6.0] @@ -591,6 +592,84 @@ class msvsTestCase(unittest.TestCase): assert not v1 or str(v1[0]) == self.highest_version, \ (v1, self.highest_version) assert len(v1) == self.number_of_versions, v1 + + def test_config_generation(self): + """Test _DSPGenerator.__init__(...)""" + if not self.highest_version : + return + + # Initialize 'static' variables + version_num, suite = msvs_parse_version(self.highest_version) + if version_num >= 10.0: + function_test = _GenerateV10DSP + elif version_num >= 7.0: + function_test = _GenerateV7DSP + else: + function_test = _GenerateV6DSP + + str_function_test = str(function_test.__init__) + dspfile = 'test.dsp' + source = 'test.cpp' + + # Create the cmdargs test list + list_variant = ['Debug|Win32','Release|Win32', + 'Debug|x64', 'Release|x64'] + list_cmdargs = ['debug=True target_arch=32', + 'debug=False target_arch=32', + 'debug=True target_arch=x64', + 'debug=False target_arch=x64'] + + # Tuple list : (parameter, dictionary of expected result per variant) + tests_cmdargs = [(None, dict.fromkeys(list_variant, '')), + ('', dict.fromkeys(list_variant, '')), + (list_cmdargs[0], dict.fromkeys(list_variant, list_cmdargs[0])), + (list_cmdargs, dict(zip(list_variant, list_cmdargs)))] + + # Run the test for each test case + for param_cmdargs, expected_cmdargs in tests_cmdargs: + debug('Testing %s. with :\n variant = %s \n cmdargs = "%s"' % \ + (str_function_test, list_variant, param_cmdargs)) + param_configs = [] + expected_configs = {} + for platform in ['Win32', 'x64']: + for variant in ['Debug', 'Release']: + variant_platform = '%s|%s' % (variant, platform) + runfile = '%s\\%s\\test.exe' % (platform, variant) + buildtarget = '%s\\%s\\test.exe' % (platform, variant) + outdir = '%s\\%s' % (platform, variant) + + # Create parameter list for this variant_platform + param_configs.append([variant_platform, runfile, buildtarget, outdir]) + + # Create expected dictionary result for this variant_platform + expected_configs[variant_platform] = \ + {'variant': variant, 'platform': platform, + 'runfile': runfile, + 'buildtarget': buildtarget, + 'outdir': outdir, + 'cmdargs': expected_cmdargs[variant_platform]} + + # Create parameter environment with final parameter dictionary + param_dict = dict(zip(('variant', 'runfile', 'buildtarget', 'outdir'), + [list(l) for l in zip(*param_configs)])) + param_dict['cmdargs'] = param_cmdargs + + # Hack to be able to run the test with a 'DummyEnv' + class _DummyEnv(DummyEnv): + def subst(self, string) : + return string + + env = _DummyEnv(param_dict) + env['MSVSSCONSCRIPT'] = '' + env['MSVS_VERSION'] = self.highest_version + + # Call function to test + genDSP = function_test(dspfile, source, env) + + # Check expected result + self.assertListEqual(genDSP.configs.keys(), expected_configs.keys()) + for key in genDSP.configs.keys(): + self.assertDictEqual(genDSP.configs[key].__dict__, expected_configs[key]) class msvs6aTestCase(msvsTestCase): """Test MSVS 6 Registry""" -- cgit v0.12 From 783d0c52593e21f8cdee0f314d9c7534315ea740 Mon Sep 17 00:00:00 2001 From: Alexandre Feblot Date: Wed, 12 Nov 2014 21:49:33 +0100 Subject: also set soname on sunos --- src/engine/SCons/Tool/__init__.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py index 81c052f..c6da57d 100644 --- a/src/engine/SCons/Tool/__init__.py +++ b/src/engine/SCons/Tool/__init__.py @@ -317,6 +317,11 @@ symlinks for the platform we are on""" shlink_flags += [ '-Wl,-soname=%s' % soname ] if Verbose: print " soname ",soname,", shlink_flags ",shlink_flags + elif platform == 'sunos': + suffix_re = re.escape(shlib_suffix + '.' + version) + (major, age, revision) = version.split(".") + soname = re.sub(suffix_re, shlib_suffix, libname) + '.' + major + shlink_flags += [ '-h', soname ] elif platform == 'cygwin': shlink_flags += [ '-Wl,-Bsymbolic', '-Wl,--out-implib,${TARGET.base}.a' ] -- cgit v0.12 From e3a660f0b60e8a06cf3e8450051a0f4472272d50 Mon Sep 17 00:00:00 2001 From: Dirk Baechle Date: Fri, 14 Nov 2014 17:23:45 +0100 Subject: - added latest contributors to CHANGES.txt --- src/CHANGES.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 1372baf..d7907ff 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -6,6 +6,12 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER + From Alexandre Feblot: + - Fix for VersionedSharedLibrary under 'sunos' platform. + + From Laurent Marchelli: + - Support for multiple cmdargs (one per variant) in VS project files. + From Dan Pidcock: - Added support for the 'PlatformToolset' tag in VS project files (#2978). -- cgit v0.12 From b52679b157050eaed717b2f2b01a9442efdc991c Mon Sep 17 00:00:00 2001 From: LaurentMarchelli Date: Wed, 26 Nov 2014 15:19:37 +0100 Subject: TempFileMunge duplicate output and duplicate temporary file generation bug fixed. --- src/engine/SCons/Platform/PlatformTests.py | 27 +++++++++++++++++++++++++++ src/engine/SCons/Platform/__init__.py | 17 ++++++++++++++++- 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/src/engine/SCons/Platform/PlatformTests.py b/src/engine/SCons/Platform/PlatformTests.py index ca3080e..46151e1 100644 --- a/src/engine/SCons/Platform/PlatformTests.py +++ b/src/engine/SCons/Platform/PlatformTests.py @@ -156,6 +156,33 @@ class TempFileMungeTestCase(unittest.TestCase): SCons.Action.print_actions = old_actions assert cmd != defined_cmd, cmd + def test_tempfilecreation_once(self): + # Init class with cmd, such that the fully expanded + # string reads "a test command line". + # Note, how we're using a command string here that is + # actually longer than the substituted one. This is to ensure + # that the TempFileMunge class internally really takes the + # length of the expanded string into account. + defined_cmd = "a $VERY $OVERSIMPLIFIED line" + t = SCons.Platform.TempFileMunge(defined_cmd) + env = SCons.Environment.SubstitutionEnvironment(tools=[]) + # Setting the line length high enough... + env['VERY'] = 'test' + env['OVERSIMPLIFIED'] = 'command' + expanded_cmd = env.subst(defined_cmd) + env['MAXLINELENGTH'] = len(expanded_cmd)-1 + # Disable printing of actions... + old_actions = SCons.Action.print_actions + SCons.Action.print_actions = 0 + # Create an instance of object derived class to allow setattrb + class TSList(object): pass + target = TSList() + cmd = t(target,None,env,0) + # ...and restoring its setting. + SCons.Action.print_actions = old_actions + assert cmd != defined_cmd, cmd + assert cmd == getattr(target, 'tempfile_cmdlist', None) + if __name__ == "__main__": suite = unittest.TestSuite() diff --git a/src/engine/SCons/Platform/__init__.py b/src/engine/SCons/Platform/__init__.py index fa6df61..6dc241e 100644 --- a/src/engine/SCons/Platform/__init__.py +++ b/src/engine/SCons/Platform/__init__.py @@ -177,6 +177,12 @@ class TempFileMunge(object): if length <= maxline: return self.cmd + # Check if we already created the temporary file for this Executor + # It should have been previously done by Action.strfunction() call + cmdlist = getattr(target, 'tempfile_cmdlist', None) + if cmdlist is not None : + return cmdlist + # We do a normpath because mktemp() has what appears to be # a bug in Windows that will use a forward slash as a path # delimiter. Windows's link mistakes that for a command line @@ -226,7 +232,16 @@ class TempFileMunge(object): if SCons.Action.print_actions: print("Using tempfile "+native_tmp+" for command line:\n"+ str(cmd[0]) + " " + " ".join(args)) - return [ cmd[0], prefix + native_tmp + '\n' + rm, native_tmp ] + + # Store the temporary file command list into the target TList hold by + # the Executor to avoid creating two temporary files one for print and + # one for execute + cmdlist = [ cmd[0], prefix + native_tmp + '\n' + rm, native_tmp ] + try : + setattr(target, 'tempfile_cmdlist', cmdlist) + except AttributeError: + pass + return cmdlist def Platform(name = platform_default()): """Select a canned Platform specification. -- cgit v0.12 From 03a3cc469fc3ac561ffcb81efe38fd08d4e9aa45 Mon Sep 17 00:00:00 2001 From: LaurentMarchelli Date: Thu, 27 Nov 2014 17:14:53 +0100 Subject: Using setattr(Node.attributes, 'tempfile_cmdlist', cmdlist) instead than setattr(TList, 'tempfile_cmdlist', cmdlist) --- src/engine/SCons/Platform/PlatformTests.py | 12 ++++++++---- src/engine/SCons/Platform/__init__.py | 22 ++++++++++++---------- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/engine/SCons/Platform/PlatformTests.py b/src/engine/SCons/Platform/PlatformTests.py index 46151e1..38ea55a 100644 --- a/src/engine/SCons/Platform/PlatformTests.py +++ b/src/engine/SCons/Platform/PlatformTests.py @@ -175,13 +175,17 @@ class TempFileMungeTestCase(unittest.TestCase): old_actions = SCons.Action.print_actions SCons.Action.print_actions = 0 # Create an instance of object derived class to allow setattrb - class TSList(object): pass - target = TSList() - cmd = t(target,None,env,0) + class Node(object) : + class Attrs(object): + pass + def __init__(self): + self.attributes = self.Attrs() + target = [Node()] + cmd = t(target, None, env, 0) # ...and restoring its setting. SCons.Action.print_actions = old_actions assert cmd != defined_cmd, cmd - assert cmd == getattr(target, 'tempfile_cmdlist', None) + assert cmd == getattr(target[0].attributes, 'tempfile_cmdlist', None) if __name__ == "__main__": suite = unittest.TestSuite() diff --git a/src/engine/SCons/Platform/__init__.py b/src/engine/SCons/Platform/__init__.py index 6dc241e..c33012b 100644 --- a/src/engine/SCons/Platform/__init__.py +++ b/src/engine/SCons/Platform/__init__.py @@ -177,10 +177,12 @@ class TempFileMunge(object): if length <= maxline: return self.cmd - # Check if we already created the temporary file for this Executor + # Check if we already created the temporary file for this target # It should have been previously done by Action.strfunction() call - cmdlist = getattr(target, 'tempfile_cmdlist', None) - if cmdlist is not None : + node = target[0] if SCons.Util.is_List(target) else target + cmdlist = getattr(node.attributes, 'tempfile_cmdlist', None) \ + if node is not None else None + if cmdlist is not None : return cmdlist # We do a normpath because mktemp() has what appears to be @@ -233,14 +235,14 @@ class TempFileMunge(object): print("Using tempfile "+native_tmp+" for command line:\n"+ str(cmd[0]) + " " + " ".join(args)) - # Store the temporary file command list into the target TList hold by - # the Executor to avoid creating two temporary files one for print and - # one for execute + # Store the temporary file command list into the target Node.attributes + # to avoid creating two temporary files one for print and one for execute. cmdlist = [ cmd[0], prefix + native_tmp + '\n' + rm, native_tmp ] - try : - setattr(target, 'tempfile_cmdlist', cmdlist) - except AttributeError: - pass + if node is not None: + try : + setattr(node.attributes, 'tempfile_cmdlist', cmdlist) + except AttributeError: + pass return cmdlist def Platform(name = platform_default()): -- cgit v0.12 From f0121389aa88ab9a3d232f5e516850d2aad2bf00 Mon Sep 17 00:00:00 2001 From: LaurentMarchelli Date: Tue, 2 Dec 2014 10:38:30 +0100 Subject: TempFileMunge does not use env['CXXCOMSTR'] for output display. --- src/engine/SCons/Platform/__init__.py | 13 +++++++++---- src/engine/SCons/Tool/jar.py | 2 +- src/engine/SCons/Tool/javac.py | 2 +- src/engine/SCons/Tool/mslib.py | 2 +- src/engine/SCons/Tool/mslink.py | 6 +++--- src/engine/SCons/Tool/msvc.py | 8 ++++---- 6 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/engine/SCons/Platform/__init__.py b/src/engine/SCons/Platform/__init__.py index c33012b..653f722 100644 --- a/src/engine/SCons/Platform/__init__.py +++ b/src/engine/SCons/Platform/__init__.py @@ -139,7 +139,7 @@ class TempFileMunge(object): Example usage: env["TEMPFILE"] = TempFileMunge - env["LINKCOM"] = "${TEMPFILE('$LINK $TARGET $SOURCES')}" + env["LINKCOM"] = "${TEMPFILE('$LINK $TARGET $SOURCES','$LINKCOMSTR')}" By default, the name of the temporary file used begins with a prefix of '@'. This may be configred for other tool chains by @@ -148,8 +148,9 @@ class TempFileMunge(object): env["TEMPFILEPREFIX"] = '-@' # diab compiler env["TEMPFILEPREFIX"] = '-via' # arm tool chain """ - def __init__(self, cmd): + def __init__(self, cmd, cmdstr = None): self.cmd = cmd + self.cmdstr = cmdstr def __call__(self, target, source, env, for_signature): if for_signature: @@ -232,8 +233,12 @@ class TempFileMunge(object): # purity get in the way of just being helpful, so we'll # reach into SCons.Action directly. if SCons.Action.print_actions: - print("Using tempfile "+native_tmp+" for command line:\n"+ - str(cmd[0]) + " " + " ".join(args)) + cmdstr = env.subst(self.cmdstr, SCons.Subst.SUBST_RAW, target, + source) if self.cmdstr is not None else '' + # Print our message only if XXXCOMSTR returns an empty string + if len(cmdstr) == 0 : + print("Using tempfile "+native_tmp+" for command line:\n"+ + str(cmd[0]) + " " + " ".join(args)) # Store the temporary file command list into the target Node.attributes # to avoid creating two temporary files one for print and one for execute. diff --git a/src/engine/SCons/Tool/jar.py b/src/engine/SCons/Tool/jar.py index 9bae729..8308927 100644 --- a/src/engine/SCons/Tool/jar.py +++ b/src/engine/SCons/Tool/jar.py @@ -97,7 +97,7 @@ def generate(env): env['_JARMANIFEST'] = jarManifest env['_JARSOURCES'] = jarSources env['_JARCOM'] = '$JAR $_JARFLAGS $TARGET $_JARMANIFEST $_JARSOURCES' - env['JARCOM'] = "${TEMPFILE('$_JARCOM')}" + env['JARCOM'] = "${TEMPFILE('$_JARCOM','$JARCOMSTR')}" env['JARSUFFIX'] = '.jar' def exists(env): diff --git a/src/engine/SCons/Tool/javac.py b/src/engine/SCons/Tool/javac.py index 5d0e32a..b26c0b3 100644 --- a/src/engine/SCons/Tool/javac.py +++ b/src/engine/SCons/Tool/javac.py @@ -218,7 +218,7 @@ def generate(env): 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['JAVACCOM'] = "${TEMPFILE('$_JAVACCOM','$JAVACCOMSTR')}" env['JAVACLASSSUFFIX'] = '.class' env['JAVASUFFIX'] = '.java' diff --git a/src/engine/SCons/Tool/mslib.py b/src/engine/SCons/Tool/mslib.py index 8a4af57..2453979 100644 --- a/src/engine/SCons/Tool/mslib.py +++ b/src/engine/SCons/Tool/mslib.py @@ -50,7 +50,7 @@ def generate(env): env['AR'] = 'lib' env['ARFLAGS'] = SCons.Util.CLVar('/nologo') - env['ARCOM'] = "${TEMPFILE('$AR $ARFLAGS /OUT:$TARGET $SOURCES')}" + env['ARCOM'] = "${TEMPFILE('$AR $ARFLAGS /OUT:$TARGET $SOURCES','$ARCOMSTR')}" env['LIBPREFIX'] = '' env['LIBSUFFIX'] = '.lib' diff --git a/src/engine/SCons/Tool/mslink.py b/src/engine/SCons/Tool/mslink.py index 40f112b..37af34e 100644 --- a/src/engine/SCons/Tool/mslink.py +++ b/src/engine/SCons/Tool/mslink.py @@ -237,11 +237,11 @@ 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') +shlibLinkAction = SCons.Action.Action('${TEMPFILE("$SHLINK $SHLINKFLAGS $_SHLINK_TARGETS $_LIBDIRFLAGS $_LIBFLAGS $_PDB $_SHLINK_SOURCES", "$SHLINKCOMSTR")}', '$SHLINKCOMSTR') compositeShLinkAction = shlibLinkAction + regServerCheck + embedManifestDllCheckAction -ldmodLinkAction = SCons.Action.Action('${TEMPFILE("$LDMODULE $LDMODULEFLAGS $_LDMODULE_TARGETS $_LIBDIRFLAGS $_LIBFLAGS $_PDB $_LDMODULE_SOURCES")}', '$LDMODULECOMSTR') +ldmodLinkAction = SCons.Action.Action('${TEMPFILE("$LDMODULE $LDMODULEFLAGS $_LDMODULE_TARGETS $_LIBDIRFLAGS $_LIBFLAGS $_PDB $_LDMODULE_SOURCES", "$LDMODULECOMSTR")}', '$LDMODULECOMSTR') compositeLdmodAction = ldmodLinkAction + regServerCheck + embedManifestDllCheckAction -exeLinkAction = SCons.Action.Action('${TEMPFILE("$LINK $LINKFLAGS /OUT:$TARGET.windows $_LIBDIRFLAGS $_LIBFLAGS $_PDB $SOURCES.windows")}', '$LINKCOMSTR') +exeLinkAction = SCons.Action.Action('${TEMPFILE("$LINK $LINKFLAGS /OUT:$TARGET.windows $_LIBDIRFLAGS $_LIBFLAGS $_PDB $SOURCES.windows", "$LINKCOMSTR")}', '$LINKCOMSTR') compositeLinkAction = exeLinkAction + embedManifestExeCheckAction def generate(env): diff --git a/src/engine/SCons/Tool/msvc.py b/src/engine/SCons/Tool/msvc.py index d42c257..878ec6e 100644 --- a/src/engine/SCons/Tool/msvc.py +++ b/src/engine/SCons/Tool/msvc.py @@ -224,17 +224,17 @@ def generate(env): 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['CCCOM'] = '${TEMPFILE("$CC $_MSVC_OUTPUT_FLAG /c $CHANGED_SOURCES $CFLAGS $CCFLAGS $_CCCOMCOM","$CCCOMSTR")}' 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['SHCCCOM'] = '${TEMPFILE("$SHCC $_MSVC_OUTPUT_FLAG /c $CHANGED_SOURCES $SHCFLAGS $SHCCFLAGS $_CCCOMCOM","$SHCCCOMSTR")}' env['CXX'] = '$CC' env['CXXFLAGS'] = SCons.Util.CLVar('$( /TP $)') - env['CXXCOM'] = '${TEMPFILE("$CXX $_MSVC_OUTPUT_FLAG /c $CHANGED_SOURCES $CXXFLAGS $CCFLAGS $_CCCOMCOM")}' + env['CXXCOM'] = '${TEMPFILE("$CXX $_MSVC_OUTPUT_FLAG /c $CHANGED_SOURCES $CXXFLAGS $CCFLAGS $_CCCOMCOM","$CXXCOMSTR")}' env['SHCXX'] = '$CXX' env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS') - env['SHCXXCOM'] = '${TEMPFILE("$SHCXX $_MSVC_OUTPUT_FLAG /c $CHANGED_SOURCES $SHCXXFLAGS $SHCCFLAGS $_CCCOMCOM")}' + env['SHCXXCOM'] = '${TEMPFILE("$SHCXX $_MSVC_OUTPUT_FLAG /c $CHANGED_SOURCES $SHCXXFLAGS $SHCCFLAGS $_CCCOMCOM","$SHCXXCOMSTR")}' env['CPPDEFPREFIX'] = '/D' env['CPPDEFSUFFIX'] = '' env['INCPREFIX'] = '/I' -- cgit v0.12 From a759567a12fbd11989bea5f8eb0238639ec15e8b Mon Sep 17 00:00:00 2001 From: Dirk Baechle Date: Fri, 19 Dec 2014 15:59:20 +0100 Subject: - switching versioned shared libs to using Node.attributes --- src/engine/SCons/Tool/__init__.py | 19 ++++++++++++++++--- src/engine/SCons/Tool/install.py | 20 ++++++++++++++------ src/engine/SCons/Tool/link.py | 32 +++++++++++++++++++++++--------- 3 files changed, 53 insertions(+), 18 deletions(-) diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py index c6da57d..0447dd9 100644 --- a/src/engine/SCons/Tool/__init__.py +++ b/src/engine/SCons/Tool/__init__.py @@ -293,7 +293,10 @@ symlinks for the platform we are on""" version = None # libname includes the version number if one was given - libname = target[0].name + if hasattr(target[0].attributes, 'shlibname'): + libname = target[0].attributes.shlibname + else: + libname = target[0].name platform = env.subst('$PLATFORM') shlib_suffix = env.subst('$SHLIBSUFFIX') shlink_flags = SCons.Util.CLVar(env.subst('$SHLINKFLAGS')) @@ -340,12 +343,22 @@ symlinks for the platform we are on""" if version: # here we need the full pathname so the links end up in the right directory - libname = target[0].path + if hasattr(target[0].attributes, 'shlibname'): + libname = target[0].attributes.shlibname + else: + libname = target[0].path + if Verbose: + print "VerShLib: target lib is = ", libname + print "VerShLib: name is = ", target[0].name + print "VerShLib: dir is = ", target[0].dir.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 + if hasattr(target[0].attributes, 'shlibname'): + lib_ver = target[0].attributes.shlibname + else: + lib_ver = target[0].name # make symlink of adjacent names in linknames for count in range(len(linknames)): linkname = linknames[count] diff --git a/src/engine/SCons/Tool/install.py b/src/engine/SCons/Tool/install.py index 66869b7..9f2e937 100644 --- a/src/engine/SCons/Tool/install.py +++ b/src/engine/SCons/Tool/install.py @@ -145,15 +145,19 @@ def copyFuncVersionedLib(dest, source, env): return 0 -def versionedLibVersion(dest, env): +def versionedLibVersion(dest, source, 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' or platform == 'sunos'): return (None, None, None) - libname = os.path.basename(dest) - install_dir = os.path.dirname(dest) + if (hasattr(source[0], 'attributes') and + hasattr(source[0].attributes, 'shlibname')): + libname = source[0].attributes.shlibname + else: + libname = os.path.basename(str(dest)) + install_dir = os.path.dirname(str(dest)) shlib_suffix = env.subst('$SHLIBSUFFIX') # See if the source name is a versioned shared library, get the version number result = False @@ -196,7 +200,7 @@ 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) + version, libname, install_dir = versionedLibVersion(dest, source, env) if version != None: # libname includes the version number if one was given @@ -258,7 +262,11 @@ def installFuncVersionedLib(target, source, env): 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): + if hasattr(t.attributes, 'shlibname'): + tpath = os.path.join(t.get_dir(), t.attributes.shlibname) + else: + tpath = t.get_path() + if install(tpath,s.get_path(),env): return 1 return 0 @@ -301,7 +309,7 @@ def add_versioned_targets_to_INSTALLED_FILES(target, source, env): 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) + version, libname, install_dir = versionedLibVersion(target[0], source, env) if version != None: # generate list of link names linknames = SCons.Tool.VersionShLibLinkNames(version,libname,env) diff --git a/src/engine/SCons/Tool/link.py b/src/engine/SCons/Tool/link.py index f70f5b8..2624946 100644 --- a/src/engine/SCons/Tool/link.py +++ b/src/engine/SCons/Tool/link.py @@ -82,13 +82,18 @@ def shlib_emitter(target, source, env): 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) + # mark the target with the shared libraries name, including + # the version number + target[0].attributes.shlibname = version_names[0] + shlib = env.File(version_names[0], directory=target[0].get_dir()) + target[0].attributes.shlibpath = shlib.path + for name in version_names[1:]: + env.SideEffect(name, shlib) + env.Clean(shlib, name) if Verbose: print "shlib_emitter: add side effect - ",name + env.Clean(shlib, target[0]) + return ([shlib], source) except KeyError: version = None return (target, source) @@ -107,9 +112,12 @@ def shlib_emitter_names(target, source, env): if version: if platform == 'posix' or platform == 'sunos': versionparts = version.split('.') - name = target[0].name + if hasattr(target[0].attributes, 'shlibname'): + name = target[0].attributes.shlibname + else: + name = target[0].name # generate library name with the version number - version_name = target[0].name + '.' + version + version_name = name + '.' + version if Verbose: print "shlib_emitter_names: target is ", version_name print "shlib_emitter_names: side effect: ", name @@ -125,7 +133,10 @@ def shlib_emitter_names(target, source, env): version_names.append(name) elif platform == 'darwin': shlib_suffix = env.subst('$SHLIBSUFFIX') - name = target[0].name + if hasattr(target[0].attributes, 'shlibname'): + name = target[0].attributes.shlibname + else: + 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) @@ -136,7 +147,10 @@ def shlib_emitter_names(target, source, env): version_names.append(version_name) elif platform == 'cygwin': shlib_suffix = env.subst('$SHLIBSUFFIX') - name = target[0].name + if hasattr(target[0].attributes, 'shlibname'): + name = target[0].attributes.shlibname + else: + 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) -- cgit v0.12 From e580cc1a08898f30e8f667b7c41bac6bd234d141 Mon Sep 17 00:00:00 2001 From: Dirk Baechle Date: Sun, 21 Dec 2014 00:46:16 +0100 Subject: - fixed typo, which would use the wrong attribute --- src/engine/SCons/Tool/__init__.py | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py index 0447dd9..2621cf9 100644 --- a/src/engine/SCons/Tool/__init__.py +++ b/src/engine/SCons/Tool/__init__.py @@ -293,10 +293,7 @@ symlinks for the platform we are on""" version = None # libname includes the version number if one was given - if hasattr(target[0].attributes, 'shlibname'): - libname = target[0].attributes.shlibname - else: - libname = target[0].name + libname = getattr(target[0].attributes, 'shlibname', target[0].name) platform = env.subst('$PLATFORM') shlib_suffix = env.subst('$SHLIBSUFFIX') shlink_flags = SCons.Util.CLVar(env.subst('$SHLINKFLAGS')) @@ -343,10 +340,7 @@ symlinks for the platform we are on""" if version: # here we need the full pathname so the links end up in the right directory - if hasattr(target[0].attributes, 'shlibname'): - libname = target[0].attributes.shlibname - else: - libname = target[0].path + libname = getattr(target[0].attributes, 'shlibpath', target[0].path) if Verbose: print "VerShLib: target lib is = ", libname print "VerShLib: name is = ", target[0].name @@ -355,10 +349,7 @@ symlinks for the platform we are on""" if Verbose: print "VerShLib: linknames ",linknames # Here we just need the file name w/o path as the target of the link - if hasattr(target[0].attributes, 'shlibname'): - lib_ver = target[0].attributes.shlibname - else: - lib_ver = target[0].name + lib_ver = getattr(target[0].attributes, 'shlibname', target[0].name) # make symlink of adjacent names in linknames for count in range(len(linknames)): linkname = linknames[count] -- cgit v0.12 From 975776d32d0f78b3a9d03a0c3ce29a3af2f1b872 Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Sun, 21 Dec 2014 15:50:29 +0000 Subject: Correct a spelling error, should fix one of the test fails. --- src/engine/SCons/Tool/ldc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/SCons/Tool/ldc.py b/src/engine/SCons/Tool/ldc.py index d74464f..768c885 100644 --- a/src/engine/SCons/Tool/ldc.py +++ b/src/engine/SCons/Tool/ldc.py @@ -101,7 +101,7 @@ def generate(env): env['DLINKCOM'] = '$DLINK -of=$TARGET $DLINKFLAGS $__DRPATH $SOURCES $_DLIBDIRFLAGS $_DLIBFLAGS' env['DSHLINK'] = '$DC' - env['DSHLINKFLAGS'] = SCons.Util.CLVar('$DLINKFLAGS -shared -defaultlib=phobos2') + env['DSHLINKFLAGS'] = SCons.Util.CLVar('$DLINKFLAGS -shared -defaultlib=phobos-ldc') env['SHDLINKCOM'] = '$DLINK -of=$TARGET $DSHLINKFLAGS $__DRPATH $SOURCES $_DLIBDIRFLAGS $_DLIBFLAGS' env['DLIBLINKPREFIX'] = '' if env['PLATFORM'] == 'win32' else '-L-l' -- cgit v0.12 From cf37fe92d43ccb0d2ec715fc603ca439588ee566 Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Sun, 21 Dec 2014 17:47:01 +0000 Subject: Hack the tests (in an agreed quasi-acceptable way) to avoid CI fails. --- src/engine/SCons/Tool/ldc.py | 2 +- test/D/DMD2.py | 1 + test/D/DMD2_Alt.py | 1 + test/D/HSTeoh/ArLibIssue/SConstruct_template | 3 +++ test/D/HSTeoh/Common/singleStringCannotBeMultipleOptions.py | 4 ++++ test/D/HSTeoh/LibCompileOptions/SConstruct_template | 3 +++ test/D/HSTeoh/LinkingProblem/SConstruct_template | 2 ++ test/D/Issues/2939_Ariovistus/Project/SConstruct_template | 3 +++ test/D/Issues/2940_Ariovistus/Project/SConstruct_template | 3 +++ test/D/SharedObjects/Common/common.py | 3 +++ test/D/SharedObjects/Image/SConstruct_template | 2 ++ 11 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/engine/SCons/Tool/ldc.py b/src/engine/SCons/Tool/ldc.py index 768c885..d519d8d 100644 --- a/src/engine/SCons/Tool/ldc.py +++ b/src/engine/SCons/Tool/ldc.py @@ -101,7 +101,7 @@ def generate(env): env['DLINKCOM'] = '$DLINK -of=$TARGET $DLINKFLAGS $__DRPATH $SOURCES $_DLIBDIRFLAGS $_DLIBFLAGS' env['DSHLINK'] = '$DC' - env['DSHLINKFLAGS'] = SCons.Util.CLVar('$DLINKFLAGS -shared -defaultlib=phobos-ldc') + env['DSHLINKFLAGS'] = SCons.Util.CLVar('$DLINKFLAGS -shared -defaultlib=phobos2-ldc') env['SHDLINKCOM'] = '$DLINK -of=$TARGET $DSHLINKFLAGS $__DRPATH $SOURCES $_DLIBDIRFLAGS $_DLIBFLAGS' env['DLIBLINKPREFIX'] = '' if env['PLATFORM'] == 'win32' else '-L-l' diff --git a/test/D/DMD2.py b/test/D/DMD2.py index fc5f79f..84ceb51 100644 --- a/test/D/DMD2.py +++ b/test/D/DMD2.py @@ -42,6 +42,7 @@ if not isExecutableOfToolAvailable(test, 'dmd'): test.write('SConstruct', """\ import os env = Environment(tools=['link', 'dmd']) +env['ENV']['HOME'] = os.environ['HOME'] # Hack for gdmd if env['PLATFORM'] == 'cygwin': env['OBJSUFFIX'] = '.obj' # trick DMD env.Program('foo', 'foo.d') """) diff --git a/test/D/DMD2_Alt.py b/test/D/DMD2_Alt.py index 11c061d..3bd58b4 100644 --- a/test/D/DMD2_Alt.py +++ b/test/D/DMD2_Alt.py @@ -42,6 +42,7 @@ if not isExecutableOfToolAvailable(test, 'dmd'): test.write('SConstruct', """\ import os env = Environment(tools=['dmd', 'link']) +env['ENV']['HOME'] = os.environ['HOME'] # Hack for gdmd if env['PLATFORM'] == 'cygwin': env['OBJSUFFIX'] = '.obj' # trick DMD env.Program('foo', 'foo.d') """) diff --git a/test/D/HSTeoh/ArLibIssue/SConstruct_template b/test/D/HSTeoh/ArLibIssue/SConstruct_template index 81f81f5..b17847a 100644 --- a/test/D/HSTeoh/ArLibIssue/SConstruct_template +++ b/test/D/HSTeoh/ArLibIssue/SConstruct_template @@ -1,3 +1,6 @@ env = Environment({}) +import os +env['ENV']['HOME'] = os.environ['HOME'] # Hack for gdmd + env.StaticLibrary('mylib', ['a.d', 'b.d']) diff --git a/test/D/HSTeoh/Common/singleStringCannotBeMultipleOptions.py b/test/D/HSTeoh/Common/singleStringCannotBeMultipleOptions.py index 26b477b..4716f1c 100644 --- a/test/D/HSTeoh/Common/singleStringCannotBeMultipleOptions.py +++ b/test/D/HSTeoh/Common/singleStringCannotBeMultipleOptions.py @@ -55,6 +55,10 @@ def testForTool(tool): 'ldc': ".*Unknown command line argument '-m64 -O'.*", }[tool] + from SCons.Environment import Base + if tool == 'dmd' and Base()['DC'] == 'gdmd': + result = ".*unrecognized command line option '-m64 -O'.*" + test.fail_test(not test.match_re_dotall(test.stderr(), result)) test.pass_test() diff --git a/test/D/HSTeoh/LibCompileOptions/SConstruct_template b/test/D/HSTeoh/LibCompileOptions/SConstruct_template index 7031f5c..1489624 100644 --- a/test/D/HSTeoh/LibCompileOptions/SConstruct_template +++ b/test/D/HSTeoh/LibCompileOptions/SConstruct_template @@ -1,5 +1,8 @@ env = Environment({}) +import os +env['ENV']['HOME'] = os.environ['HOME'] # Hack for gdmd + env.Library('mylib', 'mylib.d') prog_env = env.Clone( diff --git a/test/D/HSTeoh/LinkingProblem/SConstruct_template b/test/D/HSTeoh/LinkingProblem/SConstruct_template index a4aa795..2c53b54 100644 --- a/test/D/HSTeoh/LinkingProblem/SConstruct_template +++ b/test/D/HSTeoh/LinkingProblem/SConstruct_template @@ -6,6 +6,8 @@ environment = Environment( tools = ['cc', '{}', 'link'], LIBS = ['ncurses']) +environment['ENV']['HOME'] = os.environ['HOME'] # Hack for gdmd + environment.Object('ncurs_impl.o', 'ncurs_impl.c') environment.Program('prog', Split(""" diff --git a/test/D/Issues/2939_Ariovistus/Project/SConstruct_template b/test/D/Issues/2939_Ariovistus/Project/SConstruct_template index 55f02aa..c78ba96 100644 --- a/test/D/Issues/2939_Ariovistus/Project/SConstruct_template +++ b/test/D/Issues/2939_Ariovistus/Project/SConstruct_template @@ -2,6 +2,9 @@ from os.path import join environment = Environment({}) +import os +environment['ENV']['HOME'] = os.environ['HOME'] # Hack for gdmd + Export('environment') environment.SConscript([ diff --git a/test/D/Issues/2940_Ariovistus/Project/SConstruct_template b/test/D/Issues/2940_Ariovistus/Project/SConstruct_template index 55f02aa..c78ba96 100644 --- a/test/D/Issues/2940_Ariovistus/Project/SConstruct_template +++ b/test/D/Issues/2940_Ariovistus/Project/SConstruct_template @@ -2,6 +2,9 @@ from os.path import join environment = Environment({}) +import os +environment['ENV']['HOME'] = os.environ['HOME'] # Hack for gdmd + Export('environment') environment.SConscript([ diff --git a/test/D/SharedObjects/Common/common.py b/test/D/SharedObjects/Common/common.py index cb1e71b..83b5162 100644 --- a/test/D/SharedObjects/Common/common.py +++ b/test/D/SharedObjects/Common/common.py @@ -49,6 +49,9 @@ def testForTool(tool): if tool == 'gdc': test.skip_test('gdc does not, as at version 4.9.1, support shared libraries.\n') + if tool == 'dmd' and Base()['DC'] == 'gdmd': + test.skip_test('gdmd does not recognize the -shared option so cannot support linking of shared objects.\n') + platform = Base()['PLATFORM'] if platform == 'posix': diff --git a/test/D/SharedObjects/Image/SConstruct_template b/test/D/SharedObjects/Image/SConstruct_template index 213de7e..cae8713 100644 --- a/test/D/SharedObjects/Image/SConstruct_template +++ b/test/D/SharedObjects/Image/SConstruct_template @@ -5,4 +5,6 @@ import os environment = Environment( tools=['{}', 'link']) +environment['ENV']['HOME'] = os.environ['HOME'] # Hack for gdmd + environment.SharedLibrary('answer', 'code.d') -- cgit v0.12 From fa591a7d900aced7d709e00f55c2b6c4d6c5e945 Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Sun, 21 Dec 2014 18:08:15 +0000 Subject: Putative hack for the Fedora library misnaming. --- src/engine/SCons/Tool/ldc.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/engine/SCons/Tool/ldc.py b/src/engine/SCons/Tool/ldc.py index d519d8d..71f2668 100644 --- a/src/engine/SCons/Tool/ldc.py +++ b/src/engine/SCons/Tool/ldc.py @@ -102,6 +102,9 @@ def generate(env): env['DSHLINK'] = '$DC' env['DSHLINKFLAGS'] = SCons.Util.CLVar('$DLINKFLAGS -shared -defaultlib=phobos2-ldc') + # Hack for Fedora the packages of which use the wrong name :-( + if os.path.exists('/usr/lib64/libphobos-ldc.so'): + env['DSHLINKFLAGS'] = SCons.Util.CLVar('$DLINKFLAGS -shared -defaultlib=phobos-ldc') env['SHDLINKCOM'] = '$DLINK -of=$TARGET $DSHLINKFLAGS $__DRPATH $SOURCES $_DLIBDIRFLAGS $_DLIBFLAGS' env['DLIBLINKPREFIX'] = '' if env['PLATFORM'] == 'win32' else '-L-l' -- cgit v0.12 From d7715dc0190d7e1cf15907e47a0f71673c92bbce Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Mon, 22 Dec 2014 17:01:12 +0000 Subject: Putative solution to lakc of ncurses on one of the CI machines. --- test/D/HSTeoh/Common/linkingProblem.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/D/HSTeoh/Common/linkingProblem.py b/test/D/HSTeoh/Common/linkingProblem.py index 46351b3..ab096f2 100644 --- a/test/D/HSTeoh/Common/linkingProblem.py +++ b/test/D/HSTeoh/Common/linkingProblem.py @@ -29,7 +29,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import TestSCons -from os.path import abspath, dirname +from os.path import abspath, dirname, exists import sys sys.path.insert(1, abspath(dirname(__file__) + '/../../Support')) @@ -43,6 +43,9 @@ def testForTool(tool): if not isExecutableOfToolAvailable(test, tool) : test.skip_test("Required executable for tool '{0}' not found, skipping test.\n".format(tool)) + if not exists('/usr/bin/tset'): + test.skip_test("ncurses not apparently installed, skip this test.") + test.dir_fixture('LinkingProblem') test.write('SConstruct', open('SConstruct_template', 'r').read().format(tool)) -- cgit v0.12 From 5e562898f16fba84d5aec291954479503da275a4 Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Mon, 22 Dec 2014 17:17:08 +0000 Subject: Putative fix for the CI problem perceived to be due to 32-bit platform. --- test/D/MixedDAndC/Common/common.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/D/MixedDAndC/Common/common.py b/test/D/MixedDAndC/Common/common.py index c9ecb6a..bd761d1 100644 --- a/test/D/MixedDAndC/Common/common.py +++ b/test/D/MixedDAndC/Common/common.py @@ -29,6 +29,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import TestSCons +from os import uname from os.path import abspath, dirname import sys @@ -47,6 +48,9 @@ def testForTool(tool): test.run() + if uname()[4] not in ('x86_64',): + test.fail_test('64-bit mode not compiled in' not in test.stdout()) + test.pass_test() # Local Variables: -- cgit v0.12 From b5289dd61ad57ec7cb992e11b27399c2f9536410 Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Mon, 22 Dec 2014 17:22:52 +0000 Subject: Replace UNIX specific code with cross-platform code. --- test/D/MixedDAndC/Common/common.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/D/MixedDAndC/Common/common.py b/test/D/MixedDAndC/Common/common.py index bd761d1..b356411 100644 --- a/test/D/MixedDAndC/Common/common.py +++ b/test/D/MixedDAndC/Common/common.py @@ -29,8 +29,8 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import TestSCons -from os import uname from os.path import abspath, dirname +from platform import machine import sys sys.path.insert(1, abspath(dirname(__file__) + '/../../Support')) @@ -48,7 +48,7 @@ def testForTool(tool): test.run() - if uname()[4] not in ('x86_64',): + if machine() in ('i386',): test.fail_test('64-bit mode not compiled in' not in test.stdout()) test.pass_test() -- cgit v0.12 From bf68741be4a5f18536751459b4cea45cccffcb52 Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Mon, 22 Dec 2014 18:17:53 +0000 Subject: Remove excess blank lines. --- test/D/SharedObjects/Common/common.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/D/SharedObjects/Common/common.py b/test/D/SharedObjects/Common/common.py index 83b5162..e81cf5b 100644 --- a/test/D/SharedObjects/Common/common.py +++ b/test/D/SharedObjects/Common/common.py @@ -45,14 +45,12 @@ def testForTool(tool): if not isExecutableOfToolAvailable(test, tool) : test.skip_test("Required executable for tool '{0}' not found, skipping test.\n".format(tool)) - if tool == 'gdc': test.skip_test('gdc does not, as at version 4.9.1, support shared libraries.\n') if tool == 'dmd' and Base()['DC'] == 'gdmd': test.skip_test('gdmd does not recognize the -shared option so cannot support linking of shared objects.\n') - platform = Base()['PLATFORM'] if platform == 'posix': filename = 'code.o' -- cgit v0.12 From 90247485ca647e1fb87e10216270eb8da01d37d7 Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Mon, 22 Dec 2014 18:18:40 +0000 Subject: Cover all cases of badly named LDC phobos library, not just 64-bit. --- src/engine/SCons/Tool/ldc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/SCons/Tool/ldc.py b/src/engine/SCons/Tool/ldc.py index 71f2668..ebef55d 100644 --- a/src/engine/SCons/Tool/ldc.py +++ b/src/engine/SCons/Tool/ldc.py @@ -103,7 +103,7 @@ def generate(env): env['DSHLINK'] = '$DC' env['DSHLINKFLAGS'] = SCons.Util.CLVar('$DLINKFLAGS -shared -defaultlib=phobos2-ldc') # Hack for Fedora the packages of which use the wrong name :-( - if os.path.exists('/usr/lib64/libphobos-ldc.so'): + if os.path.exists('/usr/lib64/libphobos-ldc.so') or os.path.exists('/usr/lib32/libphobos-ldc.so') or os.path.exists('/usr/lib/libphobos-ldc.so') : env['DSHLINKFLAGS'] = SCons.Util.CLVar('$DLINKFLAGS -shared -defaultlib=phobos-ldc') env['SHDLINKCOM'] = '$DLINK -of=$TARGET $DSHLINKFLAGS $__DRPATH $SOURCES $_DLIBDIRFLAGS $_DLIBFLAGS' -- cgit v0.12 From fc7798ccedd016225f3e9d4cf9ba4dee40a5b1a4 Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Tue, 23 Dec 2014 08:12:43 +0000 Subject: Check for the header file itself on not an associated executable. --- test/D/HSTeoh/Common/linkingProblem.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/D/HSTeoh/Common/linkingProblem.py b/test/D/HSTeoh/Common/linkingProblem.py index ab096f2..b526ad7 100644 --- a/test/D/HSTeoh/Common/linkingProblem.py +++ b/test/D/HSTeoh/Common/linkingProblem.py @@ -43,7 +43,7 @@ def testForTool(tool): if not isExecutableOfToolAvailable(test, tool) : test.skip_test("Required executable for tool '{0}' not found, skipping test.\n".format(tool)) - if not exists('/usr/bin/tset'): + if not exists('/usr/include/ncurses.h'): test.skip_test("ncurses not apparently installed, skip this test.") test.dir_fixture('LinkingProblem') -- cgit v0.12 From f4e67e95ae44fbd0734e70c85a29c8b7a603e329 Mon Sep 17 00:00:00 2001 From: anatoly techtonik Date: Sun, 28 Dec 2014 14:27:15 +0300 Subject: Improve invalid --config value handling for multiple choices: Changes output of `scons --config` from: usage: scons [OPTION] [TARGET] ... SCons Error: --config option requires an argument To: usage: scons [OPTION] [TARGET] ... SCons Error: --config option requires an argument (choose from auto, force, cache) --- src/engine/SCons/Script/SConsOptions.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/engine/SCons/Script/SConsOptions.py b/src/engine/SCons/Script/SConsOptions.py index d7262a9..8ecc093 100644 --- a/src/engine/SCons/Script/SConsOptions.py +++ b/src/engine/SCons/Script/SConsOptions.py @@ -319,7 +319,13 @@ class SConsOptionParser(optparse.OptionParser): value = option.const elif len(rargs) < nargs: if nargs == 1: - self.error(_("%s option requires an argument") % opt) + if not option.choices: + self.error(_("%s option requires an argument") % opt) + else: + msg = _("%s option requires an argument " % opt) + msg += _("(choose from %s)" + % ', '.join(option.choices)) + self.error(msg) else: self.error(_("%s option requires %d arguments") % (opt, nargs)) @@ -645,18 +651,12 @@ def Parser(version): config_options = ["auto", "force" ,"cache"] - def opt_config(option, opt, value, parser, c_options=config_options): - if not value in c_options: - raise OptionValueError(opt_invalid('config', value, c_options)) - setattr(parser.values, option.dest, value) - opt_config_help = "Controls Configure subsystem: %s." \ % ", ".join(config_options) op.add_option('--config', - nargs=1, type="string", + nargs=1, choices=config_options, dest="config", default="auto", - action="callback", callback=opt_config, help = opt_config_help, metavar="MODE") -- cgit v0.12 From e544a59d8cf297b36b69582c661e9558a124d4e5 Mon Sep 17 00:00:00 2001 From: anatoly techtonik Date: Mon, 29 Dec 2014 12:46:53 +0300 Subject: Update CHANGES.txt for --config improvement --- src/CHANGES.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index d7907ff..6173b03 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -6,6 +6,9 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER + From Anatoly Techtonik: + - Show --config choices if no argument is specified (PR #202). + From Alexandre Feblot: - Fix for VersionedSharedLibrary under 'sunos' platform. -- cgit v0.12 From 4d45e513c90ddeb3b93c44c2264258aa44b7b36b Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Wed, 7 Jan 2015 11:46:42 +0000 Subject: Update Fortran tooling to support .f08 file extensions. --- src/CHANGES.txt | 3 + src/engine/SCons/Tool/FortranCommon.py | 16 ++ src/engine/SCons/Tool/f08.py | 63 +++++++ src/engine/SCons/Tool/f08.xml | 311 +++++++++++++++++++++++++++++++++ src/engine/SCons/Tool/gfortran.py | 2 +- test/Fortran/F08.py | 151 ++++++++++++++++ test/Fortran/F08COM.py | 98 +++++++++++ test/Fortran/F08COMSTR.py | 78 +++++++++ test/Fortran/F08FILESUFFIXES.py | 101 +++++++++++ test/Fortran/F08FILESUFFIXES2.py | 91 ++++++++++ test/Fortran/F08FLAGS.py | 158 +++++++++++++++++ test/Fortran/SHF08.py | 144 +++++++++++++++ 12 files changed, 1215 insertions(+), 1 deletion(-) create mode 100644 src/engine/SCons/Tool/f08.py create mode 100644 src/engine/SCons/Tool/f08.xml create mode 100644 test/Fortran/F08.py create mode 100644 test/Fortran/F08COM.py create mode 100644 test/Fortran/F08COMSTR.py create mode 100644 test/Fortran/F08FILESUFFIXES.py create mode 100644 test/Fortran/F08FILESUFFIXES2.py create mode 100644 test/Fortran/F08FLAGS.py create mode 100644 test/Fortran/SHF08.py diff --git a/src/CHANGES.txt b/src/CHANGES.txt index d7907ff..be609a5 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -6,6 +6,9 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER + From Russel Winder: + - Add support for f08 file extensions for Fortran 2008 code. + From Alexandre Feblot: - Fix for VersionedSharedLibrary under 'sunos' platform. diff --git a/src/engine/SCons/Tool/FortranCommon.py b/src/engine/SCons/Tool/FortranCommon.py index 4c5730c..2df2a32 100644 --- a/src/engine/SCons/Tool/FortranCommon.py +++ b/src/engine/SCons/Tool/FortranCommon.py @@ -247,6 +247,21 @@ def add_f03_to_env(env): DialectAddToEnv(env, "F03", F03Suffixes, F03PPSuffixes, support_module = 1) +def add_f08_to_env(env): + """Add Builders and construction variables for f08 to an Environment.""" + try: + F08Suffixes = env['F08FILESUFFIXES'] + except KeyError: + F08Suffixes = ['.f08'] + + try: + F08PPSuffixes = env['F08PPFILESUFFIXES'] + except KeyError: + F08PPSuffixes = [] + + DialectAddToEnv(env, "F08", F08Suffixes, F08PPSuffixes, + support_module = 1) + def add_all_to_env(env): """Add builders and construction variables for all supported fortran dialects.""" @@ -255,6 +270,7 @@ def add_all_to_env(env): add_f90_to_env(env) add_f95_to_env(env) add_f03_to_env(env) + add_f08_to_env(env) # Local Variables: # tab-width:4 diff --git a/src/engine/SCons/Tool/f08.py b/src/engine/SCons/Tool/f08.py new file mode 100644 index 0000000..a45a61d --- /dev/null +++ b/src/engine/SCons/Tool/f08.py @@ -0,0 +1,63 @@ +"""engine.SCons.Tool.f08 + +Tool-specific initialization for the generic Posix f08 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__ +# +# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import SCons.Defaults +import SCons.Tool +import SCons.Util +import fortran +from SCons.Tool.FortranCommon import add_all_to_env, add_f08_to_env + +compilers = ['f08'] + +def generate(env): + add_all_to_env(env) + add_f08_to_env(env) + + fcomp = env.Detect(compilers) or 'f08' + env['F08'] = fcomp + env['SHF08'] = fcomp + + env['FORTRAN'] = fcomp + env['SHFORTRAN'] = fcomp + + +def exists(env): + return env.Detect(compilers) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/f08.xml b/src/engine/SCons/Tool/f08.xml new file mode 100644 index 0000000..6a49c75 --- /dev/null +++ b/src/engine/SCons/Tool/f08.xml @@ -0,0 +1,311 @@ + + + + +%scons; + +%builders-mod; + +%functions-mod; + +%tools-mod; + +%variables-mod; +]> + + + + + + +Set construction variables for generic POSIX Fortran 08 compilers. + + + +F08 +F08FLAGS +F08COM +F08PPCOM +SHF08 +SHF08FLAGS +SHF08COM +SHF08PPCOM +_F08INCFLAGS + + +F08COMSTR +F08PPCOMSTR +SHF08COMSTR +SHF08PPCOMSTR + + + + + + +The Fortran 08 compiler. +You should normally set the &cv-link-FORTRAN; variable, +which specifies the default Fortran compiler +for all Fortran versions. +You only need to set &cv-link-F08; if you need to use a specific compiler +or compiler version for Fortran 08 files. + + + + + + + +The command line used to compile a Fortran 08 source file to an object file. +You only need to set &cv-link-F08COM; if you need to use a specific +command line for Fortran 08 files. +You should normally set the &cv-link-FORTRANCOM; variable, +which specifies the default command line +for all Fortran versions. + + + + + + + +The string displayed when a Fortran 08 source file +is compiled to an object file. +If this is not set, then &cv-link-F08COM; or &cv-link-FORTRANCOM; +(the command line) is displayed. + + + + + + + +The list of file extensions for which the F08 dialect will be used. By +default, this is ['.f08'] + + + + + + + +The list of file extensions for which the compilation + preprocessor pass for +F08 dialect will be used. By default, this is empty + + + + + + + +General user-specified options that are passed to the Fortran 08 compiler. +Note that this variable does +not +contain + +(or similar) include search path options +that scons generates automatically from &cv-link-F08PATH;. +See +&cv-link-_F08INCFLAGS; +below, +for the variable that expands to those options. +You only need to set &cv-link-F08FLAGS; if you need to define specific +user options for Fortran 08 files. +You should normally set the &cv-link-FORTRANFLAGS; variable, +which specifies the user-specified options +passed to the default Fortran compiler +for all Fortran versions. + + + + + + + +An automatically-generated construction variable +containing the Fortran 08 compiler command-line options +for specifying directories to be searched for include files. +The value of &cv-link-_F08INCFLAGS; is created +by appending &cv-link-INCPREFIX; and &cv-link-INCSUFFIX; +to the beginning and end +of each directory in &cv-link-F08PATH;. + + + + + + + +The list of directories that the Fortran 08 compiler will search for include +directories. The implicit dependency scanner will search these +directories for include files. Don't explicitly put include directory +arguments in &cv-link-F08FLAGS; because the result will be non-portable +and the directories will not be searched by the dependency scanner. Note: +directory names in &cv-link-F08PATH; will be looked-up relative to the SConscript +directory when they are used in a command. To force +&scons; +to look-up a directory relative to the root of the source tree use #: +You only need to set &cv-link-F08PATH; if you need to define a specific +include path for Fortran 08 files. +You should normally set the &cv-link-FORTRANPATH; variable, +which specifies the include path +for the default Fortran compiler +for all Fortran versions. + + + +env = Environment(F08PATH='#/include') + + + +The directory look-up can also be forced using the +&Dir;() +function: + + + +include = Dir('include') +env = Environment(F08PATH=include) + + + +The directory list will be added to command lines +through the automatically-generated +&cv-link-_F08INCFLAGS; +construction variable, +which is constructed by +appending the values of the +&cv-link-INCPREFIX; and &cv-link-INCSUFFIX; +construction variables +to the beginning and end +of each directory in &cv-link-F08PATH;. +Any command lines you define that need +the F08PATH directory list should +include &cv-link-_F08INCFLAGS;: + + + +env = Environment(F08COM="my_compiler $_F08INCFLAGS -c -o $TARGET $SOURCE") + + + + + + + +The command line used to compile a Fortran 08 source file to an object file +after first running the file through the C preprocessor. +Any options specified in the &cv-link-F08FLAGS; and &cv-link-CPPFLAGS; construction variables +are included on this command line. +You only need to set &cv-link-F08PPCOM; if you need to use a specific +C-preprocessor command line for Fortran 08 files. +You should normally set the &cv-link-FORTRANPPCOM; variable, +which specifies the default C-preprocessor command line +for all Fortran versions. + + + + + + + +The string displayed when a Fortran 08 source file +is compiled to an object file +after first running the file through the C preprocessor. +If this is not set, then &cv-link-F08PPCOM; or &cv-link-FORTRANPPCOM; +(the command line) is displayed. + + + + + + + +The Fortran 08 compiler used for generating shared-library objects. +You should normally set the &cv-link-SHFORTRAN; variable, +which specifies the default Fortran compiler +for all Fortran versions. +You only need to set &cv-link-SHF08; if you need to use a specific compiler +or compiler version for Fortran 08 files. + + + + + + + +The command line used to compile a Fortran 08 source file +to a shared-library object file. +You only need to set &cv-link-SHF08COM; if you need to use a specific +command line for Fortran 08 files. +You should normally set the &cv-link-SHFORTRANCOM; variable, +which specifies the default command line +for all Fortran versions. + + + + + + + +The string displayed when a Fortran 08 source file +is compiled to a shared-library object file. +If this is not set, then &cv-link-SHF08COM; or &cv-link-SHFORTRANCOM; +(the command line) is displayed. + + + + + + + +Options that are passed to the Fortran 08 compiler +to generated shared-library objects. +You only need to set &cv-link-SHF08FLAGS; if you need to define specific +user options for Fortran 08 files. +You should normally set the &cv-link-SHFORTRANFLAGS; variable, +which specifies the user-specified options +passed to the default Fortran compiler +for all Fortran versions. + + + + + + + +The command line used to compile a Fortran 08 source file to a +shared-library object file +after first running the file through the C preprocessor. +Any options specified in the &cv-link-SHF08FLAGS; and &cv-link-CPPFLAGS; construction variables +are included on this command line. +You only need to set &cv-link-SHF08PPCOM; if you need to use a specific +C-preprocessor command line for Fortran 08 files. +You should normally set the &cv-link-SHFORTRANPPCOM; variable, +which specifies the default C-preprocessor command line +for all Fortran versions. + + + + + + + +The string displayed when a Fortran 08 source file +is compiled to a shared-library object file +after first running the file through the C preprocessor. +If this is not set, then &cv-link-SHF08PPCOM; or &cv-link-SHFORTRANPPCOM; +(the command line) is displayed. + + + + + diff --git a/src/engine/SCons/Tool/gfortran.py b/src/engine/SCons/Tool/gfortran.py index 4f3e7e4..392a92e 100644 --- a/src/engine/SCons/Tool/gfortran.py +++ b/src/engine/SCons/Tool/gfortran.py @@ -43,7 +43,7 @@ def generate(env): Environment.""" fortran.generate(env) - for dialect in ['F77', 'F90', 'FORTRAN', 'F95', 'F03']: + for dialect in ['F77', 'F90', 'FORTRAN', 'F95', 'F03', 'F08']: env['%s' % dialect] = 'gfortran' env['SH%s' % dialect] = '$%s' % dialect if env['PLATFORM'] in ['cygwin', 'win32']: diff --git a/test/Fortran/F08.py b/test/Fortran/F08.py new file mode 100644 index 0000000..35df37c --- /dev/null +++ b/test/Fortran/F08.py @@ -0,0 +1,151 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import TestSCons + +from common import write_fake_link + +_python_ = TestSCons._python_ +_exe = TestSCons._exe + +test = TestSCons.TestSCons() + +write_fake_link(test) + +test.write('myfortran.py', r""" +import getopt +import sys +comment = '#' + sys.argv[1] +length = len(comment) +opts, args = getopt.getopt(sys.argv[2:], 'co:') +for opt, arg in opts: + if opt == '-o': out = arg +infile = open(args[0], 'rb') +outfile = open(out, 'wb') +for l in infile.readlines(): + if l[:length] != comment: + outfile.write(l) +sys.exit(0) +""") + +test.write('SConstruct', """ +env = Environment(LINK = r'%(_python_)s mylink.py', + LINKFLAGS = [], + F08 = r'%(_python_)s myfortran.py f08', + FORTRAN = r'%(_python_)s myfortran.py fortran') +env.Program(target = 'test01', source = 'test01.f') +env.Program(target = 'test02', source = 'test02.F') +env.Program(target = 'test03', source = 'test03.for') +env.Program(target = 'test04', source = 'test04.FOR') +env.Program(target = 'test05', source = 'test05.ftn') +env.Program(target = 'test06', source = 'test06.FTN') +env.Program(target = 'test07', source = 'test07.fpp') +env.Program(target = 'test08', source = 'test08.FPP') +env.Program(target = 'test09', source = 'test09.f08') +env.Program(target = 'test10', source = 'test10.F08') +""" % locals()) + +test.write('test01.f', "This is a .f file.\n#link\n#fortran\n") +test.write('test02.F', "This is a .F file.\n#link\n#fortran\n") +test.write('test03.for', "This is a .for file.\n#link\n#fortran\n") +test.write('test04.FOR', "This is a .FOR file.\n#link\n#fortran\n") +test.write('test05.ftn', "This is a .ftn file.\n#link\n#fortran\n") +test.write('test06.FTN', "This is a .FTN file.\n#link\n#fortran\n") +test.write('test07.fpp', "This is a .fpp file.\n#link\n#fortran\n") +test.write('test08.FPP', "This is a .FPP file.\n#link\n#fortran\n") +test.write('test09.f08', "This is a .f08 file.\n#link\n#f08\n") +test.write('test10.F08', "This is a .F08 file.\n#link\n#f08\n") + +test.run(arguments = '.', stderr = None) + +test.must_match('test01' + _exe, "This is a .f file.\n") +test.must_match('test02' + _exe, "This is a .F file.\n") +test.must_match('test03' + _exe, "This is a .for file.\n") +test.must_match('test04' + _exe, "This is a .FOR file.\n") +test.must_match('test05' + _exe, "This is a .ftn file.\n") +test.must_match('test06' + _exe, "This is a .FTN file.\n") +test.must_match('test07' + _exe, "This is a .fpp file.\n") +test.must_match('test08' + _exe, "This is a .FPP file.\n") +test.must_match('test09' + _exe, "This is a .f08 file.\n") +test.must_match('test10' + _exe, "This is a .F08 file.\n") + + +fc = 'f08' +g08 = test.detect_tool(fc) + +if g08: + + test.write("wrapper.py", +"""import os +import sys +open('%s', 'wb').write("wrapper.py\\n") +os.system(" ".join(sys.argv[1:])) +""" % test.workpath('wrapper.out').replace('\\', '\\\\')) + + test.write('SConstruct', """ +foo = Environment(F08 = '%(fc)s') +f08 = foo.Dictionary('F08') +bar = foo.Clone(F08 = r'%(_python_)s wrapper.py ' + f08) +foo.Program(target = 'foo', source = 'foo.f08') +bar.Program(target = 'bar', source = 'bar.f08') +""" % locals()) + + test.write('foo.f08', r""" + PROGRAM FOO + PRINT *,'foo.f08' + ENDPROGRAM FOO +""") + + test.write('bar.f08', r""" + PROGRAM BAR + PRINT *,'bar.f08' + ENDPROGRAM BAR +""") + + + test.run(arguments = 'foo' + _exe, stderr = None) + + test.run(program = test.workpath('foo'), stdout = " foo.f08\n") + + test.must_not_exist('wrapper.out') + + import sys + if sys.platform[:5] == 'sunos': + test.run(arguments = 'bar' + _exe, stderr = None) + else: + test.run(arguments = 'bar' + _exe) + + test.run(program = test.workpath('bar'), stdout = " bar.f08\n") + + test.must_match('wrapper.out', "wrapper.py\n") + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/Fortran/F08COM.py b/test/Fortran/F08COM.py new file mode 100644 index 0000000..783a163 --- /dev/null +++ b/test/Fortran/F08COM.py @@ -0,0 +1,98 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import TestSCons + +from common import write_fake_link + +_python_ = TestSCons._python_ +_exe = TestSCons._exe + +test = TestSCons.TestSCons() + +write_fake_link(test) + +test.write('myfortran.py', r""" +import sys +comment = '#' + sys.argv[1] +outfile = open(sys.argv[2], 'wb') +infile = open(sys.argv[3], 'rb') +for l in infile.readlines(): + if l[:len(comment)] != comment: + outfile.write(l) +sys.exit(0) +""") + +test.write('SConstruct', """ +env = Environment(LINK = r'%(_python_)s mylink.py', + LINKFLAGS = [], + F08COM = r'%(_python_)s myfortran.py f08 $TARGET $SOURCES', + F08PPCOM = r'%(_python_)s myfortran.py f08pp $TARGET $SOURCES', + FORTRANCOM = r'%(_python_)s myfortran.py fortran $TARGET $SOURCES', + FORTRANPPCOM = r'%(_python_)s myfortran.py fortranpp $TARGET $SOURCES') +env.Program(target = 'test01', source = 'test01.f') +env.Program(target = 'test02', source = 'test02.F') +env.Program(target = 'test03', source = 'test03.for') +env.Program(target = 'test04', source = 'test04.FOR') +env.Program(target = 'test05', source = 'test05.ftn') +env.Program(target = 'test06', source = 'test06.FTN') +env.Program(target = 'test07', source = 'test07.fpp') +env.Program(target = 'test08', source = 'test08.FPP') +env.Program(target = 'test09', source = 'test09.f08') +env.Program(target = 'test10', source = 'test10.F08') +""" % locals()) + +test.write('test01.f', "This is a .f file.\n#link\n#fortran\n") +test.write('test02.F', "This is a .F file.\n#link\n#fortranpp\n") +test.write('test03.for', "This is a .for file.\n#link\n#fortran\n") +test.write('test04.FOR', "This is a .FOR file.\n#link\n#fortranpp\n") +test.write('test05.ftn', "This is a .ftn file.\n#link\n#fortran\n") +test.write('test06.FTN', "This is a .FTN file.\n#link\n#fortranpp\n") +test.write('test07.fpp', "This is a .fpp file.\n#link\n#fortranpp\n") +test.write('test08.FPP', "This is a .FPP file.\n#link\n#fortranpp\n") +test.write('test09.f08', "This is a .f08 file.\n#link\n#f08\n") +test.write('test10.F08', "This is a .F08 file.\n#link\n#f08pp\n") + +test.run(arguments = '.', stderr = None) + +test.must_match('test01' + _exe, "This is a .f file.\n") +test.must_match('test02' + _exe, "This is a .F file.\n") +test.must_match('test03' + _exe, "This is a .for file.\n") +test.must_match('test04' + _exe, "This is a .FOR file.\n") +test.must_match('test05' + _exe, "This is a .ftn file.\n") +test.must_match('test06' + _exe, "This is a .FTN file.\n") +test.must_match('test07' + _exe, "This is a .fpp file.\n") +test.must_match('test08' + _exe, "This is a .FPP file.\n") +test.must_match('test09' + _exe, "This is a .f08 file.\n") +test.must_match('test10' + _exe, "This is a .F08 file.\n") + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/Fortran/F08COMSTR.py b/test/Fortran/F08COMSTR.py new file mode 100644 index 0000000..65bf32c --- /dev/null +++ b/test/Fortran/F08COMSTR.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import TestSCons + +_python_ = TestSCons._python_ + +test = TestSCons.TestSCons() + + + +test.write('myfc.py', r""" +import sys +fline = '#'+sys.argv[1]+'\n' +outfile = open(sys.argv[2], 'wb') +infile = open(sys.argv[3], 'rb') +for l in [l for l in infile.readlines() if l != fline]: + outfile.write(l) +sys.exit(0) +""") + +if not TestSCons.case_sensitive_suffixes('.f','.F'): + f08pp = 'f08' +else: + f08pp = 'f08pp' + + +test.write('SConstruct', """ +env = Environment(F08COM = r'%(_python_)s myfc.py f08 $TARGET $SOURCES', + F08COMSTR = 'Building f08 $TARGET from $SOURCES', + F08PPCOM = r'%(_python_)s myfc.py f08pp $TARGET $SOURCES', + F08PPCOMSTR = 'Building f08pp $TARGET from $SOURCES', + OBJSUFFIX='.obj') +env.Object(source = 'test01.f08') +env.Object(source = 'test02.F08') +""" % locals()) + +test.write('test01.f08', "A .f08 file.\n#f08\n") +test.write('test02.F08', "A .F08 file.\n#%s\n" % f08pp) + +test.run(stdout = test.wrap_stdout("""\ +Building f08 test01.obj from test01.f08 +Building %(f08pp)s test02.obj from test02.F08 +""" % locals())) + +test.must_match('test01.obj', "A .f08 file.\n") +test.must_match('test02.obj', "A .F08 file.\n") + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/Fortran/F08FILESUFFIXES.py b/test/Fortran/F08FILESUFFIXES.py new file mode 100644 index 0000000..8463403 --- /dev/null +++ b/test/Fortran/F08FILESUFFIXES.py @@ -0,0 +1,101 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import TestSCons + +from common import write_fake_link + +_python_ = TestSCons._python_ +_exe = TestSCons._exe + +test = TestSCons.TestSCons() + +write_fake_link(test) + +test.write('myfortran.py', r""" +import getopt +import sys +comment = '#' + sys.argv[1] +opts, args = getopt.getopt(sys.argv[2:], 'co:') +for opt, arg in opts: + if opt == '-o': out = arg +infile = open(args[0], 'rb') +outfile = open(out, 'wb') +for l in infile.readlines(): + if l[:len(comment)] != comment: + outfile.write(l) +sys.exit(0) +""") + +# Test default file suffix: .f90/.F90 for F90 +test.write('SConstruct', """ +env = Environment(LINK = r'%(_python_)s mylink.py', + LINKFLAGS = [], + F08 = r'%(_python_)s myfortran.py f08', + FORTRAN = r'%(_python_)s myfortran.py fortran') +env.Program(target = 'test01', source = 'test01.f') +env.Program(target = 'test02', source = 'test02.F') +env.Program(target = 'test03', source = 'test03.for') +env.Program(target = 'test04', source = 'test04.FOR') +env.Program(target = 'test05', source = 'test05.ftn') +env.Program(target = 'test06', source = 'test06.FTN') +env.Program(target = 'test07', source = 'test07.fpp') +env.Program(target = 'test08', source = 'test08.FPP') +env.Program(target = 'test09', source = 'test09.f08') +env.Program(target = 'test10', source = 'test10.F08') +""" % locals()) + +test.write('test01.f', "This is a .f file.\n#link\n#fortran\n") +test.write('test02.F', "This is a .F file.\n#link\n#fortranpp\n") +test.write('test03.for', "This is a .for file.\n#link\n#fortran\n") +test.write('test04.FOR', "This is a .FOR file.\n#link\n#fortranpp\n") +test.write('test05.ftn', "This is a .ftn file.\n#link\n#fortranpp\n") +test.write('test06.FTN', "This is a .FTN file.\n#link\n#fortranpp\n") +test.write('test07.fpp', "This is a .fpp file.\n#link\n#fortranpp\n") +test.write('test08.FPP', "This is a .FPP file.\n#link\n#fortranpp\n") +test.write('test09.f08', "This is a .f08 file.\n#link\n#f08\n") +test.write('test10.F08', "This is a .F08 file.\n#link\n#f08pp\n") + +test.run(arguments = '.', stderr = None) + +test.must_match('test01' + _exe, "This is a .f file.\n") +test.must_match('test02' + _exe, "This is a .F file.\n") +test.must_match('test03' + _exe, "This is a .for file.\n") +test.must_match('test04' + _exe, "This is a .FOR file.\n") +test.must_match('test05' + _exe, "This is a .ftn file.\n") +test.must_match('test06' + _exe, "This is a .FTN file.\n") +test.must_match('test07' + _exe, "This is a .fpp file.\n") +test.must_match('test08' + _exe, "This is a .FPP file.\n") +test.must_match('test09' + _exe, "This is a .f08 file.\n") +test.must_match('test10' + _exe, "This is a .F08 file.\n") + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/Fortran/F08FILESUFFIXES2.py b/test/Fortran/F08FILESUFFIXES2.py new file mode 100644 index 0000000..39bba44 --- /dev/null +++ b/test/Fortran/F08FILESUFFIXES2.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import TestSCons + +from common import write_fake_link + +_python_ = TestSCons._python_ +_exe = TestSCons._exe + +test = TestSCons.TestSCons() + +write_fake_link(test) + +test.write('myfortran.py', r""" +import getopt +import sys +comment = '#' + sys.argv[1] +opts, args = getopt.getopt(sys.argv[2:], 'co:') +for opt, arg in opts: + if opt == '-o': out = arg +infile = open(args[0], 'rb') +outfile = open(out, 'wb') +for l in infile.readlines(): + if l[:len(comment)] != comment: + outfile.write(l) +sys.exit(0) +""") + +# Test non-default file suffix: .f/.F for F08 +test.write('SConstruct', """ +env = Environment(LINK = r'%(_python_)s mylink.py', + LINKFLAGS = [], + F77 = r'%(_python_)s myfortran.py f77', + F08 = r'%(_python_)s myfortran.py f08', + F08FILESUFFIXES = ['.f', '.F', '.f08', '.F08'], + tools = ['default', 'f08']) +env.Program(target = 'test01', source = 'test01.f') +env.Program(target = 'test02', source = 'test02.F') +env.Program(target = 'test03', source = 'test03.f08') +env.Program(target = 'test04', source = 'test04.F08') +env.Program(target = 'test05', source = 'test05.f77') +env.Program(target = 'test06', source = 'test06.F77') +""" % locals()) + +test.write('test01.f', "This is a .f file.\n#link\n#f08\n") +test.write('test02.F', "This is a .F file.\n#link\n#f08\n") +test.write('test03.f08', "This is a .f08 file.\n#link\n#f08\n") +test.write('test04.F08', "This is a .F08 file.\n#link\n#f08\n") +test.write('test05.f77', "This is a .f77 file.\n#link\n#f77\n") +test.write('test06.F77', "This is a .F77 file.\n#link\n#f77\n") + +test.run(arguments = '.', stderr = None) + +test.must_match('test01' + _exe, "This is a .f file.\n") +test.must_match('test02' + _exe, "This is a .F file.\n") +test.must_match('test03' + _exe, "This is a .f08 file.\n") +test.must_match('test04' + _exe, "This is a .F08 file.\n") +test.must_match('test05' + _exe, "This is a .f77 file.\n") +test.must_match('test06' + _exe, "This is a .F77 file.\n") + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/Fortran/F08FLAGS.py b/test/Fortran/F08FLAGS.py new file mode 100644 index 0000000..866ea2c --- /dev/null +++ b/test/Fortran/F08FLAGS.py @@ -0,0 +1,158 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import TestSCons + +from common import write_fake_link + +_python_ = TestSCons._python_ + +test = TestSCons.TestSCons() +_exe = TestSCons._exe + +write_fake_link(test) + +test.write('myfortran.py', r""" +import getopt +import sys +comment = '#' + sys.argv[1] +opts, args = getopt.getopt(sys.argv[2:], 'co:xy') +optstring = '' +for opt, arg in opts: + if opt == '-o': out = arg + else: optstring = optstring + ' ' + opt +infile = open(args[0], 'rb') +outfile = open(out, 'wb') +outfile.write(optstring + "\n") +for l in infile.readlines(): + if l[:len(comment)] != comment: + outfile.write(l) +sys.exit(0) +""") + + + +test.write('SConstruct', """ +env = Environment(LINK = r'%(_python_)s mylink.py', + LINKFLAGS = [], + F08 = r'%(_python_)s myfortran.py g08', + F08FLAGS = '-x', + FORTRAN = r'%(_python_)s myfortran.py fortran', + FORTRANFLAGS = '-y') +env.Program(target = 'test01', source = 'test01.f') +env.Program(target = 'test02', source = 'test02.F') +env.Program(target = 'test03', source = 'test03.for') +env.Program(target = 'test04', source = 'test04.FOR') +env.Program(target = 'test05', source = 'test05.ftn') +env.Program(target = 'test06', source = 'test06.FTN') +env.Program(target = 'test07', source = 'test07.fpp') +env.Program(target = 'test08', source = 'test08.FPP') +env.Program(target = 'test09', source = 'test09.f08') +env.Program(target = 'test10', source = 'test10.F08') +""" % locals()) + +test.write('test01.f', "This is a .f file.\n#link\n#fortran\n") +test.write('test02.F', "This is a .F file.\n#link\n#fortran\n") +test.write('test03.for', "This is a .for file.\n#link\n#fortran\n") +test.write('test04.FOR', "This is a .FOR file.\n#link\n#fortran\n") +test.write('test05.ftn', "This is a .ftn file.\n#link\n#fortran\n") +test.write('test06.FTN', "This is a .FTN file.\n#link\n#fortran\n") +test.write('test07.fpp', "This is a .fpp file.\n#link\n#fortran\n") +test.write('test08.FPP', "This is a .FPP file.\n#link\n#fortran\n") +test.write('test09.f08', "This is a .f08 file.\n#link\n#g08\n") +test.write('test10.F08', "This is a .F08 file.\n#link\n#g08\n") + +test.run(arguments = '.', stderr = None) + +test.must_match('test01' + _exe, " -c -y\nThis is a .f file.\n") +test.must_match('test02' + _exe, " -c -y\nThis is a .F file.\n") +test.must_match('test03' + _exe, " -c -y\nThis is a .for file.\n") +test.must_match('test04' + _exe, " -c -y\nThis is a .FOR file.\n") +test.must_match('test05' + _exe, " -c -y\nThis is a .ftn file.\n") +test.must_match('test06' + _exe, " -c -y\nThis is a .FTN file.\n") +test.must_match('test07' + _exe, " -c -y\nThis is a .fpp file.\n") +test.must_match('test08' + _exe, " -c -y\nThis is a .FPP file.\n") +test.must_match('test09' + _exe, " -c -x\nThis is a .f08 file.\n") +test.must_match('test10' + _exe, " -c -x\nThis is a .F08 file.\n") + + +fc = 'f08' +g08 = test.detect_tool(fc) + + +if g08: + + test.write("wrapper.py", +"""import os +import sys +open('%s', 'wb').write("wrapper.py\\n") +os.system(" ".join(sys.argv[1:])) +""" % test.workpath('wrapper.out').replace('\\', '\\\\')) + + test.write('SConstruct', """ +foo = Environment(F08 = '%(fc)s') +f08 = foo.Dictionary('F08') +bar = foo.Clone(F08 = r'%(_python_)s wrapper.py ' + f08, F08FLAGS = '-Ix') +foo.Program(target = 'foo', source = 'foo.f08') +bar.Program(target = 'bar', source = 'bar.f08') +""" % locals()) + + test.write('foo.f08', r""" + PROGRAM FOO + PRINT *,'foo.f08' + ENDPROGRAM FOO +""") + + test.write('bar.f08', r""" + PROGRAM BAR + PRINT *,'bar.f08' + ENDPROGRAM FOO +""") + + + test.run(arguments = 'foo' + _exe, stderr = None) + + test.run(program = test.workpath('foo'), stdout = " foo.f08\n") + + test.must_not_exist('wrapper.out') + + import sys + if sys.platform[:5] == 'sunos': + test.run(arguments = 'bar' + _exe, stderr = None) + else: + test.run(arguments = 'bar' + _exe) + + test.run(program = test.workpath('bar'), stdout = " bar.f08\n") + + test.must_match('wrapper.out', "wrapper.py\n") + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/Fortran/SHF08.py b/test/Fortran/SHF08.py new file mode 100644 index 0000000..85f2bcd --- /dev/null +++ b/test/Fortran/SHF08.py @@ -0,0 +1,144 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import TestSCons + +_python_ = TestSCons._python_ +_obj = TestSCons._shobj +obj_ = TestSCons.shobj_ + +test = TestSCons.TestSCons() + + + +test.write('myfortran.py', r""" +import getopt +import sys +comment = '#' + sys.argv[1] +opts, args = getopt.getopt(sys.argv[2:], 'cf:o:K:') +for opt, arg in opts: + if opt == '-o': out = arg +infile = open(args[0], 'rb') +outfile = open(out, 'wb') +for l in infile.readlines(): + if l[:len(comment)] != comment: + outfile.write(l) +sys.exit(0) +""") + + + +test.write('SConstruct', """ +env = Environment(SHF08 = r'%(_python_)s myfortran.py g08', + SHFORTRAN = r'%(_python_)s myfortran.py fortran') +env.SharedObject(target = 'test01', source = 'test01.f') +env.SharedObject(target = 'test02', source = 'test02.F') +env.SharedObject(target = 'test03', source = 'test03.for') +env.SharedObject(target = 'test04', source = 'test04.FOR') +env.SharedObject(target = 'test05', source = 'test05.ftn') +env.SharedObject(target = 'test06', source = 'test06.FTN') +env.SharedObject(target = 'test07', source = 'test07.fpp') +env.SharedObject(target = 'test08', source = 'test08.FPP') +env.SharedObject(target = 'test09', source = 'test09.f08') +env.SharedObject(target = 'test10', source = 'test10.F08') +""" % locals()) + +test.write('test01.f', "This is a .f file.\n#fortran\n") +test.write('test02.F', "This is a .F file.\n#fortran\n") +test.write('test03.for', "This is a .for file.\n#fortran\n") +test.write('test04.FOR', "This is a .FOR file.\n#fortran\n") +test.write('test05.ftn', "This is a .ftn file.\n#fortran\n") +test.write('test06.FTN', "This is a .FTN file.\n#fortran\n") +test.write('test07.fpp', "This is a .fpp file.\n#fortran\n") +test.write('test08.FPP', "This is a .FPP file.\n#fortran\n") +test.write('test09.f08', "This is a .f08 file.\n#g08\n") +test.write('test10.F08', "This is a .F08 file.\n#g08\n") + +test.run(arguments = '.', stderr = None) + +test.must_match(obj_ + 'test01' + _obj, "This is a .f file.\n") +test.must_match(obj_ + 'test02' + _obj, "This is a .F file.\n") +test.must_match(obj_ + 'test03' + _obj, "This is a .for file.\n") +test.must_match(obj_ + 'test04' + _obj, "This is a .FOR file.\n") +test.must_match(obj_ + 'test05' + _obj, "This is a .ftn file.\n") +test.must_match(obj_ + 'test06' + _obj, "This is a .FTN file.\n") +test.must_match(obj_ + 'test07' + _obj, "This is a .fpp file.\n") +test.must_match(obj_ + 'test08' + _obj, "This is a .FPP file.\n") +test.must_match(obj_ + 'test09' + _obj, "This is a .f08 file.\n") +test.must_match(obj_ + 'test10' + _obj, "This is a .F08 file.\n") + +fc = 'f08' +g08 = test.detect_tool(fc) + +if g08: + + test.write("wrapper.py", +"""import os +import sys +open('%s', 'wb').write("wrapper.py\\n") +os.system(" ".join(sys.argv[1:])) +""" % test.workpath('wrapper.out').replace('\\', '\\\\')) + + test.write('SConstruct', """ +foo = Environment(SHF08 = '%(fc)s') +shf08 = foo.Dictionary('SHF08') +bar = foo.Clone(SHF08 = r'%(_python_)s wrapper.py ' + shf08) +foo.SharedObject(target = 'foo/foo', source = 'foo.f08') +bar.SharedObject(target = 'bar/bar', source = 'bar.f08') +""" % locals()) + + test.write('foo.f08', r""" + PROGRAM FOO + PRINT *,'foo.f08' + ENDPROGRAM FOO +""") + + test.write('bar.f08', r""" + PROGRAM BAR + PRINT *,'bar.f08' + ENDPROGRAM BAR +""") + + + test.run(arguments = 'foo', stderr = None) + + test.must_not_exist('wrapper.out') + + import sys + if sys.platform[:5] == 'sunos': + test.run(arguments = 'bar', stderr = None) + else: + test.run(arguments = 'bar') + + test.must_match('wrapper.out', "wrapper.py\n") + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: -- cgit v0.12 From 2e17a095249dafe84d63309bf5a03b8a9b4961a7 Mon Sep 17 00:00:00 2001 From: anatoly techtonik Date: Sun, 11 Jan 2015 16:23:36 +0300 Subject: SConsDoc.py: Calling sys.exit(-1) in imported library is bad, because it removes the trace who and when imported it. --- bin/SConsDoc.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/bin/SConsDoc.py b/bin/SConsDoc.py index e1c2b0b..e435b4a 100644 --- a/bin/SConsDoc.py +++ b/bin/SConsDoc.py @@ -127,8 +127,7 @@ except: try: import lxml except: - print("Failed to import either libxml2/libxslt or lxml") - sys.exit(1) + raise ImportError("Failed to import either libxml2/libxslt or lxml") has_etree = False if not has_libxml2: @@ -154,8 +153,7 @@ if not has_etree: # normal ElementTree install import elementtree.ElementTree as etree except ImportError: - print("Failed to import ElementTree from any known place") - sys.exit(1) + raise ImportError("Failed to import ElementTree from any known place") re_entity = re.compile("\&([^;]+);") re_entity_header = re.compile("") -- cgit v0.12 From e66ff66fb442cfa4aecdb717a2bd1c9537f2e3c3 Mon Sep 17 00:00:00 2001 From: anatoly techtonik Date: Sun, 11 Jan 2015 16:55:09 +0300 Subject: doc/SConscript: Fix build crash when XML toolchain is not installed by intercepting previously added ImportError from SConsDoc --- doc/SConscript | 55 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/doc/SConscript b/doc/SConscript index 7880ba3..6b87f6f 100644 --- a/doc/SConscript +++ b/doc/SConscript @@ -28,25 +28,43 @@ import os.path import re import sys import glob -import SConsDoc -import SConsExamples + import bootstrap Import('build_dir', 'env', 'whereis', 'revaction') -env = env.Clone() +# +# -- Check prerequisites for building the documentation --- +# +skip_doc = False -build = os.path.join(build_dir, 'doc') +try: + import SConsDoc + import SConsExamples +except ImportError as exc: + print("doc: SConsDoc failed to import, the error was:") + print(" ImportError: %s" % exc) + print(" Please make sure that python-libxml2 or python-lxml is installed.") + skip_doc = True fop = whereis('fop') xep = whereis('xep') + +if not fop and not xep: + print "doc: No PDF renderer found (fop|xep)!" + skip_doc = True + +# +# --- Configure build +# +env = env.Clone() + +build = os.path.join(build_dir, 'doc') + epydoc_cli = whereis('epydoc') gs = whereis('gs') lynx = whereis('lynx') -# -# -# dist_doc_tar_gz = '$DISTDIR/scons-doc-${VERSION}.tar.gz' tar_deps = [] @@ -55,7 +73,9 @@ tar_list = [] orig_env = env env = orig_env.Clone(SCONS_PY = File('#src/script/scons.py').rfile()) - +# +# --- Helpers --- +# def writeVersionXml(verfile, date, ver, rev): """ Helper function: Write a version.xml file. """ try: @@ -76,25 +96,8 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. """ % (date, ver, rev)) # -# Check whether we have all tools installed for -# building the documentation. +# --- Processing --- # -skip_doc = False -try: - import libxml2 - import libxslt -except: - try: - import lxml - except: - print "doc: Neither libxml2 nor lxml Python bindings found!" - print " Please install one of the packages python-libxml2 or python-lxml." - skip_doc = True - -if not fop and not xep: - print "doc: No PDF renderer found (fop|xep)!" - skip_doc = True - if skip_doc: print "doc: ...skipping building User Guide." else: -- cgit v0.12 From 505226b97a4aaf41695e3e1c818f768e35565bf9 Mon Sep 17 00:00:00 2001 From: Alexey Klimkin Date: Tue, 13 Jan 2015 17:40:33 -0800 Subject: Fix incomplete LIBS flattening and substitution in Program scanner --- src/engine/SCons/Scanner/Prog.py | 14 ++++++++++++-- src/engine/SCons/Scanner/ProgTests.py | 28 +++++++++++++++++++++++++++- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/src/engine/SCons/Scanner/Prog.py b/src/engine/SCons/Scanner/Prog.py index 49e93a5..848f874 100644 --- a/src/engine/SCons/Scanner/Prog.py +++ b/src/engine/SCons/Scanner/Prog.py @@ -38,6 +38,15 @@ def ProgramScanner(**kw): ps = SCons.Scanner.Base(scan, "ProgramScanner", **kw) return ps +def _split_libs(env, libs): + """ + Substitute environment variables and split into list. + """ + libs = env.subst(libs) + if SCons.Util.is_String(libs): + libs = libs.split() + return libs + def scan(node, env, libpath = ()): """ This scanner scans program files for static-library @@ -51,9 +60,11 @@ def scan(node, env, libpath = ()): # There are no LIBS in this environment, so just return a null list: return [] if SCons.Util.is_String(libs): - libs = libs.split() + libs = _split_libs(env, libs) else: libs = SCons.Util.flatten(libs) + libs = map(lambda x: _split_libs(env, x) if SCons.Util.is_String(x) else x, libs) + libs = SCons.Util.flatten(libs) try: prefix = env['LIBPREFIXES'] @@ -83,7 +94,6 @@ def scan(node, env, libpath = ()): adjustixes = SCons.Util.adjustixes for lib in libs: if SCons.Util.is_String(lib): - lib = env.subst(lib) for pref, suf in pairs: l = adjustixes(lib, pref, suf) l = find_file(l, libpath, verbose=print_find_libs) diff --git a/src/engine/SCons/Scanner/ProgTests.py b/src/engine/SCons/Scanner/ProgTests.py index 144addb..98e20cc 100644 --- a/src/engine/SCons/Scanner/ProgTests.py +++ b/src/engine/SCons/Scanner/ProgTests.py @@ -73,7 +73,7 @@ class DummyEnvironment(object): def subst(self, s, target=None, source=None, conv=None): try: - if s[0] == '$': + if isinstance(s, str) and s[0] == '$': return self._dict[s[1:]] except IndexError: return '' @@ -223,6 +223,30 @@ class ProgramScannerTestCase8(unittest.TestCase): deps = s(DummyNode('dummy'), env, path) assert deps == [n1, n2], deps +class ProgramScannerTestCase9(unittest.TestCase): + def runTest(self): + env = DummyEnvironment(LIBPATH=[ test.workpath("dir") ], + LIBS=['foo', '$LIBBAR'], + LIBPREFIXES=['lib'], + LIBSUFFIXES=['.a'], + LIBBAR=['sub/libbar', 'xyz.other']) + s = SCons.Scanner.Prog.ProgramScanner() + path = s.path(env) + deps = s(DummyNode('dummy'), env, path) + assert deps_match(deps, ['dir/libfoo.a', 'dir/sub/libbar.a', 'dir/libxyz.other']), list(map(str, deps)) + +class ProgramScannerTestCase10(unittest.TestCase): + def runTest(self): + env = DummyEnvironment(LIBPATH=[ test.workpath("dir") ], + LIBS=['foo', '$LIBBAR'], + LIBPREFIXES=['lib'], + LIBSUFFIXES=['.a'], + LIBBAR='sub/libbar xyz.other') + s = SCons.Scanner.Prog.ProgramScanner() + path = s.path(env) + deps = s(DummyNode('dummy'), env, path) + assert deps_match(deps, ['dir/libfoo.a', 'dir/sub/libbar.a', 'dir/libxyz.other']), list(map(str, deps)) + def suite(): suite = unittest.TestSuite() suite.addTest(ProgramScannerTestCase1()) @@ -232,6 +256,8 @@ def suite(): suite.addTest(ProgramScannerTestCase6()) suite.addTest(ProgramScannerTestCase7()) suite.addTest(ProgramScannerTestCase8()) + suite.addTest(ProgramScannerTestCase9()) + suite.addTest(ProgramScannerTestCase10()) try: unicode except NameError: pass else: -- cgit v0.12 From 7633be5b72a7070f8bb014324be653c1156a854c Mon Sep 17 00:00:00 2001 From: Dirk Baechle Date: Sun, 18 Jan 2015 01:43:36 +0100 Subject: - providing MAN page stubs when not all doc packages for the packaging process are installed - fixed refmiscinfo for MAN pages --- doc/SConscript | 41 ++++++++++++++++++++++++++++++++++++++--- doc/man/scons-time.xml | 3 ++- doc/man/scons.xml | 3 ++- doc/man/sconsign.xml | 3 ++- 4 files changed, 44 insertions(+), 6 deletions(-) diff --git a/doc/SConscript b/doc/SConscript index 6b87f6f..35eb380 100644 --- a/doc/SConscript +++ b/doc/SConscript @@ -95,11 +95,49 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. """ % (date, ver, rev)) + +# The names of the target files for the MAN pages +man_page_list = ['scons.1','scons-time.1','sconsign.1'] + +# Template for the MAN page texts when we can't properly +# create them because the skip_doc flag is set (required +# modules/tools aren't installed in the current system) +man_replace_tpl = """.TH "%(uctitle)s" "1" "%(today)s" "SCons %(version)s" "SCons %(version)s" +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.nh +.ad l +.SH "NOTE" +%(title)s \- This is a replacement file, stemming from an incomplete +packaging process without the required doc modules installed. Please +update the system and try running bootstrap.py again. +""" + # # --- Processing --- # if skip_doc: print "doc: ...skipping building User Guide." + print " ...creating fake MAN pages." + + # Since the top-level SConstruct requires the MAN + # pages to exist for the basic packaging, we create simple + # stub texts here as replacement... + scdir = os.path.join(build, 'man') + if not os.path.isdir(scdir): + os.makedirs(scdir) + + import datetime + today = datetime.date.today().strftime("%m/%d/%Y") + version = env.subst('$VERSION') + for m in man_page_list: + man, _ = os.path.splitext(m) + fman = open(os.path.join(scdir, m), "w") + fman.write(man_replace_tpl % {'uctitle' : man.upper().replace("-", "\\-"), + 'today' : today, + 'title' : man, + 'version' : version}) + fman.close() else: if not lynx: print "doc: Warning, lynx is not installed...created release packages won't be complete!" @@ -278,9 +316,6 @@ else: 'man' : (['man','epub','text'], [], []) } - # The names of the target files for the MAN pages - man_page_list = ['scons.1','scons-time.1','sconsign.1'] - # # We have to tell SCons to scan the top-level XML files which # get included by the document XML files in the subdirectories. diff --git a/doc/man/scons-time.xml b/doc/man/scons-time.xml index a1ecadf..e0fa6b1 100644 --- a/doc/man/scons-time.xml +++ b/doc/man/scons-time.xml @@ -32,7 +32,8 @@ SCONS-TIME 1 -__MONTH_YEAR__ +SCons __VERSION__ +SCons __VERSION__ scons-time diff --git a/doc/man/scons.xml b/doc/man/scons.xml index 55f2d63..08a942b 100644 --- a/doc/man/scons.xml +++ b/doc/man/scons.xml @@ -75,7 +75,8 @@ SCONS 1 -__MONTH_YEAR__ +SCons __VERSION__ +SCons __VERSION__ scons diff --git a/doc/man/sconsign.xml b/doc/man/sconsign.xml index ca99db6..44a1e5f 100644 --- a/doc/man/sconsign.xml +++ b/doc/man/sconsign.xml @@ -32,7 +32,8 @@ SCONSIGN 1 -__MONTH_YEAR__ +SCons __VERSION__ +SCons __VERSION__ sconsign -- cgit v0.12 From 8e4b5aca7a47a60ed3a5f0b98bf0804e91e182b4 Mon Sep 17 00:00:00 2001 From: Alexey Klimkin Date: Tue, 20 Jan 2015 13:26:56 -0800 Subject: Improve readability of LIB substitution code --- src/engine/SCons/Scanner/Prog.py | 22 +++++++++++++--------- src/engine/SCons/Scanner/ProgTests.py | 11 ++++------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/engine/SCons/Scanner/Prog.py b/src/engine/SCons/Scanner/Prog.py index 848f874..4781175 100644 --- a/src/engine/SCons/Scanner/Prog.py +++ b/src/engine/SCons/Scanner/Prog.py @@ -38,13 +38,21 @@ def ProgramScanner(**kw): ps = SCons.Scanner.Base(scan, "ProgramScanner", **kw) return ps -def _split_libs(env, libs): +def _subst_libs(env, libs): """ Substitute environment variables and split into list. """ - libs = env.subst(libs) if SCons.Util.is_String(libs): - libs = libs.split() + libs = env.subst(libs) + if SCons.Util.is_String(libs): + libs = libs.split() + elif SCons.Util.is_Sequence(libs): + _libs = [] + for l in libs: + _libs += _subst_libs(env, l) + libs = _libs + else: + libs = [libs] return libs def scan(node, env, libpath = ()): @@ -59,12 +67,8 @@ def scan(node, env, libpath = ()): except KeyError: # There are no LIBS in this environment, so just return a null list: return [] - if SCons.Util.is_String(libs): - libs = _split_libs(env, libs) - else: - libs = SCons.Util.flatten(libs) - libs = map(lambda x: _split_libs(env, x) if SCons.Util.is_String(x) else x, libs) - libs = SCons.Util.flatten(libs) + + libs = _subst_libs(env, libs) try: prefix = env['LIBPREFIXES'] diff --git a/src/engine/SCons/Scanner/ProgTests.py b/src/engine/SCons/Scanner/ProgTests.py index 98e20cc..ace3ff4 100644 --- a/src/engine/SCons/Scanner/ProgTests.py +++ b/src/engine/SCons/Scanner/ProgTests.py @@ -32,6 +32,7 @@ import TestUnit import SCons.Node.FS import SCons.Scanner.Prog +import SCons.Subst test = TestCmd.TestCmd(workdir = '') @@ -72,12 +73,7 @@ class DummyEnvironment(object): del self.Dictionary()[key] def subst(self, s, target=None, source=None, conv=None): - try: - if isinstance(s, str) and s[0] == '$': - return self._dict[s[1:]] - except IndexError: - return '' - return s + return SCons.Subst.scons_subst(s, self, gvars=self._dict, lvars=self._dict) def subst_path(self, path, target=None, source=None, conv=None): if not isinstance(path, list): @@ -241,7 +237,8 @@ class ProgramScannerTestCase10(unittest.TestCase): LIBS=['foo', '$LIBBAR'], LIBPREFIXES=['lib'], LIBSUFFIXES=['.a'], - LIBBAR='sub/libbar xyz.other') + LIBBAR='sub/libbar $LIBBAR2', + LIBBAR2=['xyz.other']) s = SCons.Scanner.Prog.ProgramScanner() path = s.path(env) deps = s(DummyNode('dummy'), env, path) -- cgit v0.12 From 3c229dfb912628cede20119af721862d87202c0b Mon Sep 17 00:00:00 2001 From: Alexey Klimkin Date: Mon, 26 Jan 2015 20:07:11 -0800 Subject: Add comment for a case where LIBS (or part of it) is an object --- src/engine/SCons/Scanner/Prog.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/engine/SCons/Scanner/Prog.py b/src/engine/SCons/Scanner/Prog.py index 4781175..6567b3d 100644 --- a/src/engine/SCons/Scanner/Prog.py +++ b/src/engine/SCons/Scanner/Prog.py @@ -52,6 +52,7 @@ def _subst_libs(env, libs): _libs += _subst_libs(env, l) libs = _libs else: + # libs is an object (Node, for example) libs = [libs] return libs -- cgit v0.12 From b2e68f654f456f13ad0ccefc3b09fe55475b1be1 Mon Sep 17 00:00:00 2001 From: anatoly techtonik Date: Tue, 3 Feb 2015 23:21:08 +0300 Subject: SConstruct: Compress SCons .zip archives See https://pairlist2.pair.net/pipermail/scons-dev/2015-January/002151.html --- SConstruct | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/SConstruct b/SConstruct index 27b07f2..c95c0a9 100644 --- a/SConstruct +++ b/SConstruct @@ -331,7 +331,8 @@ try: path = os.path.join(dirname, name) if os.path.isfile(path): arg.write(path) - zf = zipfile.ZipFile(str(target[0]), 'w') + # default ZipFile compression is ZIP_STORED + zf = zipfile.ZipFile(str(target[0]), 'w', compression=zipfile.ZIP_DEFLATED) olddir = os.getcwd() os.chdir(env['CD']) try: os.path.walk(env['PSV'], visit, zf) @@ -356,7 +357,7 @@ try: if not os.path.isdir(dest): open(dest, 'wb').write(zf.read(name)) -except: +except ImportError: if unzip and zip: zipit = "cd $CD && $ZIP $ZIPFLAGS $( ${TARGET.abspath} $) $PSV" unzipit = "$UNZIP $UNZIPFLAGS $SOURCES" -- cgit v0.12 From 7d89522233802f83ffa728bc0b55785faf580d32 Mon Sep 17 00:00:00 2001 From: Dirk Baechle Date: Wed, 4 Feb 2015 22:07:45 +0100 Subject: - a few simple refactorings and optimizations --- src/engine/SCons/Action.py | 34 ++++++++++++++++------------------ src/engine/SCons/ActionTests.py | 2 -- src/engine/SCons/Builder.py | 4 +--- src/engine/SCons/Executor.py | 19 ++++++++++--------- src/engine/SCons/Node/FS.py | 12 +----------- 5 files changed, 28 insertions(+), 43 deletions(-) diff --git a/src/engine/SCons/Action.py b/src/engine/SCons/Action.py index 1c746be..eecea11 100644 --- a/src/engine/SCons/Action.py +++ b/src/engine/SCons/Action.py @@ -99,8 +99,6 @@ way for wrapping up the functions. __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" -import SCons.compat - import dis import os # compat layer imports "cPickle" for us if it's available. @@ -112,7 +110,6 @@ import subprocess import SCons.Debug from SCons.Debug import logInstanceCreation import SCons.Errors -import SCons.Executor import SCons.Util import SCons.Subst @@ -357,21 +354,6 @@ def _do_create_action(act, kw): if isinstance(act, ActionBase): return act - if is_List(act): - return CommandAction(act, **kw) - - if callable(act): - try: - gen = kw['generator'] - del kw['generator'] - except KeyError: - gen = 0 - if gen: - action_type = CommandGeneratorAction - else: - action_type = FunctionAction - return action_type(act, kw) - if is_String(act): var=SCons.Util.get_environment_var(act) if var: @@ -388,6 +370,22 @@ def _do_create_action(act, kw): # The list of string commands may include a LazyAction, so we # reprocess them via _do_create_list_action. return _do_create_list_action(commands, kw) + + if is_List(act): + return CommandAction(act, **kw) + + if callable(act): + try: + gen = kw['generator'] + del kw['generator'] + except KeyError: + gen = 0 + if gen: + action_type = CommandGeneratorAction + else: + action_type = FunctionAction + return action_type(act, kw) + # Catch a common error case with a nice message: if isinstance(act, int) or isinstance(act, float): raise TypeError("Don't know how to create an Action from a number (%s)"%act) diff --git a/src/engine/SCons/ActionTests.py b/src/engine/SCons/ActionTests.py index b46347d..e069d51 100644 --- a/src/engine/SCons/ActionTests.py +++ b/src/engine/SCons/ActionTests.py @@ -23,8 +23,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" -import SCons.compat - # Define a null function and a null class for use as builder actions. # Where these are defined in the file seems to affect their byte-code # contents, so try to minimize changes by defining them here, before we diff --git a/src/engine/SCons/Builder.py b/src/engine/SCons/Builder.py index ed7650a..c82f6ac 100644 --- a/src/engine/SCons/Builder.py +++ b/src/engine/SCons/Builder.py @@ -107,8 +107,6 @@ from SCons.Debug import logInstanceCreation from SCons.Errors import InternalError, UserError import SCons.Executor import SCons.Memoize -import SCons.Node -import SCons.Node.FS import SCons.Util import SCons.Warnings @@ -862,7 +860,7 @@ class CompositeBuilder(SCons.Util.Proxy): self.set_src_suffix(self.cmdgen.src_suffixes()) def is_a_Builder(obj): - """"Returns True iff the specified obj is one of our Builder classes. + """"Returns True if the specified obj is one of our Builder classes. The test is complicated a bit by the fact that CompositeBuilder is a proxy, not a subclass of BuilderBase. diff --git a/src/engine/SCons/Executor.py b/src/engine/SCons/Executor.py index 051d275..388f8ac 100644 --- a/src/engine/SCons/Executor.py +++ b/src/engine/SCons/Executor.py @@ -554,19 +554,20 @@ def AddBatchExecutor(key, executor): nullenv = None +import SCons.Util +class NullEnvironment(SCons.Util.Null): + import SCons.CacheDir + _CacheDir_path = None + _CacheDir = SCons.CacheDir.CacheDir(None) + def get_CacheDir(self): + return self._CacheDir + + def get_NullEnvironment(): """Use singleton pattern for Null Environments.""" global nullenv - import SCons.Util - class NullEnvironment(SCons.Util.Null): - import SCons.CacheDir - _CacheDir_path = None - _CacheDir = SCons.CacheDir.CacheDir(None) - def get_CacheDir(self): - return self._CacheDir - - if not nullenv: + if nullenv is None: nullenv = NullEnvironment() return nullenv diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py index e73dd92..4db1cb3 100644 --- a/src/engine/SCons/Node/FS.py +++ b/src/engine/SCons/Node/FS.py @@ -2230,17 +2230,7 @@ class RootDir(Dir): raise SCons.Errors.UserError(msg) # There is no Node for this path name, and we're allowed # to create it. - # (note: would like to use p.rsplit('/',1) here but - # that's not in python 2.3) - # e.g.: dir_name, file_name = p.rsplit('/',1) - last_slash = p.rindex('/') - if (last_slash >= 0): - dir_name = p[:last_slash] - file_name = p[last_slash+1:] - else: - dir_name = p # shouldn't happen, just in case - file_name = '' - + dir_name, file_name = p.rsplit('/',1) dir_node = self._lookup_abs(dir_name, Dir) result = klass(file_name, dir_node, self.fs) -- cgit v0.12 From e8c3a25d13bd9424ae8d0ac927d9781e599998d6 Mon Sep 17 00:00:00 2001 From: LaurentMarchelli Date: Mon, 9 Feb 2015 16:46:16 +0100 Subject: Microsoft Visual Studio users files implementation. --- src/engine/SCons/Tool/msvs.py | 216 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 212 insertions(+), 4 deletions(-) diff --git a/src/engine/SCons/Tool/msvs.py b/src/engine/SCons/Tool/msvs.py index cb4ca55..071cb7b 100644 --- a/src/engine/SCons/Tool/msvs.py +++ b/src/engine/SCons/Tool/msvs.py @@ -198,6 +198,207 @@ def makeHierarchy(sources): # print 'Warning: failed to decompose path for '+str(file) return hierarchy +class _UserGenerator(object): + ''' + Base class for .dsp.user file generator + ''' + # Default instance values. + # Ok ... a bit defensive, but it does not seems reasonable to crash the + # build for a workspace user file. :-) + usrhead = None + usrdebg = None + usrconf = None + createfile = False + def __init__(self, dspfile, source, env): + # DebugSettings should be a list of debug dictionary sorted in the same order + # than the target list and variants + 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 'DebugSettings' not in env or env['DebugSettings'] == None: + dbg_settings = [] + elif SCons.Util.is_Dict(env['DebugSettings']): + dbg_settings = [env['DebugSettings']] + elif SCons.Util.is_List(env['dbg_settings']): + if len(env['DebugSettings']) != len(variants): + raise SCons.Errors.InternalError("Sizes of 'DebugSettings' and 'variant' lists must be the same.") + dbg_settings = [] + for ds in env['DebugSettings']: + if SCons.Util.is_Dict(ds): + dbg_settings.append(ds) + else: + dbg_settings.append({}) + else: + dbg_settings = [] + + if len(dbg_settings) == 1: + dbg_settings = dbg_settings * len(variants) + + self.createfile = self.usrhead and self.usrdebg and self.usrconf and \ + dbg_settings and bool([ds for ds in dbg_settings if ds]) + + if self.createfile: + dbg_settings = dict(zip(variants, dbg_settings)) + for var, src in dbg_settings.items(): + # Update only expected keys + trg = {} + for key in [k for k in self.usrdebg.keys() if k in src]: + trg[key] = str(src[key]) + self.configs[var].debug = trg + + def UserHeader(self): + encoding = self.env.subst('$MSVSENCODING') + versionstr = self.versionstr + self.usrfile.write(self.usrhead % locals()) + + def UserProject(self): + pass + + def Build(self): + if not self.createfile: + return + try: + filename = self.dspabs +'.user' + self.usrfile = open(filename, 'w') + except IOError, detail: + raise SCons.Errors.InternalError('Unable to open "' + filename + '" for writing:' + str(detail)) + else: + self.UserHeader() + self.UserProject() + self.usrfile.close() + +V9UserHeader = """\ + + +\t +""" + +V9UserConfiguration = """\ +\t\t +\t\t\t +\t\t +""" + +V9DebugSettings = { +'Command':'$(TargetPath)', +'WorkingDirectory': None, +'CommandArguments': None, +'Attach':'false', +'DebuggerType':'3', +'Remote':'1', +'RemoteMachine': None, +'RemoteCommand': None, +'HttpUrl': None, +'PDBPath': None, +'SQLDebugging': None, +'Environment': None, +'EnvironmentMerge':'true', +'DebuggerFlavor': None, +'MPIRunCommand': None, +'MPIRunArguments': None, +'MPIRunWorkingDirectory': None, +'ApplicationCommand': None, +'ApplicationArguments': None, +'ShimCommand': None, +'MPIAcceptMode': None, +'MPIAcceptFilter': None, +} + +class _GenerateV7User(_UserGenerator): + """Generates a Project file for MSVS .NET""" + def __init__(self, dspfile, source, env): + if self.version_num >= 9.0: + self.usrhead = V9UserHeader + self.usrconf = V9UserConfiguration + self.usrdebg = V9DebugSettings + _UserGenerator.__init__(self, dspfile, source, env) + + def UserProject(self): + confkeys = sorted(self.configs.keys()) + for kind in confkeys: + variant = self.configs[kind].variant + platform = self.configs[kind].platform + debug = self.configs[kind].debug + debug_settings = '\n'.join(['\t\t\t\t%s="%s"' % (key, xmlify(value)) + for key, value in debug.items() + if value is not None]) + self.usrfile.write(self.usrconf % locals()) + self.usrfile.write('\t\n') + +V10UserHeader = """\ + + +""" + +V10UserConfiguration = """\ +\t +%(debug_settings)s +\t +""" + +V10DebugSettings = { +'LocalDebuggerCommand': None, +'LocalDebuggerCommandArguments': None, +'LocalDebuggerEnvironment': None, +'DebuggerFlavor': 'WindowsLocalDebugger', +'LocalDebuggerWorkingDirectory': None, +'LocalDebuggerAttach': None, +'LocalDebuggerDebuggerType': None, +'LocalDebuggerMergeEnvironment': None, +'LocalDebuggerSQLDebugging': None, +'RemoteDebuggerCommand': None, +'RemoteDebuggerCommandArguments': None, +'RemoteDebuggerWorkingDirectory': None, +'RemoteDebuggerServerName': None, +'RemoteDebuggerConnection': None, +'RemoteDebuggerDebuggerType': None, +'RemoteDebuggerAttach': None, +'RemoteDebuggerSQLDebugging': None, +'DeploymentDirectory': None, +'AdditionalFiles': None, +'RemoteDebuggerDeployDebugCppRuntime': None, +'WebBrowserDebuggerHttpUrl': None, +'WebBrowserDebuggerDebuggerType': None, +'WebServiceDebuggerHttpUrl': None, +'WebServiceDebuggerDebuggerType': None, +'WebServiceDebuggerSQLDebugging': None, +} + +class _GenerateV10User(_UserGenerator): + """Generates a Project'user file for MSVS 2010""" + + def __init__(self, dspfile, source, env): + self.versionstr = '4.0' + self.usrhead = V10UserHeader + self.usrconf = V10UserConfiguration + self.usrdebg = V10DebugSettings + _UserGenerator.__init__(self, dspfile, source, env) + + def UserProject(self): + confkeys = sorted(self.configs.keys()) + for kind in confkeys: + variant = self.configs[kind].variant + platform = self.configs[kind].platform + debug = self.configs[kind].debug + debug_settings = '\n'.join(['\t\t<%s>%s' % (key, xmlify(value), key) + for key, value in debug.items() + if value is not None]) + self.usrfile.write(self.usrconf % locals()) + self.usrfile.write('') + class _DSPGenerator(object): """ Base class for DSP generators """ @@ -628,7 +829,7 @@ V8DSPConfiguration = """\ \t\t\t/> \t\t """ -class _GenerateV7DSP(_DSPGenerator): +class _GenerateV7DSP(_DSPGenerator, _GenerateV7User): """Generates a Project file for MSVS .NET""" def __init__(self, dspfile, source, env): @@ -651,6 +852,8 @@ class _GenerateV7DSP(_DSPGenerator): self.dspheader = V7DSPHeader self.dspconfiguration = V7DSPConfiguration self.file = None + + _GenerateV7User.__init__(self, dspfile, source, env) def PrintHeader(self): env = self.env @@ -875,7 +1078,9 @@ class _GenerateV7DSP(_DSPGenerator): self.PrintHeader() self.PrintProject() self.file.close() - + + _GenerateV7User.Build(self) + V10DSPHeader = """\ @@ -922,15 +1127,16 @@ V10DSPCommandLine = """\ \t\t$(NMakeForcedUsingAssemblies) """ -class _GenerateV10DSP(_DSPGenerator): +class _GenerateV10DSP(_DSPGenerator, _GenerateV10User): """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 + + _GenerateV10User.__init__(self, dspfile, source, env) def PrintHeader(self): env = self.env @@ -1182,6 +1388,8 @@ class _GenerateV10DSP(_DSPGenerator): self.PrintHeader() self.PrintProject() self.file.close() + + _GenerateV10User.Build(self) class _DSWGenerator(object): """ Base class for DSW generators """ -- cgit v0.12 From a2620590a2250a0662f8d89daeebf12adeb4e189 Mon Sep 17 00:00:00 2001 From: LaurentMarchelli Date: Thu, 12 Feb 2015 14:56:20 +0100 Subject: dumb error and output improvement. --- src/engine/SCons/Tool/msvs.py | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/engine/SCons/Tool/msvs.py b/src/engine/SCons/Tool/msvs.py index 071cb7b..d00413d 100644 --- a/src/engine/SCons/Tool/msvs.py +++ b/src/engine/SCons/Tool/msvs.py @@ -63,6 +63,7 @@ def xmlify(s): s = s.replace("&", "&") # do this first s = s.replace("'", "'") s = s.replace('"', """) + s = s.replace('\n', ' ') return s # Process a CPPPATH list in includes, given the env, target and source. @@ -224,7 +225,7 @@ class _UserGenerator(object): dbg_settings = [] elif SCons.Util.is_Dict(env['DebugSettings']): dbg_settings = [env['DebugSettings']] - elif SCons.Util.is_List(env['dbg_settings']): + elif SCons.Util.is_List(env['DebugSettings']): if len(env['DebugSettings']) != len(variants): raise SCons.Errors.InternalError("Sizes of 'DebugSettings' and 'variant' lists must be the same.") dbg_settings = [] @@ -332,10 +333,11 @@ class _GenerateV7User(_UserGenerator): variant = self.configs[kind].variant platform = self.configs[kind].platform debug = self.configs[kind].debug - debug_settings = '\n'.join(['\t\t\t\t%s="%s"' % (key, xmlify(value)) - for key, value in debug.items() - if value is not None]) - self.usrfile.write(self.usrconf % locals()) + if debug: + debug_settings = '\n'.join(['\t\t\t\t%s="%s"' % (key, xmlify(value)) + for key, value in debug.items() + if value is not None]) + self.usrfile.write(self.usrconf % locals()) self.usrfile.write('\t\n') V10UserHeader = """\ @@ -393,10 +395,11 @@ class _GenerateV10User(_UserGenerator): variant = self.configs[kind].variant platform = self.configs[kind].platform debug = self.configs[kind].debug - debug_settings = '\n'.join(['\t\t<%s>%s' % (key, xmlify(value), key) - for key, value in debug.items() - if value is not None]) - self.usrfile.write(self.usrconf % locals()) + if debug: + debug_settings = '\n'.join(['\t\t<%s>%s' % (key, xmlify(value), key) + for key, value in debug.items() + if value is not None]) + self.usrfile.write(self.usrconf % locals()) self.usrfile.write('') class _DSPGenerator(object): -- cgit v0.12 From aaef35125935febb0fefe269870f9023e223a280 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Sun, 15 Feb 2015 13:01:32 -0800 Subject: Always build 32 and 64 bit versions of the windows installer. No reason to only build the native version since python can build both regardless of currrent platform --- SConstruct | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/SConstruct b/SConstruct index c95c0a9..6367001 100644 --- a/SConstruct +++ b/SConstruct @@ -730,10 +730,9 @@ for p in [ scons ]: platform_zip = os.path.join(build, 'dist', "%s.%s.zip" % (pkg_version, platform)) - if platform == "win-amd64": - win32_exe = os.path.join(build, 'dist', "%s.win-amd64.exe" % pkg_version) - else: - win32_exe = os.path.join(build, 'dist', "%s.win32.exe" % pkg_version) + + win64_exe = os.path.join(build, 'dist', "%s.win-amd64.exe" % pkg_version) + win32_exe = os.path.join(build, 'dist', "%s.win32.exe" % pkg_version) # # Update the environment with the relevant information @@ -845,11 +844,13 @@ for p in [ scons ]: distutils_formats = [] - distutils_targets = [ win32_exe ] + distutils_targets = [ win32_exe , win64_exe ] + dist_distutils_targets = [] - dist_distutils_targets = env.Install('$DISTDIR', distutils_targets) - Local(dist_distutils_targets) - AddPostAction(dist_distutils_targets, Chmod(dist_distutils_targets, 0644)) + for target in distutils_targets: + dist_target = env.Install('$DISTDIR', target) + AddPostAction(dist_target, Chmod(dist_target, 0644)) + dist_distutils_targets += dist_target if not gzip: print "gzip not found in %s; skipping .tar.gz package for %s." % (os.environ['PATH'], pkg) @@ -1081,7 +1082,9 @@ for p in [ scons ]: commands.append("$PYTHON $PYTHONFLAGS $SETUP_PY sdist --formats=%s" % \ ','.join(distutils_formats)) - commands.append("$PYTHON $PYTHONFLAGS $SETUP_PY bdist_wininst --plat-name win32 --user-access-control auto") + commands.append("$PYTHON $PYTHONFLAGS $SETUP_PY bdist_wininst --plat-name=win32 --user-access-control auto") + + commands.append("$PYTHON $PYTHONFLAGS $SETUP_PY bdist_wininst --plat-name=win-amd64 --user-access-control auto") env.Command(distutils_targets, build_src_files, commands) -- cgit v0.12 From db5ac5ff9b00f9b787cab6abb0c0e1551c12d20d Mon Sep 17 00:00:00 2001 From: William Deegan Date: Sun, 15 Feb 2015 13:02:51 -0800 Subject: monkey patch the get_build_version() function in distutils msvccompiler.py because if it's being run on a non-windows platform it always defaults to use msvc version 6, which doesn't provide a 64 bit installer boilerplate. Switching to 9 should work with python 2.7.x --- src/setup.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/setup.py b/src/setup.py index a8b59a3..fb16bdd 100644 --- a/src/setup.py +++ b/src/setup.py @@ -81,6 +81,16 @@ import distutils.command.install_data import distutils.command.install_lib import distutils.command.install_scripts import distutils.command.build_scripts +import distutils.msvccompiler + +def get_build_version(): + """ monkey patch distutils msvc version if we're not on windows. + We need to use vc version 9 for python 2.7.x and it defaults to 6 + for non-windows platforms and there is no way to override it besides + monkey patching""" + return 9 + +distutils.msvccompiler.get_build_version = get_build_version _install = distutils.command.install.install _install_data = distutils.command.install_data.install_data -- cgit v0.12 From 5578d065b9c68ba3f5a443f3b42f628e9cba600b Mon Sep 17 00:00:00 2001 From: bdbaddog Date: Mon, 16 Feb 2015 12:55:16 -0800 Subject: Change to use function to determine if it'sa windows platform. checking for win32 was insufficient on 64 bit windows which distutils sets the platform to win-amd64 --- SConstruct | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/SConstruct b/SConstruct index 6367001..ae1a06e 100644 --- a/SConstruct +++ b/SConstruct @@ -48,6 +48,12 @@ copyright = "Copyright (c) %s The SCons Foundation" % copyright_years platform = distutils.util.get_platform() +def is_windows(): + if platform.startswith('win'): + return True + else: + return False + SConsignFile() # @@ -56,7 +62,7 @@ SConsignFile() # def whereis(file): exts = [''] - if platform == "win32": + if is_windows(): exts += ['.exe'] for dir in os.environ['PATH'].split(os.pathsep): f = os.path.join(dir, file) @@ -267,7 +273,7 @@ test_local_zip_dir = os.path.join(build_dir, "test-local-zip") unpack_tar_gz_dir = os.path.join(build_dir, "unpack-tar-gz") unpack_zip_dir = os.path.join(build_dir, "unpack-zip") -if platform == "win32": +if is_windows(): tar_hflag = '' python_project_subinst_dir = os.path.join("Lib", "site-packages", project) project_script_subinst_dir = 'Scripts' @@ -1112,7 +1118,7 @@ for p in [ scons ]: for script in scripts: # add .py extension for scons-local scripts on non-windows platforms - if platform == "win32": + if is_windows(): break local_script = os.path.join(build_dir_local, script) commands.append(Move(local_script + '.py', local_script)) @@ -1136,7 +1142,7 @@ for p in [ scons ]: Local(l) if gzip: - if platform == "win32": + if is_windows(): # avoid problem with tar interpreting c:/ as a remote machine tar_cargs = '-cz --force-local -f' else: -- cgit v0.12 From 9e2a7c517ef3bc6776227ced814b0635dae0f724 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 16 Feb 2015 16:27:30 -0800 Subject: fix test/site_scons/override.py which was failing only on Win32. loading the m4 tool was excluded in src/engine/SCons/Tool/__init__.py in tool_list(). So I've explicitly created the Environment() loading only the m4 tool. This test is checking to see if a tool in site_scons/site_tools would override the default logic. --- test/site_scons/override.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/site_scons/override.py b/test/site_scons/override.py index ad03eae..e33bb88 100644 --- a/test/site_scons/override.py +++ b/test/site_scons/override.py @@ -48,7 +48,7 @@ def exists(env): """) test.write('SConstruct', """ -e=Environment() +e=Environment(tools=['m4']) print e.subst('M4 is $M4, M4_MINE is $M4_MINE') """) test.run(arguments = '-Q .', -- cgit v0.12 From 88f988450292677f7c4b0de084585f1d561d8591 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Wed, 18 Feb 2015 15:28:45 -0800 Subject: added SDK 7.1 and 7.0A logic. Needs to be tested on systems with 7.0A installed. Also fixed some error messages when not finding requested SDK's. Previously would throw an exception --- src/engine/SCons/Tool/MSCommon/sdk.py | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/engine/SCons/Tool/MSCommon/sdk.py b/src/engine/SCons/Tool/MSCommon/sdk.py index 2bf5eef..afb37fe 100644 --- a/src/engine/SCons/Tool/MSCommon/sdk.py +++ b/src/engine/SCons/Tool/MSCommon/sdk.py @@ -19,7 +19,7 @@ # 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" @@ -172,6 +172,26 @@ SDK70VCSetupScripts = { 'x86' : r'bin\vcvars32.bat', # # If you update this list, update the documentation in Tool/mssdk.xml. SupportedSDKList = [ + WindowsSDK('7.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 = SDK70VCSetupScripts, + ), + WindowsSDK('7.0A', + 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('7.0', sanity_check_file=r'bin\SetEnv.Cmd', include_subdir='include', @@ -337,10 +357,13 @@ def mssdk_setup_env(env): elif 'MSSDK_VERSION' in env: sdk_version = env['MSSDK_VERSION'] if sdk_version is None: - msg = "SDK version %s is not installed" % repr(mssdk) + msg = "SDK version is specified as None" raise SCons.Errors.UserError(msg) sdk_version = env.subst(sdk_version) mssdk = get_sdk_by_version(sdk_version) + if mssdk is None: + msg = "SDK version %s is not installed" % sdk_version + raise SCons.Errors.UserError(msg) sdk_dir = mssdk.get_sdk_dir() debug('sdk.py:mssdk_setup_env: Using MSSDK_VERSION:%s'%sdk_dir) elif 'MSVS_VERSION' in env: -- cgit v0.12 From 7d4031dca4d8c9f73e59c8c0bcb165eb2f6248ba Mon Sep 17 00:00:00 2001 From: William Deegan Date: Thu, 19 Feb 2015 13:31:04 -0800 Subject: Fix issue found by test/Configure/Streamer1.py failing on win32 per discussion with Pawel Tomulik. Any typeerror will be handled by trying str.decode() --- src/engine/SCons/SConf.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/engine/SCons/SConf.py b/src/engine/SCons/SConf.py index d6a70ec..87432ef 100644 --- a/src/engine/SCons/SConf.py +++ b/src/engine/SCons/SConf.py @@ -197,10 +197,8 @@ class Streamer(object): try: self.s.write(str) except TypeError as e: - if e.message.startswith('unicode argument expected'): - self.s.write(str.decode()) - else: - raise + # "unicode argument expected" bug in IOStream (python 2.x) + self.s.write(str.decode()) def writelines(self, lines): for l in lines: -- cgit v0.12 From 6a87411122374088eab75fc13c083e9e43b827fc Mon Sep 17 00:00:00 2001 From: William Deegan Date: Fri, 20 Feb 2015 14:27:56 -0800 Subject: Fix failing D tests which were checking for architecture to determine bit'ness instead of using platform.architecture() to check for 32bit --- test/D/MixedDAndC/Common/common.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/D/MixedDAndC/Common/common.py b/test/D/MixedDAndC/Common/common.py index b356411..176bdc1 100644 --- a/test/D/MixedDAndC/Common/common.py +++ b/test/D/MixedDAndC/Common/common.py @@ -30,7 +30,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import TestSCons from os.path import abspath, dirname -from platform import machine +from platform import architecture import sys sys.path.insert(1, abspath(dirname(__file__) + '/../../Support')) @@ -48,7 +48,7 @@ def testForTool(tool): test.run() - if machine() in ('i386',): + if architecture()[0] == '32bit': test.fail_test('64-bit mode not compiled in' not in test.stdout()) test.pass_test() -- cgit v0.12 From d5937ecd5ed42b159f0cdfbe7c0e0ce0bc1a984f Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Sat, 21 Feb 2015 16:50:41 +0000 Subject: Putative fix for the D/MixedDAndC test fail. --- test/D/MixedDAndC/Common/common.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/D/MixedDAndC/Common/common.py b/test/D/MixedDAndC/Common/common.py index b356411..d78175d 100644 --- a/test/D/MixedDAndC/Common/common.py +++ b/test/D/MixedDAndC/Common/common.py @@ -48,8 +48,8 @@ def testForTool(tool): test.run() - if machine() in ('i386',): - test.fail_test('64-bit mode not compiled in' not in test.stdout()) + if machine() in ('i386', 'i486', 'i586', 'i686'): + test.fail_test('64-bit mode not compiled in' not in test.stderr()) test.pass_test() -- cgit v0.12 From 6cc2280c4a929d906bf0e2db4d89cf5de224e55a Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Sun, 22 Feb 2015 08:58:02 +0000 Subject: Putative fix for the ongoing D tool test fail on Debian 7 CI. --- test/D/MixedDAndC/Common/common.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/D/MixedDAndC/Common/common.py b/test/D/MixedDAndC/Common/common.py index 6c570f1..0a1c781 100644 --- a/test/D/MixedDAndC/Common/common.py +++ b/test/D/MixedDAndC/Common/common.py @@ -46,10 +46,11 @@ def testForTool(tool): test.dir_fixture('Image') - test.run() - if architecture()[0] == '32bit': + test.run(status=2) test.fail_test('64-bit mode not compiled in' not in test.stderr()) + else: + test.run() test.pass_test() -- cgit v0.12 From 78234964d1c879874ac380e6c182355ded29af13 Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Sun, 22 Feb 2015 18:47:06 +0000 Subject: Remove some dollar-parentheses. No effect on extant tests, appears to fix Issue 2994. --- src/engine/SCons/Tool/dmd.py | 12 ++++++------ src/engine/SCons/Tool/gdc.py | 10 +++++----- src/engine/SCons/Tool/ldc.py | 14 +++++++------- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/engine/SCons/Tool/dmd.py b/src/engine/SCons/Tool/dmd.py index 082d5c3..a7d46c6 100644 --- a/src/engine/SCons/Tool/dmd.py +++ b/src/engine/SCons/Tool/dmd.py @@ -82,10 +82,10 @@ def generate(env): 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['_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' @@ -122,13 +122,13 @@ def generate(env): env['DLIBDIRPREFIX'] = '-L-L' env['DLIBDIRSUFFIX'] = '' - env['_DLIBDIRFLAGS'] = '$( ${_concat(DLIBDIRPREFIX, LIBPATH, DLIBDIRSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)' + 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['_DLIBFLAGS'] = '${_concat(DLIBFLAGPREFIX, DLIBFLAGS, DLIBFLAGSUFFIX, __env__)}' env['DLIBFLAGPREFIX'] = '-' env['DLIBFLAGSUFFIX'] = '' diff --git a/src/engine/SCons/Tool/gdc.py b/src/engine/SCons/Tool/gdc.py index 048d736..799c3ab 100644 --- a/src/engine/SCons/Tool/gdc.py +++ b/src/engine/SCons/Tool/gdc.py @@ -65,10 +65,10 @@ def generate(env): 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['_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' @@ -102,7 +102,7 @@ def generate(env): 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['_DLIBFLAGS'] = '${_concat(DLIBFLAGPREFIX, DLIBFLAGS, DLIBFLAGSUFFIX, __env__)}' env['DLIBFLAGPREFIX'] = '-' env['DLIBFLAGSUFFIX'] = '' diff --git a/src/engine/SCons/Tool/ldc.py b/src/engine/SCons/Tool/ldc.py index ebef55d..8f9b117 100644 --- a/src/engine/SCons/Tool/ldc.py +++ b/src/engine/SCons/Tool/ldc.py @@ -70,10 +70,10 @@ def generate(env): 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['_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' @@ -109,18 +109,18 @@ def generate(env): 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'] = '${_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['_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['_DLIBFLAGS'] = '${_concat(DLIBFLAGPREFIX, DLIBFLAGS, DLIBFLAGSUFFIX, __env__)}' env['DLIBFLAGPREFIX'] = '-' env['DLIBFLAGSUFFIX'] = '' -- cgit v0.12 From 26146b842f0ab9543142cfd5dbb21cb609030fad Mon Sep 17 00:00:00 2001 From: William Deegan Date: Sun, 22 Feb 2015 14:44:16 -0800 Subject: Test for tigris bug 2944. DFLAGS changes not causing rebuild --- test/D/Issues/2944/image/SConstruct | 11 +++++++++++ test/D/Issues/2944/image/main.d | 11 +++++++++++ 2 files changed, 22 insertions(+) create mode 100644 test/D/Issues/2944/image/SConstruct create mode 100644 test/D/Issues/2944/image/main.d diff --git a/test/D/Issues/2944/image/SConstruct b/test/D/Issues/2944/image/SConstruct new file mode 100644 index 0000000..2c7deee --- /dev/null +++ b/test/D/Issues/2944/image/SConstruct @@ -0,0 +1,11 @@ +# -*- codig:utf-8; -*- + +env=Environment() + +change = ARGUMENTS.get('change', 0) +if int(change): + env.Append(DFLAGS = '-d') + +env.Program('proj', ['main.d']) + + diff --git a/test/D/Issues/2944/image/main.d b/test/D/Issues/2944/image/main.d new file mode 100644 index 0000000..f0aa23a --- /dev/null +++ b/test/D/Issues/2944/image/main.d @@ -0,0 +1,11 @@ +/* This program prints a + hello world message + to the console. */ + +import std.stdio; + +void main() +{ + writeln("Hello, World!"); +} + -- cgit v0.12 From 003ac6d619b34617ff7e4cda50fa7defcc3d95b4 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Sun, 22 Feb 2015 14:45:20 -0800 Subject: Test for tigris bug 2944. DFLAGS changes not causing rebuild --- .../Issues/2944/D_changed_DFLAGS_not_rebuilding.py | 23 ++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 test/D/Issues/2944/D_changed_DFLAGS_not_rebuilding.py diff --git a/test/D/Issues/2944/D_changed_DFLAGS_not_rebuilding.py b/test/D/Issues/2944/D_changed_DFLAGS_not_rebuilding.py new file mode 100644 index 0000000..1d9854f --- /dev/null +++ b/test/D/Issues/2944/D_changed_DFLAGS_not_rebuilding.py @@ -0,0 +1,23 @@ +# Test to check for issue reported in tigris bug 2994 +# http://scons.tigris.org/issues/show_bug.cgi?id=2994 +# + +import TestSCons + +test = TestSCons.TestSCons() + +dmd_present = test.detect_tool('dmd', prog='dmd') +ldc_present = test.detect_tool('ldc',prog='ldc2') +gdc_present = test.detect_tool('gdc',prog='gdc') + +if not (dmd_present or ldc_present or gdc_present): + test.skip_test("Could not load dmd ldc or gdc Tool; skipping test(s).\n") + + +test.dir_fixture('image') +test.run() +test.fail_test('main.o' not in test.stdout()) +test.run(arguments='change=1') +test.fail_test('is up to date' in test.stdout()) + +test.pass_test() -- cgit v0.12 From 1415240bf59ae22720fc6bd44c97352262e8b3e7 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Sat, 21 Feb 2015 00:09:23 -0800 Subject: remove forced 64 bit compilation. This should clear up build failures. Russel mentioned there was some issue causing him to add this logic. If the issue resurfaces, then we'll see if we can handle the corner case in more general fashion --- test/D/MixedDAndC/Common/common.py | 16 +++++++++++----- test/D/MixedDAndC/Image/SConstruct | 5 ++++- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/test/D/MixedDAndC/Common/common.py b/test/D/MixedDAndC/Common/common.py index 0a1c781..852e2e2 100644 --- a/test/D/MixedDAndC/Common/common.py +++ b/test/D/MixedDAndC/Common/common.py @@ -46,11 +46,17 @@ def testForTool(tool): test.dir_fixture('Image') - if architecture()[0] == '32bit': - test.run(status=2) - test.fail_test('64-bit mode not compiled in' not in test.stderr()) - else: - test.run() +# There was an issue with Russel mentioned but couldn't remember the details +# Which drove him to add the following logic. For now removing until +# we can determine what that issue is and if there's not a better +# way to handle the corner case +# if architecture()[0] == '32bit': +# test.run(status=2) +# test.fail_test('64-bit mode not compiled in' not in test.stderr()) +# else: +# test.run() + + test.run() test.pass_test() diff --git a/test/D/MixedDAndC/Image/SConstruct b/test/D/MixedDAndC/Image/SConstruct index 5cf58a3..176c4d3 100644 --- a/test/D/MixedDAndC/Image/SConstruct +++ b/test/D/MixedDAndC/Image/SConstruct @@ -3,7 +3,10 @@ import os environment = Environment( - DFLAGS=['-m64', '-O']) +) +# CFLAGS=['-m64'], +# DLINKFLAGS=['-m64'], +# DFLAGS=['-m64', '-O']) environment.Program('proj', [ 'proj.d', -- cgit v0.12 -- cgit v0.12 From 354388a26c7ff2ed69e4e34f41880e0e1bfb0cb1 Mon Sep 17 00:00:00 2001 From: Dirk Baechle Date: Fri, 27 Feb 2015 00:44:19 +0100 Subject: - switching Node class and NodeInfo/Binfo to using slots - memoizer subsystem now uses decorators instead of the metaclass approach --- src/engine/SCons/Action.py | 2 +- src/engine/SCons/Builder.py | 11 +- src/engine/SCons/BuilderTests.py | 69 ++-- src/engine/SCons/CacheDir.py | 16 +- src/engine/SCons/Debug.py | 13 +- src/engine/SCons/Environment.py | 10 +- src/engine/SCons/EnvironmentTests.py | 92 ++--- src/engine/SCons/Executor.py | 133 +++++--- src/engine/SCons/Memoize.py | 159 ++++----- src/engine/SCons/MemoizeTests.py | 18 +- src/engine/SCons/Node/Alias.py | 49 ++- src/engine/SCons/Node/AliasTests.py | 4 +- src/engine/SCons/Node/FS.py | 513 +++++++++++++++++----------- src/engine/SCons/Node/FSTests.py | 272 ++++++++------- src/engine/SCons/Node/NodeTests.py | 129 ++++--- src/engine/SCons/Node/Python.py | 40 ++- src/engine/SCons/Node/PythonTests.py | 4 +- src/engine/SCons/Node/__init__.py | 472 +++++++++++++++++++++---- src/engine/SCons/PathList.py | 8 +- src/engine/SCons/SConf.py | 24 +- src/engine/SCons/SConfTests.py | 2 - src/engine/SCons/SConsign.py | 38 ++- src/engine/SCons/SConsignTests.py | 4 + src/engine/SCons/Scanner/CTests.py | 13 +- src/engine/SCons/Scanner/Dir.py | 2 +- src/engine/SCons/Scanner/FortranTests.py | 13 +- src/engine/SCons/Scanner/IDLTests.py | 13 +- src/engine/SCons/Script/Main.py | 11 +- src/engine/SCons/Script/SConscript.py | 4 +- src/engine/SCons/Taskmaster.py | 2 +- src/engine/SCons/Tool/__init__.py | 2 +- src/engine/SCons/Tool/docbook/__init__.py | 6 +- src/engine/SCons/Tool/mslink.py | 4 +- src/engine/SCons/Tool/packaging/__init__.py | 16 +- src/engine/SCons/Tool/packaging/ipk.py | 2 +- src/engine/SCons/Tool/packaging/msi.py | 2 +- src/engine/SCons/Tool/packaging/rpm.py | 9 +- src/engine/SCons/Tool/rpm.py | 6 +- src/engine/SCons/Tool/swig.py | 9 +- src/engine/SCons/Util.py | 2 +- src/engine/SCons/UtilTests.py | 3 +- src/script/sconsign.py | 2 +- test/Actions/addpost-link.py | 2 +- test/CacheDir/NoCache.py | 2 +- test/Install/wrap-by-attribute.py | 4 +- test/NoClean.py | 6 +- test/Scanner/exception.py | 1 - test/explain/function-actions.py | 4 +- test/implicit-cache/DualTargets.py | 4 +- test/sconsign/script/SConsignFile.py | 42 +-- test/sconsign/script/no-SConsignFile.py | 14 +- 51 files changed, 1473 insertions(+), 809 deletions(-) diff --git a/src/engine/SCons/Action.py b/src/engine/SCons/Action.py index eecea11..5a34825 100644 --- a/src/engine/SCons/Action.py +++ b/src/engine/SCons/Action.py @@ -540,7 +540,7 @@ class _ActionAction(ActionBase): if chdir: save_cwd = os.getcwd() try: - chdir = str(chdir.abspath) + chdir = str(chdir.get_abspath()) except AttributeError: if not is_String(chdir): if executor: diff --git a/src/engine/SCons/Builder.py b/src/engine/SCons/Builder.py index c82f6ac..769b15d 100644 --- a/src/engine/SCons/Builder.py +++ b/src/engine/SCons/Builder.py @@ -352,11 +352,6 @@ class BuilderBase(object): nodes (files) from input nodes (files). """ - if SCons.Memoize.use_memoizer: - __metaclass__ = SCons.Memoize.Memoized_Metaclass - - memoizer_counters = [] - def __init__(self, action = None, prefix = '', suffix = '', @@ -758,8 +753,7 @@ class BuilderBase(object): def _get_src_builders_key(self, env): return id(env) - memoizer_counters.append(SCons.Memoize.CountDict('get_src_builders', _get_src_builders_key)) - + @SCons.Memoize.CountDictCall(_get_src_builders_key) def get_src_builders(self, env): """ Returns the list of source Builders for this Builder. @@ -795,8 +789,7 @@ class BuilderBase(object): def _subst_src_suffixes_key(self, env): return id(env) - memoizer_counters.append(SCons.Memoize.CountDict('subst_src_suffixes', _subst_src_suffixes_key)) - + @SCons.Memoize.CountDictCall(_subst_src_suffixes_key) def subst_src_suffixes(self, env): """ The suffix list may contain construction variable expansions, diff --git a/src/engine/SCons/BuilderTests.py b/src/engine/SCons/BuilderTests.py index 70a7a3f..3eca588 100644 --- a/src/engine/SCons/BuilderTests.py +++ b/src/engine/SCons/BuilderTests.py @@ -163,7 +163,8 @@ class MyNode_without_target_from_source(object): self.builder = None self.is_explicit = None self.side_effect = 0 - self.suffix = os.path.splitext(name)[1] + def get_suffix(self): + return os.path.splitext(self.name)[1] def disambiguate(self): return self def __str__(self): @@ -349,7 +350,7 @@ class BuilderTestCase(unittest.TestCase): builder = SCons.Builder.Builder(action="foo") target = builder(env, None, source='n22', srcdir='src_dir')[0] - p = target.sources[0].path + p = target.sources[0].get_internal_path() assert p == os.path.join('src_dir', 'n22'), p def test_mistaken_variables(self): @@ -487,20 +488,20 @@ class BuilderTestCase(unittest.TestCase): builder = SCons.Builder.Builder(prefix = 'lib', action='') assert builder.get_prefix(env) == 'lib' tgt = builder(env, target = 'tgt1', source = 'src1')[0] - assert tgt.path == 'libtgt1', \ - "Target has unexpected name: %s" % tgt.path + assert tgt.get_internal_path() == 'libtgt1', \ + "Target has unexpected name: %s" % tgt.get_internal_path() tgt = builder(env, target = 'tgt2a tgt2b', source = 'src2')[0] - assert tgt.path == 'libtgt2a tgt2b', \ - "Target has unexpected name: %s" % tgt.path + assert tgt.get_internal_path() == 'libtgt2a tgt2b', \ + "Target has unexpected name: %s" % tgt.get_internal_path() tgt = builder(env, target = None, source = 'src3')[0] - assert tgt.path == 'libsrc3', \ - "Target has unexpected name: %s" % tgt.path + assert tgt.get_internal_path() == 'libsrc3', \ + "Target has unexpected name: %s" % tgt.get_internal_path() tgt = builder(env, target = None, source = 'lib/src4')[0] - assert tgt.path == os.path.join('lib', 'libsrc4'), \ - "Target has unexpected name: %s" % tgt.path + assert tgt.get_internal_path() == os.path.join('lib', 'libsrc4'), \ + "Target has unexpected name: %s" % tgt.get_internal_path() tgt = builder(env, target = 'lib/tgt5', source = 'lib/src5')[0] - assert tgt.path == os.path.join('lib', 'libtgt5'), \ - "Target has unexpected name: %s" % tgt.path + assert tgt.get_internal_path() == os.path.join('lib', 'libtgt5'), \ + "Target has unexpected name: %s" % tgt.get_internal_path() def gen_prefix(env, sources): return "gen_prefix() says " + env['FOO'] @@ -520,17 +521,17 @@ class BuilderTestCase(unittest.TestCase): '.zzz' : my_emit}, action = '') tgt = builder(my_env, target = None, source = 'f1')[0] - assert tgt.path == 'default-f1', tgt.path + assert tgt.get_internal_path() == 'default-f1', tgt.get_internal_path() tgt = builder(my_env, target = None, source = 'f2.c')[0] - assert tgt.path == 'default-f2', tgt.path + assert tgt.get_internal_path() == 'default-f2', tgt.get_internal_path() tgt = builder(my_env, target = None, source = 'f3.in')[0] - assert tgt.path == 'out-f3', tgt.path + assert tgt.get_internal_path() == 'out-f3', tgt.get_internal_path() tgt = builder(my_env, target = None, source = 'f4.x')[0] - assert tgt.path == 'y-f4', tgt.path + assert tgt.get_internal_path() == 'y-f4', tgt.get_internal_path() tgt = builder(my_env, target = None, source = 'f5.foo')[0] - assert tgt.path == 'foo-f5', tgt.path + assert tgt.get_internal_path() == 'foo-f5', tgt.get_internal_path() tgt = builder(my_env, target = None, source = 'f6.zzz')[0] - assert tgt.path == 'emit-f6', tgt.path + assert tgt.get_internal_path() == 'emit-f6', tgt.get_internal_path() def test_set_suffix(self): """Test the set_suffix() method""" @@ -560,13 +561,13 @@ class BuilderTestCase(unittest.TestCase): assert b1.src_suffixes(env) == ['.c'], b1.src_suffixes(env) tgt = b1(env, target = 'tgt2', source = 'src2')[0] - assert tgt.sources[0].path == 'src2.c', \ - "Source has unexpected name: %s" % tgt.sources[0].path + assert tgt.sources[0].get_internal_path() == 'src2.c', \ + "Source has unexpected name: %s" % tgt.sources[0].get_internal_path() tgt = b1(env, target = 'tgt3', source = 'src3a src3b')[0] assert len(tgt.sources) == 1 - assert tgt.sources[0].path == 'src3a src3b.c', \ - "Unexpected tgt.sources[0] name: %s" % tgt.sources[0].path + assert tgt.sources[0].get_internal_path() == 'src3a src3b.c', \ + "Unexpected tgt.sources[0] name: %s" % tgt.sources[0].get_internal_path() b2 = SCons.Builder.Builder(src_suffix = '.2', src_builder = b1) r = sorted(b2.src_suffixes(env)) @@ -636,14 +637,14 @@ class BuilderTestCase(unittest.TestCase): builder = SCons.Builder.Builder(suffix = 'o', action='') assert builder.get_suffix(env) == '.o', builder.get_suffix(env) tgt = builder(env, target = 'tgt3', source = 'src3')[0] - assert tgt.path == 'tgt3.o', \ - "Target has unexpected name: %s" % tgt.path + assert tgt.get_internal_path() == 'tgt3.o', \ + "Target has unexpected name: %s" % tgt.get_internal_path() tgt = builder(env, target = 'tgt4a tgt4b', source = 'src4')[0] - assert tgt.path == 'tgt4a tgt4b.o', \ - "Target has unexpected name: %s" % tgt.path + assert tgt.get_internal_path() == 'tgt4a tgt4b.o', \ + "Target has unexpected name: %s" % tgt.get_internal_path() tgt = builder(env, target = None, source = 'src5')[0] - assert tgt.path == 'src5.o', \ - "Target has unexpected name: %s" % tgt.path + assert tgt.get_internal_path() == 'src5.o', \ + "Target has unexpected name: %s" % tgt.get_internal_path() def gen_suffix(env, sources): return "gen_suffix() says " + env['BAR'] @@ -663,17 +664,17 @@ class BuilderTestCase(unittest.TestCase): '.zzz' : my_emit}, action='') tgt = builder(my_env, target = None, source = 'f1')[0] - assert tgt.path == 'f1.default', tgt.path + assert tgt.get_internal_path() == 'f1.default', tgt.get_internal_path() tgt = builder(my_env, target = None, source = 'f2.c')[0] - assert tgt.path == 'f2.default', tgt.path + assert tgt.get_internal_path() == 'f2.default', tgt.get_internal_path() tgt = builder(my_env, target = None, source = 'f3.in')[0] - assert tgt.path == 'f3.out', tgt.path + assert tgt.get_internal_path() == 'f3.out', tgt.get_internal_path() tgt = builder(my_env, target = None, source = 'f4.x')[0] - assert tgt.path == 'f4.y', tgt.path + assert tgt.get_internal_path() == 'f4.y', tgt.get_internal_path() tgt = builder(my_env, target = None, source = 'f5.bar')[0] - assert tgt.path == 'f5.new', tgt.path + assert tgt.get_internal_path() == 'f5.new', tgt.get_internal_path() tgt = builder(my_env, target = None, source = 'f6.zzz')[0] - assert tgt.path == 'f6.emit', tgt.path + assert tgt.get_internal_path() == 'f6.emit', tgt.get_internal_path() def test_single_source(self): """Test Builder with single_source flag set""" diff --git a/src/engine/SCons/CacheDir.py b/src/engine/SCons/CacheDir.py index 9dd18e5..f32b326 100644 --- a/src/engine/SCons/CacheDir.py +++ b/src/engine/SCons/CacheDir.py @@ -50,11 +50,11 @@ def CacheRetrieveFunc(target, source, env): cd.CacheDebug('CacheRetrieve(%s): retrieving from %s\n', t, cachefile) if SCons.Action.execute_actions: if fs.islink(cachefile): - fs.symlink(fs.readlink(cachefile), t.path) + fs.symlink(fs.readlink(cachefile), t.get_internal_path()) else: - env.copy_from_cache(cachefile, t.path) + env.copy_from_cache(cachefile, t.get_internal_path()) st = fs.stat(cachefile) - fs.chmod(t.path, stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE) + fs.chmod(t.get_internal_path(), stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE) return 0 def CacheRetrieveString(target, source, env): @@ -63,7 +63,7 @@ def CacheRetrieveString(target, source, env): cd = env.get_CacheDir() cachedir, cachefile = cd.cachepath(t) if t.fs.exists(cachefile): - return "Retrieved `%s' from cache" % t.path + return "Retrieved `%s' from cache" % t.get_internal_path() return None CacheRetrieve = SCons.Action.Action(CacheRetrieveFunc, CacheRetrieveString) @@ -106,12 +106,12 @@ def CachePushFunc(target, source, env): raise SCons.Errors.EnvironmentError(msg) try: - if fs.islink(t.path): - fs.symlink(fs.readlink(t.path), tempfile) + if fs.islink(t.get_internal_path()): + fs.symlink(fs.readlink(t.get_internal_path()), tempfile) else: - fs.copy2(t.path, tempfile) + fs.copy2(t.get_internal_path(), tempfile) fs.rename(tempfile, cachefile) - st = fs.stat(t.path) + st = fs.stat(t.get_internal_path()) fs.chmod(cachefile, stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE) except EnvironmentError: # It's possible someone else tried writing the file at the diff --git a/src/engine/SCons/Debug.py b/src/engine/SCons/Debug.py index 9974039..b47c24c 100644 --- a/src/engine/SCons/Debug.py +++ b/src/engine/SCons/Debug.py @@ -34,6 +34,7 @@ import os import sys import time import weakref +import inspect # Global variable that gets set to 'True' by the Main script, # when the creation of class instances should get tracked. @@ -46,7 +47,12 @@ def logInstanceCreation(instance, name=None): name = instance.__class__.__name__ if name not in tracked_classes: tracked_classes[name] = [] - tracked_classes[name].append(weakref.ref(instance)) + if hasattr(instance, '__dict__'): + tracked_classes[name].append(weakref.ref(instance)) + else: + # weakref doesn't seem to work when the instance + # contains only slots... + tracked_classes[name].append(instance) def string_to_classes(s): if s == '*': @@ -66,7 +72,10 @@ def listLoggedInstances(classes, file=sys.stdout): for classname in string_to_classes(classes): file.write('\n%s:\n' % classname) for ref in tracked_classes[classname]: - obj = ref() + if inspect.isclass(ref): + obj = ref() + else: + obj = ref if obj is not None: file.write(' %s\n' % repr(obj)) diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py index 5f2c9ff..fa019b8 100644 --- a/src/engine/SCons/Environment.py +++ b/src/engine/SCons/Environment.py @@ -365,9 +365,6 @@ class SubstitutionEnvironment(object): class actually becomes useful.) """ - if SCons.Memoize.use_memoizer: - __metaclass__ = SCons.Memoize.Memoized_Metaclass - def __init__(self, **kw): """Initialization of an underlying SubstitutionEnvironment class. """ @@ -902,8 +899,6 @@ class Base(SubstitutionEnvironment): Environment. """ - memoizer_counters = [] - ####################################################################### # This is THE class for interacting with the SCons build engine, # and it contains a lot of stuff, so we're going to try to keep this @@ -1071,8 +1066,7 @@ class Base(SubstitutionEnvironment): factory = getattr(self.fs, name) return factory - memoizer_counters.append(SCons.Memoize.CountValue('_gsm')) - + @SCons.Memoize.CountMethodCall def _gsm(self): try: return self._memo['_gsm'] @@ -1802,7 +1796,7 @@ class Base(SubstitutionEnvironment): self.Replace(**kw) def _find_toolpath_dir(self, tp): - return self.fs.Dir(self.subst(tp)).srcnode().abspath + return self.fs.Dir(self.subst(tp)).srcnode().get_abspath() def Tool(self, tool, toolpath=None, **kw): if SCons.Util.is_String(tool): diff --git a/src/engine/SCons/EnvironmentTests.py b/src/engine/SCons/EnvironmentTests.py index a0869e8..9a9d2b0 100644 --- a/src/engine/SCons/EnvironmentTests.py +++ b/src/engine/SCons/EnvironmentTests.py @@ -2703,25 +2703,25 @@ def generate(env): t = env.AlwaysBuild('a', 'b$FOO', ['c', 'd'], '$BAR', env.fs.Dir('dir'), env.fs.File('file')) assert t[0].__class__.__name__ == 'Entry' - assert t[0].path == 'a' + assert t[0].get_internal_path() == 'a' assert t[0].always_build assert t[1].__class__.__name__ == 'Entry' - assert t[1].path == 'bfff' + assert t[1].get_internal_path() == 'bfff' assert t[1].always_build assert t[2].__class__.__name__ == 'Entry' - assert t[2].path == 'c' + assert t[2].get_internal_path() == 'c' assert t[2].always_build assert t[3].__class__.__name__ == 'Entry' - assert t[3].path == 'd' + assert t[3].get_internal_path() == 'd' assert t[3].always_build assert t[4].__class__.__name__ == 'Entry' - assert t[4].path == 'bbb' + assert t[4].get_internal_path() == 'bbb' assert t[4].always_build assert t[5].__class__.__name__ == 'Dir' - assert t[5].path == 'dir' + assert t[5].get_internal_path() == 'dir' assert t[5].always_build assert t[6].__class__.__name__ == 'File' - assert t[6].path == 'file' + assert t[6].get_internal_path() == 'file' assert t[6].always_build def test_VariantDir(self): @@ -2811,13 +2811,13 @@ def generate(env): assert t.builder is not None assert t.builder.action.__class__.__name__ == 'CommandAction' assert t.builder.action.cmd_list == 'buildfoo $target $source' - assert 'foo1.in' in [x.path for x in t.sources] - assert 'foo2.in' in [x.path for x in t.sources] + assert 'foo1.in' in [x.get_internal_path() for x in t.sources] + assert 'foo2.in' in [x.get_internal_path() for x in t.sources] sub = env.fs.Dir('sub') t = env.Command(target='bar.out', source='sub', action='buildbar $target $source')[0] - assert 'sub' in [x.path for x in t.sources] + assert 'sub' in [x.get_internal_path() for x in t.sources] def testFunc(env, target, source): assert str(target[0]) == 'foo.out' @@ -2828,8 +2828,8 @@ def generate(env): assert t.builder is not None assert t.builder.action.__class__.__name__ == 'FunctionAction' t.build() - assert 'foo1.in' in [x.path for x in t.sources] - assert 'foo2.in' in [x.path for x in t.sources] + assert 'foo1.in' in [x.get_internal_path() for x in t.sources] + assert 'foo2.in' in [x.get_internal_path() for x in t.sources] x = [] def test2(baz, x=x): @@ -2846,7 +2846,7 @@ def generate(env): action = 'foo', X = 'xxx')[0] assert str(t) == 'xxx.out', str(t) - assert 'xxx.in' in [x.path for x in t.sources] + assert 'xxx.in' in [x.get_internal_path() for x in t.sources] env = self.TestEnvironment(source_scanner = 'should_not_find_this') t = env.Command(target='file.out', source='file.in', @@ -2890,27 +2890,27 @@ def generate(env): t = env.Depends(target='EnvironmentTest.py', dependency='Environment.py')[0] assert t.__class__.__name__ == 'Entry', t.__class__.__name__ - assert t.path == 'EnvironmentTest.py' + assert t.get_internal_path() == 'EnvironmentTest.py' assert len(t.depends) == 1 d = t.depends[0] assert d.__class__.__name__ == 'Entry', d.__class__.__name__ - assert d.path == 'Environment.py' + assert d.get_internal_path() == 'Environment.py' t = env.Depends(target='${FOO}.py', dependency='${BAR}.py')[0] assert t.__class__.__name__ == 'File', t.__class__.__name__ - assert t.path == 'xxx.py' + assert t.get_internal_path() == 'xxx.py' assert len(t.depends) == 1 d = t.depends[0] assert d.__class__.__name__ == 'File', d.__class__.__name__ - assert d.path == 'yyy.py' + assert d.get_internal_path() == 'yyy.py' t = env.Depends(target='dir1', dependency='dir2')[0] assert t.__class__.__name__ == 'Dir', t.__class__.__name__ - assert t.path == 'dir1' + assert t.get_internal_path() == 'dir1' assert len(t.depends) == 1 d = t.depends[0] assert d.__class__.__name__ == 'Dir', d.__class__.__name__ - assert d.path == 'dir2' + assert d.get_internal_path() == 'dir2' def test_Dir(self): """Test the Dir() method""" @@ -2944,19 +2944,19 @@ def generate(env): t = env.NoClean('p_a', 'p_${BAR}b', ['p_c', 'p_d'], 'p_$FOO') assert t[0].__class__.__name__ == 'Entry', t[0].__class__.__name__ - assert t[0].path == 'p_a' + assert t[0].get_internal_path() == 'p_a' assert t[0].noclean assert t[1].__class__.__name__ == 'Dir', t[1].__class__.__name__ - assert t[1].path == 'p_hhhb' + assert t[1].get_internal_path() == 'p_hhhb' assert t[1].noclean assert t[2].__class__.__name__ == 'Entry', t[2].__class__.__name__ - assert t[2].path == 'p_c' + assert t[2].get_internal_path() == 'p_c' assert t[2].noclean assert t[3].__class__.__name__ == 'File', t[3].__class__.__name__ - assert t[3].path == 'p_d' + assert t[3].get_internal_path() == 'p_d' assert t[3].noclean assert t[4].__class__.__name__ == 'Entry', t[4].__class__.__name__ - assert t[4].path == 'p_ggg' + assert t[4].get_internal_path() == 'p_ggg' assert t[4].noclean def test_Dump(self): @@ -3074,27 +3074,27 @@ def generate(env): t = env.Ignore(target='targ.py', dependency='dep.py')[0] assert t.__class__.__name__ == 'Entry', t.__class__.__name__ - assert t.path == 'targ.py' + assert t.get_internal_path() == 'targ.py' assert len(t.ignore) == 1 i = t.ignore[0] assert i.__class__.__name__ == 'Entry', i.__class__.__name__ - assert i.path == 'dep.py' + assert i.get_internal_path() == 'dep.py' t = env.Ignore(target='$FOO$BAR', dependency='$BAR$FOO')[0] assert t.__class__.__name__ == 'File', t.__class__.__name__ - assert t.path == 'yyyzzz' + assert t.get_internal_path() == 'yyyzzz' assert len(t.ignore) == 1 i = t.ignore[0] assert i.__class__.__name__ == 'File', i.__class__.__name__ - assert i.path == 'zzzyyy' + assert i.get_internal_path() == 'zzzyyy' t = env.Ignore(target='dir1', dependency='dir2')[0] assert t.__class__.__name__ == 'Dir', t.__class__.__name__ - assert t.path == 'dir1' + assert t.get_internal_path() == 'dir1' assert len(t.ignore) == 1 i = t.ignore[0] assert i.__class__.__name__ == 'Dir', i.__class__.__name__ - assert i.path == 'dir2' + assert i.get_internal_path() == 'dir2' def test_Literal(self): """Test the Literal() method""" @@ -3123,19 +3123,19 @@ def generate(env): t = env.Precious('p_a', 'p_${BAR}b', ['p_c', 'p_d'], 'p_$FOO') assert t[0].__class__.__name__ == 'Entry', t[0].__class__.__name__ - assert t[0].path == 'p_a' + assert t[0].get_internal_path() == 'p_a' assert t[0].precious assert t[1].__class__.__name__ == 'Dir', t[1].__class__.__name__ - assert t[1].path == 'p_hhhb' + assert t[1].get_internal_path() == 'p_hhhb' assert t[1].precious assert t[2].__class__.__name__ == 'Entry', t[2].__class__.__name__ - assert t[2].path == 'p_c' + assert t[2].get_internal_path() == 'p_c' assert t[2].precious assert t[3].__class__.__name__ == 'File', t[3].__class__.__name__ - assert t[3].path == 'p_d' + assert t[3].get_internal_path() == 'p_d' assert t[3].precious assert t[4].__class__.__name__ == 'Entry', t[4].__class__.__name__ - assert t[4].path == 'p_ggg' + assert t[4].get_internal_path() == 'p_ggg' assert t[4].precious def test_Pseudo(self): @@ -3146,19 +3146,19 @@ def generate(env): t = env.Pseudo('p_a', 'p_${BAR}b', ['p_c', 'p_d'], 'p_$FOO') assert t[0].__class__.__name__ == 'Entry', t[0].__class__.__name__ - assert t[0].path == 'p_a' + assert t[0].get_internal_path() == 'p_a' assert t[0].pseudo assert t[1].__class__.__name__ == 'Dir', t[1].__class__.__name__ - assert t[1].path == 'p_hhhb' + assert t[1].get_internal_path() == 'p_hhhb' assert t[1].pseudo assert t[2].__class__.__name__ == 'Entry', t[2].__class__.__name__ - assert t[2].path == 'p_c' + assert t[2].get_internal_path() == 'p_c' assert t[2].pseudo assert t[3].__class__.__name__ == 'File', t[3].__class__.__name__ - assert t[3].path == 'p_d' + assert t[3].get_internal_path() == 'p_d' assert t[3].pseudo assert t[4].__class__.__name__ == 'Entry', t[4].__class__.__name__ - assert t[4].path == 'p_ggg' + assert t[4].get_internal_path() == 'p_ggg' assert t[4].pseudo def test_Repository(self): @@ -3263,7 +3263,7 @@ def generate(env): bar = env.Object('bar.obj', 'bar.cpp')[0] s = env.SideEffect('mylib.pdb', ['foo.obj', 'bar.obj'])[0] assert s.__class__.__name__ == 'Entry', s.__class__.__name__ - assert s.path == 'mylib.pdb' + assert s.get_internal_path() == 'mylib.pdb' assert s.side_effect assert foo.side_effects == [s] assert bar.side_effects == [s] @@ -3272,7 +3272,7 @@ def generate(env): bbb = env.Object('bbb.obj', 'bbb.cpp')[0] s = env.SideEffect('my${LIB}.pdb', ['${FOO}.obj', '${BAR}.obj'])[0] assert s.__class__.__name__ == 'File', s.__class__.__name__ - assert s.path == 'mylll.pdb' + assert s.get_internal_path() == 'mylll.pdb' assert s.side_effect assert fff.side_effects == [s], fff.side_effects assert bbb.side_effects == [s], bbb.side_effects @@ -3281,7 +3281,7 @@ def generate(env): ccc = env.Object('ccc.obj', 'ccc.cpp')[0] s = env.SideEffect('mymmm.pdb', ['ggg.obj', 'ccc.obj'])[0] assert s.__class__.__name__ == 'Dir', s.__class__.__name__ - assert s.path == 'mymmm.pdb' + assert s.get_internal_path() == 'mymmm.pdb' assert s.side_effect assert ggg.side_effects == [s], ggg.side_effects assert ccc.side_effects == [s], ccc.side_effects @@ -3290,18 +3290,18 @@ def generate(env): """Test the SourceCode() method.""" env = self.TestEnvironment(FOO='mmm', BAR='nnn') e = env.SourceCode('foo', None)[0] - assert e.path == 'foo' + assert e.get_internal_path() == 'foo' s = e.src_builder() assert s is None, s b = Builder() e = env.SourceCode(e, b)[0] - assert e.path == 'foo' + assert e.get_internal_path() == 'foo' s = e.src_builder() assert s is b, s e = env.SourceCode('$BAR$FOO', None)[0] - assert e.path == 'nnnmmm' + assert e.get_internal_path() == 'nnnmmm' s = e.src_builder() assert s is None, s diff --git a/src/engine/SCons/Executor.py b/src/engine/SCons/Executor.py index 388f8ac..98ed758 100644 --- a/src/engine/SCons/Executor.py +++ b/src/engine/SCons/Executor.py @@ -40,6 +40,10 @@ import SCons.Memoize class Batch(object): """Remembers exact association between targets and sources of executor.""" + + __slots__ = ('targets', + 'sources') + def __init__(self, targets=[], sources=[]): self.targets = targets self.sources = sources @@ -109,6 +113,48 @@ def rfile(node): return rfile() +def execute_nothing(obj, target, kw): + return 0 + +def execute_action_list(obj, target, kw): + """Actually execute the action list.""" + env = obj.get_build_env() + kw = obj.get_kw(kw) + status = 0 + for act in obj.get_action_list(): + #args = (self.get_all_targets(), self.get_all_sources(), env) + args = ([], [], env) + status = act(*args, **kw) + if isinstance(status, SCons.Errors.BuildError): + status.executor = obj + raise status + elif status: + msg = "Error %s" % status + raise SCons.Errors.BuildError( + errstr=msg, + node=obj.batches[0].targets, + executor=obj, + action=act) + return status + +_do_execute_map = {0 : execute_nothing, + 1 : execute_action_list} + + +def execute_actions_str(obj): + env = obj.get_build_env() + return "\n".join([action.genstring(obj.get_all_targets(), + obj.get_all_sources(), + env) + for action in obj.get_action_list()]) + +def execute_null_str(obj): + return '' + +_execute_str_map = {0 : execute_null_str, + 1 : execute_actions_str} + + class Executor(object): """A class for controlling instances of executing an action. @@ -117,10 +163,21 @@ class Executor(object): and sources for later processing as needed. """ - if SCons.Memoize.use_memoizer: - __metaclass__ = SCons.Memoize.Memoized_Metaclass - - memoizer_counters = [] + __slots__ = ('pre_actions', + 'post_actions', + 'env', + 'overridelist', + 'batches', + 'builder_kw', + '_memo', + 'lvars', + '_changed_sources_list', + '_changed_targets_list', + '_unchanged_sources_list', + '_unchanged_targets_list', + 'action_list', + '_do_execute', + '_execute_str') def __init__(self, action, env=None, overridelist=[{}], targets=[], sources=[], builder_kw={}): @@ -135,6 +192,8 @@ class Executor(object): else: self.batches = [] self.builder_kw = builder_kw + self._do_execute = 1 + self._execute_str = 1 self._memo = {} def get_lvars(self): @@ -284,8 +343,7 @@ class Executor(object): result.extend(target.side_effects) return result - memoizer_counters.append(SCons.Memoize.CountValue('get_build_env')) - + @SCons.Memoize.CountMethodCall def get_build_env(self): """Fetch or create the appropriate build Environment for this Executor. @@ -330,36 +388,12 @@ class Executor(object): result['executor'] = self return result - def do_nothing(self, target, kw): - return 0 - - def do_execute(self, target, kw): - """Actually execute the action list.""" - env = self.get_build_env() - kw = self.get_kw(kw) - status = 0 - for act in self.get_action_list(): - #args = (self.get_all_targets(), self.get_all_sources(), env) - args = ([], [], env) - status = act(*args, **kw) - if isinstance(status, SCons.Errors.BuildError): - status.executor = self - raise status - elif status: - msg = "Error %s" % status - raise SCons.Errors.BuildError( - errstr=msg, - node=self.batches[0].targets, - executor=self, - action=act) - return status - # use extra indirection because with new-style objects (Python 2.2 # and above) we can't override special methods, and nullify() needs # to be able to do this. def __call__(self, target, **kw): - return self.do_execute(target, kw) + return _do_execute_map[self._do_execute](self, target, kw) def cleanup(self): self._memo = {} @@ -403,24 +437,15 @@ class Executor(object): # another extra indirection for new-style objects and nullify... - def my_str(self): - env = self.get_build_env() - return "\n".join([action.genstring(self.get_all_targets(), - self.get_all_sources(), - env) - for action in self.get_action_list()]) - - def __str__(self): - return self.my_str() + return _execute_str_map[self._execute_str](self) def nullify(self): self.cleanup() - self.do_execute = self.do_nothing - self.my_str = lambda: '' - - memoizer_counters.append(SCons.Memoize.CountValue('get_contents')) + self._do_execute = 0 + self._execute_str = 0 + @SCons.Memoize.CountMethodCall def get_contents(self): """Fetch the signature contents. This is the main reason this class exists, so we can compute this once and cache it regardless @@ -493,8 +518,7 @@ class Executor(object): def _get_unignored_sources_key(self, node, ignore=()): return (node,) + tuple(ignore) - memoizer_counters.append(SCons.Memoize.CountDict('get_unignored_sources', _get_unignored_sources_key)) - + @SCons.Memoize.CountDictCall(_get_unignored_sources_key) def get_unignored_sources(self, node, ignore=()): key = (node,) + tuple(ignore) try: @@ -579,6 +603,23 @@ class Null(object): disassociate Builders from Nodes entirely, so we're not going to worry about unit tests for this--at least for now. """ + + __slots__ = ('pre_actions', + 'post_actions', + 'env', + 'overridelist', + 'batches', + 'builder_kw', + '_memo', + 'lvars', + '_changed_sources_list', + '_changed_targets_list', + '_unchanged_sources_list', + '_unchanged_targets_list', + 'action_list', + '_do_execute', + '_execute_str') + def __init__(self, *args, **kw): if SCons.Debug.track_instances: logInstanceCreation(self, 'Executor.Null') self.batches = [Batch(kw['targets'][:], [])] diff --git a/src/engine/SCons/Memoize.py b/src/engine/SCons/Memoize.py index e77aacf..5144f83 100644 --- a/src/engine/SCons/Memoize.py +++ b/src/engine/SCons/Memoize.py @@ -25,17 +25,17 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" __doc__ = """Memoizer -A metaclass implementation to count hits and misses of the computed +A decorator-based implementation to count hits and misses of the computed values that various methods cache in memory. Use of this modules assumes that wrapped methods be coded to cache their -values in a consistent way. Here is an example of wrapping a method -that returns a computed value, with no input parameters: +values in a consistent way. In particular, it requires that the class uses a +dictionary named "_memo" to store the cached values. - memoizer_counters = [] # Memoization - - memoizer_counters.append(SCons.Memoize.CountValue('foo')) # Memoization +Here is an example of wrapping a method that returns a computed value, +with no input parameters: + @SCons.Memoize.CountMethodCall def foo(self): try: # Memoization @@ -55,8 +55,7 @@ based on one or more input arguments: def _bar_key(self, argument): # Memoization return argument # Memoization - memoizer_counters.append(SCons.Memoize.CountDict('bar', _bar_key)) # Memoization - + @SCons.Memoize.CountDictCall(_bar_key) def bar(self, argument): memo_key = argument # Memoization @@ -77,10 +76,6 @@ based on one or more input arguments: return result -At one point we avoided replicating this sort of logic in all the methods -by putting it right into this module, but we've moved away from that at -present (see the "Historical Note," below.). - Deciding what to cache is tricky, because different configurations can have radically different performance tradeoffs, and because the tradeoffs involved are often so non-obvious. Consequently, deciding @@ -102,51 +97,37 @@ cache return values from a method that's being called a lot: input arguments, you don't need to use all of the arguments if some of them don't affect the return values. -Historical Note: The initial Memoizer implementation actually handled -the caching of values for the wrapped methods, based on a set of generic -algorithms for computing hashable values based on the method's arguments. -This collected caching logic nicely, but had two drawbacks: - - Running arguments through a generic key-conversion mechanism is slower - (and less flexible) than just coding these things directly. Since the - methods that need memoized values are generally performance-critical, - slowing them down in order to collect the logic isn't the right - tradeoff. - - Use of the memoizer really obscured what was being called, because - all the memoized methods were wrapped with re-used generic methods. - This made it more difficult, for example, to use the Python profiler - to figure out how to optimize the underlying methods. """ -import types - # A flag controlling whether or not we actually use memoization. use_memoizer = None -CounterList = [] +# Global list of counter objects +CounterList = {} class Counter(object): """ Base class for counting memoization hits and misses. - We expect that the metaclass initialization will have filled in - the .name attribute that represents the name of the function - being counted. + We expect that the initialization in a matching decorator will + fill in the correct class name and method name that represents + the name of the function being counted. """ - def __init__(self, method_name): + def __init__(self, cls_name, method_name): """ """ + self.cls_name = cls_name self.method_name = method_name self.hit = 0 self.miss = 0 - CounterList.append(self) + def key(self): + return self.cls_name+'.'+self.method_name def display(self): fmt = " %7d hits %7d misses %s()" - print fmt % (self.hit, self.miss, self.name) + print fmt % (self.hit, self.miss, self.key()) def __cmp__(self, other): try: - return cmp(self.name, other.name) + return cmp(self.key(), other.key()) except AttributeError: return 0 @@ -154,45 +135,39 @@ class CountValue(Counter): """ A counter class for simple, atomic memoized values. - A CountValue object should be instantiated in a class for each of + A CountValue object should be instantiated in a decorator for each of the class's methods that memoizes its return value by simply storing the return value in its _memo dictionary. - - We expect that the metaclass initialization will fill in the - .underlying_method attribute with the method that we're wrapping. - We then call the underlying_method method after counting whether - its memoized value has already been set (a hit) or not (a miss). """ - def __call__(self, *args, **kw): + def count(self, *args, **kw): + """ Counts whether the memoized value has already been + set (a hit) or not (a miss). + """ obj = args[0] if self.method_name in obj._memo: self.hit = self.hit + 1 else: self.miss = self.miss + 1 - return self.underlying_method(*args, **kw) class CountDict(Counter): """ A counter class for memoized values stored in a dictionary, with keys based on the method's input arguments. - A CountDict object is instantiated in a class for each of the + A CountDict object is instantiated in a decorator for each of the class's methods that memoizes its return value in a dictionary, indexed by some key that can be computed from one or more of its input arguments. - - We expect that the metaclass initialization will fill in the - .underlying_method attribute with the method that we're wrapping. - We then call the underlying_method method after counting whether the - computed key value is already present in the memoization dictionary - (a hit) or not (a miss). """ - def __init__(self, method_name, keymaker): + def __init__(self, cls_name, method_name, keymaker): """ """ - Counter.__init__(self, method_name) + Counter.__init__(self, cls_name, method_name) self.keymaker = keymaker - def __call__(self, *args, **kw): + def count(self, *args, **kw): + """ Counts whether the computed key value is already present + in the memoization dictionary (a hit) or not (a miss). + """ obj = args[0] try: memo_dict = obj._memo[self.method_name] @@ -204,39 +179,65 @@ class CountDict(Counter): self.hit = self.hit + 1 else: self.miss = self.miss + 1 - return self.underlying_method(*args, **kw) - -class Memoizer(object): - """Object which performs caching of method calls for its 'primary' - instance.""" - - def __init__(self): - pass def Dump(title=None): + """ Dump the hit/miss count for all the counters + collected so far. + """ if title: print title - CounterList.sort() - for counter in CounterList: - counter.display() - -class Memoized_Metaclass(type): - def __init__(cls, name, bases, cls_dict): - super(Memoized_Metaclass, cls).__init__(name, bases, cls_dict) - - for counter in cls_dict.get('memoizer_counters', []): - method_name = counter.method_name - - counter.name = cls.__name__ + '.' + method_name - counter.underlying_method = cls_dict[method_name] - - replacement_method = types.MethodType(counter, None, cls) - setattr(cls, method_name, replacement_method) + for counter in sorted(CounterList): + CounterList[counter].display() def EnableMemoization(): global use_memoizer use_memoizer = 1 +def CountMethodCall(fn): + """ Decorator for counting memoizer hits/misses while retrieving + a simple value in a class method. It wraps the given method + fn and uses a CountValue object to keep track of the + caching statistics. + Wrapping gets enabled by calling EnableMemoization(). + """ + if use_memoizer: + def wrapper(self, *args, **kwargs): + global CounterList + key = self.__class__.__name__+'.'+fn.__name__ + if key not in CounterList: + CounterList[key] = CountValue(self.__class__.__name__, fn.__name__) + CounterList[key].count(self, *args, **kwargs) + return fn(self, *args, **kwargs) + wrapper.__name__= fn.__name__ + return wrapper + else: + return fn + +def CountDictCall(keyfunc): + """ Decorator for counting memoizer hits/misses while accessing + dictionary values with a key-generating function. Like + CountMethodCall above, it wraps the given method + fn and uses a CountDict object to keep track of the + caching statistics. The dict-key function keyfunc has to + get passed in the decorator call and gets stored in the + CountDict instance. + Wrapping gets enabled by calling EnableMemoization(). + """ + def decorator(fn): + if use_memoizer: + def wrapper(self, *args, **kwargs): + global CounterList + key = self.__class__.__name__+'.'+fn.__name__ + if key not in CounterList: + CounterList[key] = CountDict(self.__class__.__name__, fn.__name__, keyfunc) + CounterList[key].count(self, *args, **kwargs) + return fn(self, *args, **kwargs) + wrapper.__name__= fn.__name__ + return wrapper + else: + return fn + return decorator + # Local Variables: # tab-width:4 # indent-tabs-mode:nil diff --git a/src/engine/SCons/MemoizeTests.py b/src/engine/SCons/MemoizeTests.py index 3606d57..77ff6bc 100644 --- a/src/engine/SCons/MemoizeTests.py +++ b/src/engine/SCons/MemoizeTests.py @@ -30,22 +30,18 @@ import TestUnit import SCons.Memoize - +# Enable memoization counting +SCons.Memoize.EnableMemoization() class FakeObject(object): - __metaclass__ = SCons.Memoize.Memoized_Metaclass - - memoizer_counters = [] - def __init__(self): self._memo = {} def _dict_key(self, argument): return argument - memoizer_counters.append(SCons.Memoize.CountDict('dict', _dict_key)) - + @SCons.Memoize.CountDictCall(_dict_key) def dict(self, argument): memo_key = argument @@ -66,8 +62,7 @@ class FakeObject(object): return result - memoizer_counters.append(SCons.Memoize.CountValue('value')) - + @SCons.Memoize.CountMethodCall def value(self): try: @@ -82,10 +77,7 @@ class FakeObject(object): return result def get_memoizer_counter(self, name): - for mc in self.memoizer_counters: - if mc.method_name == name: - return mc - return None + return SCons.Memoize.CounterList.get(self.__class__.__name__+'.'+name, None) class Returner(object): def __init__(self, result): diff --git a/src/engine/SCons/Node/Alias.py b/src/engine/SCons/Node/Alias.py index f817356..a035816 100644 --- a/src/engine/SCons/Node/Alias.py +++ b/src/engine/SCons/Node/Alias.py @@ -56,13 +56,47 @@ class AliasNameSpace(collections.UserDict): return None class AliasNodeInfo(SCons.Node.NodeInfoBase): - current_version_id = 1 + __slots__ = ('csig',) + current_version_id = 2 field_list = ['csig'] def str_to_node(self, s): return default_ans.Alias(s) + def __getstate__(self): + """ + Return all fields that shall be pickled. Walk the slots in the class + hierarchy and add those to the state dictionary. If a '__dict__' slot is + available, copy all entries to the dictionary. Also include the version + id, which is fixed for all instances of a class. + """ + state = getattr(self, '__dict__', {}).copy() + for obj in type(self).mro(): + for name in getattr(obj,'__slots__',()): + if hasattr(self, name): + state[name] = getattr(self, name) + + state['_version_id'] = self.current_version_id + try: + del state['__weakref__'] + except KeyError: + pass + + return state + + def __setstate__(self, state): + """ + Restore the attributes from a pickled state. + """ + # TODO check or discard version + del state['_version_id'] + for key, value in state.items(): + if key not in ('__weakref__',): + setattr(self, key, value) + + class AliasBuildInfo(SCons.Node.BuildInfoBase): - current_version_id = 1 + __slots__ = () + current_version_id = 2 class Alias(SCons.Node.Node): @@ -72,7 +106,9 @@ class Alias(SCons.Node.Node): def __init__(self, name): SCons.Node.Node.__init__(self) self.name = name - + self.changed_since_last_build = 1 + self.store_info = 0 + def str_for_display(self): return '"' + self.__str__() + '"' @@ -105,13 +141,6 @@ class Alias(SCons.Node.Node): # # - def changed_since_last_build(self, target, prev_ni): - cur_csig = self.get_csig() - try: - return cur_csig != prev_ni.csig - except AttributeError: - return 1 - def build(self): """A "builder" for aliases.""" pass diff --git a/src/engine/SCons/Node/AliasTests.py b/src/engine/SCons/Node/AliasTests.py index 2d11bdf..8e31875 100644 --- a/src/engine/SCons/Node/AliasTests.py +++ b/src/engine/SCons/Node/AliasTests.py @@ -103,14 +103,14 @@ class AliasNodeInfoTestCase(unittest.TestCase): """Test AliasNodeInfo initialization""" ans = SCons.Node.Alias.AliasNameSpace() aaa = ans.Alias('aaa') - ni = SCons.Node.Alias.AliasNodeInfo(aaa) + ni = SCons.Node.Alias.AliasNodeInfo() class AliasBuildInfoTestCase(unittest.TestCase): def test___init__(self): """Test AliasBuildInfo initialization""" ans = SCons.Node.Alias.AliasNameSpace() aaa = ans.Alias('aaa') - bi = SCons.Node.Alias.AliasBuildInfo(aaa) + bi = SCons.Node.Alias.AliasBuildInfo() if __name__ == "__main__": suite = unittest.TestSuite() diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py index 4db1cb3..2402fac 100644 --- a/src/engine/SCons/Node/FS.py +++ b/src/engine/SCons/Node/FS.py @@ -56,10 +56,23 @@ import SCons.Warnings from SCons.Debug import Trace -do_store_info = True print_duplicate = 0 +def sconsign_none(node): + raise NotImplementedError + +def sconsign_dir(node): + """Return the .sconsign file info for this directory, + creating it first if necessary.""" + if not node._sconsign: + import SCons.SConsign + node._sconsign = SCons.SConsign.ForDirectory(node) + return node._sconsign + +_sconsign_map = {0 : sconsign_none, + 1 : sconsign_dir} + class EntryProxyAttributeError(AttributeError): """ An AttributeError subclass for recording and displaying the name @@ -268,8 +281,8 @@ def LinkFunc(target, source, env): # who want to move their soft-linked src-trees around. Those # people should use the 'hard-copy' mode, softlinks cannot be # used for that; at least I have no idea how ... - src = source[0].abspath - dest = target[0].abspath + src = source[0].get_abspath() + dest = target[0].get_abspath() dir, file = os.path.split(dest) if dir and not target[0].fs.isdir(dir): os.makedirs(dir) @@ -302,7 +315,7 @@ LocalCopy = SCons.Action.Action(LinkFunc, LocalString) def UnlinkFunc(target, source, env): t = target[0] - t.fs.unlink(t.abspath) + t.fs.unlink(t.get_abspath()) return 0 Unlink = SCons.Action.Action(UnlinkFunc, None) @@ -310,7 +323,7 @@ Unlink = SCons.Action.Action(UnlinkFunc, None) def MkdirFunc(target, source, env): t = target[0] if not t.exists(): - t.fs.mkdir(t.abspath) + t.fs.mkdir(t.get_abspath()) return 0 Mkdir = SCons.Action.Action(MkdirFunc, None, presub=None) @@ -403,7 +416,7 @@ def do_diskcheck_match(node, predicate, errorfmt): except (AttributeError, KeyError): pass if result: - raise TypeError(errorfmt % node.abspath) + raise TypeError(errorfmt % node.get_abspath()) def ignore_diskcheck_match(node, predicate, errorfmt): pass @@ -573,7 +586,20 @@ class Base(SCons.Node.Node): object identity comparisons. """ - memoizer_counters = [] + __slots__ = ['name', + 'fs', + 'abspath', + 'labspath', + 'path', + 'tpath', + 'path_elements', + 'dir', + 'cwd', + 'duplicate', + '_local', + 'sbuilder', + '_proxy', + '_func_sconsign'] def __init__(self, name, directory, fs): """Initialize a generic Node.FS.Base object. @@ -591,27 +617,26 @@ class Base(SCons.Node.Node): #: Filename with extension as it was specified when the object was #: created; to obtain filesystem path, use Python str() function self.name = SCons.Util.silent_intern(name) - #: Cached filename extension - self.suffix = SCons.Util.silent_intern(SCons.Util.splitext(name)[1]) self.fs = fs #: Reference to parent Node.FS object assert directory, "A directory must be provided" - self.abspath = SCons.Util.silent_intern(directory.entry_abspath(name)) - self.labspath = SCons.Util.silent_intern(directory.entry_labspath(name)) - if directory.path == '.': - self.path = SCons.Util.silent_intern(name) - else: - self.path = SCons.Util.silent_intern(directory.entry_path(name)) - if directory.tpath == '.': - self.tpath = SCons.Util.silent_intern(name) - else: - self.tpath = SCons.Util.silent_intern(directory.entry_tpath(name)) - self.path_elements = directory.path_elements + [self] + self.abspath = None + self.labspath = None + self.path = None + self.tpath = None + self.path_elements = None self.dir = directory self.cwd = None # will hold the SConscript directory for target nodes self.duplicate = directory.duplicate + self.changed_since_last_build = 2 + self._func_sconsign = 0 + self._func_exists = 2 + self._func_rexists = 2 + self._func_get_contents = 0 + self._func_target_from_source = 1 + self.store_info = 1 def str_for_display(self): return '"' + self.__str__() + '"' @@ -624,13 +649,13 @@ class Base(SCons.Node.Node): if isinstance(self, klass) or klass is Entry: return raise TypeError("Tried to lookup %s '%s' as a %s." %\ - (self.__class__.__name__, self.path, klass.__name__)) + (self.__class__.__name__, self.get_internal_path(), klass.__name__)) def get_dir(self): return self.dir def get_suffix(self): - return self.suffix + return SCons.Util.splitext(self.name)[1] def rfile(self): return self @@ -643,8 +668,7 @@ class Base(SCons.Node.Node): return self._save_str() return self._get_str() - memoizer_counters.append(SCons.Memoize.CountValue('_save_str')) - + @SCons.Memoize.CountMethodCall def _save_str(self): try: return self._memo['_save_str'] @@ -681,21 +705,20 @@ class Base(SCons.Node.Node): rstr = __str__ - memoizer_counters.append(SCons.Memoize.CountValue('stat')) - + @SCons.Memoize.CountMethodCall def stat(self): try: return self._memo['stat'] except KeyError: pass - try: result = self.fs.stat(self.abspath) + try: result = self.fs.stat(self.get_abspath()) except os.error: result = None self._memo['stat'] = result return result def exists(self): - return self.stat() is not None + return SCons.Node._exists_map[self._func_exists](self) def rexists(self): - return self.rfile().exists() + return SCons.Node._rexists_map[self._func_rexists](self) def getmtime(self): st = self.stat() @@ -717,7 +740,7 @@ class Base(SCons.Node.Node): if hasattr(os, 'symlink'): def islink(self): - try: st = self.fs.lstat(self.abspath) + try: st = self.fs.lstat(self.get_abspath()) except os.error: return 0 return stat.S_ISLNK(st[stat.ST_MODE]) else: @@ -752,7 +775,7 @@ class Base(SCons.Node.Node): dir = self.fs.getcwd() if self == dir: return '.' - path_elems = self.path_elements + path_elems = self.get_path_elements() pathname = '' try: i = path_elems.index(dir) except ValueError: @@ -785,7 +808,26 @@ class Base(SCons.Node.Node): def get_abspath(self): """Get the absolute path of the file.""" - return self.abspath + return self.dir.entry_abspath(self.name) + + def get_labspath(self): + """Get the absolute path of the file.""" + return self.dir.entry_labspath(self.name) + + def get_internal_path(self): + if self.dir.path == '.': + return self.name + else: + return self.dir.entry_path(self.name) + + def get_tpath(self): + if self.dir.tpath == '.': + return self.name + else: + return self.dir.entry_tpath(self.name) + + def get_path_elements(self): + return self.dir.path_elements + [self] def for_signature(self): # Return just our name. Even an absolute path would not work, @@ -811,13 +853,12 @@ class Base(SCons.Node.Node): files that need different behavior. See Tool/swig.py for an example. """ - return self.dir.Entry(prefix + splitext(self.name)[0] + suffix) + return SCons.Node._target_from_source_map[self._func_target_from_source](self, prefix, suffix, splitext) def _Rfindalldirs_key(self, pathlist): return pathlist - memoizer_counters.append(SCons.Memoize.CountDict('Rfindalldirs', _Rfindalldirs_key)) - + @SCons.Memoize.CountDictCall(_Rfindalldirs_key) def Rfindalldirs(self, pathlist): """ Return all of the directories for a given path list, including @@ -856,8 +897,7 @@ class Base(SCons.Node.Node): cwd = self.cwd or self.fs._cwd return cwd.Rfindalldirs(pathlist) - memoizer_counters.append(SCons.Memoize.CountValue('rentry')) - + @SCons.Memoize.CountMethodCall def rentry(self): try: return self._memo['rentry'] @@ -878,7 +918,7 @@ class Base(SCons.Node.Node): def _glob1(self, pattern, ondisk=True, source=False, strings=False): return [] - + class Entry(Base): """This is the class for generic Node.FS entries--that is, things that could be a File or a Dir, but we're just not sure yet. @@ -887,6 +927,28 @@ class Entry(Base): time comes, and then call the same-named method in the transformed class.""" + __slots__ = ['scanner_paths', + 'cachedir_csig', + 'cachesig', + 'repositories', + 'srcdir', + 'entries', + 'searched', + '_sconsign', + 'variant_dirs', + 'root', + 'dirname', + 'on_disk_entries', + 'sccs_dir', + 'rcs_dir', + 'released_target_info', + 'contentsig'] + + def __init__(self, name, directory, fs): + Base.__init__(self, name, directory, fs) + self._func_exists = 3 + self._func_get_contents = 1 + def diskcheck_match(self): pass @@ -917,7 +979,7 @@ class Entry(Base): self.__class__ = Dir self._morph() elif must_exist: - msg = "No such file or directory: '%s'" % self.abspath + msg = "No such file or directory: '%s'" % self.get_abspath() raise SCons.Errors.UserError(msg) else: self.__class__ = File @@ -939,17 +1001,7 @@ class Entry(Base): def get_contents(self): """Fetch the contents of the entry. Returns the exact binary contents of the file.""" - try: - self = self.disambiguate(must_exist=1) - except SCons.Errors.UserError: - # There was nothing on disk with which to disambiguate - # this entry. Leave it as an Entry, but return a null - # string so calls to get_contents() in emitters and the - # like (e.g. in qt.py) don't have to disambiguate by hand - # or catch the exception. - return '' - else: - return self.get_contents() + return SCons.Node._get_contents_map[self._func_get_contents](self) def get_text_contents(self): """Fetch the decoded text contents of a Unicode encoded Entry. @@ -989,10 +1041,7 @@ class Entry(Base): # to make various tests pass. def exists(self): - """Return if the Entry exists. Check the file system to see - what we should turn into first. Assume a file if there's no - directory.""" - return self.disambiguate().exists() + return SCons.Node._exists_map[self._func_exists](self) def rel_path(self, other): d = self.disambiguate() @@ -1003,9 +1052,6 @@ class Entry(Base): def new_ninfo(self): return self.disambiguate().new_ninfo() - def changed_since_last_build(self, target, prev_ni): - return self.disambiguate().changed_since_last_build(target, prev_ni) - def _glob1(self, pattern, ondisk=True, source=False, strings=False): return self.disambiguate()._glob1(pattern, ondisk, source, strings) @@ -1019,9 +1065,6 @@ _classEntry = Entry class LocalFS(object): - if SCons.Memoize.use_memoizer: - __metaclass__ = SCons.Memoize.Memoized_Metaclass - # This class implements an abstraction layer for operations involving # a local file system. Essentially, this wraps any function in # the os, os.path or shutil modules that we use to actually go do @@ -1101,8 +1144,6 @@ class LocalFS(object): class FS(LocalFS): - memoizer_counters = [] - def __init__(self, path = None): """Initialize the Node.FS subsystem. @@ -1160,7 +1201,7 @@ class FS(LocalFS): if dir is not None: self._cwd = dir if change_os_dir: - os.chdir(dir.abspath) + os.chdir(dir.get_abspath()) except OSError: self._cwd = curr raise @@ -1249,9 +1290,9 @@ class FS(LocalFS): # The path is relative to the top-level SCons directory. if p in ('', '.'): - p = directory.labspath + p = directory.get_labspath() else: - p = directory.labspath + '/' + p + p = directory.get_labspath() + '/' + p else: if do_splitdrive: drive, p = _my_splitdrive(p) @@ -1285,9 +1326,9 @@ class FS(LocalFS): directory = self._cwd if p in ('', '.'): - p = directory.labspath + p = directory.get_labspath() else: - p = directory.labspath + '/' + p + p = directory.get_labspath() + '/' + p if drive: root = self.get_root(drive) @@ -1412,8 +1453,9 @@ class FS(LocalFS): return cwd.glob(pathname, ondisk, source, strings) class DirNodeInfo(SCons.Node.NodeInfoBase): + __slots__ = () # This should get reset by the FS initialization. - current_version_id = 1 + current_version_id = 2 fs = None @@ -1425,11 +1467,12 @@ class DirNodeInfo(SCons.Node.NodeInfoBase): if drive: root = self.fs.get_root(drive) if not os.path.isabs(s): - s = top.labspath + '/' + s + s = top.get_labspath() + '/' + s return root._lookup_abs(s, Entry) class DirBuildInfo(SCons.Node.BuildInfoBase): - current_version_id = 1 + __slots__ = () + current_version_id = 2 glob_magic_check = re.compile('[*?[]') @@ -1440,7 +1483,22 @@ class Dir(Base): """A class for directories in a file system. """ - memoizer_counters = [] + __slots__ = ['scanner_paths', + 'cachedir_csig', + 'cachesig', + 'repositories', + 'srcdir', + 'entries', + 'searched', + '_sconsign', + 'variant_dirs', + 'root', + 'dirname', + 'on_disk_entries', + 'sccs_dir', + 'rcs_dir', + 'released_target_info', + 'contentsig'] NodeInfo = DirNodeInfo BuildInfo = DirBuildInfo @@ -1470,6 +1528,22 @@ class Dir(Base): self._sconsign = None self.variant_dirs = [] self.root = self.dir.root + self.changed_since_last_build = 3 + self._func_sconsign = 1 + self._func_exists = 2 + self._func_get_contents = 2 + + self.abspath = SCons.Util.silent_intern(self.dir.entry_abspath(self.name)) + self.labspath = SCons.Util.silent_intern(self.dir.entry_labspath(self.name)) + if self.dir.path == '.': + self.path = SCons.Util.silent_intern(self.name) + else: + self.path = SCons.Util.silent_intern(self.dir.entry_path(self.name)) + if self.dir.tpath == '.': + self.tpath = SCons.Util.silent_intern(self.name) + else: + self.tpath = SCons.Util.silent_intern(self.dir.entry_tpath(self.name)) + self.path_elements = self.dir.path_elements + [self] # For directories, we make a difference between the directory # 'name' and the directory 'dirname'. The 'name' attribute is @@ -1562,8 +1636,7 @@ class Dir(Base): return self.srcdir.get_all_rdirs() + self.repositories return self.repositories - memoizer_counters.append(SCons.Memoize.CountValue('get_all_rdirs')) - + @SCons.Memoize.CountMethodCall def get_all_rdirs(self): try: return list(self._memo['get_all_rdirs']) @@ -1598,8 +1671,7 @@ class Dir(Base): def _rel_path_key(self, other): return str(other) - memoizer_counters.append(SCons.Memoize.CountDict('rel_path', _rel_path_key)) - + @SCons.Memoize.CountDictCall(_rel_path_key) def rel_path(self, other): """Return a path to "other" relative to this directory. """ @@ -1753,10 +1825,7 @@ class Dir(Base): def get_contents(self): """Return content signatures and names of all our children separated by new-lines. Ensure that the nodes are sorted.""" - contents = [] - for node in sorted(self.children(), key=lambda t: t.name): - contents.append('%s %s\n' % (node.get_csig(), node.name)) - return ''.join(contents) + return SCons.Node._get_contents_map[self._func_get_contents](self) def get_csig(self): """Compute the content signature for Directory nodes. In @@ -1770,8 +1839,6 @@ class Dir(Base): def do_duplicate(self, src): pass - changed_since_last_build = SCons.Node.Node.state_has_changed - def is_up_to_date(self): """If any child is not up-to-date, then this directory isn't, either.""" @@ -1795,12 +1862,8 @@ class Dir(Base): return self def sconsign(self): - """Return the .sconsign file info for this directory, - creating it first if necessary.""" - if not self._sconsign: - import SCons.SConsign - self._sconsign = SCons.SConsign.ForDirectory(self) - return self._sconsign + """Return the .sconsign file info for this directory. """ + return _sconsign_map[self._func_sconsign](self) def srcnode(self): """Dir has a special need for srcnode()...if we @@ -1817,6 +1880,23 @@ class Dir(Base): stamp = kid.get_timestamp() return stamp + def get_abspath(self): + """Get the absolute path of the file.""" + return self.abspath + + def get_labspath(self): + """Get the absolute path of the file.""" + return self.labspath + + def get_internal_path(self): + return self.path + + def get_tpath(self): + return self.tpath + + def get_path_elements(self): + return self.path_elements + def entry_abspath(self, name): return self.abspath + OS_SEP + name @@ -1887,8 +1967,7 @@ class Dir(Base): break return rentry_exists - memoizer_counters.append(SCons.Memoize.CountValue('srcdir_list')) - + @SCons.Memoize.CountMethodCall def srcdir_list(self): try: return self._memo['srcdir_list'] @@ -1929,8 +2008,7 @@ class Dir(Base): def _srcdir_find_file_key(self, filename): return filename - memoizer_counters.append(SCons.Memoize.CountDict('srcdir_find_file', _srcdir_find_file_key)) - + @SCons.Memoize.CountDictCall(_srcdir_find_file_key) def srcdir_find_file(self, filename): try: memo_dict = self._memo['srcdir_find_file'] @@ -2066,8 +2144,9 @@ class Dir(Base): if strings: r = [os.path.join(str(dir), x) for x in r] result.extend(r) - return sorted(result, key=lambda a: str(a)) + return sorted(result, key=lambda a: str(a)) + def _glob1(self, pattern, ondisk=True, source=False, strings=False): """ Globs for and returns a list of entry names matching a single @@ -2146,18 +2225,12 @@ class RootDir(Dir): add a separator when creating the path names of entries within this directory. """ + + __slots__ = ['_lookupDict'] + def __init__(self, drive, fs): if SCons.Debug.track_instances: logInstanceCreation(self, 'Node.FS.RootDir') - # We're going to be our own parent directory (".." entry and .dir - # attribute) so we have to set up some values so Base.__init__() - # won't gag won't it calls some of our methods. - self.abspath = '' - self.labspath = '' - self.path = '' - self.tpath = '' - self.path_elements = [] - self.duplicate = 0 - self.root = self + SCons.Node.Node.__init__(self) # Handle all the types of drives: if drive == '': @@ -2173,7 +2246,16 @@ class RootDir(Dir): name = drive dirname = drive + OS_SEP - Base.__init__(self, name, self, fs) + #: Filename with extension as it was specified when the object was + #: created; to obtain filesystem path, use Python str() function + self.name = SCons.Util.silent_intern(name) + self.fs = fs #: Reference to parent Node.FS object + + self.path_elements = [self] + self.dir = self + self._func_rexists = 2 + self._func_target_from_source = 1 + self.store_info = 1 # Now set our paths to what we really want them to be. The # name should already contain any necessary separators, such @@ -2184,22 +2266,65 @@ class RootDir(Dir): self.labspath = '' self.path = dirname self.tpath = dirname - self._morph() - - # Must be reset after Dir._morph() is invoked... self.dirname = dirname + self._morph() + + self.duplicate = 0 self._lookupDict = {} self._lookupDict[''] = self self._lookupDict['/'] = self - + self.root = self # The // entry is necessary because os.path.normpath() # preserves double slashes at the beginning of a path on Posix # platforms. if not has_unc: self._lookupDict['//'] = self + def _morph(self): + """Turn a file system Node (either a freshly initialized directory + object or a separate Entry object) into a proper directory object. + + Set up this directory's entries and hook it into the file + system tree. Specify that directories (this Node) don't use + signatures for calculating whether they're current. + """ + + self.repositories = [] + self.srcdir = None + + self.entries = {} + self.entries['.'] = self + self.entries['..'] = self.dir + self.cwd = self + self.searched = 0 + self._sconsign = None + self.variant_dirs = [] + self.changed_since_last_build = 3 + self._func_sconsign = 1 + self._func_exists = 2 + self._func_get_contents = 2 + + # Don't just reset the executor, replace its action list, + # because it might have some pre-or post-actions that need to + # be preserved. + # + # But don't reset the executor if there is a non-null executor + # attached already. The existing executor might have other + # targets, in which case replacing the action list with a + # Mkdir action is a big mistake. + if not hasattr(self, 'executor'): + self.builder = get_MkdirBuilder() + self.get_executor().set_action_list(self.builder.action) + else: + # Prepend MkdirBuilder action to existing action list + l = self.get_executor().action_list + a = get_MkdirBuilder().action + l.insert(0, a) + self.get_executor().set_action_list(l) + + def must_be_same(self, klass): if klass is Dir: return @@ -2278,7 +2403,8 @@ class RootDir(Dir): return _null class FileNodeInfo(SCons.Node.NodeInfoBase): - current_version_id = 1 + __slots__ = ('csig', 'timestamp', 'size') + current_version_id = 2 field_list = ['csig', 'timestamp', 'size'] @@ -2293,11 +2419,43 @@ class FileNodeInfo(SCons.Node.NodeInfoBase): if drive: root = self.fs.get_root(drive) if not os.path.isabs(s): - s = top.labspath + '/' + s + s = top.get_labspath() + '/' + s return root._lookup_abs(s, Entry) + def __getstate__(self): + """ + Return all fields that shall be pickled. Walk the slots in the class + hierarchy and add those to the state dictionary. If a '__dict__' slot is + available, copy all entries to the dictionary. Also include the version + id, which is fixed for all instances of a class. + """ + state = getattr(self, '__dict__', {}).copy() + for obj in type(self).mro(): + for name in getattr(obj,'__slots__',()): + if hasattr(self, name): + state[name] = getattr(self, name) + + state['_version_id'] = self.current_version_id + try: + del state['__weakref__'] + except KeyError: + pass + + return state + + def __setstate__(self, state): + """ + Restore the attributes from a pickled state. + """ + # TODO check or discard version + del state['_version_id'] + for key, value in state.items(): + if key not in ('__weakref__',): + setattr(self, key, value) + class FileBuildInfo(SCons.Node.BuildInfoBase): - current_version_id = 1 + __slots__ = () + current_version_id = 2 def convert_to_sconsign(self): """ @@ -2312,7 +2470,7 @@ class FileBuildInfo(SCons.Node.BuildInfoBase): else: def node_to_str(n): try: - s = n.path + s = n.get_internal_path() except AttributeError: s = str(n) else: @@ -2353,6 +2511,8 @@ class FileBuildInfo(SCons.Node.BuildInfoBase): nodeinfos = getattr(self, sattr) except AttributeError: continue + if strings is None or nodeinfos is None: + continue nodes = [] for s, ni in zip(strings, nodeinfos): if not isinstance(s, SCons.Node.Node): @@ -2366,6 +2526,8 @@ class FileBuildInfo(SCons.Node.BuildInfoBase): for bkid, bkidsig in zip(bkids, bkidsigs): result.append(str(bkid) + ': ' + ' '.join(bkidsig.format(names=names))) + if not hasattr(self,'bact'): + self.bact = "none" result.append('%s [%s]' % (self.bactsig, self.bact)) return '\n'.join(result) @@ -2373,7 +2535,22 @@ class File(Base): """A class for files in a file system. """ - memoizer_counters = [] + __slots__ = ['scanner_paths', + 'cachedir_csig', + 'cachesig', + 'repositories', + 'srcdir', + 'entries', + 'searched', + '_sconsign', + 'variant_dirs', + 'root', + 'dirname', + 'on_disk_entries', + 'sccs_dir', + 'rcs_dir', + 'released_target_info', + 'contentsig'] NodeInfo = FileNodeInfo BuildInfo = FileBuildInfo @@ -2424,6 +2601,14 @@ class File(Base): if not hasattr(self, 'released_target_info'): self.released_target_info = False + self.store_info = 1 + self._func_exists = 4 + self._func_get_contents = 3 + + # Initialize this Node's decider function to decide_source() because + # every file is a source file until it has a Builder attached... + self.changed_since_last_build = 4 + # If there was already a Builder set on this entry, then # we need to make sure we call the target-decider function, # not the source-decider. Reaching in and doing this by hand @@ -2435,22 +2620,13 @@ class File(Base): # not clear right now how to fix that, stick with what works # until it becomes clear... if self.has_builder(): - self.changed_since_last_build = self.decide_target + self.changed_since_last_build = 5 def scanner_key(self): return self.get_suffix() def get_contents(self): - if not self.rexists(): - return '' - fname = self.rfile().abspath - try: - contents = open(fname, "rb").read() - except EnvironmentError, e: - if not e.filename: - e.filename = fname - raise - return contents + return SCons.Node._get_contents_map[self._func_get_contents](self) # This attempts to figure out what the encoding of the text is # based upon the BOM bytes, and then decodes the contents so that @@ -2477,7 +2653,7 @@ class File(Base): """ if not self.rexists(): return SCons.Util.MD5signature('') - fname = self.rfile().abspath + fname = self.rfile().get_abspath() try: cs = SCons.Util.MD5filesignature(fname, chunksize=SCons.Node.FS.File.md5_chunksize*1024) @@ -2487,9 +2663,7 @@ class File(Base): raise return cs - - memoizer_counters.append(SCons.Memoize.CountValue('get_size')) - + @SCons.Memoize.CountMethodCall def get_size(self): try: return self._memo['get_size'] @@ -2505,8 +2679,7 @@ class File(Base): return size - memoizer_counters.append(SCons.Memoize.CountValue('get_timestamp')) - + @SCons.Memoize.CountMethodCall def get_timestamp(self): try: return self._memo['get_timestamp'] @@ -2522,14 +2695,6 @@ class File(Base): return timestamp - def store_info(self): - # Merge our build information into the already-stored entry. - # This accomodates "chained builds" where a file that's a target - # in one build (SConstruct file) is a source in a different build. - # See test/chained-build.py for the use case. - if do_store_info: - self.dir.sconsign().store_info(self.name, self) - convert_copy_attrs = [ 'bsources', 'bimplicit', @@ -2642,8 +2807,7 @@ class File(Base): delattr(old_entry, attr) return new_entry - memoizer_counters.append(SCons.Memoize.CountValue('get_stored_info')) - + @SCons.Memoize.CountMethodCall def get_stored_info(self): try: return self._memo['get_stored_info'] @@ -2683,8 +2847,7 @@ class File(Base): def _get_found_includes_key(self, env, scanner, path): return (id(env), id(scanner), path) - memoizer_counters.append(SCons.Memoize.CountDict('get_found_includes', _get_found_includes_key)) - + @SCons.Memoize.CountDictCall(_get_found_includes_key) def get_found_includes(self, env, scanner, path): """Return the included implicit dependencies in this file. Cache results so we only scan the file once per path @@ -2768,9 +2931,9 @@ class File(Base): # any build information that's stored in the .sconsign file # into our binfo object so it doesn't get lost. old = self.get_stored_info() - self.get_binfo().__dict__.update(old.binfo.__dict__) + self.get_binfo().merge(old.binfo) - self.store_info() + SCons.Node.store_info_map[self.store_info](self) def release_target_info(self): """Called just after this node has been marked @@ -2870,7 +3033,7 @@ class File(Base): def _rmv_existing(self): self.clear_memoized_values() - if print_duplicate: + if SCons.Node.print_duplicate: print "dup: removing existing target %s"%self e = Unlink(self, [], None) if isinstance(e, SCons.Errors.BuildError): @@ -2906,18 +3069,18 @@ class File(Base): def remove(self): """Remove this file.""" if self.exists() or self.islink(): - self.fs.unlink(self.path) + self.fs.unlink(self.get_internal_path()) return 1 return None def do_duplicate(self, src): self._createDir() - if print_duplicate: + if SCons.Node.print_duplicate: print "dup: relinking variant '%s' from '%s'"%(self, src) Unlink(self, None, None) e = Link(self, src, None) if isinstance(e, SCons.Errors.BuildError): - desc = "Cannot duplicate `%s' in `%s': %s." % (src.path, self.dir.path, e.errstr) + desc = "Cannot duplicate `%s' in `%s': %s." % (src.get_internal_path(), self.dir.path, e.errstr) raise SCons.Errors.StopError(desc) self.linked = 1 # The Link() action may or may not have actually @@ -2926,36 +3089,14 @@ class File(Base): # _rexists attributes so they can be reevaluated. self.clear() - memoizer_counters.append(SCons.Memoize.CountValue('exists')) - + @SCons.Memoize.CountMethodCall def exists(self): try: return self._memo['exists'] except KeyError: pass - # Duplicate from source path if we are set up to do this. - if self.duplicate and not self.is_derived() and not self.linked: - src = self.srcnode() - if src is not self: - # At this point, src is meant to be copied in a variant directory. - src = src.rfile() - if src.abspath != self.abspath: - if src.exists(): - self.do_duplicate(src) - # Can't return 1 here because the duplication might - # not actually occur if the -n option is being used. - else: - # The source file does not exist. Make sure no old - # copy remains in the variant directory. - if print_duplicate: - print "dup: no src for %s, unlinking old variant copy"%self - if Base.exists(self) or self.islink(): - self.fs.unlink(self.path) - # Return None explicitly because the Base.exists() call - # above will have cached its value if the file existed. - self._memo['exists'] = None - return None - result = Base.exists(self) + + result = SCons.Node._exists_map[self._func_exists](self) self._memo['exists'] = result return result @@ -3032,7 +3173,7 @@ class File(Base): def builder_set(self, builder): SCons.Node.Node.builder_set(self, builder) - self.changed_since_last_build = self.decide_target + self.changed_since_last_build = 5 def built(self): """Called just after this File node is successfully built. @@ -3049,7 +3190,7 @@ class File(Base): if (not SCons.Node.interactive and not hasattr(self.attributes, 'keep_targetinfo')): # Ensure that the build infos get computed and cached... - self.store_info() + SCons.Node.store_info_map[self.store_info](self) # ... then release some more variables. self._specific_sources = False self.labspath = None @@ -3111,16 +3252,6 @@ class File(Base): except AttributeError: return 1 - def decide_source(self, target, prev_ni): - return target.get_build_env().decide_source(self, target, prev_ni) - - def decide_target(self, target, prev_ni): - return target.get_build_env().decide_target(self, target, prev_ni) - - # Initialize this Node's decider function to decide_source() because - # every file is a source file until it has a Builder attached... - changed_since_last_build = decide_source - def is_up_to_date(self): T = 0 if T: Trace('is_up_to_date(%s):' % self) @@ -3138,7 +3269,7 @@ class File(Base): e = LocalCopy(self, r, None) if isinstance(e, SCons.Errors.BuildError): raise - self.store_info() + SCons.Node.store_info_map[self.store_info](self) if T: Trace(' 1\n') return 1 self.changed() @@ -3149,8 +3280,7 @@ class File(Base): if T: Trace(' self.exists(): %s\n' % r) return not r - memoizer_counters.append(SCons.Memoize.CountValue('rfile')) - + @SCons.Memoize.CountMethodCall def rfile(self): try: return self._memo['rfile'] @@ -3252,7 +3382,7 @@ class File(Base): # Append this node's signature... sigs.append(self.get_contents_sig()) # ...and it's path - sigs.append(self.path) + sigs.append(self.get_internal_path()) # Merge this all into a single signature result = self.cachesig = SCons.Util.MD5collect(sigs) return result @@ -3268,10 +3398,6 @@ def get_default_fs(): class FileFinder(object): """ """ - if SCons.Memoize.use_memoizer: - __metaclass__ = SCons.Memoize.Memoized_Metaclass - - memoizer_counters = [] def __init__(self): self._memo = {} @@ -3314,8 +3440,7 @@ class FileFinder(object): def _find_file_key(self, filename, paths, verbose=None): return (filename, paths) - memoizer_counters.append(SCons.Memoize.CountDict('find_file', _find_file_key)) - + @SCons.Memoize.CountDictCall(_find_file_key) def find_file(self, filename, paths, verbose=None): """ find_file(str, [Dir()]) -> [nodes] diff --git a/src/engine/SCons/Node/FSTests.py b/src/engine/SCons/Node/FSTests.py index 0326717..0c1e71f 100644 --- a/src/engine/SCons/Node/FSTests.py +++ b/src/engine/SCons/Node/FSTests.py @@ -130,34 +130,34 @@ class VariantDirTestCase(unittest.TestCase): fs.VariantDir('build', 'src') f2 = fs.File('build/test2') d1 = fs.Dir('build') - assert f1.srcnode().path == os.path.normpath('src/test1'), f1.srcnode().path - assert f2.srcnode().path == os.path.normpath('src/test2'), f2.srcnode().path - assert d1.srcnode().path == 'src', d1.srcnode().path + assert f1.srcnode().get_internal_path() == os.path.normpath('src/test1'), f1.srcnode().get_internal_path() + assert f2.srcnode().get_internal_path() == os.path.normpath('src/test2'), f2.srcnode().get_internal_path() + assert d1.srcnode().get_internal_path() == 'src', d1.srcnode().get_internal_path() fs = SCons.Node.FS.FS() f1 = fs.File('build/test1') fs.VariantDir('build', '.') f2 = fs.File('build/test2') d1 = fs.Dir('build') - assert f1.srcnode().path == 'test1', f1.srcnode().path - assert f2.srcnode().path == 'test2', f2.srcnode().path - assert d1.srcnode().path == '.', d1.srcnode().path + assert f1.srcnode().get_internal_path() == 'test1', f1.srcnode().get_internal_path() + assert f2.srcnode().get_internal_path() == 'test2', f2.srcnode().get_internal_path() + assert d1.srcnode().get_internal_path() == '.', d1.srcnode().get_internal_path() fs = SCons.Node.FS.FS() fs.VariantDir('build/var1', 'src') fs.VariantDir('build/var2', 'src') f1 = fs.File('build/var1/test1') f2 = fs.File('build/var2/test1') - assert f1.srcnode().path == os.path.normpath('src/test1'), f1.srcnode().path - assert f2.srcnode().path == os.path.normpath('src/test1'), f2.srcnode().path + assert f1.srcnode().get_internal_path() == os.path.normpath('src/test1'), f1.srcnode().get_internal_path() + assert f2.srcnode().get_internal_path() == os.path.normpath('src/test1'), f2.srcnode().get_internal_path() fs = SCons.Node.FS.FS() fs.VariantDir('../var1', 'src') fs.VariantDir('../var2', 'src') f1 = fs.File('../var1/test1') f2 = fs.File('../var2/test1') - assert f1.srcnode().path == os.path.normpath('src/test1'), f1.srcnode().path - assert f2.srcnode().path == os.path.normpath('src/test1'), f2.srcnode().path + assert f1.srcnode().get_internal_path() == os.path.normpath('src/test1'), f1.srcnode().get_internal_path() + assert f2.srcnode().get_internal_path() == os.path.normpath('src/test1'), f2.srcnode().get_internal_path() # Set up some files test.subdir('work', ['work', 'src']) @@ -210,8 +210,8 @@ class VariantDirTestCase(unittest.TestCase): f2out_2.builder = 1 fs.Repository(test.workpath('rep1')) - assert f1.srcnode().path == os.path.normpath('src/test.in'),\ - f1.srcnode().path + assert f1.srcnode().get_internal_path() == os.path.normpath('src/test.in'),\ + f1.srcnode().get_internal_path() # str(node) returns source path for duplicate = 0 assert str(f1) == os.path.normpath('src/test.in'), str(f1) # Build path does not exist @@ -221,11 +221,11 @@ class VariantDirTestCase(unittest.TestCase): # And duplicate=0 should also work just like a Repository assert f1.rexists() # rfile() should point to the source path - assert f1.rfile().path == os.path.normpath('src/test.in'),\ - f1.rfile().path + assert f1.rfile().get_internal_path() == os.path.normpath('src/test.in'),\ + f1.rfile().get_internal_path() - assert f2.srcnode().path == os.path.normpath('src/test.in'),\ - f2.srcnode().path + assert f2.srcnode().get_internal_path() == os.path.normpath('src/test.in'),\ + f2.srcnode().get_internal_path() # str(node) returns build path for duplicate = 1 assert str(f2) == os.path.normpath('build/var2/test.in'), str(f2) # Build path exists @@ -239,8 +239,8 @@ class VariantDirTestCase(unittest.TestCase): f3 = fs.File('build/var1/test2.in') f4 = fs.File('build/var2/test2.in') - assert f3.srcnode().path == os.path.normpath('src/test2.in'),\ - f3.srcnode().path + assert f3.srcnode().get_internal_path() == os.path.normpath('src/test2.in'),\ + f3.srcnode().get_internal_path() # str(node) returns source path for duplicate = 0 assert str(f3) == os.path.normpath('src/test2.in'), str(f3) # Build path does not exist @@ -250,11 +250,11 @@ class VariantDirTestCase(unittest.TestCase): # But we do have a file in the Repository assert f3.rexists() # rfile() should point to the source path - assert f3.rfile().path == os.path.normpath(test.workpath('rep1/src/test2.in')),\ - f3.rfile().path + assert f3.rfile().get_internal_path() == os.path.normpath(test.workpath('rep1/src/test2.in')),\ + f3.rfile().get_internal_path() - assert f4.srcnode().path == os.path.normpath('src/test2.in'),\ - f4.srcnode().path + assert f4.srcnode().get_internal_path() == os.path.normpath('src/test2.in'),\ + f4.srcnode().get_internal_path() # str(node) returns build path for duplicate = 1 assert str(f4) == os.path.normpath('build/var2/test2.in'), str(f4) # Build path should exist @@ -264,8 +264,8 @@ class VariantDirTestCase(unittest.TestCase): # should exist in repository, since exists() is true assert f4.rexists() # rfile() should point to ourselves - assert f4.rfile().path == os.path.normpath('build/var2/test2.in'),\ - f4.rfile().path + assert f4.rfile().get_internal_path() == os.path.normpath('build/var2/test2.in'),\ + f4.rfile().get_internal_path() f5 = fs.File('build/var1/test.out') f6 = fs.File('build/var2/test.out') @@ -285,14 +285,14 @@ class VariantDirTestCase(unittest.TestCase): assert not f7.exists() assert f7.rexists() - r = f7.rfile().path + r = f7.rfile().get_internal_path() expect = os.path.normpath(test.workpath('rep1/build/var1/test2.out')) assert r == expect, (repr(r), repr(expect)) assert not f8.exists() assert f8.rexists() - assert f8.rfile().path == os.path.normpath(test.workpath('rep1/build/var2/test2.out')),\ - f8.rfile().path + assert f8.rfile().get_internal_path() == os.path.normpath(test.workpath('rep1/build/var2/test2.out')),\ + f8.rfile().get_internal_path() # Verify the Mkdir and Link actions are called d9 = fs.Dir('build/var2/new_dir') @@ -319,9 +319,9 @@ class VariantDirTestCase(unittest.TestCase): d9.reset_executor() f9.exists() expect = os.path.join('build', 'var2', 'new_dir') - assert dir_made[0].path == expect, dir_made[0].path + assert dir_made[0].get_internal_path() == expect, dir_made[0].get_internal_path() expect = os.path.join('build', 'var2', 'new_dir', 'test9.out') - assert link_made[0].path == expect, link_made[0].path + assert link_made[0].get_internal_path() == expect, link_made[0].get_internal_path() assert f9.linked finally: SCons.Node.FS.Link = save_Link @@ -338,7 +338,7 @@ class VariantDirTestCase(unittest.TestCase): f11 = fs.File('src/file11') t, m = f11.alter_targets() - bdt = [n.path for n in t] + bdt = [n.get_internal_path() for n in t] var1_file11 = os.path.normpath('build/var1/file11') var2_file11 = os.path.normpath('build/var2/file11') assert bdt == [var1_file11, var2_file11], bdt @@ -346,11 +346,11 @@ class VariantDirTestCase(unittest.TestCase): f12 = fs.File('src/file12') f12.builder = 1 bdt, m = f12.alter_targets() - assert bdt == [], [n.path for n in bdt] + assert bdt == [], [n.get_internal_path() for n in bdt] d13 = fs.Dir('src/new_dir') t, m = d13.alter_targets() - bdt = [n.path for n in t] + bdt = [n.get_internal_path() for n in t] var1_new_dir = os.path.normpath('build/var1/new_dir') var2_new_dir = os.path.normpath('build/var2/new_dir') assert bdt == [var1_new_dir, var2_new_dir], bdt @@ -566,13 +566,13 @@ class VariantDirTestCase(unittest.TestCase): f = dir + '/f' fnode = fs.File(dir + '/f') - dp = dnode.srcnode().path + dp = dnode.srcnode().get_internal_path() expect = os.path.normpath(srcnode_map.get(dir, dir)) if dp != expect: print "Dir `%s' srcnode() `%s' != expected `%s'" % (dir, dp, expect) errors = errors + 1 - fp = fnode.srcnode().path + fp = fnode.srcnode().get_internal_path() expect = os.path.normpath(srcnode_map.get(f, f)) if fp != expect: print "File `%s' srcnode() `%s' != expected `%s'" % (f, fp, expect) @@ -584,14 +584,14 @@ class VariantDirTestCase(unittest.TestCase): fnode = fs.File(dir + '/f') t, m = dnode.alter_targets() - tp = t[0].path + tp = t[0].get_internal_path() expect = os.path.normpath(alter_map.get(dir, dir)) if tp != expect: print "Dir `%s' alter_targets() `%s' != expected `%s'" % (dir, tp, expect) errors = errors + 1 t, m = fnode.alter_targets() - tp = t[0].path + tp = t[0].get_internal_path() expect = os.path.normpath(alter_map.get(f, f)) if tp != expect: print "File `%s' alter_targets() `%s' != expected `%s'" % (f, tp, expect) @@ -698,19 +698,19 @@ class DirNodeInfoTestCase(_tempdirTestCase): def test___init__(self): """Test DirNodeInfo initialization""" ddd = self.fs.Dir('ddd') - ni = SCons.Node.FS.DirNodeInfo(ddd) + ni = SCons.Node.FS.DirNodeInfo() class DirBuildInfoTestCase(_tempdirTestCase): def test___init__(self): """Test DirBuildInfo initialization""" ddd = self.fs.Dir('ddd') - bi = SCons.Node.FS.DirBuildInfo(ddd) + bi = SCons.Node.FS.DirBuildInfo() class FileNodeInfoTestCase(_tempdirTestCase): def test___init__(self): """Test FileNodeInfo initialization""" fff = self.fs.File('fff') - ni = SCons.Node.FS.FileNodeInfo(fff) + ni = SCons.Node.FS.FileNodeInfo() assert isinstance(ni, SCons.Node.FS.FileNodeInfo) def test_update(self): @@ -718,7 +718,7 @@ class FileNodeInfoTestCase(_tempdirTestCase): test = self.test fff = self.fs.File('fff') - ni = SCons.Node.FS.FileNodeInfo(fff) + ni = SCons.Node.FS.FileNodeInfo() test.write('fff', "fff\n") @@ -765,37 +765,41 @@ class FileBuildInfoTestCase(_tempdirTestCase): def test___init__(self): """Test File.BuildInfo initialization""" fff = self.fs.File('fff') - bi = SCons.Node.FS.FileBuildInfo(fff) + bi = SCons.Node.FS.FileBuildInfo() assert bi, bi def test_convert_to_sconsign(self): """Test converting to .sconsign file format""" fff = self.fs.File('fff') - bi = SCons.Node.FS.FileBuildInfo(fff) + bi = SCons.Node.FS.FileBuildInfo() assert hasattr(bi, 'convert_to_sconsign') def test_convert_from_sconsign(self): """Test converting from .sconsign file format""" fff = self.fs.File('fff') - bi = SCons.Node.FS.FileBuildInfo(fff) + bi = SCons.Node.FS.FileBuildInfo() assert hasattr(bi, 'convert_from_sconsign') def test_prepare_dependencies(self): """Test that we have a prepare_dependencies() method""" fff = self.fs.File('fff') - bi = SCons.Node.FS.FileBuildInfo(fff) + bi = SCons.Node.FS.FileBuildInfo() bi.prepare_dependencies() def test_format(self): """Test the format() method""" f1 = self.fs.File('f1') - bi1 = SCons.Node.FS.FileBuildInfo(f1) + bi1 = SCons.Node.FS.FileBuildInfo() - s1sig = SCons.Node.FS.FileNodeInfo(self.fs.File('n1')) + self.fs.File('n1') + self.fs.File('n2') + self.fs.File('n3') + + s1sig = SCons.Node.FS.FileNodeInfo() s1sig.csig = 1 - d1sig = SCons.Node.FS.FileNodeInfo(self.fs.File('n2')) + d1sig = SCons.Node.FS.FileNodeInfo() d1sig.timestamp = 2 - i1sig = SCons.Node.FS.FileNodeInfo(self.fs.File('n3')) + i1sig = SCons.Node.FS.FileNodeInfo() i1sig.size = 3 bi1.bsources = [self.fs.File('s1')] @@ -953,7 +957,7 @@ class FSTestCase(_tempdirTestCase): assert isinstance(f1, SCons.Node.FS.File) d1_f1 = os.path.join('d1', 'f1') - assert f1.path == d1_f1, "f1.path %s != %s" % (f1.path, d1_f1) + assert f1.get_internal_path() == d1_f1, "f1.path %s != %s" % (f1.get_internal_path(), d1_f1) assert str(f1) == d1_f1, "str(f1) %s != %s" % (str(f1), d1_f1) x1 = d1.File('x1') @@ -1045,16 +1049,16 @@ class FSTestCase(_tempdirTestCase): name = os.sep if dir.up() is None: - dir_up_path = dir.path + dir_up_path = dir.get_internal_path() else: - dir_up_path = dir.up().path + dir_up_path = dir.up().get_internal_path() assert dir.name == name, \ "dir.name %s != expected name %s" % \ (dir.name, name) - assert dir.path == path, \ + assert dir.get_internal_path() == path, \ "dir.path %s != expected path %s" % \ - (dir.path, path) + (dir.get_internal_path(), path) assert str(dir) == path, \ "str(dir) %s != expected path %s" % \ (str(dir), path) @@ -1136,9 +1140,9 @@ class FSTestCase(_tempdirTestCase): # Test for a bug in 0.04 that did not like looking up # dirs with a trailing slash on Windows. d=fs.Dir('./') - assert d.path == '.', d.abspath + assert d.get_internal_path() == '.', d.get_abspath() d=fs.Dir('foo/') - assert d.path == 'foo', d.abspath + assert d.get_internal_path() == 'foo', d.get_abspath() # Test for sub-classing of node building. global built_it @@ -1167,50 +1171,50 @@ class FSTestCase(_tempdirTestCase): e1 = fs.Entry("d1") assert e1.__class__.__name__ == 'Dir' - match(e1.path, "d1") - match(e1.dir.path, ".") + match(e1.get_internal_path(), "d1") + match(e1.dir.get_internal_path(), ".") e2 = fs.Entry("d1/f1") assert e2.__class__.__name__ == 'File' - match(e2.path, "d1/f1") - match(e2.dir.path, "d1") + match(e2.get_internal_path(), "d1/f1") + match(e2.dir.get_internal_path(), "d1") e3 = fs.Entry("e3") assert e3.__class__.__name__ == 'Entry' - match(e3.path, "e3") - match(e3.dir.path, ".") + match(e3.get_internal_path(), "e3") + match(e3.dir.get_internal_path(), ".") e4 = fs.Entry("d1/e4") assert e4.__class__.__name__ == 'Entry' - match(e4.path, "d1/e4") - match(e4.dir.path, "d1") + match(e4.get_internal_path(), "d1/e4") + match(e4.dir.get_internal_path(), "d1") e5 = fs.Entry("e3/e5") assert e3.__class__.__name__ == 'Dir' - match(e3.path, "e3") - match(e3.dir.path, ".") + match(e3.get_internal_path(), "e3") + match(e3.dir.get_internal_path(), ".") assert e5.__class__.__name__ == 'Entry' - match(e5.path, "e3/e5") - match(e5.dir.path, "e3") + match(e5.get_internal_path(), "e3/e5") + match(e5.dir.get_internal_path(), "e3") e6 = fs.Dir("d1/e4") assert e6 is e4 assert e4.__class__.__name__ == 'Dir' - match(e4.path, "d1/e4") - match(e4.dir.path, "d1") + match(e4.get_internal_path(), "d1/e4") + match(e4.dir.get_internal_path(), "d1") e7 = fs.File("e3/e5") assert e7 is e5 assert e5.__class__.__name__ == 'File' - match(e5.path, "e3/e5") - match(e5.dir.path, "e3") + match(e5.get_internal_path(), "e3/e5") + match(e5.dir.get_internal_path(), "e3") fs.chdir(fs.Dir('subdir')) f11 = fs.File("f11") - match(f11.path, "subdir/f11") + match(f11.get_internal_path(), "subdir/f11") d12 = fs.Dir("d12") e13 = fs.Entry("subdir/e13") - match(e13.path, "subdir/subdir/e13") + match(e13.get_internal_path(), "subdir/subdir/e13") fs.chdir(fs.Dir('..')) # Test scanning @@ -1220,13 +1224,13 @@ class FSTestCase(_tempdirTestCase): f1.builder.target_scanner = Scanner(xyz) f1.scan() - assert f1.implicit[0].path == "xyz" + assert f1.implicit[0].get_internal_path() == "xyz" f1.implicit = [] f1.scan() assert f1.implicit == [] f1.implicit = None f1.scan() - assert f1.implicit[0].path == "xyz" + assert f1.implicit[0].get_internal_path() == "xyz" # Test underlying scanning functionality in get_found_includes() env = Environment() @@ -1284,9 +1288,9 @@ class FSTestCase(_tempdirTestCase): fs.chdir(fs.Dir('subdir')) # The cwd's path is always "." assert str(fs.getcwd()) == ".", str(fs.getcwd()) - assert fs.getcwd().path == 'subdir', fs.getcwd().path + assert fs.getcwd().get_internal_path() == 'subdir', fs.getcwd().get_internal_path() fs.chdir(fs.Dir('../..')) - assert fs.getcwd().path == test.workdir, fs.getcwd().path + assert fs.getcwd().get_internal_path() == test.workdir, fs.getcwd().get_internal_path() f1 = fs.File(test.workpath("do_i_exist")) assert not f1.exists() @@ -1589,15 +1593,15 @@ class FSTestCase(_tempdirTestCase): assert dir.name == name, \ "dir.name %s != expected name %s" % \ (dir.name, name) - assert dir.path == path, \ + assert dir.get_internal_path() == path, \ "dir.path %s != expected path %s" % \ - (dir.path, path) + (dir.get_internal_path(), path) assert str(dir) == path, \ "str(dir) %s != expected path %s" % \ (str(dir), path) - assert dir.up().path == up_path, \ + assert dir.up().get_internal_path() == up_path, \ "dir.up().path %s != expected parent path %s" % \ - (dir.up().path, up_path) + (dir.up().get_internal_path(), up_path) save_os_path = os.path save_os_sep = os.sep @@ -1691,22 +1695,22 @@ class FSTestCase(_tempdirTestCase): name = path.split(os.sep)[-1] if dir.up() is None: - dir_up_path = dir.path + dir_up_path = dir.get_internal_path() else: - dir_up_path = dir.up().path + dir_up_path = dir.up().get_internal_path() assert dir.name == name, \ "dir.name %s != expected name %s" % \ (dir.name, name) - assert dir.path == path, \ + assert dir.get_internal_path() == path, \ "dir.path %s != expected path %s" % \ - (dir.path, path) + (dir.get_internal_path(), path) assert str(dir) == path, \ "str(dir) %s != expected path %s" % \ (str(dir), path) assert dir_up_path == up_path, \ "dir.up().path %s != expected parent path %s" % \ - (dir.up().path, up_path) + (dir.up().get_internal_path(), up_path) save_os_path = os.path save_os_sep = os.sep @@ -1792,7 +1796,7 @@ class FSTestCase(_tempdirTestCase): d1 = fs.Dir('d1') d2 = d1.Dir('d2') - dirs = os.path.normpath(d2.abspath).split(os.sep) + dirs = os.path.normpath(d2.get_abspath()).split(os.sep) above_path = os.path.join(*['..']*len(dirs) + ['above']) above = d2.Dir(above_path) @@ -1831,9 +1835,9 @@ class FSTestCase(_tempdirTestCase): fs = self.fs if sys.platform not in ('win32',): return - p = fs.Dir(r"\\computername\sharename").abspath + p = fs.Dir(r"\\computername\sharename").get_abspath() assert p == r"\\computername\sharename", p - p = fs.Dir(r"\\\computername\sharename").abspath + p = fs.Dir(r"\\\computername\sharename").get_abspath() assert p == r"\\computername\sharename", p def test_rel_path(self): @@ -1980,7 +1984,7 @@ class DirTestCase(_tempdirTestCase): fs.Dir(os.path.join('ddd', 'd1', 'f4')) fs.Dir(os.path.join('ddd', 'd1', 'f5')) dir.scan() - kids = sorted([x.path for x in dir.children(None)]) + kids = sorted([x.get_internal_path() for x in dir.children(None)]) assert kids == [os.path.join('ddd', 'd1'), os.path.join('ddd', 'f1'), os.path.join('ddd', 'f2'), @@ -2024,12 +2028,12 @@ class DirTestCase(_tempdirTestCase): fs.File(os.path.join('ddd', 'f1')) dir.scan() - kids = sorted([x.path for x in dir.children()]) + kids = sorted([x.get_internal_path() for x in dir.children()]) assert kids == [os.path.join('ddd', 'f1')], kids fs.File(os.path.join('ddd', 'f2')) dir.scan() - kids = sorted([x.path for x in dir.children()]) + kids = sorted([x.get_internal_path() for x in dir.children()]) assert kids == [os.path.join('ddd', 'f1'), os.path.join('ddd', 'f2')], kids @@ -2171,8 +2175,12 @@ class DirTestCase(_tempdirTestCase): """ test = self.test - return_true = lambda: 1 + def return_true(node): + return 1 + SCons.Node._is_derived_map[2] = return_true + SCons.Node._exists_map[5] = return_true + test.subdir('src0') test.write(['src0', 'on-disk-f1'], "src0/on-disk-f1\n") test.write(['src0', 'on-disk-f2'], "src0/on-disk-f2\n") @@ -2184,14 +2192,14 @@ class DirTestCase(_tempdirTestCase): self.fs.VariantDir(bld0, src0, duplicate=0) derived_f = src0.File('derived-f') - derived_f.is_derived = return_true + derived_f._func_is_derived = 2 exists_f = src0.File('exists-f') - exists_f.exists = return_true + exists_f._func_exists = 5 derived_e = src0.Entry('derived-e') - derived_e.is_derived = return_true + derived_e._func_is_derived = 2 exists_e = src0.Entry('exists-e') - exists_e.exists = return_true + exists_e._func_exists = 5 def check(result, expect): result = list(map(str, result)) @@ -2245,14 +2253,14 @@ class DirTestCase(_tempdirTestCase): self.fs.VariantDir(bld1, src1, duplicate=1) derived_f = src1.File('derived-f') - derived_f.is_derived = return_true + derived_f._func_is_derived = 2 exists_f = src1.File('exists-f') - exists_f.exists = return_true + exists_f._func_exists = 5 derived_e = src1.Entry('derived-e') - derived_e.is_derived = return_true + derived_e._func_is_derived = 2 exists_e = src1.Entry('exists-e') - exists_e.exists = return_true + exists_e._func_exists = 5 # First check from the source directory. n = src1.srcdir_find_file('does_not_exist') @@ -2432,7 +2440,7 @@ class FileTestCase(_tempdirTestCase): build_f1 = fs.File('build/f1') assert build_f1.exists(), "%s did not realize that %s exists" % (build_f1, src_f1) - assert os.path.exists(build_f1.abspath), "%s did not get duplicated on disk" % build_f1.abspath + assert os.path.exists(build_f1.get_abspath()), "%s did not get duplicated on disk" % build_f1.get_abspath() test.unlink(['src', 'f1']) src_f1.clear() # so the next exists() call will look on disk again @@ -2441,7 +2449,7 @@ class FileTestCase(_tempdirTestCase): build_f1.clear() build_f1.linked = None assert not build_f1.exists(), "%s did not realize that %s disappeared" % (build_f1, src_f1) - assert not os.path.exists(build_f1.abspath), "%s did not get removed after %s was removed" % (build_f1, src_f1) + assert not os.path.exists(build_f1.get_abspath()), "%s did not get removed after %s was removed" % (build_f1, src_f1) @@ -2535,7 +2543,7 @@ class GlobTestCase(_tempdirTestCase): for input, string_expect, node_expect in cases: r = self.fs.Glob(input, **kwargs) if node_expect: - r = sorted(r, key=lambda a: a.path) + r = sorted(r, key=lambda a: a.get_internal_path()) result = [] for n in node_expect: if isinstance(n, str): @@ -2906,8 +2914,14 @@ class RepositoryTestCase(_tempdirTestCase): def test_rdir(self): """Test the Dir.rdir() method""" - return_true = lambda: 1 - return_false = lambda: 0 + def return_true(obj): + return 1 + def return_false(obj): + return 0 + SCons.Node._exists_map[5] = return_true + SCons.Node._exists_map[6] = return_false + SCons.Node._is_derived_map[2] = return_true + SCons.Node._is_derived_map[3] = return_false d1 = self.fs.Dir('d1') d2 = self.fs.Dir('d2') @@ -2931,19 +2945,19 @@ class RepositoryTestCase(_tempdirTestCase): assert r == os.path.join(self.rep3, 'd3'), r e1 = self.fs.Dir('e1') - e1.exists = return_false + e1._func_exists = 6 e2 = self.fs.Dir('e2') - e2.exists = return_false + e2._func_exists = 6 # Make sure we match entries in repositories, # regardless of whether they're derived or not. re1 = self.fs.Entry(os.path.join(self.rep1, 'e1')) - re1.exists = return_true - re1.is_derived = return_true + re1._func_exists = 5 + re1._func_is_derived = 2 re2 = self.fs.Entry(os.path.join(self.rep2, 'e2')) - re2.exists = return_true - re2.is_derived = return_false + re2._func_exists = 5 + re2._func_is_derived = 3 r = e1.rdir() assert r is re1, r @@ -2953,8 +2967,14 @@ class RepositoryTestCase(_tempdirTestCase): def test_rfile(self): """Test the File.rfile() method""" - return_true = lambda: 1 - return_false = lambda: 0 + def return_true(obj): + return 1 + def return_false(obj): + return 0 + SCons.Node._exists_map[5] = return_true + SCons.Node._exists_map[6] = return_false + SCons.Node._is_derived_map[2] = return_true + SCons.Node._is_derived_map[3] = return_false f1 = self.fs.File('f1') f2 = self.fs.File('f2') @@ -2978,19 +2998,19 @@ class RepositoryTestCase(_tempdirTestCase): assert r == os.path.join(self.rep3, 'f3'), r e1 = self.fs.File('e1') - e1.exists = return_false + e1._func_exists = 6 e2 = self.fs.File('e2') - e2.exists = return_false + e2._func_exists = 6 # Make sure we match entries in repositories, # regardless of whether they're derived or not. re1 = self.fs.Entry(os.path.join(self.rep1, 'e1')) - re1.exists = return_true - re1.is_derived = return_true + re1._func_exists = 5 + re1._func_is_derived = 2 re2 = self.fs.Entry(os.path.join(self.rep2, 'e2')) - re2.exists = return_true - re2.is_derived = return_false + re2._func_exists = 5 + re2._func_is_derived = 3 r = e1.rfile() assert r is re1, r @@ -3244,9 +3264,13 @@ class stored_infoTestCase(unittest.TestCase): self.xyzzy = 7 def get_entry(self, name): return self.Null() + + def test_sconsign(node): + return MySConsign() f = fs.File('file2', d) - f.dir.sconsign = MySConsign + SCons.Node.FS._sconsign_map[2] = test_sconsign + f.dir._func_sconsign = 2 bi = f.get_stored_info() assert bi.xyzzy == 7, bi @@ -3360,7 +3384,7 @@ class prepareTestCase(unittest.TestCase): xyz.set_state(0) xyz.prepare() - assert dir_made[0].path == "new_dir", dir_made[0] + assert dir_made[0].get_internal_path() == "new_dir", dir_made[0] dir = fs.Dir("dir") dir.prepare() @@ -3373,7 +3397,7 @@ class SConstruct_dirTestCase(unittest.TestCase): fs = SCons.Node.FS.FS() fs.set_SConstruct_dir(fs.Dir('xxx')) - assert fs.SConstruct_dir.path == 'xxx' + assert fs.SConstruct_dir.get_internal_path() == 'xxx' @@ -3552,7 +3576,7 @@ class SpecialAttrTestCase(unittest.TestCase): for_sig = f.suffix.for_signature() assert for_sig == 'baz.blat_suffix', for_sig - s = str(f.abspath) + s = str(f.get_abspath()) assert s == test.workpath('work', 'foo', 'bar', 'baz.blat'), s assert f.abspath.is_literal(), f.abspath for_sig = f.abspath.for_signature() diff --git a/src/engine/SCons/Node/NodeTests.py b/src/engine/SCons/Node/NodeTests.py index da502b0..a6471b4 100644 --- a/src/engine/SCons/Node/NodeTests.py +++ b/src/engine/SCons/Node/NodeTests.py @@ -184,7 +184,7 @@ class Scanner(object): called = None def __call__(self, node): self.called = 1 - return node.found_includes + return node.GetTag('found_includes') def path(self, env, dir, target=None, source=None): return () def select(self, node): @@ -200,7 +200,7 @@ class MyNode(SCons.Node.Node): def __init__(self, name): SCons.Node.Node.__init__(self) self.name = name - self.found_includes = [] + self.Tag('found_includes', []) def __str__(self): return self.name def get_found_includes(self, env, scanner, target): @@ -224,11 +224,18 @@ class Calculator(object): class NodeInfoBaseTestCase(unittest.TestCase): + # The abstract class NodeInfoBase has not enough default slots to perform + # the merge and format test (arbitrary attributes do not work). Do it with a + # derived class that does provide the slots. def test_merge(self): """Test merging NodeInfoBase attributes""" - ni1 = SCons.Node.NodeInfoBase(SCons.Node.Node()) - ni2 = SCons.Node.NodeInfoBase(SCons.Node.Node()) + + class TestNodeInfo(SCons.Node.NodeInfoBase): + __slots__ = ('a1', 'a2', 'a3') + + ni1 = TestNodeInfo() + ni2 = TestNodeInfo() ni1.a1 = 1 ni1.a2 = 2 @@ -237,27 +244,32 @@ class NodeInfoBaseTestCase(unittest.TestCase): ni2.a3 = 333 ni1.merge(ni2) - expect = {'a1':1, 'a2':222, 'a3':333, '_version_id':1} - assert ni1.__dict__ == expect, ni1.__dict__ + assert ni1.a1 == 1, ni1.a1 + assert ni1.a2 == 222, ni1.a2 + assert ni1.a3 == 333, ni1.a3 def test_update(self): """Test the update() method""" - ni = SCons.Node.NodeInfoBase(SCons.Node.Node()) + ni = SCons.Node.NodeInfoBase() ni.update(SCons.Node.Node()) def test_format(self): """Test the NodeInfoBase.format() method""" - ni1 = SCons.Node.NodeInfoBase(SCons.Node.Node()) + + class TestNodeInfo(SCons.Node.NodeInfoBase): + __slots__ = ('xxx', 'yyy', 'zzz') + + ni1 = TestNodeInfo() ni1.xxx = 'x' ni1.yyy = 'y' ni1.zzz = 'z' f = ni1.format() - assert f == ['1', 'x', 'y', 'z'], f + assert f == ['x', 'y', 'z'], f + + field_list = ['xxx', 'zzz', 'aaa'] - ni1.field_list = ['xxx', 'zzz', 'aaa'] - - f = ni1.format() + f = ni1.format(field_list) assert f == ['x', 'z', 'None'], f @@ -267,26 +279,26 @@ class BuildInfoBaseTestCase(unittest.TestCase): def test___init__(self): """Test BuildInfoBase initialization""" n = SCons.Node.Node() - bi = SCons.Node.BuildInfoBase(n) + bi = SCons.Node.BuildInfoBase() assert bi def test_merge(self): """Test merging BuildInfoBase attributes""" n1 = SCons.Node.Node() - bi1 = SCons.Node.BuildInfoBase(n1) + bi1 = SCons.Node.BuildInfoBase() n2 = SCons.Node.Node() - bi2 = SCons.Node.BuildInfoBase(n2) + bi2 = SCons.Node.BuildInfoBase() - bi1.a1 = 1 - bi1.a2 = 2 + bi1.bsources = 1 + bi1.bdepends = 2 - bi2.a2 = 222 - bi2.a3 = 333 + bi2.bdepends = 222 + bi2.bact = 333 bi1.merge(bi2) - assert bi1.a1 == 1, bi1.a1 - assert bi1.a2 == 222, bi1.a2 - assert bi1.a3 == 333, bi1.a3 + assert bi1.bsources == 1, bi1.bsources + assert bi1.bdepends == 222, bi1.bdepends + assert bi1.bact == 333, bi1.bact class NodeTestCase(unittest.TestCase): @@ -427,6 +439,7 @@ class NodeTestCase(unittest.TestCase): def test_built(self): """Test the built() method""" class SubNodeInfo(SCons.Node.NodeInfoBase): + __slots__ = ('updated',) def update(self, node): self.updated = 1 class SubNode(SCons.Node.Node): @@ -434,7 +447,7 @@ class NodeTestCase(unittest.TestCase): self.cleared = 1 n = SubNode() - n.ninfo = SubNodeInfo(n) + n.ninfo = SubNodeInfo() n.built() assert n.cleared, n.cleared assert n.ninfo.updated, n.ninfo.cleared @@ -568,32 +581,56 @@ class NodeTestCase(unittest.TestCase): def test_get_csig(self): """Test generic content signature calculation """ - node = SCons.Node.Node() - node.get_contents = lambda: 444 - result = node.get_csig() - assert result == '550a141f12de6341fba65b0ad0433500', result + + class TestNodeInfo(SCons.Node.NodeInfoBase): + __slots__ = ('csig',) + try: + SCons.Node.Node.NodeInfo = TestNodeInfo + def my_contents(obj): + return 444 + SCons.Node._get_contents_map[4] = my_contents + node = SCons.Node.Node() + node._func_get_contents = 4 + result = node.get_csig() + assert result == '550a141f12de6341fba65b0ad0433500', result + finally: + SCons.Node.Node.NodeInfo = SCons.Node.NodeInfoBase def test_get_cachedir_csig(self): """Test content signature calculation for CacheDir """ - node = SCons.Node.Node() - node.get_contents = lambda: 555 - result = node.get_cachedir_csig() - assert result == '15de21c670ae7c3f6f3f1f37029303c9', result + class TestNodeInfo(SCons.Node.NodeInfoBase): + __slots__ = ('csig',) + try: + SCons.Node.Node.NodeInfo = TestNodeInfo + def my_contents(obj): + return 555 + SCons.Node._get_contents_map[4] = my_contents + node = SCons.Node.Node() + node._func_get_contents = 4 + result = node.get_cachedir_csig() + assert result == '15de21c670ae7c3f6f3f1f37029303c9', result + finally: + SCons.Node.Node.NodeInfo = SCons.Node.NodeInfoBase def test_get_binfo(self): """Test fetching/creating a build information structure """ + class TestNodeInfo(SCons.Node.NodeInfoBase): + __slots__ = ('csig',) + SCons.Node.Node.NodeInfo = TestNodeInfo node = SCons.Node.Node() - + binfo = node.get_binfo() assert isinstance(binfo, SCons.Node.BuildInfoBase), binfo node = SCons.Node.Node() d = SCons.Node.Node() - d.get_ninfo().csig = 777 + ninfo = d.get_ninfo() + assert isinstance(ninfo, SCons.Node.NodeInfoBase), ninfo i = SCons.Node.Node() - i.get_ninfo().csig = 888 + ninfo = i.get_ninfo() + assert isinstance(ninfo, SCons.Node.NodeInfoBase), ninfo node.depends = [d] node.implicit = [i] @@ -655,7 +692,7 @@ class NodeTestCase(unittest.TestCase): """Test calling the method to store build information """ node = SCons.Node.Node() - node.store_info() + SCons.Node.store_info_map[node.store_info](node) def test_get_stored_info(self): """Test calling the method to fetch stored build information @@ -888,7 +925,7 @@ class NodeTestCase(unittest.TestCase): s = Scanner() d1 = MyNode("d1") d2 = MyNode("d2") - node.found_includes = [d1, d2] + node.Tag('found_includes', [d1, d2]) # Simple return of the found includes deps = node.get_implicit_deps(env, s, target) @@ -898,14 +935,14 @@ class NodeTestCase(unittest.TestCase): e = MyNode("eee") f = MyNode("fff") g = MyNode("ggg") - d1.found_includes = [e, f] - d2.found_includes = [e, f] - f.found_includes = [g] + d1.Tag('found_includes', [e, f]) + d2.Tag('found_includes', [e, f]) + f.Tag('found_includes', [g]) deps = node.get_implicit_deps(env, s, target) assert deps == [d1, d2, e, f, g], list(map(str, deps)) # Recursive scanning eliminates duplicates - e.found_includes = [f] + e.Tag('found_includes', [f]) deps = node.get_implicit_deps(env, s, target) assert deps == [d1, d2, e, f, g], list(map(str, deps)) @@ -994,7 +1031,7 @@ class NodeTestCase(unittest.TestCase): s = Scanner() d = MyNode("ddd") - node.found_includes = [d] + node.Tag('found_includes', [d]) node.builder.target_scanner = s assert node.implicit is None @@ -1207,7 +1244,7 @@ class NodeTestCase(unittest.TestCase): def test_Annotate(self): """Test using an interface-specific Annotate function.""" def my_annotate(node, self=self): - node.annotation = self.node_string + node.Tag('annotation', self.node_string) save_Annotate = SCons.Node.Annotate SCons.Node.Annotate = my_annotate @@ -1215,11 +1252,13 @@ class NodeTestCase(unittest.TestCase): try: self.node_string = '#1' n = SCons.Node.Node() - assert n.annotation == '#1', n.annotation + a = n.GetTag('annotation') + assert a == '#1', a self.node_string = '#2' n = SCons.Node.Node() - assert n.annotation == '#2', n.annotation + a = n.GetTag('annotation') + assert a == '#2', a finally: SCons.Node.Annotate = save_Annotate @@ -1230,7 +1269,7 @@ class NodeTestCase(unittest.TestCase): n.set_state(3) n.binfo = 'xyz' n.includes = 'testincludes' - n.found_include = {'testkey':'testvalue'} + n.Tag('found_includes', {'testkey':'testvalue'}) n.implicit = 'testimplicit' x = MyExecutor() diff --git a/src/engine/SCons/Node/Python.py b/src/engine/SCons/Node/Python.py index 3d8bdaa..f151fc5 100644 --- a/src/engine/SCons/Node/Python.py +++ b/src/engine/SCons/Node/Python.py @@ -32,15 +32,49 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import SCons.Node class ValueNodeInfo(SCons.Node.NodeInfoBase): - current_version_id = 1 + __slots__ = ('csig',) + current_version_id = 2 field_list = ['csig'] def str_to_node(self, s): return Value(s) + def __getstate__(self): + """ + Return all fields that shall be pickled. Walk the slots in the class + hierarchy and add those to the state dictionary. If a '__dict__' slot is + available, copy all entries to the dictionary. Also include the version + id, which is fixed for all instances of a class. + """ + state = getattr(self, '__dict__', {}).copy() + for obj in type(self).mro(): + for name in getattr(obj,'__slots__',()): + if hasattr(self, name): + state[name] = getattr(self, name) + + state['_version_id'] = self.current_version_id + try: + del state['__weakref__'] + except KeyError: + pass + + return state + + def __setstate__(self, state): + """ + Restore the attributes from a pickled state. + """ + # TODO check or discard version + del state['_version_id'] + for key, value in state.items(): + if key not in ('__weakref__',): + setattr(self, key, value) + + class ValueBuildInfo(SCons.Node.BuildInfoBase): - current_version_id = 1 + __slots__ = () + current_version_id = 2 class Value(SCons.Node.Node): """A class for Python variables, typically passed on the command line @@ -53,6 +87,8 @@ class Value(SCons.Node.Node): def __init__(self, value, built_value=None): SCons.Node.Node.__init__(self) self.value = value + self.changed_since_last_build = 6 + self.store_info = 0 if built_value is not None: self.built_value = built_value diff --git a/src/engine/SCons/Node/PythonTests.py b/src/engine/SCons/Node/PythonTests.py index fcdfe77..e2e36bf 100644 --- a/src/engine/SCons/Node/PythonTests.py +++ b/src/engine/SCons/Node/PythonTests.py @@ -104,13 +104,13 @@ class ValueNodeInfoTestCase(unittest.TestCase): def test___init__(self): """Test ValueNodeInfo initialization""" vvv = SCons.Node.Python.Value('vvv') - ni = SCons.Node.Python.ValueNodeInfo(vvv) + ni = SCons.Node.Python.ValueNodeInfo() class ValueBuildInfoTestCase(unittest.TestCase): def test___init__(self): """Test ValueBuildInfo initialization""" vvv = SCons.Node.Python.Value('vvv') - bi = SCons.Node.Python.ValueBuildInfo(vvv) + bi = SCons.Node.Python.ValueBuildInfo() if __name__ == "__main__": suite = unittest.TestSuite() diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py index 1f62971..f2d37c2 100644 --- a/src/engine/SCons/Node/__init__.py +++ b/src/engine/SCons/Node/__init__.py @@ -55,6 +55,8 @@ import SCons.Util from SCons.Debug import Trace +print_duplicate = 0 + def classname(obj): return str(obj.__class__).split('.')[-1] @@ -105,6 +107,233 @@ Annotate = do_nothing # clean builds and update runs (see release_target_info). interactive = False +def is_derived_none(node): + raise NotImplementedError + +def is_derived_node(node): + """ + Returns true if this node is derived (i.e. built). + """ + return node.has_builder() or node.side_effect + +_is_derived_map = {0 : is_derived_none, + 1 : is_derived_node} + +def exists_none(node): + raise NotImplementedError + +def exists_always(node): + return 1 + +def exists_base(node): + return node.stat() is not None + +def exists_entry(node): + """Return if the Entry exists. Check the file system to see + what we should turn into first. Assume a file if there's no + directory.""" + node.disambiguate() + return _exists_map[node._func_exists](node) + +def exists_file(node): + # Duplicate from source path if we are set up to do this. + if node.duplicate and not node.is_derived() and not node.linked: + src = node.srcnode() + if src is not node: + # At this point, src is meant to be copied in a variant directory. + src = src.rfile() + if src.get_abspath() != node.get_abspath(): + if src.exists(): + node.do_duplicate(src) + # Can't return 1 here because the duplication might + # not actually occur if the -n option is being used. + else: + # The source file does not exist. Make sure no old + # copy remains in the variant directory. + if print_duplicate: + print "dup: no src for %s, unlinking old variant copy"%self + if exists_base(node) or node.islink(): + node.fs.unlink(node.get_internal_path()) + # Return None explicitly because the Base.exists() call + # above will have cached its value if the file existed. + return None + return exists_base(node) + +_exists_map = {0 : exists_none, + 1 : exists_always, + 2 : exists_base, + 3 : exists_entry, + 4 : exists_file} + + +def rexists_none(node): + raise NotImplementedError + +def rexists_node(node): + return node.exists() + +def rexists_base(node): + return node.rfile().exists() + +_rexists_map = {0 : rexists_none, + 1 : rexists_node, + 2 : rexists_base} + +def get_contents_none(node): + raise NotImplementedError + +def get_contents_entry(node): + """Fetch the contents of the entry. Returns the exact binary + contents of the file.""" + try: + node = node.disambiguate(must_exist=1) + except SCons.Errors.UserError: + # There was nothing on disk with which to disambiguate + # this entry. Leave it as an Entry, but return a null + # string so calls to get_contents() in emitters and the + # like (e.g. in qt.py) don't have to disambiguate by hand + # or catch the exception. + return '' + else: + return _get_contents_map[node._func_get_contents](node) + +def get_contents_dir(node): + """Return content signatures and names of all our children + separated by new-lines. Ensure that the nodes are sorted.""" + contents = [] + for n in sorted(node.children(), key=lambda t: t.name): + contents.append('%s %s\n' % (n.get_csig(), n.name)) + return ''.join(contents) + +def get_contents_file(node): + if not node.rexists(): + return '' + fname = node.rfile().get_abspath() + try: + contents = open(fname, "rb").read() + except EnvironmentError, e: + if not e.filename: + e.filename = fname + raise + return contents + +_get_contents_map = {0 : get_contents_none, + 1 : get_contents_entry, + 2 : get_contents_dir, + 3 : get_contents_file} + +def target_from_source_none(node, prefix, suffix, splitext): + raise NotImplementedError + +def target_from_source_base(node, prefix, suffix, splitext): + return node.dir.Entry(prefix + splitext(node.name)[0] + suffix) + +_target_from_source_map = {0 : target_from_source_none, + 1 : target_from_source_base} + +# +# The new decider subsystem for Nodes +# +# We would set and overwrite the changed_since_last_build function +# before, but for being able to use slots (less memory!) we now have +# a dictionary of the different decider functions. Then in the Node +# subclasses we simply store the index to the decider that should be +# used by it. +# + +# +# First, the single decider functions +# +def changed_since_last_build_node(node, target, prev_ni): + """ + + Must be overridden in a specific subclass to return True if this + Node (a dependency) has changed since the last time it was used + to build the specified target. prev_ni is this Node's state (for + example, its file timestamp, length, maybe content signature) + as of the last time the target was built. + + Note that this method is called through the dependency, not the + target, because a dependency Node must be able to use its own + logic to decide if it changed. For example, File Nodes need to + obey if we're configured to use timestamps, but Python Value Nodes + never use timestamps and always use the content. If this method + were called through the target, then each Node's implementation + of this method would have to have more complicated logic to + handle all the different Node types on which it might depend. + """ + raise NotImplementedError + +def changed_since_last_build_alias(node, target, prev_ni): + cur_csig = node.get_csig() + try: + return cur_csig != prev_ni.csig + except AttributeError: + return 1 + +def changed_since_last_build_entry(node, target, prev_ni): + node.disambiguate() + return _decider_map[node.changed_since_last_build](node, target, prev_ni) + +def changed_since_last_build_state_changed(node, target, prev_ni): + return (node.state != SCons.Node.up_to_date) + +def decide_source(node, target, prev_ni): + return target.get_build_env().decide_source(node, target, prev_ni) + +def decide_target(node, target, prev_ni): + return target.get_build_env().decide_target(node, target, prev_ni) + +def changed_since_last_build_python(node, target, prev_ni): + cur_csig = node.get_csig() + try: + return cur_csig != prev_ni.csig + except AttributeError: + return 1 + + +# +# Now, the mapping from indices to decider functions +# +_decider_map = {0 : changed_since_last_build_node, + 1 : changed_since_last_build_alias, + 2 : changed_since_last_build_entry, + 3 : changed_since_last_build_state_changed, + 4 : decide_source, + 5 : decide_target, + 6 : changed_since_last_build_python} + +do_store_info = True + +# +# The new store_info subsystem for Nodes +# +# We would set and overwrite the store_info function +# before, but for being able to use slots (less memory!) we now have +# a dictionary of the different functions. Then in the Node +# subclasses we simply store the index to the info method that should be +# used by it. +# + +# +# First, the single info functions +# + +def store_info_pass(node): + pass + +def store_info_file(node): + # Merge our build information into the already-stored entry. + # This accommodates "chained builds" where a file that's a target + # in one build (SConstruct file) is a source in a different build. + # See test/chained-build.py for the use case. + if do_store_info: + node.dir.sconsign().store_info(node.name, node) + + +store_info_map = {0 : store_info_pass, + 1 : store_info_file} + # Classes for signature info for Nodes. class NodeInfoBase(object): @@ -114,11 +343,8 @@ class NodeInfoBase(object): Node subclasses should subclass NodeInfoBase to provide their own logic for dealing with their own Node-specific signature information. """ - current_version_id = 1 - def __init__(self, node=None): - # Create an object attribute from the class attribute so it ends up - # in the pickled data in the .sconsign file. - self._version_id = self.current_version_id + __slots__ = ('__weakref__',) + current_version_id = 2 def update(self, node): try: field_list = self.field_list @@ -138,13 +364,25 @@ class NodeInfoBase(object): def convert(self, node, val): pass def merge(self, other): - self.__dict__.update(other.__dict__) + """ + Merge the fields of another object into this object. Already existing + information is overwritten by the other instance's data. + WARNING: If a '__dict__' slot is added, it should be updated instead of + replaced. + """ + state = other.__getstate__() + self.__setstate__(state) def format(self, field_list=None, names=0): if field_list is None: try: field_list = self.field_list except AttributeError: - field_list = sorted(self.__dict__.keys()) + field_list = getattr(self, '__dict__', {}).keys() + for obj in type(self).mro(): + for slot in getattr(obj, '__slots__', ()): + if slot not in ('__weakref__', '__dict__'): + field_list.append(slot) + field_list.sort() fields = [] for field in field_list: try: @@ -157,6 +395,38 @@ class NodeInfoBase(object): fields.append(f) return fields + def __getstate__(self): + """ + Return all fields that shall be pickled. Walk the slots in the class + hierarchy and add those to the state dictionary. If a '__dict__' slot is + available, copy all entries to the dictionary. Also include the version + id, which is fixed for all instances of a class. + """ + state = getattr(self, '__dict__', {}).copy() + for obj in type(self).mro(): + for name in getattr(obj,'__slots__',()): + if hasattr(self, name): + state[name] = getattr(self, name) + + state['_version_id'] = self.current_version_id + try: + del state['__weakref__'] + except KeyError: + pass + return state + + def __setstate__(self, state): + """ + Restore the attributes from a pickled state. The version is discarded. + """ + # TODO check or discard version + del state['_version_id'] + + for key, value in state.items(): + if key not in ('__weakref__',): + setattr(self, key, value) + + class BuildInfoBase(object): """ The generic base class for build information for a Node. @@ -167,30 +437,106 @@ class BuildInfoBase(object): generic build stuff we have to track: sources, explicit dependencies, implicit dependencies, and action information. """ - current_version_id = 1 - def __init__(self, node=None): + __slots__ = ("bsourcesigs", "bdependsigs", "bimplicitsigs", "bactsig", + "bsources", "bdepends", "bact", "bimplicit", "__weakref__") + current_version_id = 2 + def __init__(self): # Create an object attribute from the class attribute so it ends up # in the pickled data in the .sconsign file. - self._version_id = self.current_version_id self.bsourcesigs = [] self.bdependsigs = [] self.bimplicitsigs = [] self.bactsig = None def merge(self, other): - self.__dict__.update(other.__dict__) + """ + Merge the fields of another object into this object. Already existing + information is overwritten by the other instance's data. + WARNING: If a '__dict__' slot is added, it should be updated instead of + replaced. + """ + state = other.__getstate__() + self.__setstate__(state) + + def __getstate__(self): + """ + Return all fields that shall be pickled. Walk the slots in the class + hierarchy and add those to the state dictionary. If a '__dict__' slot is + available, copy all entries to the dictionary. Also include the version + id, which is fixed for all instances of a class. + """ + state = getattr(self, '__dict__', {}).copy() + for obj in type(self).mro(): + for name in getattr(obj,'__slots__',()): + if hasattr(self, name): + state[name] = getattr(self, name) + + state['_version_id'] = self.current_version_id + try: + del state['__weakref__'] + except KeyError: + pass + return state + + def __setstate__(self, state): + """ + Restore the attributes from a pickled state. + """ + # TODO check or discard version + del state['_version_id'] + for key, value in state.items(): + if key not in ('__weakref__',): + setattr(self, key, value) class Node(object): """The base Node class, for entities that we know how to build, or use to build other Nodes. """ - if SCons.Memoize.use_memoizer: - __metaclass__ = SCons.Memoize.Memoized_Metaclass - - memoizer_counters = [] + __slots__ = ['sources', + 'sources_set', + '_specific_sources', + 'depends', + 'depends_set', + 'ignore', + 'ignore_set', + 'prerequisites', + 'implicit', + 'waiting_parents', + 'waiting_s_e', + 'ref_count', + 'wkids', + 'env', + 'state', + 'precious', + 'noclean', + 'nocache', + 'cached', + 'always_build', + 'includes', + 'attributes', + 'side_effect', + 'side_effects', + 'linked', + '_memo', + 'executor', + 'binfo', + 'ninfo', + 'builder', + 'is_explicit', + 'implicit_set', + 'changed_since_last_build', + 'store_info', + 'pseudo', + '_tags', + '_func_is_derived', + '_func_exists', + '_func_rexists', + '_func_get_contents', + '_func_target_from_source'] class Attrs(object): - pass + __slots__ = ('shared', '__dict__') + def __init__(self): if SCons.Debug.track_instances: logInstanceCreation(self, 'Node.Node') @@ -234,7 +580,15 @@ class Node(object): self.side_effect = 0 # true iff this node is a side effect self.side_effects = [] # the side effects of building this target self.linked = 0 # is this node linked to the variant directory? - + self.changed_since_last_build = 0 + self.store_info = 0 + self._tags = None + self._func_is_derived = 1 + self._func_exists = 1 + self._func_rexists = 1 + self._func_get_contents = 0 + self._func_target_from_source = 0 + self.clear_memoized_values() # Let the interface in which the build engine is embedded @@ -248,8 +602,7 @@ class Node(object): def get_suffix(self): return '' - memoizer_counters.append(SCons.Memoize.CountValue('get_build_env')) - + @SCons.Memoize.CountMethodCall def get_build_env(self): """Fetch the appropriate Environment to build this node. """ @@ -418,7 +771,7 @@ class Node(object): pass else: self.ninfo.update(self) - self.store_info() + SCons.Node.store_info_map[self.store_info](self) def release_target_info(self): """Called just after this node has been marked @@ -546,7 +899,7 @@ class Node(object): example: source with source builders are not derived in this sense, and hence should not return true. """ - return self.has_builder() or self.side_effect + return _is_derived_map[self._func_is_derived](self) def alter_targets(self): """Return a list of alternate targets for this Node. @@ -706,7 +1059,7 @@ class Node(object): BuildInfo = BuildInfoBase def new_ninfo(self): - ninfo = self.NodeInfo(self) + ninfo = self.NodeInfo() return ninfo def get_ninfo(self): @@ -717,7 +1070,7 @@ class Node(object): return self.ninfo def new_binfo(self): - binfo = self.BuildInfo(self) + binfo = self.BuildInfo() return binfo def get_binfo(self): @@ -802,14 +1155,6 @@ class Node(object): def get_cachedir_csig(self): return self.get_csig() - def store_info(self): - """Make the build signature permanent (that is, store it in the - .sconsign file or equivalent).""" - pass - - def do_not_store_info(self): - pass - def get_stored_info(self): return None @@ -847,13 +1192,16 @@ class Node(object): def exists(self): """Does this node exists?""" - # All node exist by default: - return 1 + return _exists_map[self._func_exists](self) def rexists(self): """Does this node exist locally or in a repositiory?""" # There are no repositories by default: - return self.exists() + return _rexists_map[self._func_rexists](self) + + def get_contents(self): + """Fetch the contents of the entry.""" + return _get_contents_map[self._func_get_contents](self) def missing(self): return not self.is_derived() and \ @@ -941,11 +1289,10 @@ class Node(object): # build info that it's cached so we can re-calculate it. self.executor_cleanup() - memoizer_counters.append(SCons.Memoize.CountValue('_children_get')) - + @SCons.Memoize.CountMethodCall def _children_get(self): try: - return self._memo['children_get'] + return self._memo['_children_get'] except KeyError: pass @@ -976,7 +1323,7 @@ class Node(object): else: children = self.all_children(scan=0) - self._memo['children_get'] = children + self._memo['_children_get'] = children return children def all_children(self, scan=1): @@ -1016,9 +1363,6 @@ class Node(object): def get_state(self): return self.state - def state_has_changed(self, target, prev_ni): - return (self.state != SCons.Node.up_to_date) - def get_env(self): env = self.env if not env: @@ -1026,28 +1370,28 @@ class Node(object): env = SCons.Defaults.DefaultEnvironment() return env - def changed_since_last_build(self, target, prev_ni): - """ - - Must be overridden in a specific subclass to return True if this - Node (a dependency) has changed since the last time it was used - to build the specified target. prev_ni is this Node's state (for - example, its file timestamp, length, maybe content signature) - as of the last time the target was built. - - Note that this method is called through the dependency, not the - target, because a dependency Node must be able to use its own - logic to decide if it changed. For example, File Nodes need to - obey if we're configured to use timestamps, but Python Value Nodes - never use timestamps and always use the content. If this method - were called through the target, then each Node's implementation - of this method would have to have more complicated logic to - handle all the different Node types on which it might depend. - """ - raise NotImplementedError - def Decider(self, function): - SCons.Util.AddMethod(self, function, 'changed_since_last_build') + foundkey = None + for k, v in _decider_map.iteritems(): + if v == function: + foundkey = k + break + if not foundkey: + foundkey = len(_decider_map) + _decider_map[foundkey] = function + self.changed_since_last_build = foundkey + + def Tag(self, key, value): + """ Add a user-defined tag. """ + if not self._tags: + self._tags = {} + self._tags[key] = value + + def GetTag(self, key): + """ Return a user-defined tag. """ + if not self._tags: + return None + return self._tags.get(key, None) def changed(self, node=None, allowcache=False): """ @@ -1095,7 +1439,7 @@ class Node(object): result = True for child, prev_ni in zip(children, then): - if child.changed_since_last_build(self, prev_ni): + if _decider_map[child.changed_since_last_build](child, self, prev_ni): if t: Trace(': %s changed' % child) result = True @@ -1266,7 +1610,7 @@ class Node(object): for k in new_bkids: if not k in old_bkids: lines.append("`%s' is a new dependency\n" % stringify(k)) - elif k.changed_since_last_build(self, osig[k]): + elif _decider_map[k.changed_since_last_build](k, self, osig[k]): lines.append("`%s' changed\n" % stringify(k)) if len(lines) == 0 and old_bkids != new_bkids: diff --git a/src/engine/SCons/PathList.py b/src/engine/SCons/PathList.py index f3de57c..350e1ac 100644 --- a/src/engine/SCons/PathList.py +++ b/src/engine/SCons/PathList.py @@ -171,11 +171,6 @@ class PathListCache(object): cheaply avoid re-parsing both values of CPPPATH by using the common value from this cache. """ - if SCons.Memoize.use_memoizer: - __metaclass__ = SCons.Memoize.Memoized_Metaclass - - memoizer_counters = [] - def __init__(self): self._memo = {} @@ -196,8 +191,7 @@ class PathListCache(object): pathlist = tuple(SCons.Util.flatten(pathlist)) return pathlist - memoizer_counters.append(SCons.Memoize.CountDict('PathList', _PathList_key)) - + @SCons.Memoize.CountDictCall(_PathList_key) def PathList(self, pathlist): """ Returns the cached _PathList object for the specified pathlist, diff --git a/src/engine/SCons/SConf.py b/src/engine/SCons/SConf.py index 87432ef..8bce8ce 100644 --- a/src/engine/SCons/SConf.py +++ b/src/engine/SCons/SConf.py @@ -175,8 +175,11 @@ class SConfBuildInfo(SCons.Node.FS.FileBuildInfo): are result (did the builder succeed last time?) and string, which contains messages of the original build phase. """ - result = None # -> 0/None -> no error, != 0 error - string = None # the stdout / stderr output when building the target + __slots__ = ('result', 'string') + + def __init__(self): + self.result = None # -> 0/None -> no error, != 0 error + self.string = None # the stdout / stderr output when building the target def set_build_result(self, result, string): self.result = result @@ -352,8 +355,10 @@ class SConfBuildTask(SCons.Taskmaster.AlwaysTask): raise SCons.Errors.ExplicitExit(self.targets[0],exc_value.code) except Exception, e: for t in self.targets: - binfo = t.get_binfo() - binfo.__class__ = SConfBuildInfo + #binfo = t.get_binfo() + #binfo.__class__ = SConfBuildInfo + binfo = SConfBuildInfo() + binfo.merge(t.get_binfo()) binfo.set_build_result(1, s.getvalue()) sconsign_entry = SCons.SConsign.SConsignEntry() sconsign_entry.binfo = binfo @@ -370,8 +375,10 @@ class SConfBuildTask(SCons.Taskmaster.AlwaysTask): raise e else: for t in self.targets: - binfo = t.get_binfo() - binfo.__class__ = SConfBuildInfo + #binfo = t.get_binfo() + #binfo.__class__ = SConfBuildInfo + binfo = SConfBuildInfo() + binfo.merge(t.get_binfo()) binfo.set_build_result(0, s.getvalue()) sconsign_entry = SCons.SConsign.SConsignEntry() sconsign_entry.binfo = binfo @@ -500,7 +507,7 @@ class SConfBase(object): # we override the store_info() method with a null place-holder # so we really control how it gets written. for n in nodes: - n.store_info = n.do_not_store_info + n.store_info = 0 if not hasattr(n, 'attributes'): n.attributes = SCons.Node.Node.Attrs() n.attributes.keep_targetinfo = 1 @@ -640,7 +647,7 @@ class SConfBase(object): ok = self.TryLink(text, extension) if( ok ): prog = self.lastTarget - pname = prog.path + pname = prog.get_internal_path() output = self.confdir.File(os.path.basename(pname)+'.out') node = self.env.Command(output, prog, [ [ pname, ">", "${TARGET}"] ]) ok = self.BuildNodes(node) @@ -684,7 +691,6 @@ class SConfBase(object): else: if not os.path.isdir( dirName ): os.makedirs( dirName ) - node._exists = 1 def _startup(self): """Private method. Set up logstream, and set the environment diff --git a/src/engine/SCons/SConfTests.py b/src/engine/SCons/SConfTests.py index 1c4b401..233ee78 100644 --- a/src/engine/SCons/SConfTests.py +++ b/src/engine/SCons/SConfTests.py @@ -221,8 +221,6 @@ class SConfTestCase(unittest.TestCase): pass def get_stored_info(self): pass - def do_not_store_info(self): - pass def get_executor(self): class Executor(object): def __init__(self, targets): diff --git a/src/engine/SCons/SConsign.py b/src/engine/SCons/SConsign.py index 6555fcb..74ee804 100644 --- a/src/engine/SCons/SConsign.py +++ b/src/engine/SCons/SConsign.py @@ -122,16 +122,40 @@ class SConsignEntry(object): XXX As coded below, we do expect a '.binfo' attribute to be added, but we'll probably generalize this in the next refactorings. """ - current_version_id = 1 + __slots__ = ("binfo", "ninfo", "__weakref__") + current_version_id = 2 + def __init__(self): # Create an object attribute from the class attribute so it ends up # in the pickled data in the .sconsign file. - _version_id = self.current_version_id + #_version_id = self.current_version_id + pass + def convert_to_sconsign(self): self.binfo.convert_to_sconsign() + def convert_from_sconsign(self, dir, name): self.binfo.convert_from_sconsign(dir, name) + def __getstate__(self): + state = getattr(self, '__dict__', {}).copy() + for obj in type(self).mro(): + for name in getattr(obj,'__slots__',()): + if hasattr(self, name): + state[name] = getattr(self, name) + + state['_version_id'] = self.current_version_id + try: + del state['__weakref__'] + except KeyError: + pass + return state + + def __setstate__(self, state): + for key, value in state.items(): + if key not in ('_version_id','__weakref__'): + setattr(self, key, value) + class Base(object): """ This is the controlling class for the signatures for the collection of @@ -202,7 +226,7 @@ class DB(Base): # Read using the path relative to the top of the Repository # (self.dir.tpath) from which we're fetching the signature # information. - path = normcase(dir.tpath) + path = normcase(dir.get_tpath()) try: rawentries = db[path] except KeyError: @@ -217,7 +241,7 @@ class DB(Base): raise except Exception, e: SCons.Warnings.warn(SCons.Warnings.CorruptSConsignWarning, - "Ignoring corrupt sconsign entry : %s (%s)\n"%(self.dir.tpath, e)) + "Ignoring corrupt sconsign entry : %s (%s)\n"%(self.dir.get_tpath(), e)) for key, entry in self.entries.items(): entry.convert_from_sconsign(dir, key) @@ -244,7 +268,7 @@ class DB(Base): # directory (self.dir.path), not relative to the top of # the Repository; we only write to our own .sconsign file, # not to .sconsign files in Repositories. - path = normcase(self.dir.path) + path = normcase(self.dir.get_internal_path()) for key, entry in self.entries.items(): entry.convert_to_sconsign() db[path] = pickle.dumps(self.entries, 1) @@ -287,7 +311,7 @@ class DirFile(Dir): """ self.dir = dir - self.sconsign = os.path.join(dir.path, '.sconsign') + self.sconsign = os.path.join(dir.get_internal_path(), '.sconsign') try: fp = open(self.sconsign, 'rb') @@ -323,7 +347,7 @@ class DirFile(Dir): self.merge() - temp = os.path.join(self.dir.path, '.scons%d' % os.getpid()) + temp = os.path.join(self.dir.get_internal_path(), '.scons%d' % os.getpid()) try: file = open(temp, 'wb') fname = temp diff --git a/src/engine/SCons/SConsignTests.py b/src/engine/SCons/SConsignTests.py index f71e53e..d40a7b6 100644 --- a/src/engine/SCons/SConsignTests.py +++ b/src/engine/SCons/SConsignTests.py @@ -62,6 +62,10 @@ class DummyNode(object): return self.binfo def get_binfo(self): return self.binfo + def get_internal_path(self): + return self.path + def get_tpath(self): + return self.tpath class SConsignTestCase(unittest.TestCase): def setUp(self): diff --git a/src/engine/SCons/Scanner/CTests.py b/src/engine/SCons/Scanner/CTests.py index 6418754..9c7df12 100644 --- a/src/engine/SCons/Scanner/CTests.py +++ b/src/engine/SCons/Scanner/CTests.py @@ -270,17 +270,18 @@ class CScannerTestCase5(unittest.TestCase): path = s.path(env) n = env.File('f3.cpp') - def my_rexists(s=n): - s.rexists_called = 1 - return s.old_rexists() - setattr(n, 'old_rexists', n.rexists) - setattr(n, 'rexists', my_rexists) + def my_rexists(s): + s.Tag('rexists_called', 1) + return SCons.Node._rexists_map[s.GetTag('old_rexists')](s) + n.Tag('old_rexists', n._func_rexists) + SCons.Node._rexists_map[3] = my_rexists + n._func_rexists = 3 deps = s(n, env, path) # Make sure rexists() got called on the file node being # scanned, essential for cooperation with VariantDir functionality. - assert n.rexists_called + assert n.GetTag('rexists_called') headers = ['f1.h', 'f2.h', 'f3-test.h', 'd1/f1.h', 'd1/f2.h', 'd1/f3-test.h'] diff --git a/src/engine/SCons/Scanner/Dir.py b/src/engine/SCons/Scanner/Dir.py index 1cecfb7..cbfb6fb 100644 --- a/src/engine/SCons/Scanner/Dir.py +++ b/src/engine/SCons/Scanner/Dir.py @@ -77,7 +77,7 @@ def scan_on_disk(node, env, path=()): that and then call the in-memory scanning function. """ try: - flist = node.fs.listdir(node.abspath) + flist = node.fs.listdir(node.get_abspath()) except (IOError, OSError): return [] e = node.Entry diff --git a/src/engine/SCons/Scanner/FortranTests.py b/src/engine/SCons/Scanner/FortranTests.py index 252da64..aaefa79 100644 --- a/src/engine/SCons/Scanner/FortranTests.py +++ b/src/engine/SCons/Scanner/FortranTests.py @@ -356,17 +356,18 @@ class FortranScannerTestCase9(unittest.TestCase): path = s.path(env) n = env.File('fff3.f') - def my_rexists(s=n): - s.rexists_called = 1 - return s.old_rexists() - setattr(n, 'old_rexists', n.rexists) - setattr(n, 'rexists', my_rexists) + def my_rexists(s): + s.Tag('rexists_called', 1) + return SCons.Node._rexists_map[s.GetTag('old_rexists')](s) + n.Tag('old_rexists', n._func_rexists) + SCons.Node._rexists_map[3] = my_rexists + n._func_rexists = 3 deps = s(n, env, path) # Make sure rexists() got called on the file node being # scanned, essential for cooperation with VariantDir functionality. - assert n.rexists_called + assert n.GetTag('rexists_called') headers = ['d1/f3.f', 'f3.f'] deps_match(self, deps, headers) diff --git a/src/engine/SCons/Scanner/IDLTests.py b/src/engine/SCons/Scanner/IDLTests.py index 675c70c..227799e 100644 --- a/src/engine/SCons/Scanner/IDLTests.py +++ b/src/engine/SCons/Scanner/IDLTests.py @@ -290,17 +290,18 @@ class IDLScannerTestCase5(unittest.TestCase): path = s.path(env) n = env.File('t3.idl') - def my_rexists(s=n): - s.rexists_called = 1 - return s.old_rexists() - setattr(n, 'old_rexists', n.rexists) - setattr(n, 'rexists', my_rexists) + def my_rexists(s): + s.Tag('rexists_called', 1) + return SCons.Node._rexists_map[s.GetTag('old_rexists')](s) + n.Tag('old_rexists', n._func_rexists) + SCons.Node._rexists_map[3] = my_rexists + n._func_rexists = 3 deps = s(n, env, path) # Make sure rexists() got called on the file node being # scanned, essential for cooperation with VariantDir functionality. - assert n.rexists_called + assert n.GetTag('rexists_called') headers = ['d1/f1.idl', 'd1/f2.idl', 'f1.idl', 'f2.idl', 'f3-test.idl', diff --git a/src/engine/SCons/Script/Main.py b/src/engine/SCons/Script/Main.py index c7a9d27..323fba9 100644 --- a/src/engine/SCons/Script/Main.py +++ b/src/engine/SCons/Script/Main.py @@ -214,7 +214,7 @@ class BuildTask(SCons.Taskmaster.OutOfDateTask): if self.top and not t.has_builder() and not t.side_effect: if not t.exists(): if t.__class__.__name__ in ('File', 'Dir', 'Entry'): - errstr="Do not know how to make %s target `%s' (%s)." % (t.__class__.__name__, t, t.abspath) + errstr="Do not know how to make %s target `%s' (%s)." % (t.__class__.__name__, t, t.get_abspath()) else: # Alias or Python or ... errstr="Do not know how to make %s target `%s'." % (t.__class__.__name__, t) sys.stderr.write("scons: *** " + errstr) @@ -351,7 +351,7 @@ class CleanTask(SCons.Taskmaster.AlwaysTask): if target in SCons.Environment.CleanTargets: files = SCons.Environment.CleanTargets[target] for f in files: - self.fs_delete(f.abspath, str(f), remove) + self.fs_delete(f.get_abspath(), str(f), remove) def show(self): for t in self._get_files_to_clean(): @@ -672,7 +672,7 @@ def _set_debug_values(options): if "prepare" in debug_values: SCons.Taskmaster.print_prepare = 1 if "duplicate" in debug_values: - SCons.Node.FS.print_duplicate = 1 + SCons.Node.print_duplicate = 1 def _create_path(plist): path = '.' @@ -946,9 +946,9 @@ def _main(parser): progress_display.set_mode(0) if options.site_dir: - _load_site_scons_dir(d.path, options.site_dir) + _load_site_scons_dir(d.get_internal_path(), options.site_dir) elif not options.no_site_dir: - _load_all_site_scons_dirs(d.path) + _load_all_site_scons_dirs(d.get_internal_path()) if options.include_dir: sys.path = options.include_dir + sys.path @@ -1111,7 +1111,6 @@ def _build_targets(fs, options, targets, target_top): display.set_mode(not options.silent) SCons.Action.print_actions = not options.silent SCons.Action.execute_actions = not options.no_exec - SCons.Node.FS.do_store_info = not options.no_exec SCons.Node.do_store_info = not options.no_exec SCons.SConf.dryrun = options.no_exec diff --git a/src/engine/SCons/Script/SConscript.py b/src/engine/SCons/Script/SConscript.py index f4a7f07..0a5720d 100644 --- a/src/engine/SCons/Script/SConscript.py +++ b/src/engine/SCons/Script/SConscript.py @@ -265,7 +265,7 @@ def _SConscript(fs, *files, **kw): call_stack[-1].globals.update({__file__:old_file}) else: SCons.Warnings.warn(SCons.Warnings.MissingSConscriptWarning, - "Ignoring missing SConscript '%s'" % f.path) + "Ignoring missing SConscript '%s'" % f.get_internal_path()) finally: SCons.Script.sconscript_reading = SCons.Script.sconscript_reading - 1 @@ -438,7 +438,7 @@ class SConsEnvironment(SCons.Environment.Base): fname = fn.get_path(src_dir) files = [os.path.join(str(variant_dir), fname)] else: - files = [fn.abspath] + files = [fn.get_abspath()] kw['src_dir'] = variant_dir self.fs.VariantDir(variant_dir, src_dir, duplicate) diff --git a/src/engine/SCons/Taskmaster.py b/src/engine/SCons/Taskmaster.py index 5de1cda..345534e 100644 --- a/src/engine/SCons/Taskmaster.py +++ b/src/engine/SCons/Taskmaster.py @@ -242,7 +242,7 @@ class Task(object): # for t in cached_targets: try: - t.fs.unlink(t.path) + t.fs.unlink(t.get_internal_path()) except (IOError, OSError): pass self.targets[0].build() diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py index 2621cf9..efd2e33 100644 --- a/src/engine/SCons/Tool/__init__.py +++ b/src/engine/SCons/Tool/__init__.py @@ -340,7 +340,7 @@ symlinks for the platform we are on""" if version: # here we need the full pathname so the links end up in the right directory - libname = getattr(target[0].attributes, 'shlibpath', target[0].path) + libname = getattr(target[0].attributes, 'shlibpath', target[0].get_internal_path()) if Verbose: print "VerShLib: target lib is = ", libname print "VerShLib: name is = ", target[0].name diff --git a/src/engine/SCons/Tool/docbook/__init__.py b/src/engine/SCons/Tool/docbook/__init__.py index 26a1a95..aead43c 100644 --- a/src/engine/SCons/Tool/docbook/__init__.py +++ b/src/engine/SCons/Tool/docbook/__init__.py @@ -448,7 +448,7 @@ def DocbookEpub(env, target, source=None, *args, **kw): Ensure all the resources in the manifest are present in the OEBPS directory. """ hrefs = [] - content_file = os.path.join(source[0].abspath, 'content.opf') + content_file = os.path.join(source[0].get_abspath(), 'content.opf') if not os.path.isfile(content_file): return @@ -491,9 +491,9 @@ def DocbookEpub(env, target, source=None, *args, **kw): 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) + referenced_file = os.path.join(source[0].get_abspath(), href) if not os.path.exists(referenced_file): - shutil.copy(href, os.path.join(source[0].abspath, href)) + shutil.copy(href, os.path.join(source[0].get_abspath(), href)) # Init list of targets/sources target, source = __extend_targets_sources(target, source) diff --git a/src/engine/SCons/Tool/mslink.py b/src/engine/SCons/Tool/mslink.py index 37af34e..69baa43 100644 --- a/src/engine/SCons/Tool/mslink.py +++ b/src/engine/SCons/Tool/mslink.py @@ -208,7 +208,7 @@ 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' + manifestSrc = target[0].get_abspath() + '.manifest' if os.path.exists(manifestSrc): ret = (embedManifestDllAction) ([target[0]],None,env) if ret: @@ -222,7 +222,7 @@ 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' + manifestSrc = target[0].get_abspath() + '.manifest' if os.path.exists(manifestSrc): ret = (embedManifestExeAction) ([target[0]],None,env) if ret: diff --git a/src/engine/SCons/Tool/packaging/__init__.py b/src/engine/SCons/Tool/packaging/__init__.py index 95311a2..1a979ab 100644 --- a/src/engine/SCons/Tool/packaging/__init__.py +++ b/src/engine/SCons/Tool/packaging/__init__.py @@ -80,7 +80,7 @@ def Tag(env, target, source, *more_tags, **kw_tags): #if not k.startswith('PACKAGING_'): if k[:10] != 'PACKAGING_': k='PACKAGING_'+k - setattr(t, k, v) + t.Tag(k, v) def Package(env, target=None, source=None, **kw): """ Entry point for the package tool. @@ -235,9 +235,11 @@ def copy_attr(f1, 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)) + if f1._tags: + pattrs = list(filter(copyit, f1._tags)) + for attr in pattrs: + f2.Tag(attr, f1.GetTag(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. @@ -262,9 +264,9 @@ def putintopackageroot(target, source, env, pkgroot, honor_install_location=1): if file.is_under(pkgroot): new_source.append(file) else: - if hasattr(file, 'PACKAGING_INSTALL_LOCATION') and\ + if file.GetTag('PACKAGING_INSTALL_LOCATION') and\ honor_install_location: - new_name=make_path_relative(file.PACKAGING_INSTALL_LOCATION) + new_name=make_path_relative(file.GetTag('PACKAGING_INSTALL_LOCATION')) else: new_name=make_path_relative(file.get_path()) @@ -301,7 +303,7 @@ def stripinstallbuilder(target, source, env): for ss in s.sources: n_source.append(ss) copy_attr(s, ss) - setattr(ss, 'PACKAGING_INSTALL_LOCATION', s.get_path()) + ss.Tag('PACKAGING_INSTALL_LOCATION', s.get_path()) return (target, n_source) diff --git a/src/engine/SCons/Tool/packaging/ipk.py b/src/engine/SCons/Tool/packaging/ipk.py index 6549445..84f4e20 100644 --- a/src/engine/SCons/Tool/packaging/ipk.py +++ b/src/engine/SCons/Tool/packaging/ipk.py @@ -120,7 +120,7 @@ def build_specfiles(source, target, env): 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') + opened_files[needle]=open(file.get_abspath(), 'w') return opened_files[needle] control_file=open_file('control', target) diff --git a/src/engine/SCons/Tool/packaging/msi.py b/src/engine/SCons/Tool/packaging/msi.py index fe78c9c..172038f 100644 --- a/src/engine/SCons/Tool/packaging/msi.py +++ b/src/engine/SCons/Tool/packaging/msi.py @@ -189,7 +189,7 @@ 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') + file = open(target[0].get_abspath(), 'w') try: # Create a document with the Wix root tag diff --git a/src/engine/SCons/Tool/packaging/rpm.py b/src/engine/SCons/Tool/packaging/rpm.py index 2bc3063..656d8fb 100644 --- a/src/engine/SCons/Tool/packaging/rpm.py +++ b/src/engine/SCons/Tool/packaging/rpm.py @@ -130,8 +130,7 @@ 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 = "" + file = open(target[0].get_abspath(), 'w') try: file.write( build_specfile_header(env) ) @@ -279,7 +278,9 @@ def build_specfile_filesection(spec, files): tags = {} for k in supported_tags.keys(): try: - tags[k]=getattr(file, k) + v = file.GetTag(k) + if v: + tags[k] = v except AttributeError: pass @@ -287,7 +288,7 @@ def build_specfile_filesection(spec, files): str = str + SimpleTagCompiler(supported_tags, mandatory=0).compile( tags ) str = str + ' ' - str = str + file.PACKAGING_INSTALL_LOCATION + str = str + file.GetTag('PACKAGING_INSTALL_LOCATION') str = str + '\n\n' return str diff --git a/src/engine/SCons/Tool/rpm.py b/src/engine/SCons/Tool/rpm.py index 1f6eafe..b7d65a8 100644 --- a/src/engine/SCons/Tool/rpm.py +++ b/src/engine/SCons/Tool/rpm.py @@ -51,11 +51,11 @@ def get_cmd(source, env): 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 ) + tar_file_with_included_specfile.get_abspath() ) def build_rpm(target, source, env): # create a temporary rpm build root. - tmpdir = os.path.join( os.path.dirname( target[0].abspath ), 'rpmtemp' ) + tmpdir = os.path.join( os.path.dirname( target[0].get_abspath() ), 'rpmtemp' ) if os.path.exists(tmpdir): shutil.rmtree(tmpdir) @@ -87,7 +87,7 @@ def build_rpm(target, source, env): expected = os.path.basename(input.get_path()) assert expected == rpm_output, "got %s but expected %s" % (rpm_output, expected) - shutil.copy( output, input.abspath ) + shutil.copy( output, input.get_abspath() ) # cleanup before leaving. diff --git a/src/engine/SCons/Tool/swig.py b/src/engine/SCons/Tool/swig.py index f166174..a315182 100644 --- a/src/engine/SCons/Tool/swig.py +++ b/src/engine/SCons/Tool/swig.py @@ -42,6 +42,7 @@ import SCons.Defaults import SCons.Scanner import SCons.Tool import SCons.Util +import SCons.Node SwigAction = SCons.Action.Action('$SWIGCOM', '$SWIGCOMSTR') @@ -117,9 +118,13 @@ def _swigEmitter(target, source, env): if outdir: java_files = [os.path.join(outdir, j) for j in java_files] java_files = list(map(env.fs.File, java_files)) + def t_from_s(t, p, s, x): + return t.dir + tsm = SCons.Node._target_from_source_map + tkey = len(tsm) + tsm[tkey] = t_from_s 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') + jf._func_target_from_source = tkey target.extend(java_files) return (target, source) diff --git a/src/engine/SCons/Util.py b/src/engine/SCons/Util.py index 822d524..4890ba2 100644 --- a/src/engine/SCons/Util.py +++ b/src/engine/SCons/Util.py @@ -992,7 +992,7 @@ class Selector(OrderedDict): def __call__(self, env, source, ext=None): if ext is None: try: - ext = source[0].suffix + ext = source[0].get_suffix() except IndexError: ext = "" try: diff --git a/src/engine/SCons/UtilTests.py b/src/engine/SCons/UtilTests.py index b0c15c5..795bc46 100644 --- a/src/engine/SCons/UtilTests.py +++ b/src/engine/SCons/UtilTests.py @@ -591,10 +591,11 @@ class UtilTestCase(unittest.TestCase): class MyNode(object): def __init__(self, name): self.name = name - self.suffix = os.path.splitext(name)[1] def __str__(self): return self.name + def get_suffix(self): + return os.path.splitext(self.name)[1] s = Selector({'a' : 'AAA', 'b' : 'BBB'}) assert s['a'] == 'AAA', s['a'] diff --git a/src/script/sconsign.py b/src/script/sconsign.py index e5e9d4f..ef32a93 100644 --- a/src/script/sconsign.py +++ b/src/script/sconsign.py @@ -278,7 +278,7 @@ def field(name, entry, verbose=Verbose): def nodeinfo_raw(name, ninfo, prefix=""): # This just formats the dictionary, which we would normally use str() # to do, except that we want the keys sorted for deterministic output. - d = ninfo.__dict__ + d = ninfo.__getstate__() try: keys = ninfo.field_list + ['_version_id'] except AttributeError: diff --git a/test/Actions/addpost-link.py b/test/Actions/addpost-link.py index a148051..04cd68d 100644 --- a/test/Actions/addpost-link.py +++ b/test/Actions/addpost-link.py @@ -54,7 +54,7 @@ myprog = env.Program('test1.c', OBJSUFFIX = '.obj', PROGSUFFIX = '.exe') if ARGUMENTS['case']=='2': - AddPostAction(myprog, Action(r'%(_python_)s strip.py ' + myprog[0].abspath)) + AddPostAction(myprog, Action(r'%(_python_)s strip.py ' + myprog[0].get_abspath())) """ % locals()) test.write('test1.c', """\ diff --git a/test/CacheDir/NoCache.py b/test/CacheDir/NoCache.py index 7e9b540..b035b44 100644 --- a/test/CacheDir/NoCache.py +++ b/test/CacheDir/NoCache.py @@ -45,7 +45,7 @@ CacheDir(r'%s') g = '%s' def ActionWithUndeclaredInputs(target,source,env): - open(target[0].abspath,'w').write(g) + open(target[0].get_abspath(),'w').write(g) Command('foo_cached', [], ActionWithUndeclaredInputs) NoCache(Command('foo_notcached', [], ActionWithUndeclaredInputs)) diff --git a/test/Install/wrap-by-attribute.py b/test/Install/wrap-by-attribute.py index 912551e..02513af 100644 --- a/test/Install/wrap-by-attribute.py +++ b/test/Install/wrap-by-attribute.py @@ -58,10 +58,10 @@ env.SconsInternalInstallFunc = env.Install env.SconsInternalInstallAsFunc = env.InstallAs def InstallWithDestDir(dir, source): - abspath = os.path.splitdrive(env.Dir(dir).abspath)[1] + abspath = os.path.splitdrive(env.Dir(dir).get_abspath())[1] return env.SconsInternalInstallFunc('$DESTDIR'+abspath, source) def InstallAsWithDestDir(target, source): - abspath = os.path.splitdrive(env.File(target).abspath)[1] + abspath = os.path.splitdrive(env.File(target).get_abspath())[1] return env.SconsInternalInstallAsFunc('$DESTDIR'+abspath, source) # Add the wrappers directly as attributes. diff --git a/test/NoClean.py b/test/NoClean.py index 01fe209..63e3e28 100644 --- a/test/NoClean.py +++ b/test/NoClean.py @@ -34,14 +34,14 @@ test = TestSCons.TestSCons() test.write('SConstruct', """ def action(target, source, env): - for t in target: open(t.path, 'w') + for t in target: open(t.get_internal_path(), 'w') Command('1.out', 'SConstruct', action) NoClean('1.out') """) test.write('SConstruct.force', """ def action(target, source, env): - for t in target: open(t.path, 'w') + for t in target: open(t.get_internal_path(), 'w') open('4.out', 'w') res = Command('3.out', 'SConstruct.force', action) Clean('4.out', res) @@ -50,7 +50,7 @@ NoClean('4.out') test.write('SConstruct.multi', """ def action(target, source, env): - for t in target: open(t.path, 'w') + for t in target: open(t.get_internal_path(), 'w') Command(['5.out', '6.out'], 'SConstruct.multi', action) NoClean('6.out') """) diff --git a/test/Scanner/exception.py b/test/Scanner/exception.py index 5af7ac3..1a14152 100644 --- a/test/Scanner/exception.py +++ b/test/Scanner/exception.py @@ -79,7 +79,6 @@ env.Cat('foo', 'foo.k') bar_in = File('bar.in') env.Cat('bar', bar_in) -bar_in.source_scanner = kscan """) test.write('foo.k', diff --git a/test/explain/function-actions.py b/test/explain/function-actions.py index e5f9ba8..bd3ad01 100644 --- a/test/explain/function-actions.py +++ b/test/explain/function-actions.py @@ -59,8 +59,8 @@ if mode: else: MyCopy = Builder(action = Copy('$TARGET', '$SOURCE')) def ChangingCopy(target, source, env): - tgt = str(target[0].abspath) - src = str(source[0].abspath) + tgt = str(target[0].get_abspath()) + src = str(source[0].get_abspath()) shutil.copy(src, tgt) ChangingCopy = Builder(action = ChangingCopy) diff --git a/test/implicit-cache/DualTargets.py b/test/implicit-cache/DualTargets.py index f0694b1..45174ea 100644 --- a/test/implicit-cache/DualTargets.py +++ b/test/implicit-cache/DualTargets.py @@ -37,14 +37,14 @@ test.write('SConstruct', """\ import os.path def emitter(target, source, env): - tgt0 = target[0].abspath + tgt0 = target[0].get_abspath() base,ext = os.path.splitext(tgt0) target.append(base + '.b') return(target, source) def source_scan(node, env, path): - path = node.abspath + path = node.get_abspath() base,ext = os.path.splitext(path) return [base + '.lib'] diff --git a/test/sconsign/script/SConsignFile.py b/test/sconsign/script/SConsignFile.py index a9f79f4..74fb1f0 100644 --- a/test/sconsign/script/SConsignFile.py +++ b/test/sconsign/script/SConsignFile.py @@ -173,33 +173,33 @@ inc2.h: %(sig_re)s \d+ \d+ test.run_sconsign(arguments = "--raw .sconsign", stdout = r"""=== .: -SConstruct: {'csig': None, 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 1} -fake_cc\.py: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 1} -fake_link\.py: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 1} +SConstruct: {'csig': None, 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 2} +fake_cc\.py: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 2} +fake_link\.py: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 2} === sub1: -hello.c: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 1} -hello.exe: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 1} - %(sub1_hello_obj)s: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 1} - fake_link\.py: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 1} +hello.c: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 2} +hello.exe: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 2} + %(sub1_hello_obj)s: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 2} + fake_link\.py: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 2} %(sig_re)s \[.*\] -hello.obj: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 1} - %(sub1_hello_c)s: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 1} - fake_cc\.py: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 1} +hello.obj: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 2} + %(sub1_hello_c)s: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 2} + fake_cc\.py: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 2} %(sig_re)s \[.*\] === sub2: -hello.c: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 1} -hello.exe: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 1} - %(sub2_hello_obj)s: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 1} - fake_link\.py: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 1} +hello.c: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 2} +hello.exe: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 2} + %(sub2_hello_obj)s: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 2} + fake_link\.py: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 2} %(sig_re)s \[.*\] -hello.obj: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 1} - %(sub2_hello_c)s: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 1} - %(sub2_inc1_h)s: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 1} - %(sub2_inc2_h)s: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 1} - fake_cc\.py: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 1} +hello.obj: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 2} + %(sub2_hello_c)s: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 2} + %(sub2_inc1_h)s: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 2} + %(sub2_inc2_h)s: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 2} + fake_cc\.py: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 2} %(sig_re)s \[.*\] -inc1.h: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 1} -inc2.h: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 1} +inc1.h: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 2} +inc2.h: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 2} """ % locals()) expect = r"""=== .: diff --git a/test/sconsign/script/no-SConsignFile.py b/test/sconsign/script/no-SConsignFile.py index 829d650..09ecfa2 100644 --- a/test/sconsign/script/no-SConsignFile.py +++ b/test/sconsign/script/no-SConsignFile.py @@ -159,14 +159,14 @@ hello.obj: %(sig_re)s \d+ \d+ test.run_sconsign(arguments = "sub1/.sconsign", stdout=expect) test.run_sconsign(arguments = "--raw sub1/.sconsign", - stdout = r"""hello.c: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 1} -hello.exe: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 1} - %(sub1_hello_obj)s: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 1} - fake_link\.py: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 1} + stdout = r"""hello.c: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 2} +hello.exe: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 2} + %(sub1_hello_obj)s: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 2} + fake_link\.py: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 2} %(sig_re)s \[.*\] -hello.obj: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 1} - %(sub1_hello_c)s: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 1} - fake_cc\.py: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 1} +hello.obj: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 2} + %(sub1_hello_c)s: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 2} + fake_cc\.py: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 2} %(sig_re)s \[.*\] """ % locals()) -- cgit v0.12 From 031f81e98e247a618ab45c19c66cc1da06e407be Mon Sep 17 00:00:00 2001 From: William Deegan Date: Fri, 27 Feb 2015 12:25:20 -0800 Subject: dummy change to debug issue with buildbot and branches --- bootstrap.py | 1 + 1 file changed, 1 insertion(+) diff --git a/bootstrap.py b/bootstrap.py index f3bc105..c5b3021 100755 --- a/bootstrap.py +++ b/bootstrap.py @@ -220,3 +220,4 @@ if __name__ == "__main__": # indent-tabs-mode:nil # End: # vim: set expandtab tabstop=4 shiftwidth=4: + -- cgit v0.12 From 4a70ef047b1b954e2f4edb8ab62dc58c2716bd59 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Fri, 27 Feb 2015 12:41:40 -0800 Subject: dummy change to debug issue with buildbot and branches --- bootstrap.py | 1 - 1 file changed, 1 deletion(-) diff --git a/bootstrap.py b/bootstrap.py index c5b3021..f3bc105 100755 --- a/bootstrap.py +++ b/bootstrap.py @@ -220,4 +220,3 @@ if __name__ == "__main__": # indent-tabs-mode:nil # End: # vim: set expandtab tabstop=4 shiftwidth=4: - -- cgit v0.12 From fb06d440880a60134f06ed2dac203a3710e94982 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Fri, 27 Feb 2015 17:50:39 -0800 Subject: dummy change to test buildbot changes --- bootstrap.py | 1 + 1 file changed, 1 insertion(+) diff --git a/bootstrap.py b/bootstrap.py index f3bc105..c5b3021 100755 --- a/bootstrap.py +++ b/bootstrap.py @@ -220,3 +220,4 @@ if __name__ == "__main__": # indent-tabs-mode:nil # End: # vim: set expandtab tabstop=4 shiftwidth=4: + -- cgit v0.12 From 7a6c65148df801b3a345080fdd826f932cd88a19 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Fri, 27 Feb 2015 17:55:38 -0800 Subject: dummy change to test buildbot changes --- bootstrap.py | 1 - 1 file changed, 1 deletion(-) diff --git a/bootstrap.py b/bootstrap.py index c5b3021..f3bc105 100755 --- a/bootstrap.py +++ b/bootstrap.py @@ -220,4 +220,3 @@ if __name__ == "__main__": # indent-tabs-mode:nil # End: # vim: set expandtab tabstop=4 shiftwidth=4: - -- cgit v0.12 From 70545358cf838a2142ec39c925bcde00ebff72f6 Mon Sep 17 00:00:00 2001 From: hhsprings Date: Fri, 13 Mar 2015 23:02:05 +0900 Subject: =?UTF-8?q?This=20patch=20is=20not=20for=20Python=202.7,=20but=20f?= =?UTF-8?q?or=20`Microsoft=20Visual=20C++=20Compiler=20for=20Python=202.7'?= =?UTF-8?q?.=20Althouh=20maintainers=20claims=20`This=20will=20be=20the=20?= =?UTF-8?q?last=20release=20to=20support=20Python=20versions=20earlier=20t?= =?UTF-8?q?han=202.7,=20as=20we=20begin=20to=20move=20toward=20supporting?= =?UTF-8?q?=20Python=203.`,=20that=E2=80=99s=20not=20the=20same=20as=20sup?= =?UTF-8?q?porting=20compiler.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/engine/SCons/Tool/MSCommon/common.py | 4 +- src/engine/SCons/Tool/MSCommon/vc.py | 84 ++++++++++++++++++++------------ 2 files changed, 55 insertions(+), 33 deletions(-) diff --git a/src/engine/SCons/Tool/MSCommon/common.py b/src/engine/SCons/Tool/MSCommon/common.py index ccfe739..9549a66 100644 --- a/src/engine/SCons/Tool/MSCommon/common.py +++ b/src/engine/SCons/Tool/MSCommon/common.py @@ -84,8 +84,8 @@ def is_win64(): return _is_win64 -def read_reg(value): - return SCons.Util.RegGetValue(SCons.Util.HKEY_LOCAL_MACHINE, value)[0] +def read_reg(value, hkroot=SCons.Util.HKEY_LOCAL_MACHINE): + return SCons.Util.RegGetValue(hkroot, value)[0] def has_reg(value): """Return True if the given key exists in HKEY_LOCAL_MACHINE, False diff --git a/src/engine/SCons/Tool/MSCommon/vc.py b/src/engine/SCons/Tool/MSCommon/vc.py index 97cb349..71117cd 100644 --- a/src/engine/SCons/Tool/MSCommon/vc.py +++ b/src/engine/SCons/Tool/MSCommon/vc.py @@ -35,6 +35,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" __doc__ = """Module for Visual C/C++ detection and configuration. """ import SCons.compat +import SCons.Util import os import platform @@ -137,32 +138,46 @@ def get_host_target(env): _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'] + '12.0' : [ + (SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VisualStudio\12.0\Setup\VC\ProductDir'), + ], + '12.0Exp' : [ + (SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VCExpress\12.0\Setup\VC\ProductDir'), + ], + '11.0': [ + (SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VisualStudio\11.0\Setup\VC\ProductDir'), + ], + '11.0Exp' : [ + (SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VCExpress\11.0\Setup\VC\ProductDir'), + ], + '10.0': [ + (SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VisualStudio\10.0\Setup\VC\ProductDir'), + ], + '10.0Exp' : [ + (SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VCExpress\10.0\Setup\VC\ProductDir'), + ], + '9.0': [ + (SCons.Util.HKEY_CURRENT_USER, r'Microsoft\DevDiv\VCForPython\9.0\installdir',), + (SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VisualStudio\9.0\Setup\VC\ProductDir',), + ], + '9.0Exp' : [ + (SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VCExpress\9.0\Setup\VC\ProductDir'), + ], + '8.0': [ + (SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VisualStudio\8.0\Setup\VC\ProductDir'), + ], + '8.0Exp': [ + (SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VCExpress\8.0\Setup\VC\ProductDir'), + ], + '7.1': [ + (SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VisualStudio\7.1\Setup\VC\ProductDir'), + ], + '7.0': [ + (SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VisualStudio\7.0\Setup\VC\ProductDir'), + ], + '6.0': [ + (SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VisualStudio\6.0\Setup\Microsoft Visual C++\ProductDir'), + ] } def msvc_version_to_maj_min(msvc_version): @@ -212,18 +227,25 @@ def find_vc_pdir(msvc_version): 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 + for hkroot, key in hkeys: try: - comps = common.read_reg(key) + comps = None + if common.is_win64(): + try: + # ordinally at win64, try Wow6432Node first. + comps = common.read_reg(root + 'Wow6432Node\\' + key, hkroot) + except WindowsError, e: + # at Microsoft Visual Studio for Python 2.7, value is not in Wow6432Node + pass + if not comps: + # not Win64, or Microsoft Visual Studio for Python 2.7 + comps = common.read_reg(root + key, hkroot) except WindowsError, e: debug('find_vc_dir(): no VC registry key %s' % repr(key)) else: -- cgit v0.12 From 03ad733f25bc07f118c179be767bc251b13cb95c Mon Sep 17 00:00:00 2001 From: William Deegan Date: Sat, 14 Mar 2015 15:19:10 -0700 Subject: null change to test new buildbot server --- runtest.py | 1 + 1 file changed, 1 insertion(+) diff --git a/runtest.py b/runtest.py index b7cbdc6..5cee8f1 100755 --- a/runtest.py +++ b/runtest.py @@ -907,3 +907,4 @@ else: # indent-tabs-mode:nil # End: # vim: set expandtab tabstop=4 shiftwidth=4: + -- cgit v0.12 From e32814ad2ce3b984e9a8af558a5b0fbb4a754d73 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Sat, 14 Mar 2015 15:23:25 -0700 Subject: null change to test new buildbot server --- runtest.py | 1 - 1 file changed, 1 deletion(-) diff --git a/runtest.py b/runtest.py index 5cee8f1..b7cbdc6 100755 --- a/runtest.py +++ b/runtest.py @@ -907,4 +907,3 @@ else: # indent-tabs-mode:nil # End: # vim: set expandtab tabstop=4 shiftwidth=4: - -- cgit v0.12 From 7e15cea215477c4eb495be1e8459e7eacd02b235 Mon Sep 17 00:00:00 2001 From: William Roberts Date: Tue, 17 Mar 2015 14:26:53 -0700 Subject: bug 2831: Allow appending Help text to Options Output http://scons.tigris.org/issues/show_bug.cgi?id=2831 In order to append, rather than clobber Help() generated text, use Help("my message", append=True) The append argument is only respected on the first call to this method as it operates on global data. --- src/CHANGES.txt | 3 +++ src/engine/SCons/Script/Main.py | 3 +++ src/engine/SCons/Script/SConscript.py | 4 ++-- src/engine/SCons/Script/__init__.py | 15 ++++++++++++--- 4 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 55b48a5..cd98f12 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -6,6 +6,9 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER + From William Roberts: + - Fix bug 2831 and allow Help() text to be appended to AddOption() help. + From Russel Winder: - Add support for f08 file extensions for Fortran 2008 code. diff --git a/src/engine/SCons/Script/Main.py b/src/engine/SCons/Script/Main.py index c7a9d27..4ccd2b3 100644 --- a/src/engine/SCons/Script/Main.py +++ b/src/engine/SCons/Script/Main.py @@ -484,6 +484,9 @@ def GetOption(name): def SetOption(name, value): return OptionsParser.values.set_option(name, value) +def PrintHelp(file=None): + OptionsParser.print_help(file=file) + # class Stats(object): def __init__(self): diff --git a/src/engine/SCons/Script/SConscript.py b/src/engine/SCons/Script/SConscript.py index f4a7f07..3502534 100644 --- a/src/engine/SCons/Script/SConscript.py +++ b/src/engine/SCons/Script/SConscript.py @@ -499,9 +499,9 @@ class SConsEnvironment(SCons.Environment.Base): name = self.subst(name) return SCons.Script.Main.GetOption(name) - def Help(self, text): + def Help(self, text, append=False): text = self.subst(text, raw=1) - SCons.Script.HelpFunction(text) + SCons.Script.HelpFunction(text, append=append) def Import(self, *vars): try: diff --git a/src/engine/SCons/Script/__init__.py b/src/engine/SCons/Script/__init__.py index bb7b632..a9d7708 100644 --- a/src/engine/SCons/Script/__init__.py +++ b/src/engine/SCons/Script/__init__.py @@ -41,6 +41,7 @@ start_time = time.time() import collections import os +import StringIO import sys # Special chicken-and-egg handling of the "--debug=memoizer" flag: @@ -107,6 +108,7 @@ QuestionTask = Main.QuestionTask #SConscriptSettableOptions = Main.SConscriptSettableOptions AddOption = Main.AddOption +PrintHelp = Main.PrintHelp GetOption = Main.GetOption SetOption = Main.SetOption Progress = Main.Progress @@ -258,10 +260,17 @@ def _Set_Default_Targets(env, tlist): # help_text = None -def HelpFunction(text): +def HelpFunction(text, append=False): global help_text - if SCons.Script.help_text is None: - SCons.Script.help_text = text + if help_text is None: + if append: + s = StringIO.StringIO() + PrintHelp(s) + help_text = s.getvalue() + s.close() + else: + help_text = "" + help_text = help_text + "\nLocal Build Variables:\n" + text else: help_text = help_text + text -- cgit v0.12 From 976a3d27a47bf69eb886a92be06a09d7face2f55 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 23 Mar 2015 16:54:17 -0700 Subject: initial pass at improving documentation of versioned shared library logic --- src/engine/SCons/Tool/__init__.xml | 5 +++++ src/engine/SCons/Tool/install.xml | 19 +++++++++++++++---- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/engine/SCons/Tool/__init__.xml b/src/engine/SCons/Tool/__init__.xml index dd06f12..ee56fc3 100644 --- a/src/engine/SCons/Tool/__init__.xml +++ b/src/engine/SCons/Tool/__init__.xml @@ -205,6 +205,11 @@ and Y are numbers, and Z is a number but can also contain letters to designate alpha, beta, or release candidate patch levels. + +env.SharedLibrary(target = 'bar', source = ['bar.c', 'foo.o'], SHLIBVERSION='1.5.2') + + + This builder may create multiple links to the library. On a POSIX system, for the shared library libbar.so.2.3.1, the links created would be diff --git a/src/engine/SCons/Tool/install.xml b/src/engine/SCons/Tool/install.xml index 0a0ad71..da82c6e 100644 --- a/src/engine/SCons/Tool/install.xml +++ b/src/engine/SCons/Tool/install.xml @@ -68,6 +68,14 @@ and source arguments list different numbers of files or directories. + + +env.InstallAs(target = '/usr/local/bin/foo', + source = 'foo_debug') +env.InstallAs(target = ['../lib/libfoo.a', '../lib/libbar.a'], + source = ['libFOO.a', 'libBAR.a']) + + @@ -77,14 +85,17 @@ arguments list different numbers of files or directories. Installs a versioned shared library. The &cv-link-SHLIBVERSION; construction variable should be defined in the environment to confirm the version number in the library name. +If &cv-link-SHLIBVERSION is not defined a warning will be issued +and the name of the library will be parsed to derive the version. The symlinks appropriate to the architecture will be generated. -env.InstallAs(target = '/usr/local/bin/foo', - source = 'foo_debug') -env.InstallAs(target = ['../lib/libfoo.a', '../lib/libbar.a'], - source = ['libFOO.a', 'libBAR.a']) +env.InstallVersionedLib(target = '/usr/local/bin/foo', + source = 'libxyz.1.5.2.so') +env.InstallVersionedLib(target = '/usr/local/bin/foo', + source = 'libxyz.1.5.2.so', + SHLIBVERSION='1.5.2') -- cgit v0.12 From dae900cb134bc4fc74943f2c5a1f6a6303f9aa61 Mon Sep 17 00:00:00 2001 From: William Blevins Date: Mon, 23 Mar 2015 22:21:33 -0400 Subject: Issue 2395: Symlink support hotfix. Symlink contents now copied correctly with relative path when ( cwd != symlink directory ). --- src/engine/SCons/Defaults.py | 5 ++--- test/Copy-Symlinks.py | 51 ++++++++++++++++++++++++++++++++++++++------ 2 files changed, 47 insertions(+), 9 deletions(-) diff --git a/src/engine/SCons/Defaults.py b/src/engine/SCons/Defaults.py index 3f60bc0..6500443 100644 --- a/src/engine/SCons/Defaults.py +++ b/src/engine/SCons/Defaults.py @@ -198,11 +198,10 @@ def copy_func(dest, src, symlinks=True): shutil.copy2(file, dest) return 0 elif os.path.islink(src): - linkto = os.readlink(src) if symlinks: - return os.symlink(linkto, dest) + return os.symlink(os.readlink(src), dest) else: - return copy_func(dest, linkto, symlinks) + return copy_func(dest, os.path.realpath(src)) elif os.path.isfile(src): return shutil.copy2(src, dest) else: diff --git a/test/Copy-Symlinks.py b/test/Copy-Symlinks.py index 640e76c..2b8b824 100644 --- a/test/Copy-Symlinks.py +++ b/test/Copy-Symlinks.py @@ -50,18 +50,24 @@ treeToLink = 'tree' treelinkToCopy = 'treelinkToCopy' badToLink = 'None' # do not write this item badlinkToCopy = 'badlinkToCopy' +relToLink = os.path.join( treeToLink, fileToLink ) +rellinkToCopy = 'relLinkToCopy' test.symlink( fileToLink, filelinkToCopy ) test.symlink( dirToLink, dirlinkToCopy ) test.symlink( treeToLink, treelinkToCopy ) test.symlink( badToLink, badlinkToCopy ) +test.symlink( relToLink, rellinkToCopy ) test.write( fileToLink, fileContents ) test.subdir( dirToLink ) test.subdir( treeToLink ) -test.write( os.path.join( treeToLink, fileToLink ), fileContents ) +test.write( relToLink, fileContents ) -test.write('SConstruct', +sconstructPath = 'SConstruct' +sconscriptPath = os.path.join( treeToLink, 'SConscript' ) + +test.write( sconstructPath, """\ import SCons.Defaults SCons.Defaults.DefaultEnvironment( tools = [] ) @@ -81,17 +87,32 @@ Execute( Copy( 'L6', '%(treelinkToCopy)s', True ) ) Execute( Copy( 'Fails', '%(badlinkToCopy)s', False ) ) Execute( Copy( 'L7', '%(badlinkToCopy)s' ) ) Execute( Copy( 'L8', '%(badlinkToCopy)s', True ) ) + +SConscript( '%(sconscriptPath)s' ) +""" +% locals() +) + +relLinkCopyPath = os.path.join( '..', rellinkToCopy ) + +test.write( sconscriptPath, +"""\ +Execute( Copy( 'F2', '%(relLinkCopyPath)s', False ) ) +Execute( Copy( 'L9', '%(relLinkCopyPath)s' ) ) +Execute( Copy( 'L10', '%(relLinkCopyPath)s', True ) ) """ % locals() ) -test.must_exist( 'SConstruct' ) +test.must_exist( sconstructPath ) +test.must_exist( sconscriptPath ) test.must_exist( fileToLink ) test.must_exist( filelinkToCopy ) test.must_exist( dirlinkToCopy ) test.must_exist( treelinkToCopy ) test.must_not_exist( badToLink ) test.must_exist( badlinkToCopy ) +test.must_exist( rellinkToCopy ) expectStdout = test.wrap_stdout( read_str = @@ -105,9 +126,12 @@ Copy("L4", "%(dirlinkToCopy)s") Copy("T1", "%(treelinkToCopy)s") Copy("L5", "%(treelinkToCopy)s") Copy("L6", "%(treelinkToCopy)s") -Copy("Fails", "badlinkToCopy") +Copy("Fails", "%(badlinkToCopy)s") Copy("L7", "%(badlinkToCopy)s") Copy("L8", "%(badlinkToCopy)s") +Copy("F2", "%(relLinkCopyPath)s") +Copy("L9", "%(relLinkCopyPath)s") +Copy("L10", "%(relLinkCopyPath)s") ''' % locals(), build_str = '''\ @@ -117,13 +141,18 @@ scons: `.' is up to date. expectStderr = \ '''\ -scons: *** None: No such file or directory -''' +scons: *** %s: No such file or directory +''' % os.path.join( os.getcwd(), badToLink ) test.run( stdout = expectStdout, stderr = expectStderr, status = None ) +F2 = os.path.join( treeToLink, 'F2' ) +L9 = os.path.join( treeToLink, 'L9' ) +L10 = os.path.join( treeToLink, 'L10' ) + test.must_exist('D1') test.must_exist('F1') +test.must_exist( F2 ) test.must_exist('L2') test.must_exist('L3') test.must_exist('L4') @@ -131,17 +160,21 @@ test.must_exist('L5') test.must_exist('L6') test.must_exist('L7') test.must_exist('L8') +test.must_exist( L9 ) +test.must_exist( L10 ) test.must_exist('T1') test.must_not_exist( 'Fails' ) test.must_match( fileToLink, fileContents ) test.must_match( 'F1', fileContents ) +test.must_match( F2 , fileContents ) test.must_match( 'L1', fileContents ) test.must_match( 'L2', fileContents ) test.must_match( os.path.join( treeToLink, fileToLink ), fileContents ) test.fail_test( condition=os.path.islink('D1') ) test.fail_test( condition=os.path.islink('F1') ) +test.fail_test( condition=os.path.islink( F2 ) ) test.fail_test( condition=os.path.islink('T1') ) test.fail_test( condition=(not os.path.isdir('D1')) ) test.fail_test( condition=(not os.path.isfile('F1')) ) @@ -154,8 +187,12 @@ test.fail_test( condition=(not os.path.islink('L5')) ) test.fail_test( condition=(not os.path.islink('L6')) ) test.fail_test( condition=(not os.path.islink('L7')) ) test.fail_test( condition=(not os.path.islink('L8')) ) +test.fail_test( condition=(not os.path.islink( L9 )) ) +test.fail_test( condition=(not os.path.islink( L10 )) ) test.fail_test( condition=(os.path.exists('L7')) ) test.fail_test( condition=(os.path.exists('L8')) ) +test.fail_test( condition=(os.path.exists( L9 )) ) +test.fail_test( condition=(os.path.exists( L10 )) ) test.fail_test( condition=(os.readlink(filelinkToCopy) != os.readlink('L1')) ) test.fail_test( condition=(os.readlink(filelinkToCopy) != os.readlink('L2')) ) test.fail_test( condition=(os.readlink(dirlinkToCopy) != os.readlink('L3')) ) @@ -164,6 +201,8 @@ test.fail_test( condition=(os.readlink(treelinkToCopy) != os.readlink('L5')) ) test.fail_test( condition=(os.readlink(treelinkToCopy) != os.readlink('L6')) ) test.fail_test( condition=(os.readlink(badlinkToCopy) != os.readlink('L7')) ) test.fail_test( condition=(os.readlink(badlinkToCopy) != os.readlink('L8')) ) +test.fail_test( condition=(os.readlink(rellinkToCopy) != os.readlink( L9 )) ) +test.fail_test( condition=(os.readlink(rellinkToCopy) != os.readlink( L10 )) ) test.pass_test() -- cgit v0.12 From 458243d778741340ae33bf92672595c3db08b3f4 Mon Sep 17 00:00:00 2001 From: William Blevins Date: Mon, 23 Mar 2015 22:38:49 -0400 Subject: Updated debug-count test case. Now tests against current interpreter vs default path option. --- test/option/debug-count.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/test/option/debug-count.py b/test/option/debug-count.py index 3f8a23c..39c1222 100644 --- a/test/option/debug-count.py +++ b/test/option/debug-count.py @@ -28,6 +28,7 @@ Test that the --debug=count option works. """ import re +import sys import TestSCons @@ -85,11 +86,13 @@ scons: warning: --debug=count is not supported when running SCons \twith the python -O option or optimized \\(.pyo\\) modules. """ + TestSCons.file_expr -test.run(arguments = '--debug=count -h', - interpreter = ['python', '-O'], - stderr = expect_warning, - match = TestSCons.match_re) - +test.run( + arguments = '--debug=count -h', + # Test against current interpreter vs default path option. + interpreter = [ sys.executable, '-O' ], + stderr = expect_warning, + match = TestSCons.match_re +) test.pass_test() -- cgit v0.12 From 3b45927301d3dd1d5af54798c85b8f80c6571678 Mon Sep 17 00:00:00 2001 From: William Blevins Date: Mon, 23 Mar 2015 22:48:48 -0400 Subject: Updated jni header directory expectations for tests. My openjdk install link/dir also contained the architecture. Example: RPM package java-1.7.0-openjdk-devel-1.7.0.75-2.5.4.0.el6_6.x86_64 created link /usr/lib/jvm/java-1.7.0-openjdk.x86_64 Affected tests: test/Java/multi-step.py test/Java/swig-dependencies.py --- QMTest/TestSCons.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/QMTest/TestSCons.py b/QMTest/TestSCons.py index 8635f8e..923e319 100644 --- a/QMTest/TestSCons.py +++ b/QMTest/TestSCons.py @@ -693,7 +693,7 @@ class TestSCons(TestCommon): else: jni_dirs = ['/System/Library/Frameworks/JavaVM.framework/Versions/%s*/Headers/jni.h'%version] jni_dirs.extend(['/usr/lib/jvm/java-*-sun-%s*/include/jni.h'%version, - '/usr/lib/jvm/java-%s*-openjdk/include/jni.h'%version, + '/usr/lib/jvm/java-%s*-openjdk*/include/jni.h'%version, '/usr/java/jdk%s*/include/jni.h'%version]) dirs = self.paths(jni_dirs) if not dirs: -- cgit v0.12 From be0ee2179a7c9db85e518e626612d0ae0918c790 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 23 Mar 2015 23:05:11 -0700 Subject: added more info to the section on InstallVersionedLib(). fixed having InstallAs example in the text for InstallVersionedLib() --- doc/generated/builders.gen | 879 +++++----- doc/generated/functions.gen | 1277 +++++++------- doc/generated/tools.gen | 643 +++---- doc/generated/variables.gen | 3409 +++++++++++++++---------------------- doc/generated/variables.mod | 4 +- src/engine/SCons/Tool/install.xml | 2 +- 6 files changed, 2676 insertions(+), 3538 deletions(-) diff --git a/doc/generated/builders.gen b/doc/generated/builders.gen index 3d534b0..d08833f 100644 --- a/doc/generated/builders.gen +++ b/doc/generated/builders.gen @@ -1,4 +1,4 @@ - + %scons; @@ -12,7 +12,7 @@ %variables-mod; ]> - + CFile() @@ -20,18 +20,17 @@ env.CFile() - - + Builds a C source file given a lex (.l) or yacc (.y) input file. -The suffix specified by the $CFILESUFFIX construction variable +The suffix specified by the $CFILESUFFIX construction variable (.c by default) is automatically added to the target if it is not already present. Example: - + # builds foo.c env.CFile(target = 'foo.c', source = 'foo.l') # builds bar.c @@ -46,13 +45,12 @@ env.CFile(target = 'bar', source = 'bar.y') env.Command() - - -The Command "Builder" is actually implemented + +The Command "Builder" is actually implemented as a function that looks like a Builder, but actually takes an additional argument of the action from which the Builder should be made. -See the Command function description +See the Command function description for the calling syntax and details. @@ -64,19 +62,18 @@ for the calling syntax and details. env.CXXFile() - - + Builds a C++ source file given a lex (.ll) or yacc (.yy) input file. -The suffix specified by the $CXXFILESUFFIX construction variable +The suffix specified by the $CXXFILESUFFIX construction variable (.cc by default) is automatically added to the target if it is not already present. Example: - + # builds foo.cc env.CXXFile(target = 'foo.cc', source = 'foo.ll') # builds bar.cc @@ -91,20 +88,19 @@ env.CXXFile(target = 'bar', source = 'bar.yy') env.DocbookEpub() - - + A pseudo-Builder, providing a Docbook toolchain for EPUB output. -env = Environment(tools=['docbook']) +env = Environment(tools=['docbook']) env.DocbookEpub('manual.epub', 'manual.xml') - + or simply -env = Environment(tools=['docbook']) +env = Environment(tools=['docbook']) env.DocbookEpub('manual') @@ -117,17 +113,16 @@ env.DocbookEpub('manual') env.DocbookHtml() - - + A pseudo-Builder, providing a Docbook toolchain for HTML output. -env = Environment(tools=['docbook']) +env = Environment(tools=['docbook']) env.DocbookHtml('manual.html', 'manual.xml') - + or simply -env = Environment(tools=['docbook']) +env = Environment(tools=['docbook']) env.DocbookHtml('manual') @@ -139,35 +134,34 @@ env.DocbookHtml('manual') env.DocbookHtmlChunked() - - + A pseudo-Builder, providing a Docbook toolchain for chunked HTML output. It supports the base.dir parameter. The chunkfast.xsl file (requires "EXSLT") is used as the default stylesheet. Basic syntax: -env = Environment(tools=['docbook']) +env = Environment(tools=['docbook']) env.DocbookHtmlChunked('manual') - + where manual.xml is the input file. -If you use the root.filename +If you use the root.filename parameter in your own stylesheets you have to specify the new target name. This ensures that the dependencies get correct, especially for the cleanup via scons -c: -env = Environment(tools=['docbook']) +env = Environment(tools=['docbook']) env.DocbookHtmlChunked('mymanual.html', 'manual', xsl='htmlchunk.xsl') -Some basic support for the base.dir is provided. You +Some basic support for the base.dir is provided. You can add the base_dir keyword to your Builder call, and the given prefix gets prepended to all the created filenames: -env = Environment(tools=['docbook']) +env = Environment(tools=['docbook']) env.DocbookHtmlChunked('manual', xsl='htmlchunk.xsl', base_dir='output/') -Make sure that you don't forget the trailing slash for the base folder, else +Make sure that you don't forget the trailing slash for the base folder, else your files get renamed only! @@ -179,35 +173,34 @@ your files get renamed only! env.DocbookHtmlhelp() - - + A pseudo-Builder, providing a Docbook toolchain for HTMLHELP output. Its basic syntax is: -env = Environment(tools=['docbook']) +env = Environment(tools=['docbook']) env.DocbookHtmlhelp('manual') - + where manual.xml is the input file. -If you use the root.filename +If you use the root.filename parameter in your own stylesheets you have to specify the new target name. This ensures that the dependencies get correct, especially for the cleanup via scons -c: -env = Environment(tools=['docbook']) +env = Environment(tools=['docbook']) env.DocbookHtmlhelp('mymanual.html', 'manual', xsl='htmlhelp.xsl') -Some basic support for the base.dir parameter +Some basic support for the base.dir parameter is provided. You can add the base_dir keyword to your Builder call, and the given prefix gets prepended to all the created filenames: -env = Environment(tools=['docbook']) +env = Environment(tools=['docbook']) env.DocbookHtmlhelp('manual', xsl='htmlhelp.xsl', base_dir='output/') -Make sure that you don't forget the trailing slash for the base folder, else +Make sure that you don't forget the trailing slash for the base folder, else your files get renamed only! @@ -220,16 +213,15 @@ your files get renamed only! env.DocbookMan() - - + A pseudo-Builder, providing a Docbook toolchain for Man page output. Its basic syntax is: -env = Environment(tools=['docbook']) +env = Environment(tools=['docbook']) env.DocbookMan('manual') - + where manual.xml is the input file. Note, that you can specify a target name, but the actual output names are automatically set from the refname entries in your XML source. @@ -243,20 +235,19 @@ set from the refname entries in your XML source. env.DocbookPdf() - - + A pseudo-Builder, providing a Docbook toolchain for PDF output. -env = Environment(tools=['docbook']) +env = Environment(tools=['docbook']) env.DocbookPdf('manual.pdf', 'manual.xml') - + or simply -env = Environment(tools=['docbook']) +env = Environment(tools=['docbook']) env.DocbookPdf('manual') @@ -269,33 +260,32 @@ env.DocbookPdf('manual') env.DocbookSlidesHtml() - - + A pseudo-Builder, providing a Docbook toolchain for HTML slides output. -env = Environment(tools=['docbook']) +env = Environment(tools=['docbook']) env.DocbookSlidesHtml('manual') -If you use the titlefoil.html parameter in +If you use the titlefoil.html parameter in your own stylesheets you have to give the new target name. This ensures that the dependencies get correct, especially for the cleanup via scons -c: -env = Environment(tools=['docbook']) +env = Environment(tools=['docbook']) env.DocbookSlidesHtml('mymanual.html','manual', xsl='slideshtml.xsl') -Some basic support for the base.dir parameter +Some basic support for the base.dir parameter is provided. You can add the base_dir keyword to your Builder call, and the given prefix gets prepended to all the created filenames: -env = Environment(tools=['docbook']) +env = Environment(tools=['docbook']) env.DocbookSlidesHtml('manual', xsl='slideshtml.xsl', base_dir='output/') -Make sure that you don't forget the trailing slash for the base folder, else +Make sure that you don't forget the trailing slash for the base folder, else your files get renamed only! @@ -308,20 +298,19 @@ your files get renamed only! env.DocbookSlidesPdf() - - + A pseudo-Builder, providing a Docbook toolchain for PDF slides output. -env = Environment(tools=['docbook']) +env = Environment(tools=['docbook']) env.DocbookSlidesPdf('manual.pdf', 'manual.xml') - + or simply -env = Environment(tools=['docbook']) +env = Environment(tools=['docbook']) env.DocbookSlidesPdf('manual') @@ -333,12 +322,11 @@ env.DocbookSlidesPdf('manual') env.DocbookXInclude() - - + A pseudo-Builder, for resolving XIncludes in a separate processing step. -env = Environment(tools=['docbook']) +env = Environment(tools=['docbook']) env.DocbookXInclude('manual_xincluded.xml', 'manual.xml') @@ -350,16 +338,15 @@ env.DocbookXInclude('manual_xincluded.xml', 'manual.xml') env.DocbookXslt() - - + A pseudo-Builder, applying a given XSL transformation to the input file. -env = Environment(tools=['docbook']) +env = Environment(tools=['docbook']) env.DocbookXslt('manual_transformed.xml', 'manual.xml', xsl='transform.xslt') -Note, that this builder requires the xsl parameter +Note, that this builder requires the xsl parameter to be set. @@ -371,41 +358,40 @@ to be set. env.DVI() - - + Builds a .dvi file from a .tex, .ltx or .latex input file. If the source file suffix is .tex, -scons +scons will examine the contents of the file; if the string \documentclass or \documentstyle is found, the file is assumed to be a LaTeX file and -the target is built by invoking the $LATEXCOM command line; -otherwise, the $TEXCOM command line is used. +the target is built by invoking the $LATEXCOM command line; +otherwise, the $TEXCOM command line is used. If the file is a LaTeX file, the -DVI +DVI builder method will also examine the contents of the .aux -file and invoke the $BIBTEX command line +file and invoke the $BIBTEX command line if the string bibdata is found, -start $MAKEINDEX to generate an index if a +start $MAKEINDEX to generate an index if a .ind file is found and will examine the contents .log -file and re-run the $LATEXCOM command +file and re-run the $LATEXCOM command if the log file says it is necessary. - + The suffix .dvi (hard-coded within TeX itself) is automatically added to the target @@ -413,7 +399,7 @@ if it is not already present. Examples: - + # builds from aaa.tex env.DVI(target = 'aaa.dvi', source = 'aaa.tex') # builds bbb.dvi @@ -430,14 +416,13 @@ env.DVI(target = 'ccc.dvi', source = 'ccc.latex') env.Gs() - - + A Builder for explicitly calling the gs executable. Depending on the underlying OS, the different names gs, gsos2 and gswin32c are tried. -env = Environment(tools=['gs']) +env = Environment(tools=['gs']) env.Gs('cover.jpg','scons-scons.pdf', GSFLAGS='-dNOPAUSE -dBATCH -sDEVICE=jpeg -dFirstPage=1 -dLastPage=1 -q') ) @@ -451,8 +436,7 @@ env.Gs('cover.jpg','scons-scons.pdf', env.Install() - - + Installs one or more source files or directories in the specified target, which must be a directory. @@ -462,7 +446,7 @@ sources may be given as a string or as a node returned by a builder. - + env.Install('/usr/local/bin', source = ['foo', 'bar']) @@ -474,8 +458,7 @@ env.Install('/usr/local/bin', source = ['foo', 'bar']) env.InstallAs() - - + Installs one or more source files or directories to specific names, allowing changing a file or directory name @@ -486,6 +469,14 @@ and source arguments list different numbers of files or directories. + + +env.InstallAs(target = '/usr/local/bin/foo', + source = 'foo_debug') +env.InstallAs(target = ['../lib/libfoo.a', '../lib/libbar.a'], + source = ['libFOO.a', 'libBAR.a']) + + @@ -495,19 +486,21 @@ arguments list different numbers of files or directories. env.InstallVersionedLib() - - -Installs a versioned shared library. The $SHLIBVERSION + +Installs a versioned shared library. The $SHLIBVERSION construction variable should be defined in the environment to confirm the version number in the library name. +If $SHLIBVERSION is not defined a warning will be issued +and the name of the library will be parsed to derive the version. The symlinks appropriate to the architecture will be generated. - -env.InstallAs(target = '/usr/local/bin/foo', - source = 'foo_debug') -env.InstallAs(target = ['../lib/libfoo.a', '../lib/libbar.a'], - source = ['libFOO.a', 'libBAR.a']) + +env.InstallVersionedLib(target = '/usr/local/bin/foo', + source = 'libxyz.1.5.2.so') +env.InstallVersionedLib(target = '/usr/local/bin/foo', + source = 'libxyz.1.5.2.so', + SHLIBVERSION='1.5.2') @@ -518,41 +511,40 @@ env.InstallAs(target = ['../lib/libfoo.a', '../lib/libbar.a'], env.Jar() - - + Builds a Java archive (.jar) file from the specified list of sources. Any directories in the source list will be searched for .class files). Any .java files in the source list will be compiled to .class files -by calling the Java Builder. +by calling the Java Builder. - -If the $JARCHDIR value is set, the -jar + +If the $JARCHDIR value is set, the +jar command will change to the specified directory using the option. -If $JARCHDIR is not set explicitly, -SCons will use the top of any subdirectory tree +If $JARCHDIR is not set explicitly, +SCons will use the top of any subdirectory tree in which Java .class -were built by the Java Builder. +were built by the Java Builder. - + If the contents any of the source files begin with the string Manifest-Version, the file is assumed to be a manifest and is passed to the -jar +jar command with the option set. - + env.Jar(target = 'foo.jar', source = 'classes') env.Jar(target = 'bar.jar', @@ -567,8 +559,7 @@ env.Jar(target = 'bar.jar', env.Java() - - + Builds one or more Java class files. The sources may be any combination of explicit .java files, @@ -576,7 +567,7 @@ or directory trees which will be scanned for .java files. - + SCons will parse each source .java file to find the classes (including inner classes) @@ -587,7 +578,7 @@ The class files will be placed underneath the specified target directory. - + SCons will also search each Java file for the Java package name, which it assumes can be found on a line @@ -610,17 +601,17 @@ will generate a corresponding class file. - + Examples: - + env.Java(target = 'classes', source = 'src') env.Java(target = 'classes', source = ['src1', 'src2']) env.Java(target = 'classes', source = ['File1.java', 'File2.java']) - + Java source files can use the native encoding for the underlying OS. Since SCons compiles in simple ASCII mode by default, the compiler will generate warnings about unmappable characters, @@ -632,7 +623,7 @@ so that the compile will work if it is done on a system with a different encoding. - + env = Environment() env['ENV']['LANG'] = 'en_GB.UTF-8' @@ -645,8 +636,7 @@ env['ENV']['LANG'] = 'en_GB.UTF-8' env.JavaH() - - + Builds C header and source files for implementing Java native methods. The target can be either a directory @@ -656,29 +646,29 @@ will contain all of the definitions. The source can be the names of .class files, the names of .java files to be compiled into .class files -by calling the Java builder method, +by calling the Java builder method, or the objects returned from the -Java +Java builder method. - + If the construction variable -$JAVACLASSDIR +$JAVACLASSDIR is set, either in the environment or in the call to the -JavaH +JavaH builder method itself, then the value of the variable will be stripped from the beginning of any .class file names. - + Examples: - + # builds java_native.h classes = env.Java(target = 'classdir', source = 'src') env.JavaH(target = 'java_native.h', source = classes) @@ -701,10 +691,9 @@ env.JavaH(target = 'export', env.Library() - - + A synonym for the -StaticLibrary +StaticLibrary builder method. @@ -716,11 +705,10 @@ builder method. env.LoadableModule() - - + On most systems, this is the same as -SharedLibrary. +SharedLibrary. On Mac OS X (Darwin) platforms, this creates a loadable module bundle. @@ -733,10 +721,9 @@ this creates a loadable module bundle. env.M4() - - + Builds an output file from an M4 input file. -This uses a default $M4FLAGS value of +This uses a default $M4FLAGS value of , which considers all warnings to be fatal and stops on the first warning @@ -744,7 +731,7 @@ when using the GNU version of m4. Example: - + env.M4(target = 'foo.c', source = 'foo.c.m4') @@ -756,15 +743,14 @@ env.M4(target = 'foo.c', source = 'foo.c.m4') env.Moc() - - + Builds an output file from a moc input file. Moc input files are either header files or cxx files. This builder is only available after using the -tool 'qt'. See the $QTDIR variable for more information. +tool 'qt'. See the $QTDIR variable for more information. Example: - + env.Moc('foo.h') # generates moc_foo.cc env.Moc('foo.cpp') # generates foo.moc @@ -777,48 +763,47 @@ env.Moc('foo.cpp') # generates foo.moc env.MOFiles() - - -This builder belongs to msgfmt tool. The builder compiles + +This builder belongs to msgfmt tool. The builder compiles PO files to MO files. - + Example 1. Create pl.mo and en.mo by compiling pl.po and en.po: - + # ... env.MOFiles(['pl', 'en']) - + Example 2. Compile files for languages defined in LINGUAS file: - + # ... env.MOFiles(LINGUAS_FILE = 1) - + Example 3. Create pl.mo and en.mo by compiling pl.po and en.po plus files for languages defined in LINGUAS file: - + # ... env.MOFiles(['pl', 'en'], LINGUAS_FILE = 1) - + Example 4. Compile files for languages defined in LINGUAS file (another version): - + # ... env['LINGUAS_FILE'] = 1 env.MOFiles() @@ -832,17 +817,16 @@ Compile files for languages defined in LINGUAS file env.MSVSProject() - - + Builds a Microsoft Visual Studio project file, and by default builds a solution file as well. - + This builds a Visual Studio project file, based on the version of Visual Studio that is configured (either the latest installed version, or the version specified by -$MSVS_VERSION +$MSVS_VERSION in the Environment constructor). For Visual Studio 6, it will generate a .dsp @@ -852,7 +836,7 @@ For Visual Studio 7 (.NET) and later versions, it will generate a file. - + By default, this also generates a solution file for the specified project, @@ -865,16 +849,16 @@ file for Visual Studio 7 (.NET). This behavior may be disabled by specifying auto_build_solution=0 when you call -MSVSProject, +MSVSProject, in which case you presumably want to build the solution file(s) by calling the -MSVSSolution +MSVSSolution Builder (see below). - -The MSVSProject builder + +The MSVSProject builder takes several lists of filenames to be placed into the project file. These are currently limited to @@ -885,24 +869,24 @@ These are currently limited to and misc. These are pretty self-explanatory, but it should be noted that these -lists are added to the $SOURCES construction variable as strings, +lists are added to the $SOURCES construction variable as strings, NOT as SCons File Nodes. This is because they represent file names to be added to the project file, not the source files used to build the project file. - + The above filename lists are all optional, although at least one must be specified for the resulting project file to be non-empty. - + In addition to the above lists of values, the following values may be specified: - + target: The name of the target .dsp @@ -912,12 +896,12 @@ file. The correct suffix for the version of Visual Studio must be used, but the -$MSVSPROJECTSUFFIX +$MSVSPROJECTSUFFIX construction variable will be defined to the correct value (see example below). - + variant: The name of this particular variant. For Visual Studio 7 projects, @@ -933,13 +917,13 @@ character: Debug|Xbox. The default target platform is Win32. Multiple calls to -MSVSProject +MSVSProject with different variants are allowed; all variants will be added to the project file with their appropriate build targets and sources. - + buildtarget: An optional string, node, or list of strings or nodes (one per build variant), to tell the Visual Studio debugger @@ -951,7 +935,7 @@ entries must match the number of entries. - + runfile: The name of the file that Visual Studio 7 and later will run and debug. @@ -964,28 +948,28 @@ the default is the same as the specified value. - -Note that because SCons always executes its build commands -from the directory in which the SConstruct file is located, + +Note that because SCons always executes its build commands +from the directory in which the SConstruct file is located, if you generate a project file in a different directory -than the SConstruct directory, +than the SConstruct directory, users will not be able to double-click on the file name in compilation error messages displayed in the Visual Studio console output window. This can be remedied by adding the Visual C/C++ /FC -compiler option to the $CCFLAGS variable +compiler option to the $CCFLAGS variable so that the compiler will print the full path name of any files that cause compilation errors. - + Example usage: - + barsrcs = ['bar.cpp'], barincs = ['bar.h'], barlocalincs = ['StdAfx.h'] @@ -1013,17 +997,16 @@ env.MSVSProject(target = 'Bar' + env['MSVSPROJECTSUFFIX'], env.MSVSSolution() - - + Builds a Microsoft Visual Studio solution file. - + This builds a Visual Studio solution file, based on the version of Visual Studio that is configured (either the latest installed version, or the version specified by -$MSVS_VERSION +$MSVS_VERSION in the construction environment). For Visual Studio 6, it will generate a .dsw @@ -1034,19 +1017,19 @@ generate a file. - + The following values must be specified: - + target: The name of the target .dsw or .sln file. The correct suffix for the version of Visual Studio must be used, but the value -$MSVSSOLUTIONSUFFIX +$MSVSSOLUTIONSUFFIX will be defined to the correct value (see example below). - + variant: The name of this particular variant, or a list of variant names (the latter is only supported for MSVS 7 solutions). These are @@ -1055,10 +1038,10 @@ you want. For MSVS 7 they may also specify target platform, like this "Debug|Xbox". Default platform is Win32. - + projects: A list of project file names, or Project nodes returned by calls to the -MSVSProject +MSVSProject Builder, to be placed into the solution file. It should be noted that these file names are NOT added to the $SOURCES @@ -1067,11 +1050,11 @@ is because they represent file names to be added to the solution file, not the source files used to build the solution file. - + Example Usage: - + env.MSVSSolution(target = 'Bar' + env['MSVSSOLUTIONSUFFIX'], projects = ['bar' + env['MSVSPROJECTSUFFIX']], variant = 'Release') @@ -1085,10 +1068,9 @@ env.MSVSSolution(target = 'Bar' + env['MSVSSOLUTIONSUFFIX'], env.Object() - - + A synonym for the -StaticObject +StaticObject builder method. @@ -1100,41 +1082,39 @@ builder method. env.Package() - - + Builds a Binary Package of the given source files. - + env.Package(source = FindInstalledFiles()) - - + Builds software distribution packages. Packages consist of files to install and packaging information. -The former may be specified with the source parameter and may be left out, -in which case the FindInstalledFiles function will collect -all files that have an Install or InstallAs Builder attached. -If the target is not specified +The former may be specified with the source parameter and may be left out, +in which case the FindInstalledFiles function will collect +all files that have an Install or InstallAs Builder attached. +If the target is not specified it will be deduced from additional information given to this Builder. - + The packaging information is specified with the help of construction variables documented below. This information is called a tag to stress that -some of them can also be attached to files with the Tag function. +some of them can also be attached to files with the Tag function. The mandatory ones will complain if they were not specified. They vary depending on chosen target packager. - + The target packager may be selected with the "PACKAGETYPE" command line -option or with the $PACKAGETYPE construction variable. Currently +option or with the $PACKAGETYPE construction variable. Currently the following packagers available: - + * msi - Microsoft Installer * rpm - Redhat Package Manger * ipkg - Itsy Package Management System @@ -1146,11 +1126,11 @@ the following packagers available: * src_zip - zip file source - + An updated list is always available under the "package_type" option when running "scons --help" on a project that has packaging activated. - + env = Environment(tools=['default', 'packaging']) env.Install('/bin/', 'my_program') env.Package( NAME = 'foo', @@ -1173,8 +1153,7 @@ env.Package( NAME = 'foo', env.PCH() - - + Builds a Microsoft Visual C++ precompiled header. Calling this builder method returns a list of two targets: the PCH as the first element, and the object @@ -1186,7 +1165,7 @@ conjuction with the PCH construction variable to force object files to use the precompiled header: - + env['PCH'] = env.PCH('StdAfx.cpp')[0] @@ -1198,21 +1177,20 @@ env['PCH'] = env.PCH('StdAfx.cpp')[0] env.PDF() - - + Builds a .pdf file from a .dvi input file (or, by extension, a .tex, .ltx, or .latex input file). -The suffix specified by the $PDFSUFFIX construction variable +The suffix specified by the $PDFSUFFIX construction variable (.pdf by default) is added automatically to the target if it is not already present. Example: - + # builds from aaa.tex env.PDF(target = 'aaa.pdf', source = 'aaa.tex') # builds bbb.pdf from bbb.dvi @@ -1227,100 +1205,99 @@ env.PDF(target = 'bbb', source = 'bbb.dvi') env.POInit() - - -This builder belongs to msginit tool. The builder initializes missing -PO file(s) if $POAUTOINIT is set. If -$POAUTOINIT is not set (default), POInit prints instruction for + +This builder belongs to msginit tool. The builder initializes missing +PO file(s) if $POAUTOINIT is set. If +$POAUTOINIT is not set (default), POInit prints instruction for user (that is supposed to be a translator), telling how the PO file should be initialized. In normal projects -you should not use POInit and use POUpdate -instead. POUpdate chooses intelligently between -msgmerge(1) and msginit(1). POInit +you should not use POInit and use POUpdate +instead. POUpdate chooses intelligently between +msgmerge(1) and msginit(1). POInit always uses msginit(1) and should be regarded as builder for special purposes or for temporary use (e.g. for quick, one time initialization of a bunch of PO files) or for tests. - -Target nodes defined through POInit are not built by default (they're + +Target nodes defined through POInit are not built by default (they're Ignored from '.' node) but are added to special Alias ('po-create' by default). -The alias name may be changed through the $POCREATE_ALIAS +The alias name may be changed through the $POCREATE_ALIAS construction variable. All PO files defined through -POInit may be easily initialized by scons po-create. +POInit may be easily initialized by scons po-create. - + Example 1. Initialize en.po and pl.po from messages.pot: - + # ... env.POInit(['en', 'pl']) # messages.pot --> [en.po, pl.po] - + Example 2. Initialize en.po and pl.po from foo.pot: - + # ... env.POInit(['en', 'pl'], ['foo']) # foo.pot --> [en.po, pl.po] - + Example 3. Initialize en.po and pl.po from -foo.pot but using $POTDOMAIN construction +foo.pot but using $POTDOMAIN construction variable: - + # ... env.POInit(['en', 'pl'], POTDOMAIN='foo') # foo.pot --> [en.po, pl.po] - + Example 4. Initialize PO files for languages defined in LINGUAS file. The files will be initialized from template messages.pot: - + # ... env.POInit(LINGUAS_FILE = 1) # needs 'LINGUAS' file - + Example 5. Initialize en.po and pl.pl PO files plus files for languages defined in LINGUAS file. The files will be initialized from template messages.pot: - + # ... env.POInit(['en', 'pl'], LINGUAS_FILE = 1) - + Example 6. You may preconfigure your environment first, and then initialize PO files: - + # ... env['POAUTOINIT'] = 1 env['LINGUAS_FILE'] = 1 env['POTDOMAIN'] = 'foo' env.POInit() - + which has same efect as: - + # ... env.POInit(POAUTOINIT = 1, LINGUAS_FILE = 1, POTDOMAIN = 'foo') @@ -1333,21 +1310,20 @@ which has same efect as: env.PostScript() - - + Builds a .ps file from a .dvi input file (or, by extension, a .tex, .ltx, or .latex input file). -The suffix specified by the $PSSUFFIX construction variable +The suffix specified by the $PSSUFFIX construction variable (.ps by default) is added automatically to the target if it is not already present. Example: - + # builds from aaa.tex env.PostScript(target = 'aaa.ps', source = 'aaa.tex') # builds bbb.ps from bbb.dvi @@ -1362,24 +1338,23 @@ env.PostScript(target = 'bbb', source = 'bbb.dvi') env.POTUpdate() - - -The builder belongs to xgettext tool. The builder updates target + +The builder belongs to xgettext tool. The builder updates target POT file if exists or creates one if it doesn't. The node is not built by default (i.e. it is Ignored from '.'), but only on demand (i.e. when given POT file is required or when special alias is invoked). This builder adds its targe node (messages.pot, say) to a special alias (pot-update by default, see -$POTUPDATE_ALIAS) so you can update/create them easily with +$POTUPDATE_ALIAS) so you can update/create them easily with scons pot-update. The file is not written until there is no real change in internationalized messages (or in comments that enter POT file). - + You may see xgettext(1) being invoked by the -xgettext tool even if there is no real change in internationalized +xgettext tool even if there is no real change in internationalized messages (so the POT file is not being updated). This happens every time a source file has changed. In such case we invoke xgettext(1) and compare its output with the content of @@ -1387,38 +1362,38 @@ happens every time a source file has changed. In such case we invoke not. - + Example 1. Let's create po/ directory and place following SConstruct script there: - + # SConstruct in 'po/' subdir env = Environment( tools = ['default', 'xgettext'] ) env.POTUpdate(['foo'], ['../a.cpp', '../b.cpp']) env.POTUpdate(['bar'], ['../c.cpp', '../d.cpp']) - + Then invoke scons few times: - + user@host:$ scons # Does not create foo.pot nor bar.pot user@host:$ scons foo.pot # Updates or creates foo.pot user@host:$ scons pot-update # Updates or creates foo.pot and bar.pot user@host:$ scons -c # Does not clean foo.pot nor bar.pot. - + the results shall be as the comments above say. - + Example 2. -The POTUpdate builder may be used with no target specified, in which +The POTUpdate builder may be used with no target specified, in which case default target messages.pot will be used. The -default target may also be overriden by setting $POTDOMAIN construction -variable or providing it as an override to POTUpdate builder: +default target may also be overriden by setting $POTDOMAIN construction +variable or providing it as an override to POTUpdate builder: - + # SConstruct script env = Environment( tools = ['default', 'xgettext'] ) env['POTDOMAIN'] = "foo" @@ -1426,49 +1401,49 @@ variable or providing it as an override to - + Example 3. The sources may be specified within separate file, for example POTFILES.in: - + # POTFILES.in in 'po/' subdirectory ../a.cpp ../b.cpp # end of file - + The name of the file (POTFILES.in) containing the list of -sources is provided via $XGETTEXTFROM: +sources is provided via $XGETTEXTFROM: - + # SConstruct file in 'po/' subdirectory env = Environment( tools = ['default', 'xgettext'] ) env.POTUpdate(XGETTEXTFROM = 'POTFILES.in') - + Example 4. -You may use $XGETTEXTPATH to define source search path. Assume, for +You may use $XGETTEXTPATH to define source search path. Assume, for example, that you have files a.cpp, b.cpp, po/SConstruct, po/POTFILES.in. Then your POT-related files could look as below: - + # POTFILES.in in 'po/' subdirectory a.cpp b.cpp # end of file - + # SConstruct file in 'po/' subdirectory env = Environment( tools = ['default', 'xgettext'] ) env.POTUpdate(XGETTEXTFROM = 'POTFILES.in', XGETTEXTPATH='../') - + Example 5. Multiple search directories may be defined within a list, i.e. XGETTEXTPATH = ['dir1', 'dir2', ...]. The order in the list @@ -1476,48 +1451,48 @@ determines the search order of source files. The path to the first file found is used. - + Let's create 0/1/po/SConstruct script: - + # SConstruct file in '0/1/po/' subdirectory env = Environment( tools = ['default', 'xgettext'] ) env.POTUpdate(XGETTEXTFROM = 'POTFILES.in', XGETTEXTPATH=['../', '../../']) - + and 0/1/po/POTFILES.in: - + # POTFILES.in in '0/1/po/' subdirectory a.cpp # end of file - + Write two *.cpp files, the first one is 0/a.cpp: - + /* 0/a.cpp */ gettext("Hello from ../../a.cpp") - + and the second is 0/1/a.cpp: - + /* 0/1/a.cpp */ gettext("Hello from ../a.cpp") - + then run scons. You'll obtain 0/1/po/messages.pot with the message "Hello from ../a.cpp". When you reverse order in $XGETTEXTFOM, i.e. when you write SConscript as - + # SConstruct file in '0/1/po/' subdirectory env = Environment( tools = ['default', 'xgettext'] ) env.POTUpdate(XGETTEXTFROM = 'POTFILES.in', XGETTEXTPATH=['../../', '../']) - + then the messages.pot will contain msgid "Hello from ../../a.cpp" line and not msgid "Hello from ../a.cpp". @@ -1532,107 +1507,106 @@ then the messages.pot will contain env.POUpdate() - - -The builder belongs to msgmerge tool. The builder updates + +The builder belongs to msgmerge tool. The builder updates PO files with msgmerge(1), or initializes missing PO files as described in documentation of -msginit tool and POInit builder (see also -$POAUTOINIT). Note, that POUpdate does not add its -targets to po-create alias as POInit +msginit tool and POInit builder (see also +$POAUTOINIT). Note, that POUpdate does not add its +targets to po-create alias as POInit does. - -Target nodes defined through POUpdate are not built by default + +Target nodes defined through POUpdate are not built by default (they're Ignored from '.' node). Instead, they are added automatically to special Alias ('po-update' by default). The alias name may be changed -through the $POUPDATE_ALIAS construction variable. You can easilly +through the $POUPDATE_ALIAS construction variable. You can easilly update PO files in your project by scons po-update. - + Example 1. Update en.po and pl.po from -messages.pot template (see also $POTDOMAIN), +messages.pot template (see also $POTDOMAIN), assuming that the later one exists or there is rule to build it (see -POTUpdate): +POTUpdate): - + # ... env.POUpdate(['en','pl']) # messages.pot --> [en.po, pl.po] - + Example 2. Update en.po and pl.po from foo.pot template: - + # ... env.POUpdate(['en', 'pl'], ['foo']) # foo.pot --> [en.po, pl.pl] - + Example 3. Update en.po and pl.po from foo.pot (another version): - + # ... env.POUpdate(['en', 'pl'], POTDOMAIN='foo') # foo.pot -- > [en.po, pl.pl] - + Example 4. Update files for languages defined in LINGUAS file. The files are updated from messages.pot template: - + # ... env.POUpdate(LINGUAS_FILE = 1) # needs 'LINGUAS' file - + Example 5. Same as above, but update from foo.pot template: - + # ... env.POUpdate(LINGUAS_FILE = 1, source = ['foo']) - + Example 6. Update en.po and pl.po plus files for languages defined in LINGUAS file. The files are updated from messages.pot template: - + # produce 'en.po', 'pl.po' + files defined in 'LINGUAS': env.POUpdate(['en', 'pl' ], LINGUAS_FILE = 1) - + Example 7. -Use $POAUTOINIT to automatically initialize PO file +Use $POAUTOINIT to automatically initialize PO file if it doesn't exist: - + # ... env.POUpdate(LINGUAS_FILE = 1, POAUTOINIT = 1) - + Example 8. Update PO files for languages defined in LINGUAS file. The files are updated from foo.pot template. All necessary settings are pre-configured via environment. - + # ... env['POAUTOINIT'] = 1 env['LINGUAS_FILE'] = 1 @@ -1649,29 +1623,28 @@ pre-configured via environment. env.Program() - - + Builds an executable given one or more object files or C, C++, D, or Fortran source files. If any C, C++, D or Fortran source files are specified, then they will be automatically compiled to object files using the -Object +Object builder method; see that builder method's description for a list of legal source file suffixes and how they are interpreted. The target executable file prefix -(specified by the $PROGPREFIX construction variable; nothing by default) +(specified by the $PROGPREFIX construction variable; nothing by default) and suffix -(specified by the $PROGSUFFIX construction variable; +(specified by the $PROGSUFFIX construction variable; by default, .exe on Windows systems, nothing on POSIX systems) are automatically added to the target if not already present. Example: - + env.Program(target = 'foo', source = ['foo.o', 'bar.c', 'baz.f']) @@ -1683,8 +1656,7 @@ env.Program(target = 'foo', source = ['foo.o', 'bar.c', 'baz.f']) env.RES() - - + Builds a Microsoft Visual C++ resource file. This builder method is only provided when Microsoft Visual C++ or MinGW is being used as the compiler. The @@ -1697,7 +1669,7 @@ file is scanned for implicit dependencies as though it were a C file. Example: - + env.RES('resource.rc') @@ -1709,8 +1681,7 @@ env.RES('resource.rc') env.RMIC() - - + Builds stub and skeleton class files for remote objects from Java .class files. @@ -1719,16 +1690,16 @@ relative to which the stub and skeleton class files will be written. The source can be the names of .class files, or the objects return from the -Java +Java builder method. - + If the construction variable -$JAVACLASSDIR +$JAVACLASSDIR is set, either in the environment or in the call to the -RMIC +RMIC builder method itself, then the value of the variable will be stripped from the @@ -1736,7 +1707,7 @@ beginning of any .class file names. - + classes = env.Java(target = 'classdir', source = 'src') env.RMIC(target = 'outdir1', source = classes) @@ -1756,8 +1727,7 @@ env.RMIC(target = 'outdir3', env.RPCGenClient() - - + Generates an RPC client stub (_clnt.c) file from a specified RPC (.x) source file. Because rpcgen only builds output files @@ -1766,7 +1736,7 @@ the command will be executed in the source file's directory by default. - + # Builds src/rpcif_clnt.c env.RPCGenClient('src/rpcif.x') @@ -1779,8 +1749,7 @@ env.RPCGenClient('src/rpcif.x') env.RPCGenHeader() - - + Generates an RPC header (.h) file from a specified RPC (.x) source file. Because rpcgen only builds output files @@ -1789,7 +1758,7 @@ the command will be executed in the source file's directory by default. - + # Builds src/rpcif.h env.RPCGenHeader('src/rpcif.x') @@ -1802,8 +1771,7 @@ env.RPCGenHeader('src/rpcif.x') env.RPCGenService() - - + Generates an RPC server-skeleton (_svc.c) file from a specified RPC (.x) source file. Because rpcgen only builds output files @@ -1812,7 +1780,7 @@ the command will be executed in the source file's directory by default. - + # Builds src/rpcif_svc.c env.RPCGenClient('src/rpcif.x') @@ -1825,8 +1793,7 @@ env.RPCGenClient('src/rpcif.x') env.RPCGenXDR() - - + Generates an RPC XDR routine (_xdr.c) file from a specified RPC (.x) source file. Because rpcgen only builds output files @@ -1835,7 +1802,7 @@ the command will be executed in the source file's directory by default. - + # Builds src/rpcif_xdr.c env.RPCGenClient('src/rpcif.x') @@ -1848,8 +1815,7 @@ env.RPCGenClient('src/rpcif.x') env.SharedLibrary() - - + Builds a shared library (.so on a POSIX system, .dll on Windows) @@ -1861,24 +1827,24 @@ compiled to object files. The static library prefix and suffix (if any) are automatically added to the target. The target library file prefix -(specified by the $SHLIBPREFIX construction variable; +(specified by the $SHLIBPREFIX construction variable; by default, lib on POSIX systems, nothing on Windows systems) and suffix -(specified by the $SHLIBSUFFIX construction variable; +(specified by the $SHLIBSUFFIX construction variable; by default, .dll on Windows systems, .so on POSIX systems) are automatically added to the target if not already present. Example: - + env.SharedLibrary(target = 'bar', source = ['bar.c', 'foo.o']) - + On Windows systems, the -SharedLibrary +SharedLibrary builder method will always build an import (.lib) library in addition to the shared (.dll) library, @@ -1887,9 +1853,9 @@ if there is not already a .lib file explicitly listed in the targets. - + On Cygwin systems, the -SharedLibrary +SharedLibrary builder method will always build an import (.dll.a) library in addition to the shared (.dll) library, @@ -1898,34 +1864,39 @@ if there is not already a .dll.a file explicitly listed in the targets. - + Any object files listed in the source must have been built for a shared library (that is, using the -SharedObject +SharedObject builder method). -scons +scons will raise an error if there is any mismatch. - + On some platforms, there is a distinction between a shared library (loaded automatically by the system to resolve external references) and a loadable module (explicitly loaded by user action). -For maximum portability, use the LoadableModule builder for the latter. +For maximum portability, use the LoadableModule builder for the latter. - -When the $SHLIBVERSION construction variable is defined a versioned -shared library is created. This modifies the $SHLINKFLAGS as required, + +When the $SHLIBVERSION construction variable is defined a versioned +shared library is created. This modifies the $SHLINKFLAGS as required, adds the version number to the library name, and creates the symlinks that -are needed. $SHLIBVERSION needs to be of the form X.Y.Z, where X +are needed. $SHLIBVERSION needs to be of the form X.Y.Z, where X and Y are numbers, and Z is a number but can also contain letters to designate alpha, beta, or release candidate patch levels. - + +env.SharedLibrary(target = 'bar', source = ['bar.c', 'foo.o'], SHLIBVERSION='1.5.2') + + + + This builder may create multiple links to the library. On a POSIX system, for the shared library libbar.so.2.3.1, the links created would be libbar.so and libbar.so.2; on a Darwin (OSX) system @@ -1933,28 +1904,28 @@ the library would be libbar.2.3.1.dylib and the link would be libbar.dylib. - + On Windows systems, specifying register=1 will cause the .dll to be registered after it is built using REGSVR32. The command that is run -("regsvr32" by default) is determined by $REGSVR construction -variable, and the flags passed are determined by $REGSVRFLAGS. By -default, $REGSVRFLAGS includes the option, +("regsvr32" by default) is determined by $REGSVR construction +variable, and the flags passed are determined by $REGSVRFLAGS. By +default, $REGSVRFLAGS includes the option, to prevent dialogs from popping up and requiring user attention when it is run. If you change -$REGSVRFLAGS, be sure to include the option. +$REGSVRFLAGS, be sure to include the option. For example, - + env.SharedLibrary(target = 'bar', source = ['bar.cxx', 'foo.obj'], register=1) - + will register bar.dll as a COM object when it is done linking it. @@ -1967,13 +1938,12 @@ when it is done linking it. env.SharedObject() - - + Builds an object file for inclusion in a shared library. Source files must have one of the same set of extensions specified above for the -StaticObject +StaticObject builder method. On some platforms building a shared object requires additional compiler option @@ -1988,21 +1958,21 @@ and shared objects to be linked into a shared library, and will use the same suffix for shared and normal (static) objects. The target object file prefix -(specified by the $SHOBJPREFIX construction variable; -by default, the same as $OBJPREFIX) +(specified by the $SHOBJPREFIX construction variable; +by default, the same as $OBJPREFIX) and suffix -(specified by the $SHOBJSUFFIX construction variable) +(specified by the $SHOBJSUFFIX construction variable) are automatically added to the target if not already present. Examples: - + env.SharedObject(target = 'ddd', source = 'ddd.c') env.SharedObject(target = 'eee.o', source = 'eee.cpp') env.SharedObject(target = 'fff.obj', source = 'fff.for') - + Note that the source files will be scanned according to the suffix mappings in the SourceFileScanner @@ -2019,8 +1989,7 @@ below, for more information. env.StaticLibrary() - - + Builds a static library given one or more object files or C, C++, D or Fortran source files. If any source files are given, @@ -2029,29 +1998,29 @@ compiled to object files. The static library prefix and suffix (if any) are automatically added to the target. The target library file prefix -(specified by the $LIBPREFIX construction variable; +(specified by the $LIBPREFIX construction variable; by default, lib on POSIX systems, nothing on Windows systems) and suffix -(specified by the $LIBSUFFIX construction variable; +(specified by the $LIBSUFFIX construction variable; by default, .lib on Windows systems, .a on POSIX systems) are automatically added to the target if not already present. Example: - + env.StaticLibrary(target = 'bar', source = ['bar.c', 'foo.o']) - + Any object files listed in the source must have been built for a static library (that is, using the -StaticObject +StaticObject builder method). -scons +scons will raise an error if there is any mismatch. @@ -2063,14 +2032,13 @@ will raise an error if there is any mismatch. env.StaticObject() - - + Builds a static object file from one or more C, C++, D, or Fortran source files. Source files must have one of the following extensions: - + .asm assembly language file .ASM assembly language file .c C file @@ -2101,24 +2069,24 @@ Source files must have one of the following extensions: .SPP assembly language file + C pre-processor - + The target object file prefix -(specified by the $OBJPREFIX construction variable; nothing by default) +(specified by the $OBJPREFIX construction variable; nothing by default) and suffix -(specified by the $OBJSUFFIX construction variable; +(specified by the $OBJSUFFIX construction variable; .obj on Windows systems, .o on POSIX systems) are automatically added to the target if not already present. Examples: - + env.StaticObject(target = 'aaa', source = 'aaa.c') env.StaticObject(target = 'bbb.o', source = 'bbb.c++') env.StaticObject(target = 'ccc.obj', source = 'ccc.f') - + Note that the source files will be scanned according to the suffix mappings in SourceFileScanner @@ -2135,28 +2103,27 @@ below, for more information. env.Substfile() - - -The Substfile builder creates a single text file from another file or set of -files by concatenating them with $LINESEPARATOR and replacing text -using the $SUBST_DICT construction variable. Nested lists of source files -are flattened. See also Textfile. + +The Substfile builder creates a single text file from another file or set of +files by concatenating them with $LINESEPARATOR and replacing text +using the $SUBST_DICT construction variable. Nested lists of source files +are flattened. See also Textfile. - + If a single source file is present with an .in suffix, the suffix is stripped and the remainder is used as the default target name. - -The prefix and suffix specified by the $SUBSTFILEPREFIX -and $SUBSTFILESUFFIX construction variables + +The prefix and suffix specified by the $SUBSTFILEPREFIX +and $SUBSTFILESUFFIX construction variables (the null string by default in both cases) are automatically added to the target if they are not already present. - -If a construction variable named $SUBST_DICT is present, + +If a construction variable named $SUBST_DICT is present, it may be either a Python dictionary or a sequence of (key,value) tuples. If it is a dictionary it is converted into a list of tuples in an arbitrary order, so if one key is a prefix of another key @@ -2164,7 +2131,7 @@ or if one substitution could be further expanded by another subsitition, it is unpredictable whether the expansion will occur. - + Any occurrences of a key in the source are replaced by the corresponding value, which may be a Python callable function or a string. @@ -2173,7 +2140,7 @@ Strings are subst-expanded and the result replaces the key. - + env = Environment(tools = ['default', 'textfile']) env['prefix'] = '/usr/bin' @@ -2225,13 +2192,12 @@ subst.Substfile('pgm2.c', [Value('#include "@foo@.h"'), env.Tar() - - + Builds a tar archive of the specified files and/or directories. Unlike most builder methods, the -Tar +Tar builder method may be called multiple times for a given target; each additional call @@ -2241,11 +2207,11 @@ Any source directories will be scanned for changes to any on-disk files, regardless of whether or not -scons +scons knows about them from other Builder or function calls. - + env.Tar('src.tar', 'src') # Create the stuff.tar file. @@ -2271,29 +2237,28 @@ env.Tar('foo') env.Textfile() - - -The Textfile builder generates a single text file. + +The Textfile builder generates a single text file. The source strings constitute the lines; nested lists of sources are flattened. -$LINESEPARATOR is used to separate the strings. +$LINESEPARATOR is used to separate the strings. - -If present, the $SUBST_DICT construction variable + +If present, the $SUBST_DICT construction variable is used to modify the strings before they are written; -see the Substfile description for details. +see the Substfile description for details. - -The prefix and suffix specified by the $TEXTFILEPREFIX -and $TEXTFILESUFFIX construction variables + +The prefix and suffix specified by the $TEXTFILEPREFIX +and $TEXTFILESUFFIX construction variables (the null string and .txt by default, respectively) are automatically added to the target if they are not already present. Examples: - + # builds/writes foo.txt env.Textfile(target = 'foo.txt', source = ['Goethe', 42, 'Schiller']) @@ -2342,50 +2307,49 @@ blob.txt env.Translate() - - -This pseudo-builder belongs to gettext toolset. The builder extracts + +This pseudo-builder belongs to gettext toolset. The builder extracts internationalized messages from source files, updates POT template (if necessary) and then updates PO translations (if -necessary). If $POAUTOINIT is set, missing PO files +necessary). If $POAUTOINIT is set, missing PO files will be automatically created (i.e. without translator person intervention). -The variables $LINGUAS_FILE and $POTDOMAIN are taken into -acount too. All other construction variables used by POTUpdate, and -POUpdate work here too. +The variables $LINGUAS_FILE and $POTDOMAIN are taken into +acount too. All other construction variables used by POTUpdate, and +POUpdate work here too. - + Example 1. The simplest way is to specify input files and output languages inline in -a SCons script when invoking Translate +a SCons script when invoking Translate - + # SConscript in 'po/' directory env = Environment( tools = ["default", "gettext"] ) env['POAUTOINIT'] = 1 env.Translate(['en','pl'], ['../a.cpp','../b.cpp']) - + Example 2. If you wish, you may also stick to conventional style known from autotools, i.e. using POTFILES.in and LINGUAS files - + # LINGUAS en pl #end - + # POTFILES.in a.cpp b.cpp # end - + # SConscript env = Environment( tools = ["default", "gettext"] ) env['POAUTOINIT'] = 1 @@ -2393,7 +2357,7 @@ env['XGETTEXTPATH'] = ['../'] env.Translate(LINGUAS_FILE = 1, XGETTEXTFROM = 'POTFILES.in') - + The last approach is perhaps the recommended one. It allows easily split internationalization/localization onto separate SCons scripts, where a script in source tree is responsible for translations (from sources to @@ -2410,11 +2374,11 @@ so the source tree looks familiar to translators, and they may work with the project in their usual way. - + Example 3. Let's prepare a development tree as below - + project/ + SConstruct + build/ @@ -2425,11 +2389,11 @@ Let's prepare a development tree as below + POTFILES.in + LINGUAS - + with build being variant directory. Write the top-level SConstruct script as follows - + # SConstruct env = Environment( tools = ["default", "gettext"] ) VariantDir('build', 'src', duplicate = 0) @@ -2437,23 +2401,23 @@ with build being variant directory. Write the top-level SConscript('src/po/SConscript.i18n', exports = 'env') SConscript('build/po/SConscript', exports = 'env') - + the src/po/SConscript.i18n as - + # src/po/SConscript.i18n Import('env') env.Translate(LINGUAS_FILE=1, XGETTEXTFROM='POTFILES.in', XGETTEXTPATH=['../']) - + and the src/po/SConscript - + # src/po/SConscript Import('env') env.MOFiles(LINGUAS_FILE = 1) - + Such setup produces POT and PO files under source tree in src/po/ and binary MO files under variant tree in @@ -2463,7 +2427,7 @@ not be committed back to source repositories (e.g. MO files). - + In above example, the PO files are not updated, nor created automatically when you issue scons '.' command. The files must be updated (created) by hand via scons @@ -2480,8 +2444,7 @@ running scons '.'. env.TypeLibrary() - - + Builds a Windows type library (.tlb) file from an input IDL file (.idl). In addition, it will build the associated inteface stub and @@ -2490,11 +2453,11 @@ naming them according to the base name of the .idl file. For example, - + env.TypeLibrary(source="foo.idl") - + Will create foo.tlb, foo.h, foo_i.c, @@ -2512,22 +2475,21 @@ files. env.Uic() - - + Builds a header file, an implementation file and a moc file from an ui file. and returns the corresponding nodes in the above order. This builder is only available after using the tool 'qt'. Note: you can specify .ui files directly as source -files to the Program, -Library and SharedLibrary builders +files to the Program, +Library and SharedLibrary builders without using this builder. Using this builder lets you override the standard naming conventions (be careful: prefixes are always prepended to names of built files; if you don't want prefixes, you may set them to ``). -See the $QTDIR variable for more information. +See the $QTDIR variable for more information. Example: - + env.Uic('foo.ui') # -> ['foo.h', 'uic_foo.cc', 'moc_foo.cc'] env.Uic(target = Split('include/foo.h gen/uicfoo.cc gen/mocfoo.cc'), source = 'foo.ui') # -> ['include/foo.h', 'gen/uicfoo.cc', 'gen/mocfoo.cc'] @@ -2541,13 +2503,12 @@ env.Uic(target = Split('include/foo.h gen/uicfoo.cc gen/mocfoo.cc'), env.Zip() - - + Builds a zip archive of the specified files and/or directories. Unlike most builder methods, the -Zip +Zip builder method may be called multiple times for a given target; each additional call @@ -2557,11 +2518,11 @@ Any source directories will be scanned for changes to any on-disk files, regardless of whether or not -scons +scons knows about them from other Builder or function calls. - + env.Zip('src.zip', 'src') # Create the stuff.zip file. diff --git a/doc/generated/functions.gen b/doc/generated/functions.gen index 62a9ab3..b1f1cbe 100644 --- a/doc/generated/functions.gen +++ b/doc/generated/functions.gen @@ -1,4 +1,4 @@ - + %scons; @@ -12,7 +12,7 @@ %variables-mod; ]> - + Action(action, [cmd/str/fun, [var, ...]] [option=value, ...]) @@ -20,8 +20,7 @@ env.Action(action, [cmd/str/fun, [var, ...]] [option=value, ...]) - - + Creates an Action object for the specified action. @@ -29,7 +28,7 @@ See the section "Action Objects," below, for a complete explanation of the arguments and behavior. - + Note that the env.Action() form of the invocation will expand @@ -56,8 +55,7 @@ until the Action object is actually used. env.AddMethod(function, [name]) - - + When called with the AddMethod() form, @@ -86,11 +84,11 @@ specified itself is used for the method name. - + Examples: - + # Note that the first argument to the function to # be attached as a method must be the object through # which the method will be called; the Python @@ -116,8 +114,7 @@ env.other_method_name('another arg') AddOption(arguments) - - + This function adds a new command-line option to be recognized. The specified arguments @@ -129,12 +126,12 @@ see the documentation for for a thorough discussion of its option-processing capabities. - + In addition to the arguments and values supported by the optparse.add_option() method, the SCons -AddOption +AddOption function allows you to set the nargs keyword value to @@ -146,7 +143,7 @@ argument. When nargs = '?' is passed to the -AddOption +AddOption function, the const keyword argument @@ -156,28 +153,28 @@ option is specified on the command line without an explicit argument. - + If no default= keyword argument is supplied when calling -AddOption, +AddOption, the option will have a default value of None. - + Once a new command-line option has been added with -AddOption, +AddOption, the option value may be accessed using -GetOption +GetOption or env.GetOption(). The value may also be set, using -SetOption +SetOption or env.SetOption(), if conditions in a -SConscript +SConscript require overriding any default value. Note, however, that a value specified on the command line will @@ -185,7 +182,7 @@ value specified on the command line will override a value set by any SConscript file. - + Any specified help= strings for the new option(s) @@ -197,22 +194,22 @@ options (the latter only if no other help text is specified in the SConscript files). The help text for the local options specified by -AddOption +AddOption will appear below the SCons options themselves, under a separate Local Options heading. The options will appear in the help text in the order in which the -AddOption +AddOption calls occur. - + Example: - + AddOption('--prefix', dest='prefix', nargs=1, type='string', @@ -230,8 +227,7 @@ env = Environment(PREFIX = GetOption('prefix')) env.AddPostAction(target, action) - - + Arranges for the specified action to be performed @@ -244,7 +240,7 @@ can be converted into an Action object (see below). - + When multiple targets are supplied, the action may be called multiple times, once after each action that generates @@ -259,8 +255,7 @@ one or more targets in the list. env.AddPreAction(target, action) - - + Arranges for the specified action to be performed @@ -273,14 +268,14 @@ can be converted into an Action object (see below). - + When multiple targets are specified, the action(s) may be called multiple times, once before each action that generates one or more targets in the list. - + Note that if any of the targets are built in multiple steps, the action will be invoked just before the "final" action that specifically @@ -291,16 +286,16 @@ from a specified source file via an intermediate object file: - + foo = Program('foo.c') AddPreAction(foo, 'pre_action') - + The specified pre_action would be executed before -scons +scons calls the link command that actually generates the executable program binary foo, @@ -317,8 +312,7 @@ file into an object file. env.Alias(alias, [targets, [action]]) - - + Creates one or more phony targets that expand to one or more other targets. An optional @@ -332,17 +326,17 @@ which exists outside of any file system. This Node object, or the alias name, may be used as a dependency of any other target, including another alias. -Alias +Alias can be called multiple times for the same alias to add additional targets to the alias, or additional actions to the list for this alias. - + Examples: - + Alias('install') Alias('install', '/usr/bin') Alias(['install', 'install-lib'], '/usr/local/lib') @@ -358,8 +352,7 @@ env.Alias('update', ['file1', 'file2'], "update_database $SOURCES") AllowSubstExceptions([exception, ...]) - - + Specifies the exceptions that will be allowed when expanding construction variables. By default, @@ -375,19 +368,19 @@ will generate an error message and terminate processing. - + If -AllowSubstExceptions +AllowSubstExceptions is called multiple times, each call completely overwrites the previous list of allowed exceptions. - + Example: - + # Requires that all construction variable names exist. # (You may wish to do this if you want to enforce strictly # that all construction variables must be defined before use.) @@ -406,14 +399,13 @@ AllowSubstExceptions(IndexError, NameError, ZeroDivisionError) env.AlwaysBuild(target, ...) - - + Marks each given target so that it is always assumed to be out of date, and will always be rebuilt if needed. Note, however, that -AlwaysBuild +AlwaysBuild does not add its target(s) to the default target list, so the targets will only be built if they are specified on the command line, @@ -422,7 +414,7 @@ they will always be built if so specified. Multiple targets can be passed in to a single call to -AlwaysBuild. +AlwaysBuild. @@ -430,8 +422,7 @@ Multiple targets can be passed in to a single call to env.Append(key=val, [...]) - - + Appends the specified keyword arguments to the end of construction variables in the environment. If the Environment does not have @@ -447,11 +438,11 @@ and the lists are added together. (See also the Prepend method, below.) - + Example: - + env.Append(CCFLAGS = ' -g', FOO = ['foo.yyy']) @@ -460,8 +451,7 @@ env.Append(CCFLAGS = ' -g', FOO = ['foo.yyy']) env.AppendENVPath(name, newpath, [envname, sep, delete_existing]) - - + This appends new path elements to the given path in the specified external environment (ENV @@ -479,18 +469,18 @@ case where the given old path variable is a list instead of a string, in which case a list will be returned instead of a string. - + If delete_existing is 0, then adding a path that already exists will not move it to the end; it will stay where it is in the list. - + Example: - + print 'before:',env['ENV']['INCLUDE'] include_path = '/foo/bar:/foo' env.AppendENVPath('INCLUDE', include_path) @@ -506,8 +496,7 @@ after: /biz:/foo/bar:/foo env.AppendUnique(key=val, [...], delete_existing=0) - - + Appends the specified keyword arguments to the end of construction variables in the environment. If the Environment does not have @@ -523,11 +512,11 @@ existing matching values are removed first, so existing values in the arg list move to the end of the list. - + Example: - + env.AppendUnique(CCFLAGS = '-g', FOO = ['foo.yyy']) @@ -536,29 +525,28 @@ env.AppendUnique(CCFLAGS = '-g', FOO = ['foo.yyy']) env.BitKeeper() - - + A factory function that returns a Builder object to be used to fetch source files using BitKeeper. The returned Builder is intended to be passed to the -SourceCode +SourceCode function. - + This function is deprecated. For details, see the entry for the -SourceCode +SourceCode function. - + Example: - + env.SourceCode('.', env.BitKeeper()) @@ -570,10 +558,9 @@ env.SourceCode('.', env.BitKeeper()) env.BuildDir(build_dir, src_dir, [duplicate]) - - + Deprecated synonyms for -VariantDir +VariantDir and env.VariantDir(). The @@ -581,7 +568,7 @@ The argument becomes the variant_dir argument of -VariantDir +VariantDir or env.VariantDir(). @@ -594,8 +581,7 @@ or env.Builder(action, [arguments]) - - + Creates a Builder object for the specified action. @@ -603,7 +589,7 @@ See the section "Builder Objects," below, for a complete explanation of the arguments and behavior. - + Note that the env.Builder() form of the invocation will expand @@ -618,7 +604,7 @@ construction environment through which env.Builder() was called. The -Builder +Builder form delays all variable expansion until after the Builder object is actually called. @@ -631,15 +617,14 @@ until after the Builder object is actually called. env.CacheDir(cache_dir) - - + Specifies that -scons +scons will maintain a cache of derived files in cache_dir. The derived files in the cache will be shared among all the builds using the same -CacheDir +CacheDir call. Specifying a cache_dir @@ -648,13 +633,13 @@ of disables derived file caching. - + Calling env.CacheDir() will only affect targets built through the specified construction environment. Calling -CacheDir +CacheDir sets a global default that will be used by all targets built through construction environments @@ -665,21 +650,21 @@ have an specified. - + When a CacheDir() is being used and -scons +scons finds a derived file that needs to be rebuilt, it will first look in the cache to see if a derived file has already been built from identical input files and an identical build action (as incorporated into the MD5 build signature). If so, -scons +scons will retrieve the file from the cache. If the derived file is not present in the cache, -scons +scons will rebuild it and then place a copy of the built file in the cache (identified by its MD5 build signature), @@ -688,20 +673,20 @@ builds that need to build the same derived file from identical inputs. - + Use of a specified -CacheDir +CacheDir may be disabled for any invocation by using the option. - + If the option is used, -scons +scons will place a copy of all derived files in the cache, @@ -709,17 +694,17 @@ even if they already existed and were not built by this invocation. This is useful to populate a cache the first time -CacheDir +CacheDir is added to a build, or after using the option. - + When using -CacheDir, -scons +CacheDir, +scons will report, "Retrieved `file' from cache," unless the @@ -728,7 +713,7 @@ option is being used. When the option is used, -scons +scons will print the action that would have been used to build the file, @@ -740,9 +725,9 @@ a given derived file has been built in-place or retrieved from the cache. - + The -NoCache +NoCache method can be used to disable caching of specific files. This can be useful if inputs and/or outputs of some tool are impossible to predict or prohibitively large. @@ -756,8 +741,7 @@ predict or prohibitively large. env.Clean(targets, files_or_dirs) - - + This specifies a list of files or directories which should be removed whenever the targets are specified with the @@ -765,28 +749,28 @@ command line option. The specified targets may be a list or an individual target. Multiple calls to -Clean +Clean are legal, and create new targets or add files and directories to the clean list for the specified targets. - + Multiple files or directories should be specified either as separate arguments to the -Clean +Clean method, or as a list. -Clean +Clean will also accept the return value of any of the construction environment Builder methods. Examples: - + The related -NoClean +NoClean function overrides calling -Clean +Clean for the same target, and any targets passed to both functions will not @@ -795,23 +779,23 @@ be removed by the option. - + Examples: - + Clean('foo', ['bar', 'baz']) Clean('dist', env.Program('hello', 'hello.c')) Clean(['foo', 'bar'], 'something_else_to_clean') - + In this example, installing the project creates a subdirectory for the documentation. This statement causes the subdirectory to be removed if the project is deinstalled. - + Clean(docdir, os.path.join(docdir, projectname)) @@ -820,8 +804,7 @@ Clean(docdir, os.path.join(docdir, projectname)) env.Clone([key=val, ...]) - - + Returns a separate copy of a construction environment. If there are any keyword arguments specified, they are added to the returned copy, @@ -829,32 +812,32 @@ overwriting any existing values for the keywords. - + Example: - + env2 = env.Clone() env3 = env.Clone(CCFLAGS = '-g') - + Additionally, a list of tools and a toolpath may be specified, as in the Environment constructor: - + def MyTool(env): env['FOO'] = 'bar' env4 = env.Clone(tools = ['msvc', MyTool]) - + The parse_flags keyword argument is also recognized: - + # create an environment for compiling programs that use wxWidgets wx_env = env.Clone(parse_flags = '!wx-config --cflags --cxxflags') @@ -867,8 +850,7 @@ wx_env = env.Clone(parse_flags = '!wx-config --cflags --cxxflags') env.Command(target, source, action, [key=val, ...]) - - + Executes a specific action (or list of actions) to build a target file or files. @@ -877,7 +859,7 @@ than defining a separate Builder object for a single special-case build. - + As a special case, the source_scanner keyword argument can @@ -893,12 +875,12 @@ changes to files that aren't already specified in other Builder of function calls.) - + Any other keyword arguments specified override any same-named existing construction variables. - + An action can be an external command, specified as a string, or a callable Python object; @@ -915,11 +897,11 @@ or by a to ignore the exit status of the external command. - + Examples: - + env.Command('foo.out', 'foo.in', "$FOO_BUILD < $SOURCES > $TARGET") @@ -937,9 +919,9 @@ env.Command('baz.out', 'baz.in', rename ]) - + Note that the -Command +Command function will usually assume, by default, that the specified targets and/or sources are Files, if no other part of the configuration @@ -948,24 +930,24 @@ If necessary, you can explicitly specify that targets or source nodes should be treated as directoriese by using the -Dir +Dir or env.Dir() functions. - + Examples: - + env.Command('ddd.list', Dir('ddd'), 'ls -l $SOURCE > $TARGET') env['DISTDIR'] = 'destination/directory' env.Command(env.Dir('$DISTDIR')), None, make_distdir) - + (Also note that SCons will usually automatically create any directory necessary to hold a target file, so you normally don't need to create directories by hand.) @@ -979,8 +961,7 @@ so you normally don't need to create directories by hand.) env.Configure([custom_tests, conf_dir, log_file, config_h]) - - + Creates a Configure object for integrated functionality similar to GNU autoconf. See the section "Configure Contexts," @@ -992,8 +973,7 @@ below, for a complete explanation of the arguments and behavior. env.Copy([key=val, ...]) - - + A now-deprecated synonym for env.Clone(). @@ -1003,8 +983,7 @@ A now-deprecated synonym for env.CVS(repository, module) - - + A factory function that returns a Builder object to be used to fetch source files @@ -1013,17 +992,17 @@ CVS repository. The returned Builder is intended to be passed to the -SourceCode +SourceCode function. - + This function is deprecated. For details, see the entry for the -SourceCode +SourceCode function. - + The optional specified module will be added to the beginning @@ -1037,11 +1016,11 @@ directory hierarchy in your local build directory. - + Examples: - + # Will fetch foo/bar/src.c # from /usr/local/CVSROOT/foo/bar/src.c. env.SourceCode('.', env.CVS('/usr/local/CVSROOT')) @@ -1063,8 +1042,7 @@ env.SourceCode('.', env.CVS('/usr/local/CVSROOT', 'foo/bar')) env.Decider(function) - - + Specifies that all up-to-date decisions for targets built through this construction environment will be handled by the specified @@ -1076,7 +1054,7 @@ that specify the type of decision function to be performed: - + timestamp-newer @@ -1159,11 +1137,11 @@ all within a single second. - + Examples: - + # Use exact timestamp matches by default. Decider('timestamp-match') @@ -1172,7 +1150,7 @@ Decider('timestamp-match') env.Decider('content') - + In addition to the above already-available functions, the function @@ -1180,7 +1158,7 @@ argument may be an actual Python function that takes the following three arguments: - + dependency @@ -1228,7 +1206,7 @@ size, or content signature. - + The function should return a @@ -1256,11 +1234,11 @@ Ignoring some or all of the function arguments is perfectly normal. - + Example: - + def my_decider(dependency, target, prev_ni): return not os.path.exists(str(target)) @@ -1275,55 +1253,54 @@ env.Decider(my_decider) env.Default(targets) - - + This specifies a list of default targets, which will be built by -scons +scons if no explicit targets are given on the command line. Multiple calls to -Default +Default are legal, and add to the list of default targets. - + Multiple targets should be specified as separate arguments to the -Default +Default method, or as a list. -Default +Default will also accept the Node returned by any of a construction environment's builder methods. - + Examples: - + Default('foo', 'bar', 'baz') env.Default(['a', 'b', 'c']) hello = env.Program('hello', 'hello.c') env.Default(hello) - + An argument to -Default +Default of None will clear all default targets. Later calls to -Default +Default will add to the (now empty) default-target list like normal. - + The current list of targets added using the -Default +Default function or method is available in the DEFAULT_TARGETS list; @@ -1335,8 +1312,7 @@ see below. DefaultEnvironment([args]) - - + Creates and returns a default construction environment object. This construction environment is used internally by SCons in order to execute many of the global functions in this list, @@ -1352,8 +1328,7 @@ from source code management systems. env.Depends(target, dependency) - - + Specifies an explicit dependency; the target @@ -1376,11 +1351,11 @@ is not caught by a Scanner for the file. - + Example: - + env.Depends('foo', 'other-input-file-for-foo') mylib = env.Library('mylib.c') @@ -1401,8 +1376,7 @@ env.Depends(bar, installed_lib) env.Dictionary([vars]) - - + Returns a dictionary object containing copies of all of the construction variables in the environment. @@ -1411,11 +1385,11 @@ only the specified construction variables are returned in the dictionary. - + Example: - + dict = env.Dictionary() cc_dict = env.Dictionary('CC', 'CCFLAGS', 'CCCOM') @@ -1428,8 +1402,7 @@ cc_dict = env.Dictionary('CC', 'CCFLAGS', 'CCCOM') env.Dir(name, [directory]) - - + This returns a Directory Node, an object that represents the specified directory name. @@ -1442,7 +1415,7 @@ If no is specified, the current script's directory is used as the parent. - + If name is a list, SCons returns a list of Dir nodes. @@ -1450,7 +1423,7 @@ Construction variables are expanded in name. - + Directory Nodes can be used anywhere you would supply a string as a directory name to a Builder method or function. @@ -1464,8 +1437,7 @@ see "File and Directory Nodes," below. env.Dump([key]) - - + Returns a pretty printable representation of the environment. key, if not @@ -1473,36 +1445,36 @@ if not should be a string containing the name of the variable of interest. - + This SConstruct: - + env=Environment() print env.Dump('CCCOM') - + will print: - + '$CC -c -o $TARGET $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS $SOURCES' - + While this SConstruct: - + env=Environment() print env.Dump() - + will print: - + { 'AR': 'ar', 'ARCOM': '$AR $ARFLAGS $TARGET $SOURCES\n$RANLIB $RANLIBFLAGS $TARGET', 'ARFLAGS': ['r'], @@ -1520,8 +1492,7 @@ will print: env.EnsurePythonVersion(major, minor) - - + Ensure that the Python version is at least major.minor. This function will @@ -1529,11 +1500,11 @@ print out an error message and exit SCons with a non-zero exit code if the actual Python version is not late enough. - + Example: - + EnsurePythonVersion(2,2) @@ -1545,8 +1516,7 @@ EnsurePythonVersion(2,2) env.EnsureSConsVersion(major, minor, [revision]) - - + Ensure that the SCons version is at least major.minor, or @@ -1559,11 +1529,11 @@ print out an error message and exit SCons with a non-zero exit code if the actual SCons version is not late enough. - + Examples: - + EnsureSConsVersion(0,14) EnsureSConsVersion(0,96,90) @@ -1577,8 +1547,7 @@ EnsureSConsVersion(0,96,90) env.Environment([key=value, ...]) - - + Return a new construction environment initialized with the specified key=value @@ -1593,8 +1562,7 @@ pairs. env.Execute(action, [strfunction, varlist]) - - + Executes an Action object. The specified action @@ -1612,14 +1580,14 @@ or return value of the Python function will be returned. - + Note that -scons +scons will print an error message if the executed action fails--that is, exits with or returns a non-zero value. -scons +scons will not, however, @@ -1628,12 +1596,12 @@ if the specified action fails. If you want the build to stop in response to a failed -Execute +Execute call, you must explicitly check for a non-zero return value: - + Execute(Copy('file.out', 'file.in')) if Execute("mkdir sub/dir/ectory"): @@ -1649,10 +1617,9 @@ if Execute("mkdir sub/dir/ectory"): env.Exit([value]) - - + This tells -scons +scons to exit immediately with the specified value. @@ -1670,29 +1637,28 @@ is used if no value is specified. env.Export(vars) - - + This tells -scons +scons to export a list of variables from the current SConscript file to all other SConscript files. The exported variables are kept in a global collection, so subsequent calls to -Export +Export will over-write previous exports that have the same name. Multiple variable names can be passed to -Export +Export as separate arguments or as a list. Keyword arguments can be used to provide names and their values. A dictionary can be used to map variables to a different name when exported. Both local variables and global variables can be exported. - + Examples: - + env = Environment() # Make env available for all SConscript files to Import(). Export("env") @@ -1711,15 +1677,15 @@ Export(debug = env) Export({"debug":env}) - + Note that the -SConscript +SConscript function supports an exports argument that makes it easier to to export a variable or set of variables to a single SConscript file. See the description of the -SConscript +SConscript function, below. @@ -1731,8 +1697,7 @@ function, below. env.File(name, [directory]) - - + This returns a File Node, an object that represents the specified file @@ -1743,7 +1708,7 @@ can be a relative or absolute path. is an optional directory that will be used as the parent directory. - + If name is a list, SCons returns a list of File nodes. @@ -1751,7 +1716,7 @@ Construction variables are expanded in name. - + File Nodes can be used anywhere you would supply a string as a file name to a Builder method or function. @@ -1768,8 +1733,7 @@ see "File and Directory Nodes," below. env.FindFile(file, dirs) - - + Search for file in the path specified by @@ -1781,11 +1745,11 @@ this function also searches for derived files that have not yet been built. - + Example: - + foo = env.FindFile('foo', ['dir1', 'dir2']) @@ -1797,25 +1761,24 @@ foo = env.FindFile('foo', ['dir1', 'dir2']) env.FindInstalledFiles() - - + Returns the list of targets set up by the -Install +Install or -InstallAs +InstallAs builders. - + This function serves as a convenient method to select the contents of a binary package. - + Example: - + Install( '/bin', [ 'executable_a', 'executable_b' ] ) # will return the file node list @@ -1834,8 +1797,7 @@ FindInstalledFiles() FindPathDirs(variable) - - + Returns a function (actually a callable Python object) intended to be used as the @@ -1847,14 +1809,14 @@ in a construction environment and treat the construction variable's value as a list of directory paths that should be searched (like -$CPPPATH, -$LIBPATH, +$CPPPATH, +$LIBPATH, etc.). - + Note that use of -FindPathDirs +FindPathDirs is generally preferable to writing your own path_function @@ -1862,11 +1824,11 @@ for the following reasons: 1) The returned list will contain all appropriate directories found in source trees (when -VariantDir +VariantDir is used) or in code repositories (when -Repository +Repository or the option are used). @@ -1878,11 +1840,11 @@ and avoid re-scanning the directories for files, when possible. - + Example: - + def my_scan(node, env, path, arg): # Code to scan file contents goes here... return include_files @@ -1900,8 +1862,7 @@ scanner = Scanner(name = 'myscanner', env.FindSourceFiles(node='"."') - - + Returns the list of nodes which serve as the source of the built files. It does so by inspecting the dependency tree starting at the optional argument @@ -1911,16 +1872,16 @@ which defaults to the '"."'-node. It will then return all leaves of These are all children which have no further children. - + This function is a convenient method to select the contents of a Source Package. - + Example: - + Program( 'src/main_a.c' ) Program( 'src/main_b.c' ) Program( 'main_c.c' ) @@ -1932,7 +1893,7 @@ FindSourceFiles() FindSourceFiles( 'src' ) - + As you can see build support files (SConstruct in the above example) will also be returned by this function. @@ -1945,8 +1906,7 @@ will also be returned by this function. env.Flatten(sequence) - - + Takes a sequence (that is, a Python list or tuple) that may contain nested sequences and returns a flattened list containing @@ -1959,11 +1919,11 @@ but direct Python manipulation of these lists does not. - + Examples: - + foo = Object('foo.c') bar = Object('bar.c') @@ -1986,8 +1946,7 @@ for object in Flatten(objects): GetBuildFailures() - - + Returns a list of exceptions for the actions that failed while attempting to build targets. @@ -1999,13 +1958,13 @@ that record various aspects of the build failure: - + .node The node that was being built when the build failure occurred. - + .status The numeric exit status returned by the command or Python function @@ -2013,7 +1972,7 @@ that failed when trying to build the specified Node. - + .errstr The SCons error string describing the build failure. @@ -2023,7 +1982,7 @@ to indicate that an executed command exited with a status of 2.) - + .filename The name of the file or directory that actually caused the failure. @@ -2046,7 +2005,7 @@ attribute will be sub/dir. - + .executor The SCons Executor object for the target Node @@ -2056,7 +2015,7 @@ the construction environment used for the failed action. - + .action The actual SCons Action object that failed. This will be one specific action @@ -2065,26 +2024,26 @@ actions that would have been executed to build the target. - + .command The actual expanded command that was executed and failed, after expansion of -$TARGET, -$SOURCE, +$TARGET, +$SOURCE, and other construction variables. - + Note that the -GetBuildFailures +GetBuildFailures function will always return an empty list until any build failure has occurred, which means that -GetBuildFailures +GetBuildFailures will always return an empty list while the -SConscript +SConscript files are being read. Its primary intended use is for functions that will be @@ -2096,7 +2055,7 @@ function. Example: - + import atexit def print_build_failures(): @@ -2115,10 +2074,9 @@ atexit.register(print_build_failures) env.GetBuildPath(file, [...]) - - + Returns the -scons +scons path name (or names) for the specified file (or files). @@ -2126,7 +2084,7 @@ The specified file or files may be -scons +scons Nodes or strings representing path names. @@ -2138,10 +2096,9 @@ Nodes or strings representing path names. env.GetLaunchDir() - - + Returns the absolute path name of the directory from which -scons +scons was initially invoked. This can be useful when using the , @@ -2150,7 +2107,7 @@ or options, which internally change to the directory in which the -SConstruct +SConstruct file is found. @@ -2162,17 +2119,16 @@ file is found. env.GetOption(name) - - + This function provides a way to query the value of SCons options set on scons command line (or set using the -SetOption +SetOption function). The options supported are: - + cache_debug @@ -2417,7 +2373,7 @@ which corresponds to --warn and --warning. - + See the documentation for the corresponding command line object for information about each specific option. @@ -2431,12 +2387,11 @@ option. env.Glob(pattern, [ondisk, source, strings]) - - + Returns Nodes (or strings) that match the specified pattern, relative to the directory of the current -SConscript +SConscript file. The env.Glob() @@ -2446,20 +2401,20 @@ and returns whatever matches the resulting expanded pattern. - + The specified pattern uses Unix shell style metacharacters for matching: - + * matches everything ? matches any single character [seq] matches any character in seq [!seq] matches any char not in seq - + If the first character of a filename is a dot, it must be matched explicitly. Character matches do @@ -2467,17 +2422,17 @@ Character matches do span directory separators. - + The -Glob +Glob knows about repositories (see the -Repository +Repository function) and source directories (see the -VariantDir +VariantDir function) and returns a Node (or string, if so configured) @@ -2487,7 +2442,7 @@ anywhere in a corresponding repository or source directory. - + The ondisk argument may be set to @@ -2501,7 +2456,7 @@ return corresponding Nodes for any on-disk matches found. - + The source argument may be set to @@ -2509,20 +2464,20 @@ argument may be set to (or any equivalent value) to specify that, when the local directory is a -VariantDir, +VariantDir, the returned Nodes should be from the corresponding source directory, not the local directory. - + The strings argument may be set to True (or any equivalent value) to have the -Glob +Glob function return strings, not Nodes, that represent the matched files or directories. The returned strings will be relative to @@ -2531,22 +2486,22 @@ the local (SConscript) directory. arbitrary manipulation of file names, but if the returned strings are passed to a different -SConscript +SConscript file, any Node translation will be relative to the other -SConscript +SConscript directory, not the original -SConscript +SConscript directory.) - + Examples: - + Program('foo', Glob('*.c')) Zip('/tmp/everything', Glob('.??*') + Glob('*')) @@ -2559,17 +2514,16 @@ Zip('/tmp/everything', Glob('.??*') + Glob('*')) env.Help(text) - - + This specifies help text to be printed if the argument is given to -scons. +scons. If -Help +Help is called multiple times, the text is appended together in the order that -Help +Help is called. @@ -2581,34 +2535,33 @@ is called. env.Ignore(target, dependency) - - + The specified dependency file(s) will be ignored when deciding if the target file(s) need to be rebuilt. - + You can also use -Ignore +Ignore to remove a target from the default build. In order to do this you must specify the directory the target will be built in as the target, and the file you want to skip building as the dependency. - + Note that this will only remove the dependencies listed from the files built by default. It will still be built if that dependency is needed by another object being built. See the third and forth examples below. - + Examples: - + env.Ignore('foo', 'foo.c') env.Ignore('bar', ['bar1.h', 'bar2.h']) env.Ignore('.','foobar.obj') @@ -2623,31 +2576,30 @@ env.Ignore('bar','bar/foobar.obj') env.Import(vars) - - + This tells -scons +scons to import a list of variables into the current SConscript file. This will import variables that were exported with -Export +Export or in the exports argument to -SConscript. +SConscript. Variables exported by -SConscript +SConscript have precedence. Multiple variable names can be passed to -Import +Import as separate arguments or as a list. The variable "*" can be used to import all variables. - + Examples: - + Import("env") Import("env", "variable") Import(["env", "variable"]) @@ -2662,8 +2614,7 @@ Import("*") env.Literal(string) - - + The specified string will be preserved as-is @@ -2678,8 +2629,7 @@ and not have construction variables expanded. env.Local(targets) - - + The specified targets will have copies made in the local tree, @@ -2693,8 +2643,7 @@ Returns a list of the target Node or Nodes. env.MergeFlags(arg, [unique]) - - + Merges the specified arg values to the construction environment's construction variables. @@ -2702,7 +2651,7 @@ If the arg argument is not a dictionary, it is converted to one by calling -env.ParseFlags +env.ParseFlags on the argument before the values are merged. Note that @@ -2711,10 +2660,10 @@ must be a single value, so multiple strings must be passed in as a list, not as separate arguments to -env.MergeFlags. +env.MergeFlags. - + By default, duplicate values are eliminated; you can, however, specify @@ -2730,11 +2679,11 @@ All other construction variables keep the right-most unique value. - + Examples: - + # Add an optimization flag to $CCFLAGS. env.MergeFlags('-O3') @@ -2757,39 +2706,38 @@ env.MergeFlags(['-O3', env.NoCache(target, ...) - - + Specifies a list of files which should not be cached whenever the -CacheDir +CacheDir method has been activated. The specified targets may be a list or an individual target. - + Multiple files should be specified either as separate arguments to the -NoCache +NoCache method, or as a list. -NoCache +NoCache will also accept the return value of any of the construction environment Builder methods. - + Calling -NoCache +NoCache on directories and other non-File Node types has no effect because only File Nodes are cached. - + Examples: - + NoCache('foo.elf') NoCache(env.Program('hello', 'hello.c')) @@ -2802,8 +2750,7 @@ NoCache(env.Program('hello', 'hello.c')) env.NoClean(target, ...) - - + Specifies a list of files or directories which should not be removed whenever the targets (or their dependencies) @@ -2813,7 +2760,7 @@ command line option. The specified targets may be a list or an individual target. Multiple calls to -NoClean +NoClean are legal, and prevent each specified target from being removed by calls to the @@ -2821,21 +2768,21 @@ from being removed by calls to the option. - + Multiple files or directories should be specified either as separate arguments to the -NoClean +NoClean method, or as a list. -NoClean +NoClean will also accept the return value of any of the construction environment Builder methods. - + Calling -NoClean +NoClean for a target overrides calling -Clean +Clean for the same target, and any targets passed to both functions will not @@ -2844,11 +2791,11 @@ be removed by the option. - + Examples: - + NoClean('foo.elf') NoClean(env.Program('hello', 'hello.c')) @@ -2858,8 +2805,7 @@ NoClean(env.Program('hello', 'hello.c')) env.ParseConfig(command, [function, unique]) - - + Calls the specified function to modify the environment as specified by the output of @@ -2867,7 +2813,7 @@ to modify the environment as specified by the output of The default function is -env.MergeFlags, +env.MergeFlags, which expects the output of a typical *-config command @@ -2884,11 +2830,11 @@ to allow duplicate values to be added. - + Interpreted options and the construction variables they affect are as specified for the -env.ParseFlags +env.ParseFlags method (which this method calls). See that method's description, below, for a table of options and construction variables. @@ -2902,18 +2848,17 @@ for a table of options and construction variables. env.ParseDepends(filename, [must_exist, only_one]) - - + Parses the contents of the specified filename as a list of dependencies in the style of -Make +Make or mkdep, and explicitly establishes all of the listed dependencies. - + By default, it is not an error if the specified @@ -2929,7 +2874,7 @@ generate an error if the file does not exist, or is otherwise inaccessible. - + The optional only_one argument may be set to a non-zero @@ -2951,15 +2896,15 @@ one output file into a corresponding file. - + The filename and all of the files listed therein will be interpreted relative to the directory of the -SConscript +SConscript file which calls the -ParseDepends +ParseDepends function. @@ -2968,26 +2913,25 @@ function. env.ParseFlags(flags, ...) - - + Parses one or more strings containing typical command-line flags for GCC tool chains and returns a dictionary with the flag values separated into the appropriate SCons construction variables. This is intended as a companion to the -env.MergeFlags +env.MergeFlags method, but allows for the values in the returned dictionary to be modified, if necessary, before merging them into the construction environment. (Note that -env.MergeFlags +env.MergeFlags will call this method if its argument is not a dictionary, so it is usually not necessary to call -env.ParseFlags +env.ParseFlags directly unless you want to manipulate the values.) - + If the first character in any string is an exclamation mark (!), the rest of the string is executed as a command, @@ -2996,12 +2940,12 @@ parsed as GCC tool chain command-line flags and added to the resulting dictionary. - + Flag values are translated accordig to the prefix found, and added to the following construction variables: - + -arch CCFLAGS, LINKFLAGS -D CPPDEFINES -framework FRAMEWORKS @@ -3025,19 +2969,19 @@ and added to the following construction variables: + CCFLAGS, LINKFLAGS - + Any other strings not associated with options are assumed to be the names of libraries and added to the -$LIBS +$LIBS construction variable. - + Examples (all of which produce the same result): - + dict = env.ParseFlags('-O2 -Dfoo -Dbar=1') dict = env.ParseFlags('-O2', '-Dfoo', '-Dbar=1') dict = env.ParseFlags(['-O2', '-Dfoo -Dbar=1']) @@ -3049,33 +2993,32 @@ dict = env.ParseFlags('-O2', '!echo -Dfoo -Dbar=1') env.Perforce() - - + A factory function that returns a Builder object to be used to fetch source files from the Perforce source code management system. The returned Builder is intended to be passed to the -SourceCode +SourceCode function. - + This function is deprecated. For details, see the entry for the -SourceCode +SourceCode function. - + Example: - + env.SourceCode('.', env.Perforce()) - + Perforce uses a number of external environment variables for its operation. Consequently, this function adds the @@ -3099,39 +3042,38 @@ USERNAME. Platform(string) - - + The -Platform +Platform form returns a callable object that can be used to initialize a construction environment using the platform keyword of the -Environment +Environment function. - + Example: - + env = Environment(platform = Platform('win32')) - + The -env.Platform +env.Platform form applies the callable object for the specified platform string to the environment through which the method was called. - + env.Platform('posix') - + Note that the win32 platform adds the @@ -3140,7 +3082,7 @@ and SystemRoot variables from the user's external environment to the construction environment's -$ENV +$ENV dictionary. This is so that any executed commands that use sockets to connect with other systems @@ -3158,15 +3100,14 @@ will work on Windows systems. env.Precious(target, ...) - - + Marks each given target as precious so it is not deleted before it is rebuilt. Normally -scons +scons deletes a target before building it. Multiple targets can be passed in to a single call to -Precious. +Precious. @@ -3174,8 +3115,7 @@ Multiple targets can be passed in to a single call to env.Prepend(key=val, [...]) - - + Appends the specified keyword arguments to the beginning of construction variables in the environment. If the Environment does not have @@ -3191,11 +3131,11 @@ and the lists are added together. (See also the Append method, above.) - + Example: - + env.Prepend(CCFLAGS = '-g ', FOO = ['foo.yyy']) @@ -3204,11 +3144,10 @@ env.Prepend(CCFLAGS = '-g ', FOO = ['foo.yyy']) env.PrependENVPath(name, newpath, [envname, sep, delete_existing]) - - + This appends new path elements to the given path in the specified external environment -($ENV +($ENV by default). This will only add any particular path once (leaving the first one it encounters and @@ -3223,7 +3162,7 @@ case where the given old path variable is a list instead of a string, in which case a list will be returned instead of a string. - + If delete_existing is 0, then adding a path that already exists @@ -3231,22 +3170,22 @@ will not move it to the beginning; it will stay where it is in the list. - + Example: - + print 'before:',env['ENV']['INCLUDE'] include_path = '/foo/bar:/foo' env.PrependENVPath('INCLUDE', include_path) print 'after:',env['ENV']['INCLUDE'] - + The above example will print: - + before: /biz:/foo after: /foo/bar:/foo:/biz @@ -3256,8 +3195,7 @@ after: /foo/bar:/foo:/biz env.PrependUnique(key=val, delete_existing=0, [...]) - - + Appends the specified keyword arguments to the beginning of construction variables in the environment. If the Environment does not have @@ -3273,11 +3211,11 @@ existing matching values are removed first, so existing values in the arg list move to the front of the list. - + Example: - + env.PrependUnique(CCFLAGS = '-g', FOO = ['foo.yyy']) @@ -3292,14 +3230,13 @@ env.PrependUnique(CCFLAGS = '-g', FOO = ['foo.yyy']) Progress(list_of_strings, [interval, file, overwrite]) - - + Allows SCons to show progress made during the build by displaying a string or calling a function while evaluating Nodes (e.g. files). - + If the first specified argument is a Python callable (a function or an object that has a __call__() @@ -3321,19 +3258,19 @@ if SCons ever changes the interface to call the function with additional arguments in the future.) - + An example of a simple custom progress function that prints a string containing the Node name every 10 Nodes: - + def my_progress_function(node, *args, **kw): print 'Evaluating node %s!' % node Progress(my_progress_function, interval=10) - + A more complicated example of a custom progress display object that prints a string containing a count every 100 evaluated Nodes. @@ -3344,7 +3281,7 @@ at the end so that the string will overwrite itself on a display: - + import sys class ProgressCounter(object): count = 0 @@ -3354,9 +3291,9 @@ class ProgressCounter(object): Progress(ProgressCounter(), interval=100) - + If the first argument -Progress +Progress is a string, the string will be displayed every @@ -3372,14 +3309,14 @@ on the error output, one dot for every 100 evaluated Nodes: - + import sys Progress('.', interval=100, file=sys.stderr) - + If the string contains the verbatim substring -$TARGET, +$TARGET, it will be replaced with the Node. Note that, for performance reasons, this is not @@ -3397,14 +3334,14 @@ keyword argument to make sure the previously-printed file name is overwritten with blank spaces: - + import sys Progress('$TARGET\r', overwrite=True) - + If the first argument to -Progress +Progress is a list of strings, then each string in the list will be displayed in rotating fashion every @@ -3414,7 +3351,7 @@ This can be used to implement a "spinner" on the user's screen as follows: - + Progress(['-\r', '\\\r', '|\r', '/\r'], interval=5) @@ -3426,18 +3363,17 @@ Progress(['-\r', '\\\r', '|\r', '/\r'], interval=5) env.Pseudo(target, ...) - - + This indicates that each given target should not be created by the build rule, and if the target is created, an error will be generated. This is similar to the gnu make .PHONY target. However, in the vast majority of cases, an -Alias +Alias is more appropriate. Multiple targets can be passed in to a single call to -Pseudo. +Pseudo. @@ -3445,35 +3381,34 @@ Multiple targets can be passed in to a single call to env.RCS() - - + A factory function that returns a Builder object to be used to fetch source files from RCS. The returned Builder is intended to be passed to the -SourceCode +SourceCode function: - + This function is deprecated. For details, see the entry for the -SourceCode +SourceCode function. - + Examples: - + env.SourceCode('.', env.RCS()) - + Note that -scons +scons will fetch source files from RCS subdirectories automatically, so configuring RCS @@ -3492,17 +3427,16 @@ for a specific subdirectory. env.Replace(key=val, [...]) - - + Replaces construction variables in the Environment with the specified keyword arguments. - + Example: - + env.Replace(CCFLAGS = '-g', FOO = 'foo.xxx') @@ -3514,21 +3448,20 @@ env.Replace(CCFLAGS = '-g', FOO = 'foo.xxx') env.Repository(directory) - - + Specifies that directory is a repository to be searched for files. Multiple calls to -Repository +Repository are legal, and each one adds to the list of repositories that will be searched. - + To -scons, +scons, a repository is a copy of the source tree, from the top-level directory on down, which may contain @@ -3539,26 +3472,26 @@ The canonical example would be an official source tree maintained by an integrator. If the repository contains derived files, then the derived files should have been built using -scons, +scons, so that the repository contains the necessary signature information to allow -scons +scons to figure out when it is appropriate to use the repository copy of a derived file, instead of building one locally. - + Note that if an up-to-date derived file already exists in a repository, -scons +scons will not make a copy in the local directory tree. In order to guarantee that a local copy will be made, use the -Local +Local method. @@ -3570,8 +3503,7 @@ method. env.Requires(target, prerequisite) - - + Specifies an order-only relationship between the specified target file(s) and the specified prerequisite file(s). @@ -3585,11 +3517,11 @@ and will not be rebuilt simply because the prerequisite file(s) change. - + Example: - + env.Requires('foo', 'file-that-must-be-built-before-foo') @@ -3598,8 +3530,7 @@ env.Requires('foo', 'file-that-must-be-built-before-foo') Return([vars..., stop=]) - - + By default, this stops processing the current SConscript file and returns to the calling SConscript file @@ -3607,32 +3538,32 @@ the values of the variables named in the vars string arguments. Multiple strings contaning variable names may be passed to -Return. +Return. Any strings that contain white space - + The optional stop= keyword argument may be set to a false value to continue processing the rest of the SConscript file after the -Return +Return call. This was the default behavior prior to SCons 0.98. However, the values returned are still the values of the variables in the named vars at the point -Return +Return is called. - + Examples: - + # Returns without returning a value. Return() @@ -3654,8 +3585,7 @@ Return('val1 val2') env.Scanner(function, [argument, keys, path_function, node_class, node_factory, scan_check, recursive]) - - + Creates a Scanner object for the specified function. @@ -3668,29 +3598,28 @@ below, for a complete explanation of the arguments and behavior. env.SCCS() - - + A factory function that returns a Builder object to be used to fetch source files from SCCS. The returned Builder is intended to be passed to the -SourceCode +SourceCode function. - + Example: - + env.SourceCode('.', env.SCCS()) - + Note that -scons +scons will fetch source files from SCCS subdirectories automatically, so configuring SCCS @@ -3718,24 +3647,23 @@ for a specific subdirectory. env.SConscript(dirs=subdirs, [name=script, exports, variant_dir, duplicate]) - - + This tells -scons +scons to execute one or more subsidiary SConscript (configuration) files. Any variables returned by a called script using -Return +Return will be returned by the call to -SConscript. +SConscript. There are two ways to call the -SConscript +SConscript function. - + The first way you can call -SConscript +SConscript is to explicitly specify one or more scripts as the first argument. @@ -3743,45 +3671,45 @@ A single script may be specified as a string; multiple scripts must be specified as a list (either explicitly or as created by a function like -Split). +Split). Examples: - + SConscript('SConscript') # run SConscript in the current directory SConscript('src/SConscript') # run SConscript in the src directory SConscript(['src/SConscript', 'doc/SConscript']) config = SConscript('MyConfig.py') - + The second way you can call -SConscript +SConscript is to specify a list of (sub)directory names as a dirs=subdirs keyword argument. In this case, -scons +scons will, by default, execute a subsidiary configuration file named -SConscript +SConscript in each of the specified directories. You may specify a name other than -SConscript +SConscript by supplying an optional name=script keyword argument. The first three examples below have the same effect as the first three examples above: - + SConscript(dirs='.') # run SConscript in the current directory SConscript(dirs='src') # run SConscript in the src directory SConscript(dirs=['src', 'doc']) SConscript(dirs=['sub1', 'sub2'], name='MySConscript') - + The optional exports argument provides a list of variable names or a dictionary of @@ -3790,28 +3718,28 @@ named values to export to the These variables are locally exported only to the specified script(s), and do not affect the global pool of variables used by the -Export +Export function. The subsidiary script(s) must use the -Import +Import function to import the variables. Examples: - + foo = SConscript('sub/SConscript', exports='env') SConscript('dir/SConscript', exports=['env', 'variable']) SConscript(dirs='subdir', exports='env variable') SConscript(dirs=['one', 'two', 'three'], exports='shared_info') - + If the optional variant_dir argument is present, it causes an effect equivalent to the -VariantDir +VariantDir method described below. (If variant_dir @@ -3828,14 +3756,14 @@ and arguments are interpreted relative to the directory of the calling --> argument is interpreted relative to the directory of the calling -SConscript +SConscript file. See the description of the -VariantDir +VariantDir function below for additional details and restrictions. - + If variant_dir is present, @@ -3845,46 +3773,46 @@ but is not, --> the source directory is the directory in which the -SConscript +SConscript file resides and the -SConscript +SConscript file is evaluated as if it were in the variant_dir directory: - + SConscript('src/SConscript', variant_dir = 'build') - + is equivalent to - + VariantDir('build', 'src') SConscript('build/SConscript') - + This later paradigm is often used when the sources are in the same directory as the -SConstruct: +SConstruct: - + SConscript('SConscript', variant_dir = 'build') - + is equivalent to - + VariantDir('build', '.') SConscript('build/SConscript') - + - + Here are some composite examples: - + # collect the configuration information and use it to build src and doc shared_info = SConscript('MyConfig.py') SConscript('src/SConscript', exports='shared_info') SConscript('doc/SConscript', exports='shared_info') - + # build debugging and production versions. SConscript # can use Dir('.').path to determine variant. SConscript('SConscript', variant_dir='debug', duplicate=0) SConscript('SConscript', variant_dir='prod', duplicate=0) - + # build debugging and production versions. SConscript # is passed flags to use. opts = { 'CPPDEFINES' : ['DEBUG'], 'CCFLAGS' : '-pgdb' } @@ -3944,7 +3872,7 @@ opts = { 'CPPDEFINES' : ['NODEBUG'], 'CCFLAGS' : '-O' } SConscript('SConscript', variant_dir='prod', duplicate=0, exports=opts) - + # build common documentation and compile for different architectures SConscript('doc/SConscript', variant_dir='build/doc', duplicate=0) SConscript('src/SConscript', variant_dir='build/x86', duplicate=0) @@ -3959,10 +3887,9 @@ SConscript('src/SConscript', variant_dir='build/ppc', duplicate=0) env.SConscriptChdir(value) - - + By default, -scons +scons changes its working directory to the directory in which each subsidiary SConscript file lives. @@ -3970,14 +3897,14 @@ This behavior may be disabled by specifying either: - + SConscriptChdir(0) env.SConscriptChdir(0) - + in which case -scons +scons will stay in the top-level directory while reading all SConscript files. (This may be necessary when building from repositories, @@ -3989,11 +3916,11 @@ SConscriptChdir() multiple times. - + Example: - + env = Environment() SConscriptChdir(0) SConscript('foo/SConscript') # will not chdir to foo @@ -4009,10 +3936,9 @@ SConscript('bar/SConscript') # will chdir to bar env.SConsignFile([file, dbm_module]) - - + This tells -scons +scons to store all file signatures in the specified database file. @@ -4029,17 +3955,17 @@ If file is not an absolute path name, the file is placed in the same directory as the top-level -SConstruct +SConstruct file. - + If file is None, then -scons +scons will store file signatures in a separate .sconsign @@ -4049,7 +3975,7 @@ not in one global database file. prior to SCons 0.96.91 and 0.97.) - + The optional dbm_module argument can be used to specify @@ -4061,11 +3987,11 @@ Python data structures, and which works on all Python versions. - + Examples: - + # Explicitly stores signatures in ".sconsign.dblite" # in the top-level SConstruct directory (the # default behavior). @@ -4088,14 +4014,13 @@ SConsignFile(None) env.SetDefault(key=val, [...]) - - + Sets construction variables to default values specified with the keyword arguments if (and only if) the variables are not already set. The following statements are equivalent: - + env.SetDefault(FOO = 'foo') if 'FOO' not in env: env['FOO'] = 'foo' @@ -4109,13 +4034,12 @@ if 'FOO' not in env: env['FOO'] = 'foo' env.SetOption(name, value) - - + This function provides a way to set a select subset of the scons command line options from a SConscript file. The options supported are: - + clean @@ -4192,17 +4116,17 @@ which corresponds to --stack-size. - + See the documentation for the corresponding command line object for information about each specific option. - + Example: - + SetOption('max_drift', 1) @@ -4214,8 +4138,7 @@ SetOption('max_drift', 1) env.SideEffect(side_effect, target) - - + Declares side_effect as a side effect of building @@ -4233,7 +4156,7 @@ files for a static library, and various log files are created updated as side effects of various TeX commands. If a target is a side effect of multiple build commands, -scons +scons will ensure that only one set of commands is executed at a time. Consequently, you only need to use this method @@ -4241,7 +4164,7 @@ for side-effect targets that are built as a result of multiple build commands. - + Because multiple build commands may update the same side effect file, by default the @@ -4265,9 +4188,9 @@ is cleaned whenever a specific is cleaned, you must specify this explicitly with the -Clean +Clean or -env.Clean +env.Clean function. @@ -4279,17 +4202,16 @@ function. env.SourceCode(entries, builder) - - + This function and its associate factory functions are deprecated. There is no replacement. The intended use was to keep a local tree in sync with an archive, but in actuality the function only causes the archive to be fetched on the first run. -Synchronizing with the archive is best done external to SCons. +Synchronizing with the archive is best done external to SCons. - + Arrange for non-existent source files to be fetched from a source code management system using the specified @@ -4302,30 +4224,30 @@ source files or directories in which source files can be found. - + For any non-existent source files, -scons +scons will search up the directory tree and use the first -SourceCode +SourceCode builder it finds. The specified builder may be None, in which case -scons +scons will not use a builder to fetch source files for the specified entries, even if a -SourceCode +SourceCode builder has been specified for a directory higher up the tree. - -scons + +scons will, by default, fetch files from SCCS or RCS subdirectories without explicit configuration. @@ -4337,11 +4259,11 @@ and speed up your build a little by disabling these searches as follows: - + env.SourceCode('.', None) - + Note that if the specified builder is one you create by hand, @@ -4350,8 +4272,8 @@ construction environment to use when fetching a source file. - -scons + +scons provides a set of canned factory functions that return appropriate Builders for various popular @@ -4359,14 +4281,14 @@ source code management systems. Canonical examples of invocation include: - + env.SourceCode('.', env.BitKeeper('/usr/local/BKsources')) env.SourceCode('src', env.CVS('/usr/local/CVSROOT')) env.SourceCode('/', env.RCS()) env.SourceCode(['f1.c', 'f2.c'], env.SCCS()) env.SourceCode('no_source.c', None) - + @@ -4378,21 +4300,20 @@ env.SourceCode('no_source.c', None) env.SourceSignatures(type) - - + Note: Although it is not yet officially deprecated, use of this function is discouraged. See the -Decider +Decider function for a more flexible and straightforward way to configure SCons' decision-making. - + The -SourceSignatures +SourceSignatures function tells -scons +scons how to decide if a source file (a file that is not built from any other files) has changed since the last time it @@ -4403,7 +4324,7 @@ or timestamp. - + If the environment method is used, the specified type of source signature is only used when deciding whether targets @@ -4414,19 +4335,19 @@ used for all decisions about whether targets are up-to-date. - + MD5 means -scons +scons decides that a source file has changed if the MD5 checksum of its contents has changed since the last time it was used to rebuild a particular target file. - + timestamp means -scons +scons decides that a source file has changed if its timestamp (modification time) has changed since the last time it was used to rebuild a particular target file. @@ -4436,14 +4357,14 @@ by default it will also rebuild if the dependency is than the last time it was used to rebuild the target file.) - + There is no different between the two behaviors for Python -Value +Value node objects. - + MD5 signatures take longer to compute, but are more accurate than @@ -4453,21 +4374,21 @@ The default value is MD5. - + Note that the default -TargetSignatures +TargetSignatures setting (see below) is to use this -SourceSignatures +SourceSignatures setting for any target files that are used to build other target files. Consequently, changing the value of -SourceSignatures +SourceSignatures will, by default, affect the up-to-date decision for all files in the build (or all files built with a specific construction environment when -env.SourceSignatures +env.SourceSignatures is used). @@ -4479,8 +4400,7 @@ is used). env.Split(arg) - - + Returns a list of file names or other objects. If arg is a string, it will be split on strings of white-space characters @@ -4493,11 +4413,11 @@ it will be returned as a list containing just the object. - + Example: - + files = Split("f1.c f2.c f3.c") files = env.Split("f4.c f5.c f6.c") files = Split(""" @@ -4512,14 +4432,13 @@ files = Split(""" env.subst(input, [raw, target, source, conv]) - - + Performs construction variable interpolation on the specified string or sequence argument input. - + By default, leading or trailing white space will be removed from the result. @@ -4551,7 +4470,7 @@ pairs (as is done for signature calculation). - + If the input is a sequence (list or tuple), the individual elements of @@ -4559,7 +4478,7 @@ the sequence will be expanded, and the results will be returned as a list. - + The optional target and @@ -4568,20 +4487,20 @@ keyword arguments must be set to lists of target and source nodes, respectively, if you want the -$TARGET, -$TARGETS, -$SOURCE +$TARGET, +$TARGETS, +$SOURCE and -$SOURCES +$SOURCES to be available for expansion. This is usually necessary if you are calling -env.subst +env.subst from within a Python function used as an SCons action. - + Returned string values or sequence elements are converted to their string representation by default. The optional @@ -4599,11 +4518,11 @@ idiom to pass in an unnamed function that simply returns its unconverted argument. - + Example: - + print env.subst("The C compiler is: $CC") def compile(target, source, env): @@ -4620,20 +4539,19 @@ source_nodes = env.subst('$EXPAND_TO_NODELIST', Tag(node, tags) - - + Annotates file or directory Nodes with information about how the -Package +Package Builder should package those files or directories. All tags are optional. - + Examples: - + # makes sure the built library will be installed with 0644 file # access mode Tag( Library( 'lib.c' ), UNIX_ATTR="0644" ) @@ -4650,21 +4568,20 @@ Tag( 'file2.txt', DOC ) env.TargetSignatures(type) - - + Note: Although it is not yet officially deprecated, use of this function is discouraged. See the -Decider +Decider function for a more flexible and straightforward way to configure SCons' decision-making. - + The -TargetSignatures +TargetSignatures function tells -scons +scons how to decide if a target file (a file that is @@ -4681,7 +4598,7 @@ or "source". - + If the environment method is used, the specified type of target signature is only used for targets built with that environment. @@ -4692,17 +4609,17 @@ don't have an explicit target signature type specified for their environments. - + "content" (or its synonym "MD5") means -scons +scons decides that a target file has changed if the MD5 checksum of its contents has changed since the last time it was used to rebuild some other target file. This means -scons +scons will open up MD5 sum the contents of target files after they're built, @@ -4711,10 +4628,10 @@ and may decide that it does not need to rebuild rebuilt with exactly the same contents as the last time. - + "timestamp" means -scons +scons decides that a target file has changed if its timestamp (modification time) has changed since the last time it was used to rebuild some other target file. @@ -4724,33 +4641,33 @@ by default it will also rebuild if the dependency is than the last time it was used to rebuild the target file.) - + "source" means -scons +scons decides that a target file has changed as specified by the corresponding -SourceSignatures +SourceSignatures setting ("MD5" or "timestamp"). This means that -scons +scons will treat all input files to a target the same way, regardless of whether they are source files or have been built from other files. - + "build" means -scons +scons decides that a target file has changed if it has been rebuilt in this invocation or if its content or timestamp have changed as specified by the corresponding -SourceSignatures +SourceSignatures setting. This "propagates" the status of a rebuilt file so that other "downstream" target files @@ -4759,7 +4676,7 @@ even if the contents or the timestamp have not changed. - + "build" signatures are fastest because "content" @@ -4781,18 +4698,18 @@ The default value is "source". - + Because the default setting is "source", using -SourceSignatures +SourceSignatures is generally preferable to -TargetSignatures, +TargetSignatures, so that the up-to-date decision will be consistent for all files (or all files built with a specific construction environment). Use of -TargetSignatures +TargetSignatures provides specific control for how built target files affect their "downstream" dependencies. @@ -4805,10 +4722,9 @@ affect their "downstream" dependencies. env.Tool(string, [toolpath, **kw]) - - + The -Tool +Tool form of the function returns a callable object that can be used to initialize @@ -4820,21 +4736,21 @@ in which case the object will add the necessary variables to the construction environment and the name of the tool will be added to the -$TOOLS +$TOOLS construction variable. - + Additional keyword arguments are passed to the tool's generate() method. - + Examples: - + env = Environment(tools = [ Tool('msvc') ]) env = Environment() @@ -4844,22 +4760,22 @@ u = Tool('opengl', toolpath = ['tools']) u(env) # adds 'opengl' to the TOOLS variable - + The -env.Tool +env.Tool form of the function applies the callable object for the specified tool string to the environment through which the method was called. - + Additional keyword arguments are passed to the tool's generate() method. - + env.Tool('gcc') env.Tool('opengl', toolpath = ['build/tools']) @@ -4872,8 +4788,7 @@ env.Tool('opengl', toolpath = ['build/tools']) env.Value(value, [built_value]) - - + Returns a Node object representing the specified Python value. Value Nodes can be used as dependencies of targets. If the result of calling @@ -4887,7 +4802,7 @@ When using timestamp source signatures, Value Nodes' timestamps are equal to the system time when the Node is created. - + The returned Value Node object has a write() method that can be used to "build" a Value Node @@ -4903,11 +4818,11 @@ There is a corresponding method that will return the built value of the Node. - + Examples: - + env = Environment() def create(target, source, env): @@ -4949,10 +4864,9 @@ env.UpdateValue(target = Value(output), source = Value(input)) env.VariantDir(variant_dir, src_dir, [duplicate]) - - + Use the -VariantDir +VariantDir function to create a copy of your sources in another location: if a name under variant_dir @@ -4965,8 +4879,8 @@ than the original sources by simply refering to the sources (and targets) within the variant tree. - -VariantDir + +VariantDir can be called multiple times with the same src_dir to set up multiple builds with different options @@ -4984,9 +4898,9 @@ TODO: src_dir = '.' works fine with a build dir under it. --> - + The default behavior is for -scons +scons to physically duplicate the source files in the variant tree. Thus, a build performed in the variant tree is guaranteed to be identical to a build performed in the source tree even if @@ -4997,7 +4911,7 @@ or individual compilers or other invoked tools are hard-coded to put derived files in the same directory as source files. - + If possible on the platform, the duplication is performed by linking rather than copying; see also the @@ -5008,14 +4922,14 @@ files and directories that are not used are not present in variant_dir. - + Duplicating the source tree may be disabled by setting the duplicate argument to 0 (zero). This will cause -scons +scons to invoke Builders using the path names of source files in src_dir and the path names of derived files within @@ -5026,9 +4940,9 @@ and is usually safe for most builds (but see above for cases that may cause problems). - + Note that -VariantDir +VariantDir works most naturally with a subsidiary SConscript file. However, you would then call the subsidiary SConscript file not in the source directory, but in the @@ -5036,11 +4950,11 @@ not in the source directory, but in the regardless of the value of duplicate. This is how you tell -scons +scons which variant of a source tree to build: - + # run src/SConscript in two variant directories VariantDir('build/variant1', 'src') SConscript('build/variant1/SConscript') @@ -5048,31 +4962,31 @@ VariantDir('build/variant2', 'src') SConscript('build/variant2/SConscript') - + See also the -SConscript +SConscript function, described above, for another way to specify a variant directory in conjunction with calling a subsidiary SConscript file. - + Examples: - + # use names in the build directory, not the source directory VariantDir('build', 'src', duplicate=0) Program('build/prog', 'build/source.c') - + # this builds both the source and docs in a separate subtree VariantDir('build', '.', duplicate=0) SConscript(dirs=['build/src','build/doc']) - + # same as previous example, but only uses SConscript SConscript(dirs='src', variant_dir='build/src', duplicate=0) SConscript(dirs='doc', variant_dir='build/doc', duplicate=0) @@ -5086,8 +5000,7 @@ SConscript(dirs='doc', variant_dir='build/doc', duplicate=0) env.WhereIs(program, [path, pathext, reject]) - - + Searches for the specified executable program, returning the full path name to the program diff --git a/doc/generated/tools.gen b/doc/generated/tools.gen index aea2aa6..2d4e691 100644 --- a/doc/generated/tools.gen +++ b/doc/generated/tools.gen @@ -1,4 +1,4 @@ - + %scons; @@ -12,127 +12,112 @@ %variables-mod; ]> - + 386asm - - + Sets construction variables for the 386ASM assembler for the Phar Lap ETS embedded operating system. -Sets: &cv-link-AS;, &cv-link-ASCOM;, &cv-link-ASFLAGS;, &cv-link-ASPPCOM;, &cv-link-ASPPFLAGS;.Uses: &cv-link-CC;, &cv-link-CPPFLAGS;, &cv-link-_CPPDEFFLAGS;, &cv-link-_CPPINCFLAGS;. +Sets: &cv-link-AS;, &cv-link-ASCOM;, &cv-link-ASFLAGS;, &cv-link-ASPPCOM;, &cv-link-ASPPFLAGS;.Uses: &cv-link-CC;, &cv-link-CPPFLAGS;, &cv-link-_CPPDEFFLAGS;, &cv-link-_CPPINCFLAGS;. aixc++ - - + Sets construction variables for the IMB xlc / Visual Age C++ compiler. -Sets: &cv-link-CXX;, &cv-link-CXXVERSION;, &cv-link-SHCXX;, &cv-link-SHOBJSUFFIX;. +Sets: &cv-link-CXX;, &cv-link-CXXVERSION;, &cv-link-SHCXX;, &cv-link-SHOBJSUFFIX;. aixcc - - + Sets construction variables for the IBM xlc / Visual Age C compiler. -Sets: &cv-link-CC;, &cv-link-CCVERSION;, &cv-link-SHCC;. +Sets: &cv-link-CC;, &cv-link-CCVERSION;, &cv-link-SHCC;. aixf77 - - + Sets construction variables for the IBM Visual Age f77 Fortran compiler. -Sets: &cv-link-F77;, &cv-link-SHF77;. +Sets: &cv-link-F77;, &cv-link-SHF77;. aixlink - - + Sets construction variables for the IBM Visual Age linker. -Sets: &cv-link-LINKFLAGS;, &cv-link-SHLIBSUFFIX;, &cv-link-SHLINKFLAGS;. +Sets: &cv-link-LINKFLAGS;, &cv-link-SHLIBSUFFIX;, &cv-link-SHLINKFLAGS;. applelink - - + Sets construction variables for the Apple linker (similar to the GNU linker). -Sets: &cv-link-FRAMEWORKPATHPREFIX;, &cv-link-LDMODULECOM;, &cv-link-LDMODULEFLAGS;, &cv-link-LDMODULEPREFIX;, &cv-link-LDMODULESUFFIX;, &cv-link-LINKCOM;, &cv-link-SHLINKCOM;, &cv-link-SHLINKFLAGS;, &cv-link-_FRAMEWORKPATH;, &cv-link-_FRAMEWORKS;.Uses: &cv-link-FRAMEWORKSFLAGS;. +Sets: &cv-link-FRAMEWORKPATHPREFIX;, &cv-link-LDMODULECOM;, &cv-link-LDMODULEFLAGS;, &cv-link-LDMODULEPREFIX;, &cv-link-LDMODULESUFFIX;, &cv-link-LINKCOM;, &cv-link-SHLINKCOM;, &cv-link-SHLINKFLAGS;, &cv-link-_FRAMEWORKPATH;, &cv-link-_FRAMEWORKS;.Uses: &cv-link-FRAMEWORKSFLAGS;. ar - - -Sets construction variables for the ar library archiver. + +Sets construction variables for the ar library archiver. -Sets: &cv-link-AR;, &cv-link-ARCOM;, &cv-link-ARFLAGS;, &cv-link-LIBPREFIX;, &cv-link-LIBSUFFIX;, &cv-link-RANLIB;, &cv-link-RANLIBCOM;, &cv-link-RANLIBFLAGS;. +Sets: &cv-link-AR;, &cv-link-ARCOM;, &cv-link-ARFLAGS;, &cv-link-LIBPREFIX;, &cv-link-LIBSUFFIX;, &cv-link-RANLIB;, &cv-link-RANLIBCOM;, &cv-link-RANLIBFLAGS;. as - - -Sets construction variables for the as assembler. + +Sets construction variables for the as assembler. -Sets: &cv-link-AS;, &cv-link-ASCOM;, &cv-link-ASFLAGS;, &cv-link-ASPPCOM;, &cv-link-ASPPFLAGS;.Uses: &cv-link-CC;, &cv-link-CPPFLAGS;, &cv-link-_CPPDEFFLAGS;, &cv-link-_CPPINCFLAGS;. +Sets: &cv-link-AS;, &cv-link-ASCOM;, &cv-link-ASFLAGS;, &cv-link-ASPPCOM;, &cv-link-ASPPFLAGS;.Uses: &cv-link-CC;, &cv-link-CPPFLAGS;, &cv-link-_CPPDEFFLAGS;, &cv-link-_CPPINCFLAGS;. bcc32 - - + Sets construction variables for the bcc32 compiler. -Sets: &cv-link-CC;, &cv-link-CCCOM;, &cv-link-CCFLAGS;, &cv-link-CFILESUFFIX;, &cv-link-CFLAGS;, &cv-link-CPPDEFPREFIX;, &cv-link-CPPDEFSUFFIX;, &cv-link-INCPREFIX;, &cv-link-INCSUFFIX;, &cv-link-SHCC;, &cv-link-SHCCCOM;, &cv-link-SHCCFLAGS;, &cv-link-SHCFLAGS;, &cv-link-SHOBJSUFFIX;.Uses: &cv-link-_CPPDEFFLAGS;, &cv-link-_CPPINCFLAGS;. +Sets: &cv-link-CC;, &cv-link-CCCOM;, &cv-link-CCFLAGS;, &cv-link-CFILESUFFIX;, &cv-link-CFLAGS;, &cv-link-CPPDEFPREFIX;, &cv-link-CPPDEFSUFFIX;, &cv-link-INCPREFIX;, &cv-link-INCSUFFIX;, &cv-link-SHCC;, &cv-link-SHCCCOM;, &cv-link-SHCCFLAGS;, &cv-link-SHCFLAGS;, &cv-link-SHOBJSUFFIX;.Uses: &cv-link-_CPPDEFFLAGS;, &cv-link-_CPPINCFLAGS;. BitKeeper - - + Sets construction variables for the BitKeeper source code control system. -Sets: &cv-link-BITKEEPER;, &cv-link-BITKEEPERCOM;, &cv-link-BITKEEPERGET;, &cv-link-BITKEEPERGETFLAGS;.Uses: &cv-link-BITKEEPERCOMSTR;. +Sets: &cv-link-BITKEEPER;, &cv-link-BITKEEPERCOM;, &cv-link-BITKEEPERGET;, &cv-link-BITKEEPERGETFLAGS;.Uses: &cv-link-BITKEEPERCOMSTR;. cc - - + Sets construction variables for generic POSIX C copmilers. -Sets: &cv-link-CC;, &cv-link-CCCOM;, &cv-link-CCFLAGS;, &cv-link-CFILESUFFIX;, &cv-link-CFLAGS;, &cv-link-CPPDEFPREFIX;, &cv-link-CPPDEFSUFFIX;, &cv-link-FRAMEWORKPATH;, &cv-link-FRAMEWORKS;, &cv-link-INCPREFIX;, &cv-link-INCSUFFIX;, &cv-link-SHCC;, &cv-link-SHCCCOM;, &cv-link-SHCCFLAGS;, &cv-link-SHCFLAGS;, &cv-link-SHOBJSUFFIX;.Uses: &cv-link-PLATFORM;. +Sets: &cv-link-CC;, &cv-link-CCCOM;, &cv-link-CCFLAGS;, &cv-link-CFILESUFFIX;, &cv-link-CFLAGS;, &cv-link-CPPDEFPREFIX;, &cv-link-CPPDEFSUFFIX;, &cv-link-FRAMEWORKPATH;, &cv-link-FRAMEWORKS;, &cv-link-INCPREFIX;, &cv-link-INCSUFFIX;, &cv-link-SHCC;, &cv-link-SHCCCOM;, &cv-link-SHCCFLAGS;, &cv-link-SHCFLAGS;, &cv-link-SHOBJSUFFIX;.Uses: &cv-link-PLATFORM;. cvf - - + Sets construction variables for the Compaq Visual Fortran compiler. -Sets: &cv-link-FORTRAN;, &cv-link-FORTRANCOM;, &cv-link-FORTRANMODDIR;, &cv-link-FORTRANMODDIRPREFIX;, &cv-link-FORTRANMODDIRSUFFIX;, &cv-link-FORTRANPPCOM;, &cv-link-OBJSUFFIX;, &cv-link-SHFORTRANCOM;, &cv-link-SHFORTRANPPCOM;.Uses: &cv-link-CPPFLAGS;, &cv-link-FORTRANFLAGS;, &cv-link-SHFORTRANFLAGS;, &cv-link-_CPPDEFFLAGS;, &cv-link-_FORTRANINCFLAGS;, &cv-link-_FORTRANMODFLAG;. +Sets: &cv-link-FORTRAN;, &cv-link-FORTRANCOM;, &cv-link-FORTRANMODDIR;, &cv-link-FORTRANMODDIRPREFIX;, &cv-link-FORTRANMODDIRSUFFIX;, &cv-link-FORTRANPPCOM;, &cv-link-OBJSUFFIX;, &cv-link-SHFORTRANCOM;, &cv-link-SHFORTRANPPCOM;.Uses: &cv-link-CPPFLAGS;, &cv-link-FORTRANFLAGS;, &cv-link-SHFORTRANFLAGS;, &cv-link-_CPPDEFFLAGS;, &cv-link-_FORTRANINCFLAGS;, &cv-link-_FORTRANMODFLAG;. CVS - - + Sets construction variables for the CVS source code management system. -Sets: &cv-link-CVS;, &cv-link-CVSCOFLAGS;, &cv-link-CVSCOM;, &cv-link-CVSFLAGS;.Uses: &cv-link-CVSCOMSTR;. +Sets: &cv-link-CVS;, &cv-link-CVSCOFLAGS;, &cv-link-CVSCOM;, &cv-link-CVSFLAGS;.Uses: &cv-link-CVSCOMSTR;. cXX - - + Sets construction variables for generic POSIX C++ compilers. -Sets: &cv-link-CPPDEFPREFIX;, &cv-link-CPPDEFSUFFIX;, &cv-link-CXX;, &cv-link-CXXCOM;, &cv-link-CXXFILESUFFIX;, &cv-link-CXXFLAGS;, &cv-link-INCPREFIX;, &cv-link-INCSUFFIX;, &cv-link-OBJSUFFIX;, &cv-link-SHCXX;, &cv-link-SHCXXCOM;, &cv-link-SHCXXFLAGS;, &cv-link-SHOBJSUFFIX;.Uses: &cv-link-CXXCOMSTR;. +Sets: &cv-link-CPPDEFPREFIX;, &cv-link-CPPDEFSUFFIX;, &cv-link-CXX;, &cv-link-CXXCOM;, &cv-link-CXXFILESUFFIX;, &cv-link-CXXFLAGS;, &cv-link-INCPREFIX;, &cv-link-INCSUFFIX;, &cv-link-OBJSUFFIX;, &cv-link-SHCXX;, &cv-link-SHCXXCOM;, &cv-link-SHCXXFLAGS;, &cv-link-SHOBJSUFFIX;.Uses: &cv-link-CXXCOMSTR;. default - - + Sets variables by calling a default list of Tool modules for the platform on which SCons is running. @@ -140,16 +125,14 @@ for the platform on which SCons is running. dmd - - + Sets construction variables for D language compiler DMD. -Sets: &cv-link-DC;, &cv-link-DCOM;, &cv-link-DDEBUG;, &cv-link-DDEBUGPREFIX;, &cv-link-DDEBUGSUFFIX;, &cv-link-DFILESUFFIX;, &cv-link-DFLAGPREFIX;, &cv-link-DFLAGS;, &cv-link-DFLAGSUFFIX;, &cv-link-DINCPREFIX;, &cv-link-DINCSUFFIX;, &cv-link-DLIB;, &cv-link-DLIBCOM;, &cv-link-DLIBDIRPREFIX;, &cv-link-DLIBDIRSUFFIX;, &cv-link-DLIBFLAGPREFIX;, &cv-link-DLIBFLAGSUFFIX;, &cv-link-DLIBLINKPREFIX;, &cv-link-DLIBLINKSUFFIX;, &cv-link-DLINK;, &cv-link-DLINKCOM;, &cv-link-DLINKFLAGS;, &cv-link-DPATH;, &cv-link-DVERPREFIX;, &cv-link-DVERSIONS;, &cv-link-DVERSUFFIX;, &cv-link-RPATHPREFIX;, &cv-link-RPATHSUFFIX;, &cv-link-SHDC;, &cv-link-SHDCOM;, &cv-link-SHDLINK;, &cv-link-SHDLINKCOM;, &cv-link-SHDLINKFLAGS;, &cv-link-_DDEBUGFLAGS;, &cv-link-_DFLAGS;, &cv-link-_DINCFLAGS;, &cv-link-_DLIBDIRFLAGS;, &cv-link-_DLIBFLAGS;, &cv-link-_DLIBFLAGS;, &cv-link-_DVERFLAGS;, &cv-link-_RPATH;. +Sets: &cv-link-DC;, &cv-link-DCOM;, &cv-link-DDEBUG;, &cv-link-DDEBUGPREFIX;, &cv-link-DDEBUGSUFFIX;, &cv-link-DFILESUFFIX;, &cv-link-DFLAGPREFIX;, &cv-link-DFLAGS;, &cv-link-DFLAGSUFFIX;, &cv-link-DINCPREFIX;, &cv-link-DINCSUFFIX;, &cv-link-DLIB;, &cv-link-DLIBCOM;, &cv-link-DLIBDIRPREFIX;, &cv-link-DLIBDIRSUFFIX;, &cv-link-DLIBFLAGPREFIX;, &cv-link-DLIBFLAGSUFFIX;, &cv-link-DLIBLINKPREFIX;, &cv-link-DLIBLINKSUFFIX;, &cv-link-DLINK;, &cv-link-DLINKCOM;, &cv-link-DLINKFLAGS;, &cv-link-DPATH;, &cv-link-DVERPREFIX;, &cv-link-DVERSIONS;, &cv-link-DVERSUFFIX;, &cv-link-RPATHPREFIX;, &cv-link-RPATHSUFFIX;, &cv-link-SHDC;, &cv-link-SHDCOM;, &cv-link-SHDLINK;, &cv-link-SHDLINKCOM;, &cv-link-SHDLINKFLAGS;, &cv-link-_DDEBUGFLAGS;, &cv-link-_DFLAGS;, &cv-link-_DINCFLAGS;, &cv-link-_DLIBDIRFLAGS;, &cv-link-_DLIBFLAGS;, &cv-link-_DLIBFLAGS;, &cv-link-_DVERFLAGS;, &cv-link-_RPATH;. docbook - -This tool tries to make working with Docbook in SCons a little easier. + This tool tries to make working with Docbook in SCons a little easier. It provides several toolchains for creating different output formats, like HTML or PDF. Contained in the package is a distribution of the Docbook XSL stylesheets as of version 1.76.1. @@ -157,27 +140,27 @@ As long as you don't specify your own stylesheets for customization, these official versions are picked as default...which should reduce the inevitable setup hassles for you. -Implicit dependencies to images and XIncludes are detected automatically +Implicit dependencies to images and XIncludes are detected automatically if you meet the HTML requirements. The additional stylesheet utils/xmldepend.xsl by Paul DuBois is used for this purpose. -Note, that there is no support for XML catalog resolving offered! This tool calls +Note, that there is no support for XML catalog resolving offered! This tool calls the XSLT processors and PDF renderers with the stylesheets you specified, that's it. The rest lies in your hands and you still have to know what you're doing when resolving names via a catalog. -For activating the tool "docbook", you have to add its name to the Environment constructor, +For activating the tool "docbook", you have to add its name to the Environment constructor, like this -env = Environment(tools=['docbook']) +env = Environment(tools=['docbook']) -On its startup, the Docbook tool tries to find a required xsltproc processor, and +On its startup, the Docbook tool tries to find a required xsltproc processor, and a PDF renderer, e.g. fop. So make sure that these are added to your system's environment PATH and can be called directly, without specifying their full path. -For the most basic processing of Docbook to HTML, you need to have installed +For the most basic processing of Docbook to HTML, you need to have installed -the Python lxml binding to libxml2, or +the Python lxml binding to libxml2, or the direct Python bindings for libxml2/libxslt, or @@ -188,49 +171,49 @@ and xalan. -Rendering to PDF requires you to have one of the applications +Rendering to PDF requires you to have one of the applications fop or xep installed. -Creating a HTML or PDF document is very simple and straightforward. Say +Creating a HTML or PDF document is very simple and straightforward. Say -env = Environment(tools=['docbook']) +env = Environment(tools=['docbook']) env.DocbookHtml('manual.html', 'manual.xml') env.DocbookPdf('manual.pdf', 'manual.xml') -to get both outputs from your XML source manual.xml. As a shortcut, you can +to get both outputs from your XML source manual.xml. As a shortcut, you can give the stem of the filenames alone, like this: -env = Environment(tools=['docbook']) +env = Environment(tools=['docbook']) env.DocbookHtml('manual') env.DocbookPdf('manual') -and get the same result. Target and source lists are also supported: +and get the same result. Target and source lists are also supported: -env = Environment(tools=['docbook']) +env = Environment(tools=['docbook']) env.DocbookHtml(['manual.html','reference.html'], ['manual.xml','reference.xml']) -or even +or even -env = Environment(tools=['docbook']) +env = Environment(tools=['docbook']) env.DocbookHtml(['manual','reference']) -Whenever you leave out the list of sources, you may not specify a file extension! The +Whenever you leave out the list of sources, you may not specify a file extension! The Tool uses the given names as file stems, and adds the suffixes for target and source files accordingly. -The rules given above are valid for the Builders DocbookHtml, -DocbookPdf, DocbookEpub, DocbookSlidesPdf and DocbookXInclude. For the -DocbookMan transformation you +The rules given above are valid for the Builders DocbookHtml, +DocbookPdf, DocbookEpub, DocbookSlidesPdf and DocbookXInclude. For the +DocbookMan transformation you can specify a target name, but the actual output names are automatically set from the refname entries in your XML source. -The Builders DocbookHtmlChunked, DocbookHtmlhelp and -DocbookSlidesHtml are special, in that: +The Builders DocbookHtmlChunked, DocbookHtmlhelp and +DocbookSlidesHtml are special, in that: -they create a large set of files, where the exact names and their number depend +they create a large set of files, where the exact names and their number depend on the content of the source file, and @@ -239,24 +222,24 @@ XSL transformation is not picked up by the stylesheets. -As a result, there is simply no use in specifying a target HTML name. +As a result, there is simply no use in specifying a target HTML name. So the basic syntax for these builders is always: -env = Environment(tools=['docbook']) +env = Environment(tools=['docbook']) env.DocbookHtmlhelp('manual') -If you want to use a specific XSL file, you can set the +If you want to use a specific XSL file, you can set the additional xsl parameter to your Builder call as follows: -env.DocbookHtml('other.html', 'manual.xml', xsl='html.xsl') +env.DocbookHtml('other.html', 'manual.xml', xsl='html.xsl') -Since this may get tedious if you always use the same local naming for your customized XSL files, +Since this may get tedious if you always use the same local naming for your customized XSL files, e.g. html.xsl for HTML and pdf.xsl for PDF output, a set of variables for setting the default XSL name is provided. These are: -DOCBOOK_DEFAULT_XSL_HTML +DOCBOOK_DEFAULT_XSL_HTML DOCBOOK_DEFAULT_XSL_HTMLCHUNKED DOCBOOK_DEFAULT_XSL_HTMLHELP DOCBOOK_DEFAULT_XSL_PDF @@ -265,762 +248,680 @@ DOCBOOK_DEFAULT_XSL_MAN DOCBOOK_DEFAULT_XSL_SLIDESPDF DOCBOOK_DEFAULT_XSL_SLIDESHTML -and you can set them when constructing your environment: +and you can set them when constructing your environment: -env = Environment(tools=['docbook'], +env = Environment(tools=['docbook'], DOCBOOK_DEFAULT_XSL_HTML='html.xsl', DOCBOOK_DEFAULT_XSL_PDF='pdf.xsl') env.DocbookHtml('manual') # now uses html.xsl -Sets: &cv-link-DOCBOOK_DEFAULT_XSL_EPUB;, &cv-link-DOCBOOK_DEFAULT_XSL_HTML;, &cv-link-DOCBOOK_DEFAULT_XSL_HTMLCHUNKED;, &cv-link-DOCBOOK_DEFAULT_XSL_HTMLHELP;, &cv-link-DOCBOOK_DEFAULT_XSL_MAN;, &cv-link-DOCBOOK_DEFAULT_XSL_PDF;, &cv-link-DOCBOOK_DEFAULT_XSL_SLIDESHTML;, &cv-link-DOCBOOK_DEFAULT_XSL_SLIDESPDF;, &cv-link-DOCBOOK_FOP;, &cv-link-DOCBOOK_FOPCOM;, &cv-link-DOCBOOK_FOPFLAGS;, &cv-link-DOCBOOK_XMLLINT;, &cv-link-DOCBOOK_XMLLINTCOM;, &cv-link-DOCBOOK_XMLLINTFLAGS;, &cv-link-DOCBOOK_XSLTPROC;, &cv-link-DOCBOOK_XSLTPROCCOM;, &cv-link-DOCBOOK_XSLTPROCFLAGS;, &cv-link-DOCBOOK_XSLTPROCPARAMS;.Uses: &cv-link-DOCBOOK_FOPCOMSTR;, &cv-link-DOCBOOK_XMLLINTCOMSTR;, &cv-link-DOCBOOK_XSLTPROCCOMSTR;. +Sets: &cv-link-DOCBOOK_DEFAULT_XSL_EPUB;, &cv-link-DOCBOOK_DEFAULT_XSL_HTML;, &cv-link-DOCBOOK_DEFAULT_XSL_HTMLCHUNKED;, &cv-link-DOCBOOK_DEFAULT_XSL_HTMLHELP;, &cv-link-DOCBOOK_DEFAULT_XSL_MAN;, &cv-link-DOCBOOK_DEFAULT_XSL_PDF;, &cv-link-DOCBOOK_DEFAULT_XSL_SLIDESHTML;, &cv-link-DOCBOOK_DEFAULT_XSL_SLIDESPDF;, &cv-link-DOCBOOK_FOP;, &cv-link-DOCBOOK_FOPCOM;, &cv-link-DOCBOOK_FOPFLAGS;, &cv-link-DOCBOOK_XMLLINT;, &cv-link-DOCBOOK_XMLLINTCOM;, &cv-link-DOCBOOK_XMLLINTFLAGS;, &cv-link-DOCBOOK_XSLTPROC;, &cv-link-DOCBOOK_XSLTPROCCOM;, &cv-link-DOCBOOK_XSLTPROCFLAGS;, &cv-link-DOCBOOK_XSLTPROCPARAMS;.Uses: &cv-link-DOCBOOK_FOPCOMSTR;, &cv-link-DOCBOOK_XMLLINTCOMSTR;, &cv-link-DOCBOOK_XSLTPROCCOMSTR;. dvi - - -Attaches the DVI builder to the + +Attaches the DVI builder to the construction environment. dvipdf - - + Sets construction variables for the dvipdf utility. -Sets: &cv-link-DVIPDF;, &cv-link-DVIPDFCOM;, &cv-link-DVIPDFFLAGS;.Uses: &cv-link-DVIPDFCOMSTR;. +Sets: &cv-link-DVIPDF;, &cv-link-DVIPDFCOM;, &cv-link-DVIPDFFLAGS;.Uses: &cv-link-DVIPDFCOMSTR;. dvips - - + Sets construction variables for the dvips utility. -Sets: &cv-link-DVIPS;, &cv-link-DVIPSFLAGS;, &cv-link-PSCOM;, &cv-link-PSPREFIX;, &cv-link-PSSUFFIX;.Uses: &cv-link-PSCOMSTR;. +Sets: &cv-link-DVIPS;, &cv-link-DVIPSFLAGS;, &cv-link-PSCOM;, &cv-link-PSPREFIX;, &cv-link-PSSUFFIX;.Uses: &cv-link-PSCOMSTR;. f03 - - + Set construction variables for generic POSIX Fortran 03 compilers. -Sets: &cv-link-F03;, &cv-link-F03COM;, &cv-link-F03FLAGS;, &cv-link-F03PPCOM;, &cv-link-SHF03;, &cv-link-SHF03COM;, &cv-link-SHF03FLAGS;, &cv-link-SHF03PPCOM;, &cv-link-_F03INCFLAGS;.Uses: &cv-link-F03COMSTR;, &cv-link-F03PPCOMSTR;, &cv-link-SHF03COMSTR;, &cv-link-SHF03PPCOMSTR;. +Sets: &cv-link-F03;, &cv-link-F03COM;, &cv-link-F03FLAGS;, &cv-link-F03PPCOM;, &cv-link-SHF03;, &cv-link-SHF03COM;, &cv-link-SHF03FLAGS;, &cv-link-SHF03PPCOM;, &cv-link-_F03INCFLAGS;.Uses: &cv-link-F03COMSTR;, &cv-link-F03PPCOMSTR;, &cv-link-SHF03COMSTR;, &cv-link-SHF03PPCOMSTR;. f08 - - + Set construction variables for generic POSIX Fortran 08 compilers. -Sets: &cv-link-F08;, &cv-link-F08COM;, &cv-link-F08FLAGS;, &cv-link-F08PPCOM;, &cv-link-SHF08;, &cv-link-SHF08COM;, &cv-link-SHF08FLAGS;, &cv-link-SHF08PPCOM;, &cv-link-_F08INCFLAGS;.Uses: &cv-link-F08COMSTR;, &cv-link-F08PPCOMSTR;, &cv-link-SHF08COMSTR;, &cv-link-SHF08PPCOMSTR;. +Sets: &cv-link-F08;, &cv-link-F08COM;, &cv-link-F08FLAGS;, &cv-link-F08PPCOM;, &cv-link-SHF08;, &cv-link-SHF08COM;, &cv-link-SHF08FLAGS;, &cv-link-SHF08PPCOM;, &cv-link-_F08INCFLAGS;.Uses: &cv-link-F08COMSTR;, &cv-link-F08PPCOMSTR;, &cv-link-SHF08COMSTR;, &cv-link-SHF08PPCOMSTR;. f77 - - + Set construction variables for generic POSIX Fortran 77 compilers. -Sets: &cv-link-F77;, &cv-link-F77COM;, &cv-link-F77FILESUFFIXES;, &cv-link-F77FLAGS;, &cv-link-F77PPCOM;, &cv-link-F77PPFILESUFFIXES;, &cv-link-FORTRAN;, &cv-link-FORTRANCOM;, &cv-link-FORTRANFLAGS;, &cv-link-SHF77;, &cv-link-SHF77COM;, &cv-link-SHF77FLAGS;, &cv-link-SHF77PPCOM;, &cv-link-SHFORTRAN;, &cv-link-SHFORTRANCOM;, &cv-link-SHFORTRANFLAGS;, &cv-link-SHFORTRANPPCOM;, &cv-link-_F77INCFLAGS;.Uses: &cv-link-F77COMSTR;, &cv-link-F77PPCOMSTR;, &cv-link-FORTRANCOMSTR;, &cv-link-FORTRANPPCOMSTR;, &cv-link-SHF77COMSTR;, &cv-link-SHF77PPCOMSTR;, &cv-link-SHFORTRANCOMSTR;, &cv-link-SHFORTRANPPCOMSTR;. +Sets: &cv-link-F77;, &cv-link-F77COM;, &cv-link-F77FILESUFFIXES;, &cv-link-F77FLAGS;, &cv-link-F77PPCOM;, &cv-link-F77PPFILESUFFIXES;, &cv-link-FORTRAN;, &cv-link-FORTRANCOM;, &cv-link-FORTRANFLAGS;, &cv-link-SHF77;, &cv-link-SHF77COM;, &cv-link-SHF77FLAGS;, &cv-link-SHF77PPCOM;, &cv-link-SHFORTRAN;, &cv-link-SHFORTRANCOM;, &cv-link-SHFORTRANFLAGS;, &cv-link-SHFORTRANPPCOM;, &cv-link-_F77INCFLAGS;.Uses: &cv-link-F77COMSTR;, &cv-link-F77PPCOMSTR;, &cv-link-FORTRANCOMSTR;, &cv-link-FORTRANPPCOMSTR;, &cv-link-SHF77COMSTR;, &cv-link-SHF77PPCOMSTR;, &cv-link-SHFORTRANCOMSTR;, &cv-link-SHFORTRANPPCOMSTR;. f90 - - + Set construction variables for generic POSIX Fortran 90 compilers. -Sets: &cv-link-F90;, &cv-link-F90COM;, &cv-link-F90FLAGS;, &cv-link-F90PPCOM;, &cv-link-SHF90;, &cv-link-SHF90COM;, &cv-link-SHF90FLAGS;, &cv-link-SHF90PPCOM;, &cv-link-_F90INCFLAGS;.Uses: &cv-link-F90COMSTR;, &cv-link-F90PPCOMSTR;, &cv-link-SHF90COMSTR;, &cv-link-SHF90PPCOMSTR;. +Sets: &cv-link-F90;, &cv-link-F90COM;, &cv-link-F90FLAGS;, &cv-link-F90PPCOM;, &cv-link-SHF90;, &cv-link-SHF90COM;, &cv-link-SHF90FLAGS;, &cv-link-SHF90PPCOM;, &cv-link-_F90INCFLAGS;.Uses: &cv-link-F90COMSTR;, &cv-link-F90PPCOMSTR;, &cv-link-SHF90COMSTR;, &cv-link-SHF90PPCOMSTR;. f95 - - + Set construction variables for generic POSIX Fortran 95 compilers. -Sets: &cv-link-F95;, &cv-link-F95COM;, &cv-link-F95FLAGS;, &cv-link-F95PPCOM;, &cv-link-SHF95;, &cv-link-SHF95COM;, &cv-link-SHF95FLAGS;, &cv-link-SHF95PPCOM;, &cv-link-_F95INCFLAGS;.Uses: &cv-link-F95COMSTR;, &cv-link-F95PPCOMSTR;, &cv-link-SHF95COMSTR;, &cv-link-SHF95PPCOMSTR;. +Sets: &cv-link-F95;, &cv-link-F95COM;, &cv-link-F95FLAGS;, &cv-link-F95PPCOM;, &cv-link-SHF95;, &cv-link-SHF95COM;, &cv-link-SHF95FLAGS;, &cv-link-SHF95PPCOM;, &cv-link-_F95INCFLAGS;.Uses: &cv-link-F95COMSTR;, &cv-link-F95PPCOMSTR;, &cv-link-SHF95COMSTR;, &cv-link-SHF95PPCOMSTR;. fortran - - + Set construction variables for generic POSIX Fortran compilers. -Sets: &cv-link-FORTRAN;, &cv-link-FORTRANCOM;, &cv-link-FORTRANFLAGS;, &cv-link-SHFORTRAN;, &cv-link-SHFORTRANCOM;, &cv-link-SHFORTRANFLAGS;, &cv-link-SHFORTRANPPCOM;.Uses: &cv-link-FORTRANCOMSTR;, &cv-link-FORTRANPPCOMSTR;, &cv-link-SHFORTRANCOMSTR;, &cv-link-SHFORTRANPPCOMSTR;. +Sets: &cv-link-FORTRAN;, &cv-link-FORTRANCOM;, &cv-link-FORTRANFLAGS;, &cv-link-SHFORTRAN;, &cv-link-SHFORTRANCOM;, &cv-link-SHFORTRANFLAGS;, &cv-link-SHFORTRANPPCOM;.Uses: &cv-link-FORTRANCOMSTR;, &cv-link-FORTRANPPCOMSTR;, &cv-link-SHFORTRANCOMSTR;, &cv-link-SHFORTRANPPCOMSTR;. g++ - - -Set construction variables for the gXX C++ compiler. + +Set construction variables for the gXX C++ compiler. -Sets: &cv-link-CXX;, &cv-link-CXXVERSION;, &cv-link-SHCXXFLAGS;, &cv-link-SHOBJSUFFIX;. +Sets: &cv-link-CXX;, &cv-link-CXXVERSION;, &cv-link-SHCXXFLAGS;, &cv-link-SHOBJSUFFIX;. g77 - - -Set construction variables for the g77 Fortran compiler. -Calls the f77 Tool module + +Set construction variables for the g77 Fortran compiler. +Calls the f77 Tool module to set variables. gas - - -Sets construction variables for the gas assembler. -Calls the as module. + +Sets construction variables for the gas assembler. +Calls the as module. -Sets: &cv-link-AS;. +Sets: &cv-link-AS;. gcc - - -Set construction variables for the gcc C compiler. + +Set construction variables for the gcc C compiler. -Sets: &cv-link-CC;, &cv-link-CCVERSION;, &cv-link-SHCCFLAGS;. +Sets: &cv-link-CC;, &cv-link-CCVERSION;, &cv-link-SHCCFLAGS;. gdc - - + Sets construction variables for the D language compiler GDC. -Sets: &cv-link-DC;, &cv-link-DCOM;, &cv-link-DDEBUG;, &cv-link-DDEBUGPREFIX;, &cv-link-DDEBUGSUFFIX;, &cv-link-DFILESUFFIX;, &cv-link-DFLAGPREFIX;, &cv-link-DFLAGS;, &cv-link-DFLAGSUFFIX;, &cv-link-DINCPREFIX;, &cv-link-DINCSUFFIX;, &cv-link-DLIB;, &cv-link-DLIBCOM;, &cv-link-DLIBFLAGPREFIX;, &cv-link-DLIBFLAGSUFFIX;, &cv-link-DLINK;, &cv-link-DLINKCOM;, &cv-link-DLINKFLAGPREFIX;, &cv-link-DLINKFLAGS;, &cv-link-DLINKFLAGSUFFIX;, &cv-link-DPATH;, &cv-link-DVERPREFIX;, &cv-link-DVERSIONS;, &cv-link-DVERSUFFIX;, &cv-link-RPATHPREFIX;, &cv-link-RPATHSUFFIX;, &cv-link-SHDC;, &cv-link-SHDCOM;, &cv-link-SHDLINK;, &cv-link-SHDLINKCOM;, &cv-link-SHDLINKFLAGS;, &cv-link-_DDEBUGFLAGS;, &cv-link-_DFLAGS;, &cv-link-_DINCFLAGS;, &cv-link-_DLIBFLAGS;, &cv-link-_DVERFLAGS;, &cv-link-_RPATH;. +Sets: &cv-link-DC;, &cv-link-DCOM;, &cv-link-DDEBUG;, &cv-link-DDEBUGPREFIX;, &cv-link-DDEBUGSUFFIX;, &cv-link-DFILESUFFIX;, &cv-link-DFLAGPREFIX;, &cv-link-DFLAGS;, &cv-link-DFLAGSUFFIX;, &cv-link-DINCPREFIX;, &cv-link-DINCSUFFIX;, &cv-link-DLIB;, &cv-link-DLIBCOM;, &cv-link-DLIBFLAGPREFIX;, &cv-link-DLIBFLAGSUFFIX;, &cv-link-DLINK;, &cv-link-DLINKCOM;, &cv-link-DLINKFLAGPREFIX;, &cv-link-DLINKFLAGS;, &cv-link-DLINKFLAGSUFFIX;, &cv-link-DPATH;, &cv-link-DVERPREFIX;, &cv-link-DVERSIONS;, &cv-link-DVERSUFFIX;, &cv-link-RPATHPREFIX;, &cv-link-RPATHSUFFIX;, &cv-link-SHDC;, &cv-link-SHDCOM;, &cv-link-SHDLINK;, &cv-link-SHDLINKCOM;, &cv-link-SHDLINKFLAGS;, &cv-link-_DDEBUGFLAGS;, &cv-link-_DFLAGS;, &cv-link-_DINCFLAGS;, &cv-link-_DLIBFLAGS;, &cv-link-_DVERFLAGS;, &cv-link-_RPATH;. gettext - - + This is actually a toolset, which supports internationalization and localization of sofware being constructed with SCons. The toolset loads following tools: - + - xgettext - to extract internationalized messages from source code to + xgettext - to extract internationalized messages from source code to POT file(s), - msginit - may be optionally used to initialize PO + msginit - may be optionally used to initialize PO files, - msgmerge - to update PO files, that already contain + msgmerge - to update PO files, that already contain translated messages, - msgfmt - to compile textual PO file to binary + msgfmt - to compile textual PO file to binary installable MO file. - -When you enable gettext, it internally loads all abovementioned tools, + +When you enable gettext, it internally loads all abovementioned tools, so you're encouraged to see their individual documentation. - + Each of the above tools provides its own builder(s) which may be used to perform particular activities related to software internationalization. You may be however interested in top-level builder -Translate described few paragraphs later. +Translate described few paragraphs later. - -To use gettext tools add 'gettext' tool to your + +To use gettext tools add 'gettext' tool to your environment: - + env = Environment( tools = ['default', 'gettext'] ) gfortran - - + Sets construction variables for the GNU F95/F2003 GNU compiler. -Sets: &cv-link-F77;, &cv-link-F90;, &cv-link-F95;, &cv-link-FORTRAN;, &cv-link-SHF77;, &cv-link-SHF77FLAGS;, &cv-link-SHF90;, &cv-link-SHF90FLAGS;, &cv-link-SHF95;, &cv-link-SHF95FLAGS;, &cv-link-SHFORTRAN;, &cv-link-SHFORTRANFLAGS;. +Sets: &cv-link-F77;, &cv-link-F90;, &cv-link-F95;, &cv-link-FORTRAN;, &cv-link-SHF77;, &cv-link-SHF77FLAGS;, &cv-link-SHF90;, &cv-link-SHF90FLAGS;, &cv-link-SHF95;, &cv-link-SHF95FLAGS;, &cv-link-SHFORTRAN;, &cv-link-SHFORTRANFLAGS;. gnulink - - + Set construction variables for GNU linker/loader. -Sets: &cv-link-RPATHPREFIX;, &cv-link-RPATHSUFFIX;, &cv-link-SHLINKFLAGS;. +Sets: &cv-link-RPATHPREFIX;, &cv-link-RPATHSUFFIX;, &cv-link-SHLINKFLAGS;. gs - - + This Tool sets the required construction variables for working with the Ghostscript command. It also registers an appropriate Action -with the PDF Builder (PDF), such that the conversion from +with the PDF Builder (PDF), such that the conversion from PS/EPS to PDF happens automatically for the TeX/LaTeX toolchain. -Finally, it adds an explicit Ghostscript Builder (Gs) to the +Finally, it adds an explicit Ghostscript Builder (Gs) to the environment. -Sets: &cv-link-GS;, &cv-link-GSCOM;, &cv-link-GSFLAGS;.Uses: &cv-link-GSCOMSTR;. +Sets: &cv-link-GS;, &cv-link-GSCOM;, &cv-link-GSFLAGS;.Uses: &cv-link-GSCOMSTR;. hpc++ - - + Set construction variables for the compilers aCC on HP/UX systems. hpcc - - + Set construction variables for the aCC on HP/UX systems. -Calls the cXX tool for additional variables. +Calls the cXX tool for additional variables. -Sets: &cv-link-CXX;, &cv-link-CXXVERSION;, &cv-link-SHCXXFLAGS;. +Sets: &cv-link-CXX;, &cv-link-CXXVERSION;, &cv-link-SHCXXFLAGS;. hplink - - + Sets construction variables for the linker on HP/UX systems. -Sets: &cv-link-LINKFLAGS;, &cv-link-SHLIBSUFFIX;, &cv-link-SHLINKFLAGS;. +Sets: &cv-link-LINKFLAGS;, &cv-link-SHLIBSUFFIX;, &cv-link-SHLINKFLAGS;. icc - - + Sets construction variables for the icc compiler on OS/2 systems. -Sets: &cv-link-CC;, &cv-link-CCCOM;, &cv-link-CFILESUFFIX;, &cv-link-CPPDEFPREFIX;, &cv-link-CPPDEFSUFFIX;, &cv-link-CXXCOM;, &cv-link-CXXFILESUFFIX;, &cv-link-INCPREFIX;, &cv-link-INCSUFFIX;.Uses: &cv-link-CCFLAGS;, &cv-link-CFLAGS;, &cv-link-CPPFLAGS;, &cv-link-_CPPDEFFLAGS;, &cv-link-_CPPINCFLAGS;. +Sets: &cv-link-CC;, &cv-link-CCCOM;, &cv-link-CFILESUFFIX;, &cv-link-CPPDEFPREFIX;, &cv-link-CPPDEFSUFFIX;, &cv-link-CXXCOM;, &cv-link-CXXFILESUFFIX;, &cv-link-INCPREFIX;, &cv-link-INCSUFFIX;.Uses: &cv-link-CCFLAGS;, &cv-link-CFLAGS;, &cv-link-CPPFLAGS;, &cv-link-_CPPDEFFLAGS;, &cv-link-_CPPINCFLAGS;. icl - - + Sets construction variables for the Intel C/C++ compiler. -Calls the intelc Tool module to set its variables. +Calls the intelc Tool module to set its variables. ifl - - + Sets construction variables for the Intel Fortran compiler. -Sets: &cv-link-FORTRAN;, &cv-link-FORTRANCOM;, &cv-link-FORTRANPPCOM;, &cv-link-SHFORTRANCOM;, &cv-link-SHFORTRANPPCOM;.Uses: &cv-link-CPPFLAGS;, &cv-link-FORTRANFLAGS;, &cv-link-_CPPDEFFLAGS;, &cv-link-_FORTRANINCFLAGS;. +Sets: &cv-link-FORTRAN;, &cv-link-FORTRANCOM;, &cv-link-FORTRANPPCOM;, &cv-link-SHFORTRANCOM;, &cv-link-SHFORTRANPPCOM;.Uses: &cv-link-CPPFLAGS;, &cv-link-FORTRANFLAGS;, &cv-link-_CPPDEFFLAGS;, &cv-link-_FORTRANINCFLAGS;. ifort - - + Sets construction variables for newer versions of the Intel Fortran compiler for Linux. -Sets: &cv-link-F77;, &cv-link-F90;, &cv-link-F95;, &cv-link-FORTRAN;, &cv-link-SHF77;, &cv-link-SHF77FLAGS;, &cv-link-SHF90;, &cv-link-SHF90FLAGS;, &cv-link-SHF95;, &cv-link-SHF95FLAGS;, &cv-link-SHFORTRAN;, &cv-link-SHFORTRANFLAGS;. +Sets: &cv-link-F77;, &cv-link-F90;, &cv-link-F95;, &cv-link-FORTRAN;, &cv-link-SHF77;, &cv-link-SHF77FLAGS;, &cv-link-SHF90;, &cv-link-SHF90FLAGS;, &cv-link-SHF95;, &cv-link-SHF95FLAGS;, &cv-link-SHFORTRAN;, &cv-link-SHFORTRANFLAGS;. ilink - - + Sets construction variables for the ilink linker on OS/2 systems. -Sets: &cv-link-LIBDIRPREFIX;, &cv-link-LIBDIRSUFFIX;, &cv-link-LIBLINKPREFIX;, &cv-link-LIBLINKSUFFIX;, &cv-link-LINK;, &cv-link-LINKCOM;, &cv-link-LINKFLAGS;. +Sets: &cv-link-LIBDIRPREFIX;, &cv-link-LIBDIRSUFFIX;, &cv-link-LIBLINKPREFIX;, &cv-link-LIBLINKSUFFIX;, &cv-link-LINK;, &cv-link-LINKCOM;, &cv-link-LINKFLAGS;. ilink32 - - + Sets construction variables for the Borland ilink32 linker. -Sets: &cv-link-LIBDIRPREFIX;, &cv-link-LIBDIRSUFFIX;, &cv-link-LIBLINKPREFIX;, &cv-link-LIBLINKSUFFIX;, &cv-link-LINK;, &cv-link-LINKCOM;, &cv-link-LINKFLAGS;. +Sets: &cv-link-LIBDIRPREFIX;, &cv-link-LIBDIRSUFFIX;, &cv-link-LIBLINKPREFIX;, &cv-link-LIBLINKSUFFIX;, &cv-link-LINK;, &cv-link-LINKCOM;, &cv-link-LINKFLAGS;. install - - + Sets construction variables for file and directory installation. -Sets: &cv-link-INSTALL;, &cv-link-INSTALLSTR;. +Sets: &cv-link-INSTALL;, &cv-link-INSTALLSTR;. intelc - - + Sets construction variables for the Intel C/C++ compiler (Linux and Windows, version 7 and later). -Calls the gcc or msvc +Calls the gcc or msvc (on Linux and Windows, respectively) to set underlying variables. -Sets: &cv-link-AR;, &cv-link-CC;, &cv-link-CXX;, &cv-link-INTEL_C_COMPILER_VERSION;, &cv-link-LINK;. +Sets: &cv-link-AR;, &cv-link-CC;, &cv-link-CXX;, &cv-link-INTEL_C_COMPILER_VERSION;, &cv-link-LINK;. jar - - -Sets construction variables for the jar utility. + +Sets construction variables for the jar utility. -Sets: &cv-link-JAR;, &cv-link-JARCOM;, &cv-link-JARFLAGS;, &cv-link-JARSUFFIX;.Uses: &cv-link-JARCOMSTR;. +Sets: &cv-link-JAR;, &cv-link-JARCOM;, &cv-link-JARFLAGS;, &cv-link-JARSUFFIX;.Uses: &cv-link-JARCOMSTR;. javac - - -Sets construction variables for the javac compiler. + +Sets construction variables for the javac compiler. -Sets: &cv-link-JAVABOOTCLASSPATH;, &cv-link-JAVAC;, &cv-link-JAVACCOM;, &cv-link-JAVACFLAGS;, &cv-link-JAVACLASSPATH;, &cv-link-JAVACLASSSUFFIX;, &cv-link-JAVASOURCEPATH;, &cv-link-JAVASUFFIX;.Uses: &cv-link-JAVACCOMSTR;. +Sets: &cv-link-JAVABOOTCLASSPATH;, &cv-link-JAVAC;, &cv-link-JAVACCOM;, &cv-link-JAVACFLAGS;, &cv-link-JAVACLASSPATH;, &cv-link-JAVACLASSSUFFIX;, &cv-link-JAVASOURCEPATH;, &cv-link-JAVASUFFIX;.Uses: &cv-link-JAVACCOMSTR;. javah - - -Sets construction variables for the javah tool. + +Sets construction variables for the javah tool. -Sets: &cv-link-JAVACLASSSUFFIX;, &cv-link-JAVAH;, &cv-link-JAVAHCOM;, &cv-link-JAVAHFLAGS;.Uses: &cv-link-JAVACLASSPATH;, &cv-link-JAVAHCOMSTR;. +Sets: &cv-link-JAVACLASSSUFFIX;, &cv-link-JAVAH;, &cv-link-JAVAHCOM;, &cv-link-JAVAHFLAGS;.Uses: &cv-link-JAVACLASSPATH;, &cv-link-JAVAHCOMSTR;. latex - - -Sets construction variables for the latex utility. + +Sets construction variables for the latex utility. -Sets: &cv-link-LATEX;, &cv-link-LATEXCOM;, &cv-link-LATEXFLAGS;.Uses: &cv-link-LATEXCOMSTR;. +Sets: &cv-link-LATEX;, &cv-link-LATEXCOM;, &cv-link-LATEXFLAGS;.Uses: &cv-link-LATEXCOMSTR;. ldc - - + Sets construction variables for the D language compiler LDC2. -Sets: &cv-link-DC;, &cv-link-DCOM;, &cv-link-DDEBUG;, &cv-link-DDEBUGPREFIX;, &cv-link-DDEBUGSUFFIX;, &cv-link-DFILESUFFIX;, &cv-link-DFLAGPREFIX;, &cv-link-DFLAGS;, &cv-link-DFLAGSUFFIX;, &cv-link-DINCPREFIX;, &cv-link-DINCSUFFIX;, &cv-link-DLIB;, &cv-link-DLIBCOM;, &cv-link-DLIBDIRPREFIX;, &cv-link-DLIBDIRSUFFIX;, &cv-link-DLIBFLAGPREFIX;, &cv-link-DLIBFLAGSUFFIX;, &cv-link-DLIBLINKPREFIX;, &cv-link-DLIBLINKSUFFIX;, &cv-link-DLINK;, &cv-link-DLINKCOM;, &cv-link-DLINKFLAGPREFIX;, &cv-link-DLINKFLAGS;, &cv-link-DLINKFLAGSUFFIX;, &cv-link-DPATH;, &cv-link-DVERPREFIX;, &cv-link-DVERSIONS;, &cv-link-DVERSUFFIX;, &cv-link-RPATHPREFIX;, &cv-link-RPATHSUFFIX;, &cv-link-SHDC;, &cv-link-SHDCOM;, &cv-link-SHDLINK;, &cv-link-SHDLINKCOM;, &cv-link-SHDLINKFLAGS;, &cv-link-_DDEBUGFLAGS;, &cv-link-_DFLAGS;, &cv-link-_DINCFLAGS;, &cv-link-_DLIBDIRFLAGS;, &cv-link-_DLIBFLAGS;, &cv-link-_DLIBFLAGS;, &cv-link-_DVERFLAGS;, &cv-link-_RPATH;. +Sets: &cv-link-DC;, &cv-link-DCOM;, &cv-link-DDEBUG;, &cv-link-DDEBUGPREFIX;, &cv-link-DDEBUGSUFFIX;, &cv-link-DFILESUFFIX;, &cv-link-DFLAGPREFIX;, &cv-link-DFLAGS;, &cv-link-DFLAGSUFFIX;, &cv-link-DINCPREFIX;, &cv-link-DINCSUFFIX;, &cv-link-DLIB;, &cv-link-DLIBCOM;, &cv-link-DLIBDIRPREFIX;, &cv-link-DLIBDIRSUFFIX;, &cv-link-DLIBFLAGPREFIX;, &cv-link-DLIBFLAGSUFFIX;, &cv-link-DLIBLINKPREFIX;, &cv-link-DLIBLINKSUFFIX;, &cv-link-DLINK;, &cv-link-DLINKCOM;, &cv-link-DLINKFLAGPREFIX;, &cv-link-DLINKFLAGS;, &cv-link-DLINKFLAGSUFFIX;, &cv-link-DPATH;, &cv-link-DVERPREFIX;, &cv-link-DVERSIONS;, &cv-link-DVERSUFFIX;, &cv-link-RPATHPREFIX;, &cv-link-RPATHSUFFIX;, &cv-link-SHDC;, &cv-link-SHDCOM;, &cv-link-SHDLINK;, &cv-link-SHDLINKCOM;, &cv-link-SHDLINKFLAGS;, &cv-link-_DDEBUGFLAGS;, &cv-link-_DFLAGS;, &cv-link-_DINCFLAGS;, &cv-link-_DLIBDIRFLAGS;, &cv-link-_DLIBFLAGS;, &cv-link-_DLIBFLAGS;, &cv-link-_DVERFLAGS;, &cv-link-_RPATH;. lex - - -Sets construction variables for the lex lexical analyser. + +Sets construction variables for the lex lexical analyser. -Sets: &cv-link-LEX;, &cv-link-LEXCOM;, &cv-link-LEXFLAGS;.Uses: &cv-link-LEXCOMSTR;. +Sets: &cv-link-LEX;, &cv-link-LEXCOM;, &cv-link-LEXFLAGS;.Uses: &cv-link-LEXCOMSTR;. link - - + Sets construction variables for generic POSIX linkers. -Sets: &cv-link-LDMODULE;, &cv-link-LDMODULECOM;, &cv-link-LDMODULEFLAGS;, &cv-link-LDMODULEPREFIX;, &cv-link-LDMODULESUFFIX;, &cv-link-LIBDIRPREFIX;, &cv-link-LIBDIRSUFFIX;, &cv-link-LIBLINKPREFIX;, &cv-link-LIBLINKSUFFIX;, &cv-link-LINK;, &cv-link-LINKCOM;, &cv-link-LINKFLAGS;, &cv-link-SHLIBSUFFIX;, &cv-link-SHLINK;, &cv-link-SHLINKCOM;, &cv-link-SHLINKFLAGS;.Uses: &cv-link-LDMODULECOMSTR;, &cv-link-LINKCOMSTR;, &cv-link-SHLINKCOMSTR;. +Sets: &cv-link-LDMODULE;, &cv-link-LDMODULECOM;, &cv-link-LDMODULEFLAGS;, &cv-link-LDMODULEPREFIX;, &cv-link-LDMODULESUFFIX;, &cv-link-LIBDIRPREFIX;, &cv-link-LIBDIRSUFFIX;, &cv-link-LIBLINKPREFIX;, &cv-link-LIBLINKSUFFIX;, &cv-link-LINK;, &cv-link-LINKCOM;, &cv-link-LINKFLAGS;, &cv-link-SHLIBSUFFIX;, &cv-link-SHLINK;, &cv-link-SHLINKCOM;, &cv-link-SHLINKFLAGS;.Uses: &cv-link-LDMODULECOMSTR;, &cv-link-LINKCOMSTR;, &cv-link-SHLINKCOMSTR;. linkloc - - + Sets construction variables for the LinkLoc linker for the Phar Lap ETS embedded operating system. -Sets: &cv-link-LIBDIRPREFIX;, &cv-link-LIBDIRSUFFIX;, &cv-link-LIBLINKPREFIX;, &cv-link-LIBLINKSUFFIX;, &cv-link-LINK;, &cv-link-LINKCOM;, &cv-link-LINKFLAGS;, &cv-link-SHLINK;, &cv-link-SHLINKCOM;, &cv-link-SHLINKFLAGS;.Uses: &cv-link-LINKCOMSTR;, &cv-link-SHLINKCOMSTR;. +Sets: &cv-link-LIBDIRPREFIX;, &cv-link-LIBDIRSUFFIX;, &cv-link-LIBLINKPREFIX;, &cv-link-LIBLINKSUFFIX;, &cv-link-LINK;, &cv-link-LINKCOM;, &cv-link-LINKFLAGS;, &cv-link-SHLINK;, &cv-link-SHLINKCOM;, &cv-link-SHLINKFLAGS;.Uses: &cv-link-LINKCOMSTR;, &cv-link-SHLINKCOMSTR;. m4 - - -Sets construction variables for the m4 macro processor. + +Sets construction variables for the m4 macro processor. -Sets: &cv-link-M4;, &cv-link-M4COM;, &cv-link-M4FLAGS;.Uses: &cv-link-M4COMSTR;. +Sets: &cv-link-M4;, &cv-link-M4COM;, &cv-link-M4FLAGS;.Uses: &cv-link-M4COMSTR;. masm - - + Sets construction variables for the Microsoft assembler. -Sets: &cv-link-AS;, &cv-link-ASCOM;, &cv-link-ASFLAGS;, &cv-link-ASPPCOM;, &cv-link-ASPPFLAGS;.Uses: &cv-link-ASCOMSTR;, &cv-link-ASPPCOMSTR;, &cv-link-CPPFLAGS;, &cv-link-_CPPDEFFLAGS;, &cv-link-_CPPINCFLAGS;. +Sets: &cv-link-AS;, &cv-link-ASCOM;, &cv-link-ASFLAGS;, &cv-link-ASPPCOM;, &cv-link-ASPPFLAGS;.Uses: &cv-link-ASCOMSTR;, &cv-link-ASPPCOMSTR;, &cv-link-CPPFLAGS;, &cv-link-_CPPDEFFLAGS;, &cv-link-_CPPINCFLAGS;. midl - - + Sets construction variables for the Microsoft IDL compiler. -Sets: &cv-link-MIDL;, &cv-link-MIDLCOM;, &cv-link-MIDLFLAGS;.Uses: &cv-link-MIDLCOMSTR;. +Sets: &cv-link-MIDL;, &cv-link-MIDLCOM;, &cv-link-MIDLFLAGS;.Uses: &cv-link-MIDLCOMSTR;. mingw - - + Sets construction variables for MinGW (Minimal Gnu on Windows). -Sets: &cv-link-AS;, &cv-link-CC;, &cv-link-CXX;, &cv-link-LDMODULECOM;, &cv-link-LIBPREFIX;, &cv-link-LIBSUFFIX;, &cv-link-OBJSUFFIX;, &cv-link-RC;, &cv-link-RCCOM;, &cv-link-RCFLAGS;, &cv-link-RCINCFLAGS;, &cv-link-RCINCPREFIX;, &cv-link-RCINCSUFFIX;, &cv-link-SHCCFLAGS;, &cv-link-SHCXXFLAGS;, &cv-link-SHLINKCOM;, &cv-link-SHLINKFLAGS;, &cv-link-SHOBJSUFFIX;, &cv-link-WINDOWSDEFPREFIX;, &cv-link-WINDOWSDEFSUFFIX;.Uses: &cv-link-RCCOMSTR;, &cv-link-SHLINKCOMSTR;. +Sets: &cv-link-AS;, &cv-link-CC;, &cv-link-CXX;, &cv-link-LDMODULECOM;, &cv-link-LIBPREFIX;, &cv-link-LIBSUFFIX;, &cv-link-OBJSUFFIX;, &cv-link-RC;, &cv-link-RCCOM;, &cv-link-RCFLAGS;, &cv-link-RCINCFLAGS;, &cv-link-RCINCPREFIX;, &cv-link-RCINCSUFFIX;, &cv-link-SHCCFLAGS;, &cv-link-SHCXXFLAGS;, &cv-link-SHLINKCOM;, &cv-link-SHLINKFLAGS;, &cv-link-SHOBJSUFFIX;, &cv-link-WINDOWSDEFPREFIX;, &cv-link-WINDOWSDEFSUFFIX;.Uses: &cv-link-RCCOMSTR;, &cv-link-SHLINKCOMSTR;. msgfmt - - -This scons tool is a part of scons gettext toolset. It provides scons + +This scons tool is a part of scons gettext toolset. It provides scons interface to msgfmt(1) command, which generates binary message catalog (MO) from a textual translation description (PO). -Sets: &cv-link-MOSUFFIX;, &cv-link-MSGFMT;, &cv-link-MSGFMTCOM;, &cv-link-MSGFMTCOMSTR;, &cv-link-MSGFMTFLAGS;, &cv-link-POSUFFIX;.Uses: &cv-link-LINGUAS_FILE;. +Sets: &cv-link-MOSUFFIX;, &cv-link-MSGFMT;, &cv-link-MSGFMTCOM;, &cv-link-MSGFMTCOMSTR;, &cv-link-MSGFMTFLAGS;, &cv-link-POSUFFIX;.Uses: &cv-link-LINGUAS_FILE;. msginit - - -This scons tool is a part of scons gettext toolset. It provides + +This scons tool is a part of scons gettext toolset. It provides scons interface to msginit(1) program, which creates new PO file, initializing the meta information with values from user's environment (or options). -Sets: &cv-link-MSGINIT;, &cv-link-MSGINITCOM;, &cv-link-MSGINITCOMSTR;, &cv-link-MSGINITFLAGS;, &cv-link-POAUTOINIT;, &cv-link-POCREATE_ALIAS;, &cv-link-POSUFFIX;, &cv-link-POTSUFFIX;, &cv-link-_MSGINITLOCALE;.Uses: &cv-link-LINGUAS_FILE;, &cv-link-POAUTOINIT;, &cv-link-POTDOMAIN;. +Sets: &cv-link-MSGINIT;, &cv-link-MSGINITCOM;, &cv-link-MSGINITCOMSTR;, &cv-link-MSGINITFLAGS;, &cv-link-POAUTOINIT;, &cv-link-POCREATE_ALIAS;, &cv-link-POSUFFIX;, &cv-link-POTSUFFIX;, &cv-link-_MSGINITLOCALE;.Uses: &cv-link-LINGUAS_FILE;, &cv-link-POAUTOINIT;, &cv-link-POTDOMAIN;. msgmerge - - -This scons tool is a part of scons gettext toolset. It provides + +This scons tool is a part of scons gettext toolset. It provides scons interface to msgmerge(1) command, which merges two Uniform style .po files together. -Sets: &cv-link-MSGMERGE;, &cv-link-MSGMERGECOM;, &cv-link-MSGMERGECOMSTR;, &cv-link-MSGMERGEFLAGS;, &cv-link-POSUFFIX;, &cv-link-POTSUFFIX;, &cv-link-POUPDATE_ALIAS;.Uses: &cv-link-LINGUAS_FILE;, &cv-link-POAUTOINIT;, &cv-link-POTDOMAIN;. +Sets: &cv-link-MSGMERGE;, &cv-link-MSGMERGECOM;, &cv-link-MSGMERGECOMSTR;, &cv-link-MSGMERGEFLAGS;, &cv-link-POSUFFIX;, &cv-link-POTSUFFIX;, &cv-link-POUPDATE_ALIAS;.Uses: &cv-link-LINGUAS_FILE;, &cv-link-POAUTOINIT;, &cv-link-POTDOMAIN;. mslib - - + Sets construction variables for the Microsoft mslib library archiver. -Sets: &cv-link-AR;, &cv-link-ARCOM;, &cv-link-ARFLAGS;, &cv-link-LIBPREFIX;, &cv-link-LIBSUFFIX;.Uses: &cv-link-ARCOMSTR;. +Sets: &cv-link-AR;, &cv-link-ARCOM;, &cv-link-ARFLAGS;, &cv-link-LIBPREFIX;, &cv-link-LIBSUFFIX;.Uses: &cv-link-ARCOMSTR;. mslink - - + Sets construction variables for the Microsoft linker. -Sets: &cv-link-LDMODULE;, &cv-link-LDMODULECOM;, &cv-link-LDMODULEFLAGS;, &cv-link-LDMODULEPREFIX;, &cv-link-LDMODULESUFFIX;, &cv-link-LIBDIRPREFIX;, &cv-link-LIBDIRSUFFIX;, &cv-link-LIBLINKPREFIX;, &cv-link-LIBLINKSUFFIX;, &cv-link-LINK;, &cv-link-LINKCOM;, &cv-link-LINKFLAGS;, &cv-link-REGSVR;, &cv-link-REGSVRCOM;, &cv-link-REGSVRFLAGS;, &cv-link-SHLINK;, &cv-link-SHLINKCOM;, &cv-link-SHLINKFLAGS;, &cv-link-WIN32DEFPREFIX;, &cv-link-WIN32DEFSUFFIX;, &cv-link-WIN32EXPPREFIX;, &cv-link-WIN32EXPSUFFIX;, &cv-link-WINDOWSDEFPREFIX;, &cv-link-WINDOWSDEFSUFFIX;, &cv-link-WINDOWSEXPPREFIX;, &cv-link-WINDOWSEXPSUFFIX;, &cv-link-WINDOWSPROGMANIFESTPREFIX;, &cv-link-WINDOWSPROGMANIFESTSUFFIX;, &cv-link-WINDOWSSHLIBMANIFESTPREFIX;, &cv-link-WINDOWSSHLIBMANIFESTSUFFIX;, &cv-link-WINDOWS_INSERT_DEF;.Uses: &cv-link-LDMODULECOMSTR;, &cv-link-LINKCOMSTR;, &cv-link-REGSVRCOMSTR;, &cv-link-SHLINKCOMSTR;. +Sets: &cv-link-LDMODULE;, &cv-link-LDMODULECOM;, &cv-link-LDMODULEFLAGS;, &cv-link-LDMODULEPREFIX;, &cv-link-LDMODULESUFFIX;, &cv-link-LIBDIRPREFIX;, &cv-link-LIBDIRSUFFIX;, &cv-link-LIBLINKPREFIX;, &cv-link-LIBLINKSUFFIX;, &cv-link-LINK;, &cv-link-LINKCOM;, &cv-link-LINKFLAGS;, &cv-link-REGSVR;, &cv-link-REGSVRCOM;, &cv-link-REGSVRFLAGS;, &cv-link-SHLINK;, &cv-link-SHLINKCOM;, &cv-link-SHLINKFLAGS;, &cv-link-WIN32DEFPREFIX;, &cv-link-WIN32DEFSUFFIX;, &cv-link-WIN32EXPPREFIX;, &cv-link-WIN32EXPSUFFIX;, &cv-link-WINDOWSDEFPREFIX;, &cv-link-WINDOWSDEFSUFFIX;, &cv-link-WINDOWSEXPPREFIX;, &cv-link-WINDOWSEXPSUFFIX;, &cv-link-WINDOWSPROGMANIFESTPREFIX;, &cv-link-WINDOWSPROGMANIFESTSUFFIX;, &cv-link-WINDOWSSHLIBMANIFESTPREFIX;, &cv-link-WINDOWSSHLIBMANIFESTSUFFIX;, &cv-link-WINDOWS_INSERT_DEF;.Uses: &cv-link-LDMODULECOMSTR;, &cv-link-LINKCOMSTR;, &cv-link-REGSVRCOMSTR;, &cv-link-SHLINKCOMSTR;. mssdk - - + Sets variables for Microsoft Platform SDK and/or Windows SDK. Note that unlike most other Tool modules, mssdk does not set construction variables, but sets the environment variables -in the environment SCons uses to execute +in the environment SCons uses to execute the Microsoft toolchain: %INCLUDE%, %LIB%, %LIBPATH% and %PATH%. -Uses: &cv-link-MSSDK_DIR;, &cv-link-MSSDK_VERSION;, &cv-link-MSVS_VERSION;. +Uses: &cv-link-MSSDK_DIR;, &cv-link-MSSDK_VERSION;, &cv-link-MSVS_VERSION;. msvc - - + Sets construction variables for the Microsoft Visual C/C++ compiler. -Sets: &cv-link-BUILDERS;, &cv-link-CC;, &cv-link-CCCOM;, &cv-link-CCFLAGS;, &cv-link-CCPCHFLAGS;, &cv-link-CCPDBFLAGS;, &cv-link-CFILESUFFIX;, &cv-link-CFLAGS;, &cv-link-CPPDEFPREFIX;, &cv-link-CPPDEFSUFFIX;, &cv-link-CXX;, &cv-link-CXXCOM;, &cv-link-CXXFILESUFFIX;, &cv-link-CXXFLAGS;, &cv-link-INCPREFIX;, &cv-link-INCSUFFIX;, &cv-link-OBJPREFIX;, &cv-link-OBJSUFFIX;, &cv-link-PCHCOM;, &cv-link-PCHPDBFLAGS;, &cv-link-RC;, &cv-link-RCCOM;, &cv-link-RCFLAGS;, &cv-link-SHCC;, &cv-link-SHCCCOM;, &cv-link-SHCCFLAGS;, &cv-link-SHCFLAGS;, &cv-link-SHCXX;, &cv-link-SHCXXCOM;, &cv-link-SHCXXFLAGS;, &cv-link-SHOBJPREFIX;, &cv-link-SHOBJSUFFIX;.Uses: &cv-link-CCCOMSTR;, &cv-link-CXXCOMSTR;, &cv-link-PCH;, &cv-link-PCHSTOP;, &cv-link-PDB;, &cv-link-SHCCCOMSTR;, &cv-link-SHCXXCOMSTR;. +Sets: &cv-link-BUILDERS;, &cv-link-CC;, &cv-link-CCCOM;, &cv-link-CCFLAGS;, &cv-link-CCPCHFLAGS;, &cv-link-CCPDBFLAGS;, &cv-link-CFILESUFFIX;, &cv-link-CFLAGS;, &cv-link-CPPDEFPREFIX;, &cv-link-CPPDEFSUFFIX;, &cv-link-CXX;, &cv-link-CXXCOM;, &cv-link-CXXFILESUFFIX;, &cv-link-CXXFLAGS;, &cv-link-INCPREFIX;, &cv-link-INCSUFFIX;, &cv-link-OBJPREFIX;, &cv-link-OBJSUFFIX;, &cv-link-PCHCOM;, &cv-link-PCHPDBFLAGS;, &cv-link-RC;, &cv-link-RCCOM;, &cv-link-RCFLAGS;, &cv-link-SHCC;, &cv-link-SHCCCOM;, &cv-link-SHCCFLAGS;, &cv-link-SHCFLAGS;, &cv-link-SHCXX;, &cv-link-SHCXXCOM;, &cv-link-SHCXXFLAGS;, &cv-link-SHOBJPREFIX;, &cv-link-SHOBJSUFFIX;.Uses: &cv-link-CCCOMSTR;, &cv-link-CXXCOMSTR;, &cv-link-PCH;, &cv-link-PCHSTOP;, &cv-link-PDB;, &cv-link-SHCCCOMSTR;, &cv-link-SHCXXCOMSTR;. msvs - - + Sets construction variables for Microsoft Visual Studio. -Sets: &cv-link-MSVSBUILDCOM;, &cv-link-MSVSCLEANCOM;, &cv-link-MSVSENCODING;, &cv-link-MSVSPROJECTCOM;, &cv-link-MSVSREBUILDCOM;, &cv-link-MSVSSCONS;, &cv-link-MSVSSCONSCOM;, &cv-link-MSVSSCONSCRIPT;, &cv-link-MSVSSCONSFLAGS;, &cv-link-MSVSSOLUTIONCOM;. +Sets: &cv-link-MSVSBUILDCOM;, &cv-link-MSVSCLEANCOM;, &cv-link-MSVSENCODING;, &cv-link-MSVSPROJECTCOM;, &cv-link-MSVSREBUILDCOM;, &cv-link-MSVSSCONS;, &cv-link-MSVSSCONSCOM;, &cv-link-MSVSSCONSCRIPT;, &cv-link-MSVSSCONSFLAGS;, &cv-link-MSVSSOLUTIONCOM;. mwcc - - + Sets construction variables for the Metrowerks CodeWarrior compiler. -Sets: &cv-link-CC;, &cv-link-CCCOM;, &cv-link-CFILESUFFIX;, &cv-link-CPPDEFPREFIX;, &cv-link-CPPDEFSUFFIX;, &cv-link-CXX;, &cv-link-CXXCOM;, &cv-link-CXXFILESUFFIX;, &cv-link-INCPREFIX;, &cv-link-INCSUFFIX;, &cv-link-MWCW_VERSION;, &cv-link-MWCW_VERSIONS;, &cv-link-SHCC;, &cv-link-SHCCCOM;, &cv-link-SHCCFLAGS;, &cv-link-SHCFLAGS;, &cv-link-SHCXX;, &cv-link-SHCXXCOM;, &cv-link-SHCXXFLAGS;.Uses: &cv-link-CCCOMSTR;, &cv-link-CXXCOMSTR;, &cv-link-SHCCCOMSTR;, &cv-link-SHCXXCOMSTR;. +Sets: &cv-link-CC;, &cv-link-CCCOM;, &cv-link-CFILESUFFIX;, &cv-link-CPPDEFPREFIX;, &cv-link-CPPDEFSUFFIX;, &cv-link-CXX;, &cv-link-CXXCOM;, &cv-link-CXXFILESUFFIX;, &cv-link-INCPREFIX;, &cv-link-INCSUFFIX;, &cv-link-MWCW_VERSION;, &cv-link-MWCW_VERSIONS;, &cv-link-SHCC;, &cv-link-SHCCCOM;, &cv-link-SHCCFLAGS;, &cv-link-SHCFLAGS;, &cv-link-SHCXX;, &cv-link-SHCXXCOM;, &cv-link-SHCXXFLAGS;.Uses: &cv-link-CCCOMSTR;, &cv-link-CXXCOMSTR;, &cv-link-SHCCCOMSTR;, &cv-link-SHCXXCOMSTR;. mwld - - + Sets construction variables for the Metrowerks CodeWarrior linker. -Sets: &cv-link-AR;, &cv-link-ARCOM;, &cv-link-LIBDIRPREFIX;, &cv-link-LIBDIRSUFFIX;, &cv-link-LIBLINKPREFIX;, &cv-link-LIBLINKSUFFIX;, &cv-link-LINK;, &cv-link-LINKCOM;, &cv-link-SHLINK;, &cv-link-SHLINKCOM;, &cv-link-SHLINKFLAGS;. +Sets: &cv-link-AR;, &cv-link-ARCOM;, &cv-link-LIBDIRPREFIX;, &cv-link-LIBDIRSUFFIX;, &cv-link-LIBLINKPREFIX;, &cv-link-LIBLINKSUFFIX;, &cv-link-LINK;, &cv-link-LINKCOM;, &cv-link-SHLINK;, &cv-link-SHLINKCOM;, &cv-link-SHLINKFLAGS;. nasm - - + Sets construction variables for the nasm Netwide Assembler. -Sets: &cv-link-AS;, &cv-link-ASCOM;, &cv-link-ASFLAGS;, &cv-link-ASPPCOM;, &cv-link-ASPPFLAGS;.Uses: &cv-link-ASCOMSTR;, &cv-link-ASPPCOMSTR;. +Sets: &cv-link-AS;, &cv-link-ASCOM;, &cv-link-ASFLAGS;, &cv-link-ASPPCOM;, &cv-link-ASPPFLAGS;.Uses: &cv-link-ASCOMSTR;, &cv-link-ASPPCOMSTR;. packaging - - + A framework for building binary and source packages. Packaging - - -Sets construction variables for the Package Builder. + +Sets construction variables for the Package Builder. pdf - - + Sets construction variables for the Portable Document Format builder. -Sets: &cv-link-PDFPREFIX;, &cv-link-PDFSUFFIX;. +Sets: &cv-link-PDFPREFIX;, &cv-link-PDFSUFFIX;. pdflatex - - -Sets construction variables for the pdflatex utility. + +Sets construction variables for the pdflatex utility. -Sets: &cv-link-LATEXRETRIES;, &cv-link-PDFLATEX;, &cv-link-PDFLATEXCOM;, &cv-link-PDFLATEXFLAGS;.Uses: &cv-link-PDFLATEXCOMSTR;. +Sets: &cv-link-LATEXRETRIES;, &cv-link-PDFLATEX;, &cv-link-PDFLATEXCOM;, &cv-link-PDFLATEXFLAGS;.Uses: &cv-link-PDFLATEXCOMSTR;. pdftex - - -Sets construction variables for the pdftex utility. + +Sets construction variables for the pdftex utility. -Sets: &cv-link-LATEXRETRIES;, &cv-link-PDFLATEX;, &cv-link-PDFLATEXCOM;, &cv-link-PDFLATEXFLAGS;, &cv-link-PDFTEX;, &cv-link-PDFTEXCOM;, &cv-link-PDFTEXFLAGS;.Uses: &cv-link-PDFLATEXCOMSTR;, &cv-link-PDFTEXCOMSTR;. +Sets: &cv-link-LATEXRETRIES;, &cv-link-PDFLATEX;, &cv-link-PDFLATEXCOM;, &cv-link-PDFLATEXFLAGS;, &cv-link-PDFTEX;, &cv-link-PDFTEXCOM;, &cv-link-PDFTEXFLAGS;.Uses: &cv-link-PDFLATEXCOMSTR;, &cv-link-PDFTEXCOMSTR;. Perforce - - + Sets construction variables for interacting with the Perforce source code management system. -Sets: &cv-link-P4;, &cv-link-P4COM;, &cv-link-P4FLAGS;.Uses: &cv-link-P4COMSTR;. +Sets: &cv-link-P4;, &cv-link-P4COM;, &cv-link-P4FLAGS;.Uses: &cv-link-P4COMSTR;. qt - - + Sets construction variables for building Qt applications. -Sets: &cv-link-QTDIR;, &cv-link-QT_AUTOSCAN;, &cv-link-QT_BINPATH;, &cv-link-QT_CPPPATH;, &cv-link-QT_LIB;, &cv-link-QT_LIBPATH;, &cv-link-QT_MOC;, &cv-link-QT_MOCCXXPREFIX;, &cv-link-QT_MOCCXXSUFFIX;, &cv-link-QT_MOCFROMCXXCOM;, &cv-link-QT_MOCFROMCXXFLAGS;, &cv-link-QT_MOCFROMHCOM;, &cv-link-QT_MOCFROMHFLAGS;, &cv-link-QT_MOCHPREFIX;, &cv-link-QT_MOCHSUFFIX;, &cv-link-QT_UIC;, &cv-link-QT_UICCOM;, &cv-link-QT_UICDECLFLAGS;, &cv-link-QT_UICDECLPREFIX;, &cv-link-QT_UICDECLSUFFIX;, &cv-link-QT_UICIMPLFLAGS;, &cv-link-QT_UICIMPLPREFIX;, &cv-link-QT_UICIMPLSUFFIX;, &cv-link-QT_UISUFFIX;. +Sets: &cv-link-QTDIR;, &cv-link-QT_AUTOSCAN;, &cv-link-QT_BINPATH;, &cv-link-QT_CPPPATH;, &cv-link-QT_LIB;, &cv-link-QT_LIBPATH;, &cv-link-QT_MOC;, &cv-link-QT_MOCCXXPREFIX;, &cv-link-QT_MOCCXXSUFFIX;, &cv-link-QT_MOCFROMCXXCOM;, &cv-link-QT_MOCFROMCXXFLAGS;, &cv-link-QT_MOCFROMHCOM;, &cv-link-QT_MOCFROMHFLAGS;, &cv-link-QT_MOCHPREFIX;, &cv-link-QT_MOCHSUFFIX;, &cv-link-QT_UIC;, &cv-link-QT_UICCOM;, &cv-link-QT_UICDECLFLAGS;, &cv-link-QT_UICDECLPREFIX;, &cv-link-QT_UICDECLSUFFIX;, &cv-link-QT_UICIMPLFLAGS;, &cv-link-QT_UICIMPLPREFIX;, &cv-link-QT_UICIMPLSUFFIX;, &cv-link-QT_UISUFFIX;. RCS - - + Sets construction variables for the interaction with the Revision Control System. -Sets: &cv-link-RCS;, &cv-link-RCS_CO;, &cv-link-RCS_COCOM;, &cv-link-RCS_COFLAGS;.Uses: &cv-link-RCS_COCOMSTR;. +Sets: &cv-link-RCS;, &cv-link-RCS_CO;, &cv-link-RCS_COCOM;, &cv-link-RCS_COFLAGS;.Uses: &cv-link-RCS_COCOMSTR;. rmic - - -Sets construction variables for the rmic utility. + +Sets construction variables for the rmic utility. -Sets: &cv-link-JAVACLASSSUFFIX;, &cv-link-RMIC;, &cv-link-RMICCOM;, &cv-link-RMICFLAGS;.Uses: &cv-link-RMICCOMSTR;. +Sets: &cv-link-JAVACLASSSUFFIX;, &cv-link-RMIC;, &cv-link-RMICCOM;, &cv-link-RMICFLAGS;.Uses: &cv-link-RMICCOMSTR;. rpcgen - - + Sets construction variables for building with RPCGEN. -Sets: &cv-link-RPCGEN;, &cv-link-RPCGENCLIENTFLAGS;, &cv-link-RPCGENFLAGS;, &cv-link-RPCGENHEADERFLAGS;, &cv-link-RPCGENSERVICEFLAGS;, &cv-link-RPCGENXDRFLAGS;. +Sets: &cv-link-RPCGEN;, &cv-link-RPCGENCLIENTFLAGS;, &cv-link-RPCGENFLAGS;, &cv-link-RPCGENHEADERFLAGS;, &cv-link-RPCGENSERVICEFLAGS;, &cv-link-RPCGENXDRFLAGS;. SCCS - - + Sets construction variables for interacting with the Source Code Control System. -Sets: &cv-link-SCCS;, &cv-link-SCCSCOM;, &cv-link-SCCSFLAGS;, &cv-link-SCCSGETFLAGS;.Uses: &cv-link-SCCSCOMSTR;. +Sets: &cv-link-SCCS;, &cv-link-SCCSCOM;, &cv-link-SCCSFLAGS;, &cv-link-SCCSGETFLAGS;.Uses: &cv-link-SCCSCOMSTR;. sgiar - - + Sets construction variables for the SGI library archiver. -Sets: &cv-link-AR;, &cv-link-ARCOMSTR;, &cv-link-ARFLAGS;, &cv-link-LIBPREFIX;, &cv-link-LIBSUFFIX;, &cv-link-SHLINK;, &cv-link-SHLINKFLAGS;.Uses: &cv-link-ARCOMSTR;, &cv-link-SHLINKCOMSTR;. +Sets: &cv-link-AR;, &cv-link-ARCOMSTR;, &cv-link-ARFLAGS;, &cv-link-LIBPREFIX;, &cv-link-LIBSUFFIX;, &cv-link-SHLINK;, &cv-link-SHLINKFLAGS;.Uses: &cv-link-ARCOMSTR;, &cv-link-SHLINKCOMSTR;. sgic++ - - + Sets construction variables for the SGI C++ compiler. -Sets: &cv-link-CXX;, &cv-link-CXXFLAGS;, &cv-link-SHCXX;, &cv-link-SHOBJSUFFIX;. +Sets: &cv-link-CXX;, &cv-link-CXXFLAGS;, &cv-link-SHCXX;, &cv-link-SHOBJSUFFIX;. sgicc - - + Sets construction variables for the SGI C compiler. -Sets: &cv-link-CXX;, &cv-link-SHOBJSUFFIX;. +Sets: &cv-link-CXX;, &cv-link-SHOBJSUFFIX;. sgilink - - + Sets construction variables for the SGI linker. -Sets: &cv-link-LINK;, &cv-link-RPATHPREFIX;, &cv-link-RPATHSUFFIX;, &cv-link-SHLINKFLAGS;. +Sets: &cv-link-LINK;, &cv-link-RPATHPREFIX;, &cv-link-RPATHSUFFIX;, &cv-link-SHLINKFLAGS;. sunar - - + Sets construction variables for the Sun library archiver. -Sets: &cv-link-AR;, &cv-link-ARCOM;, &cv-link-ARFLAGS;, &cv-link-LIBPREFIX;, &cv-link-LIBSUFFIX;, &cv-link-SHLINK;, &cv-link-SHLINKCOM;, &cv-link-SHLINKFLAGS;.Uses: &cv-link-ARCOMSTR;, &cv-link-SHLINKCOMSTR;. +Sets: &cv-link-AR;, &cv-link-ARCOM;, &cv-link-ARFLAGS;, &cv-link-LIBPREFIX;, &cv-link-LIBSUFFIX;, &cv-link-SHLINK;, &cv-link-SHLINKCOM;, &cv-link-SHLINKFLAGS;.Uses: &cv-link-ARCOMSTR;, &cv-link-SHLINKCOMSTR;. sunc++ - - + Sets construction variables for the Sun C++ compiler. -Sets: &cv-link-CXX;, &cv-link-CXXVERSION;, &cv-link-SHCXX;, &cv-link-SHCXXFLAGS;, &cv-link-SHOBJPREFIX;, &cv-link-SHOBJSUFFIX;. +Sets: &cv-link-CXX;, &cv-link-CXXVERSION;, &cv-link-SHCXX;, &cv-link-SHCXXFLAGS;, &cv-link-SHOBJPREFIX;, &cv-link-SHOBJSUFFIX;. suncc - - + Sets construction variables for the Sun C compiler. -Sets: &cv-link-CXX;, &cv-link-SHCCFLAGS;, &cv-link-SHOBJPREFIX;, &cv-link-SHOBJSUFFIX;. +Sets: &cv-link-CXX;, &cv-link-SHCCFLAGS;, &cv-link-SHOBJPREFIX;, &cv-link-SHOBJSUFFIX;. sunf77 - - -Set construction variables for the Sun f77 Fortran compiler. + +Set construction variables for the Sun f77 Fortran compiler. -Sets: &cv-link-F77;, &cv-link-FORTRAN;, &cv-link-SHF77;, &cv-link-SHF77FLAGS;, &cv-link-SHFORTRAN;, &cv-link-SHFORTRANFLAGS;. +Sets: &cv-link-F77;, &cv-link-FORTRAN;, &cv-link-SHF77;, &cv-link-SHF77FLAGS;, &cv-link-SHFORTRAN;, &cv-link-SHFORTRANFLAGS;. sunf90 - - -Set construction variables for the Sun f90 Fortran compiler. + +Set construction variables for the Sun f90 Fortran compiler. -Sets: &cv-link-F90;, &cv-link-FORTRAN;, &cv-link-SHF90;, &cv-link-SHF90FLAGS;, &cv-link-SHFORTRAN;, &cv-link-SHFORTRANFLAGS;. +Sets: &cv-link-F90;, &cv-link-FORTRAN;, &cv-link-SHF90;, &cv-link-SHF90FLAGS;, &cv-link-SHFORTRAN;, &cv-link-SHFORTRANFLAGS;. sunf95 - - -Set construction variables for the Sun f95 Fortran compiler. + +Set construction variables for the Sun f95 Fortran compiler. -Sets: &cv-link-F95;, &cv-link-FORTRAN;, &cv-link-SHF95;, &cv-link-SHF95FLAGS;, &cv-link-SHFORTRAN;, &cv-link-SHFORTRANFLAGS;. +Sets: &cv-link-F95;, &cv-link-FORTRAN;, &cv-link-SHF95;, &cv-link-SHF95FLAGS;, &cv-link-SHFORTRAN;, &cv-link-SHFORTRANFLAGS;. sunlink - - + Sets construction variables for the Sun linker. -Sets: &cv-link-RPATHPREFIX;, &cv-link-RPATHSUFFIX;, &cv-link-SHLINKFLAGS;. +Sets: &cv-link-RPATHPREFIX;, &cv-link-RPATHSUFFIX;, &cv-link-SHLINKFLAGS;. swig - - + Sets construction variables for the SWIG interface generator. -Sets: &cv-link-SWIG;, &cv-link-SWIGCFILESUFFIX;, &cv-link-SWIGCOM;, &cv-link-SWIGCXXFILESUFFIX;, &cv-link-SWIGDIRECTORSUFFIX;, &cv-link-SWIGFLAGS;, &cv-link-SWIGINCPREFIX;, &cv-link-SWIGINCSUFFIX;, &cv-link-SWIGPATH;, &cv-link-SWIGVERSION;, &cv-link-_SWIGINCFLAGS;.Uses: &cv-link-SWIGCOMSTR;. +Sets: &cv-link-SWIG;, &cv-link-SWIGCFILESUFFIX;, &cv-link-SWIGCOM;, &cv-link-SWIGCXXFILESUFFIX;, &cv-link-SWIGDIRECTORSUFFIX;, &cv-link-SWIGFLAGS;, &cv-link-SWIGINCPREFIX;, &cv-link-SWIGINCSUFFIX;, &cv-link-SWIGPATH;, &cv-link-SWIGVERSION;, &cv-link-_SWIGINCFLAGS;.Uses: &cv-link-SWIGCOMSTR;. tar - - -Sets construction variables for the tar archiver. + +Sets construction variables for the tar archiver. -Sets: &cv-link-TAR;, &cv-link-TARCOM;, &cv-link-TARFLAGS;, &cv-link-TARSUFFIX;.Uses: &cv-link-TARCOMSTR;. +Sets: &cv-link-TAR;, &cv-link-TARCOM;, &cv-link-TARFLAGS;, &cv-link-TARSUFFIX;.Uses: &cv-link-TARCOMSTR;. tex - - + Sets construction variables for the TeX formatter and typesetter. -Sets: &cv-link-BIBTEX;, &cv-link-BIBTEXCOM;, &cv-link-BIBTEXFLAGS;, &cv-link-LATEX;, &cv-link-LATEXCOM;, &cv-link-LATEXFLAGS;, &cv-link-MAKEINDEX;, &cv-link-MAKEINDEXCOM;, &cv-link-MAKEINDEXFLAGS;, &cv-link-TEX;, &cv-link-TEXCOM;, &cv-link-TEXFLAGS;.Uses: &cv-link-BIBTEXCOMSTR;, &cv-link-LATEXCOMSTR;, &cv-link-MAKEINDEXCOMSTR;, &cv-link-TEXCOMSTR;. +Sets: &cv-link-BIBTEX;, &cv-link-BIBTEXCOM;, &cv-link-BIBTEXFLAGS;, &cv-link-LATEX;, &cv-link-LATEXCOM;, &cv-link-LATEXFLAGS;, &cv-link-MAKEINDEX;, &cv-link-MAKEINDEXCOM;, &cv-link-MAKEINDEXFLAGS;, &cv-link-TEX;, &cv-link-TEXCOM;, &cv-link-TEXFLAGS;.Uses: &cv-link-BIBTEXCOMSTR;, &cv-link-LATEXCOMSTR;, &cv-link-MAKEINDEXCOMSTR;, &cv-link-TEXCOMSTR;. textfile - - -Set construction variables for the Textfile and Substfile builders. + +Set construction variables for the Textfile and Substfile builders. -Sets: &cv-link-LINESEPARATOR;, &cv-link-SUBSTFILEPREFIX;, &cv-link-SUBSTFILESUFFIX;, &cv-link-TEXTFILEPREFIX;, &cv-link-TEXTFILESUFFIX;.Uses: &cv-link-SUBST_DICT;. +Sets: &cv-link-LINESEPARATOR;, &cv-link-SUBSTFILEPREFIX;, &cv-link-SUBSTFILESUFFIX;, &cv-link-TEXTFILEPREFIX;, &cv-link-TEXTFILESUFFIX;.Uses: &cv-link-SUBST_DICT;. tlib - - + Sets construction variables for the Borlan tib library archiver. -Sets: &cv-link-AR;, &cv-link-ARCOM;, &cv-link-ARFLAGS;, &cv-link-LIBPREFIX;, &cv-link-LIBSUFFIX;.Uses: &cv-link-ARCOMSTR;. +Sets: &cv-link-AR;, &cv-link-ARCOM;, &cv-link-ARFLAGS;, &cv-link-LIBPREFIX;, &cv-link-LIBSUFFIX;.Uses: &cv-link-ARCOMSTR;. xgettext - - -This scons tool is a part of scons gettext toolset. It provides + +This scons tool is a part of scons gettext toolset. It provides scons interface to xgettext(1) program, which extracts internationalized messages from source code. The tool -provides POTUpdate builder to make PO +provides POTUpdate builder to make PO Template files. -Sets: &cv-link-POTSUFFIX;, &cv-link-POTUPDATE_ALIAS;, &cv-link-XGETTEXTCOM;, &cv-link-XGETTEXTCOMSTR;, &cv-link-XGETTEXTFLAGS;, &cv-link-XGETTEXTFROM;, &cv-link-XGETTEXTFROMPREFIX;, &cv-link-XGETTEXTFROMSUFFIX;, &cv-link-XGETTEXTPATH;, &cv-link-XGETTEXTPATHPREFIX;, &cv-link-XGETTEXTPATHSUFFIX;, &cv-link-_XGETTEXTDOMAIN;, &cv-link-_XGETTEXTFROMFLAGS;, &cv-link-_XGETTEXTPATHFLAGS;.Uses: &cv-link-POTDOMAIN;. +Sets: &cv-link-POTSUFFIX;, &cv-link-POTUPDATE_ALIAS;, &cv-link-XGETTEXTCOM;, &cv-link-XGETTEXTCOMSTR;, &cv-link-XGETTEXTFLAGS;, &cv-link-XGETTEXTFROM;, &cv-link-XGETTEXTFROMPREFIX;, &cv-link-XGETTEXTFROMSUFFIX;, &cv-link-XGETTEXTPATH;, &cv-link-XGETTEXTPATHPREFIX;, &cv-link-XGETTEXTPATHSUFFIX;, &cv-link-_XGETTEXTDOMAIN;, &cv-link-_XGETTEXTFROMFLAGS;, &cv-link-_XGETTEXTPATHFLAGS;.Uses: &cv-link-POTDOMAIN;. yacc - - -Sets construction variables for the yacc parse generator. + +Sets construction variables for the yacc parse generator. -Sets: &cv-link-YACC;, &cv-link-YACCCOM;, &cv-link-YACCFLAGS;, &cv-link-YACCHFILESUFFIX;, &cv-link-YACCHXXFILESUFFIX;, &cv-link-YACCVCGFILESUFFIX;.Uses: &cv-link-YACCCOMSTR;. +Sets: &cv-link-YACC;, &cv-link-YACCCOM;, &cv-link-YACCFLAGS;, &cv-link-YACCHFILESUFFIX;, &cv-link-YACCHXXFILESUFFIX;, &cv-link-YACCVCGFILESUFFIX;.Uses: &cv-link-YACCCOMSTR;. zip - - -Sets construction variables for the zip archiver. + +Sets construction variables for the zip archiver. -Sets: &cv-link-ZIP;, &cv-link-ZIPCOM;, &cv-link-ZIPCOMPRESSION;, &cv-link-ZIPFLAGS;, &cv-link-ZIPSUFFIX;.Uses: &cv-link-ZIPCOMSTR;. +Sets: &cv-link-ZIP;, &cv-link-ZIPCOM;, &cv-link-ZIPCOMPRESSION;, &cv-link-ZIPFLAGS;, &cv-link-ZIPSUFFIX;.Uses: &cv-link-ZIPCOMSTR;. diff --git a/doc/generated/variables.gen b/doc/generated/variables.gen index d007758..1555a3f 100644 --- a/doc/generated/variables.gen +++ b/doc/generated/variables.gen @@ -1,4 +1,4 @@ - + %scons; @@ -12,19 +12,17 @@ %variables-mod; ]> - + AR - - + The static library archiver. ARCHITECTURE - - + Specifies the system architecture for which the package is being built. The default is the system architecture @@ -39,46 +37,41 @@ and as part of the name of a generated RPM file. ARCOM - - + The command line used to generate a static library from object files. ARCOMSTR - - + The string displayed when an object file is generated from an assembly-language source file. -If this is not set, then $ARCOM (the command line) is displayed. +If this is not set, then $ARCOM (the command line) is displayed. - + env = Environment(ARCOMSTR = "Archiving $TARGET") ARFLAGS - - + General options passed to the static library archiver. AS - - + The assembler. ASCOM - - + The command line used to generate an object file from an assembly-language source file. @@ -86,69 +79,63 @@ from an assembly-language source file. ASCOMSTR - - + The string displayed when an object file is generated from an assembly-language source file. -If this is not set, then $ASCOM (the command line) is displayed. +If this is not set, then $ASCOM (the command line) is displayed. - + env = Environment(ASCOMSTR = "Assembling $TARGET") ASFLAGS - - + General options passed to the assembler. ASPPCOM - - + The command line used to assemble an assembly-language source file into an object file after first running the file through the C preprocessor. Any options specified -in the $ASFLAGS and $CPPFLAGS construction variables +in the $ASFLAGS and $CPPFLAGS construction variables are included on this command line. ASPPCOMSTR - - + The string displayed when an object file is generated from an assembly-language source file after first running the file through the C preprocessor. -If this is not set, then $ASPPCOM (the command line) is displayed. +If this is not set, then $ASPPCOM (the command line) is displayed. - + env = Environment(ASPPCOMSTR = "Assembling $TARGET") ASPPFLAGS - - + General options when an assembling an assembly-language source file into an object file after first running the file through the C preprocessor. -The default is to use the value of $ASFLAGS. +The default is to use the value of $ASFLAGS. BIBTEX - - + The bibliography generator for the TeX formatter and typesetter and the LaTeX structured formatter and typesetter. @@ -156,8 +143,7 @@ LaTeX structured formatter and typesetter. BIBTEXCOM - - + The command line used to call the bibliography generator for the TeX formatter and typesetter and the LaTeX structured formatter and typesetter. @@ -166,22 +152,20 @@ typesetter. BIBTEXCOMSTR - - + The string displayed when generating a bibliography for TeX or LaTeX. -If this is not set, then $BIBTEXCOM (the command line) is displayed. +If this is not set, then $BIBTEXCOM (the command line) is displayed. - + env = Environment(BIBTEXCOMSTR = "Generating bibliography $TARGET") BIBTEXFLAGS - - + General options passed to the bibliography generator for the TeX formatter and typesetter and the LaTeX structured formatter and typesetter. @@ -189,16 +173,14 @@ and typesetter and the LaTeX structured formatter and typesetter. BITKEEPER - - + The BitKeeper executable. BITKEEPERCOM - - + The command line for fetching source files using BitKeeper. @@ -206,28 +188,25 @@ fetching source files using BitKeeper. BITKEEPERCOMSTR - - + The string displayed when fetching a source file using BitKeeper. -If this is not set, then $BITKEEPERCOM +If this is not set, then $BITKEEPERCOM (the command line) is displayed. BITKEEPERGET - - -The command ($BITKEEPER) and subcommand + +The command ($BITKEEPER) and subcommand for fetching source files using BitKeeper. BITKEEPERGETFLAGS - - + Options that are passed to the BitKeeper get subcommand. @@ -236,8 +215,7 @@ subcommand. BUILDERS - - + A dictionary mapping the names of the builders available through this environment to underlying Builder objects. @@ -248,26 +226,26 @@ If you initialize this variable when an Environment is created: - + env = Environment(BUILDERS = {'NewBuilder' : foo}) - + the default Builders will no longer be available. To use a new Builder object in addition to the default Builders, add your new Builder object like this: - + env = Environment() env.Append(BUILDERS = {'NewBuilder' : foo}) - + or this: - + env = Environment() env['BUILDERS]['NewBuilder'] = foo @@ -275,70 +253,64 @@ env['BUILDERS]['NewBuilder'] = foo CC - - + The C compiler. CCCOM - - + The command line used to compile a C source file to a (static) object -file. Any options specified in the $CFLAGS, $CCFLAGS and -$CPPFLAGS construction variables are included on this command +file. Any options specified in the $CFLAGS, $CCFLAGS and +$CPPFLAGS construction variables are included on this command line. CCCOMSTR - - + The string displayed when a C source file is compiled to a (static) object file. -If this is not set, then $CCCOM (the command line) is displayed. +If this is not set, then $CCCOM (the command line) is displayed. - + env = Environment(CCCOMSTR = "Compiling static object $TARGET") CCFLAGS - - + General options that are passed to the C and C++ compilers. CCPCHFLAGS - - + Options added to the compiler command line to support building with precompiled headers. The default value expands expands to the appropriate Microsoft Visual C++ command-line options -when the $PCH construction variable is set. +when the $PCH construction variable is set. CCPDBFLAGS - - + Options added to the compiler command line to support storing debugging information in a Microsoft Visual C++ PDB file. The default value expands expands to appropriate Microsoft Visual C++ command-line options -when the $PDB construction variable is set. +when the $PDB construction variable is set. - + The Visual C++ compiler option that SCons uses by default to generate PDB information is . This works correctly with parallel () builds @@ -351,31 +323,30 @@ link-time performance, although parallel builds will no longer work. - + You can generate PDB files with the -switch by overriding the default $CCPDBFLAGS variable as follows: +switch by overriding the default $CCPDBFLAGS variable as follows: - + env['CCPDBFLAGS'] = ['${(PDB and "/Zi /Fd%s" % File(PDB)) or ""}'] - + An alternative would be to use the to put the debugging information in a separate .pdb file for each object file by overriding -the $CCPDBFLAGS variable as follows: +the $CCPDBFLAGS variable as follows: - + env['CCPDBFLAGS'] = '/Zi /Fd${TARGET}.pdb' CCVERSION - - + The version number of the C compiler. This may or may not be set, depending on the specific C compiler being used. @@ -384,8 +355,7 @@ depending on the specific C compiler being used. CFILESUFFIX - - + The suffix for C source files. This is used by the internal CFile builder when generating C files from Lex (.l) or YACC (.y) input files. @@ -402,16 +372,14 @@ as C files. CFLAGS - - + General options that are passed to the C compiler (C only; not C++). CHANGE_SPECFILE - - + A hook for modifying the file that controls the packaging build (the .spec for RPM, the control for Ipkg, @@ -424,8 +392,7 @@ XXX CHANGED_SOURCES - - + A reserved variable name that may not be set or used in a construction environment. (See "Variable Substitution," below.) @@ -434,8 +401,7 @@ that may not be set or used in a construction environment. CHANGED_TARGETS - - + A reserved variable name that may not be set or used in a construction environment. (See "Variable Substitution," below.) @@ -444,8 +410,7 @@ that may not be set or used in a construction environment. CHANGELOG - - + The name of a file containing the change log text to be included in the package. This is included as the @@ -457,9 +422,8 @@ section of the RPM _concat - - -A function used to produce variables like $_CPPINCFLAGS. It takes + +A function used to produce variables like $_CPPINCFLAGS. It takes four or five arguments: a prefix to concatenate onto each element, a list of elements, a suffix to concatenate onto each element, an environment @@ -467,15 +431,14 @@ for variable interpolation, and an optional function that will be called to transform the list before concatenation. - + env['_CPPINCFLAGS'] = '$( ${_concat(INCPREFIX, CPPPATH, INCSUFFIX, __env__, RDirs)} $)', CONFIGUREDIR - - + The name of the directory in which Configure context test files are written. The default is @@ -489,8 +452,7 @@ file. CONFIGURELOG - - + The name of the Configure context log file. The default is config.log @@ -503,48 +465,46 @@ file. _CPPDEFFLAGS - - + An automatically-generated construction variable containing the C preprocessor command-line options to define values. -The value of $_CPPDEFFLAGS is created -by appending $CPPDEFPREFIX and $CPPDEFSUFFIX +The value of $_CPPDEFFLAGS is created +by appending $CPPDEFPREFIX and $CPPDEFSUFFIX to the beginning and end -of each definition in $CPPDEFINES. +of each definition in $CPPDEFINES. CPPDEFINES - - + A platform independent specification of C preprocessor definitions. The definitions will be added to command lines through the automatically-generated -$_CPPDEFFLAGS construction variable (see above), +$_CPPDEFFLAGS construction variable (see above), which is constructed according to -the type of value of $CPPDEFINES: +the type of value of $CPPDEFINES: - -If $CPPDEFINES is a string, + +If $CPPDEFINES is a string, the values of the -$CPPDEFPREFIX and $CPPDEFSUFFIX +$CPPDEFPREFIX and $CPPDEFSUFFIX construction variables will be added to the beginning and end. - + # Will add -Dxyz to POSIX compiler command lines, # and /Dxyz to Microsoft Visual C++ command lines. env = Environment(CPPDEFINES='xyz') - -If $CPPDEFINES is a list, + +If $CPPDEFINES is a list, the values of the -$CPPDEFPREFIX and $CPPDEFSUFFIX +$CPPDEFPREFIX and $CPPDEFSUFFIX construction variables will be appended to the beginning and end of each element in the list. @@ -553,16 +513,16 @@ then the first item is the name being defined and the second item is its value: - + # Will add -DB=2 -DA to POSIX compiler command lines, # and /DB=2 /DA to Microsoft Visual C++ command lines. env = Environment(CPPDEFINES=[('B', 2), 'A']) - -If $CPPDEFINES is a dictionary, + +If $CPPDEFINES is a dictionary, the values of the -$CPPDEFPREFIX and $CPPDEFSUFFIX +$CPPDEFPREFIX and $CPPDEFSUFFIX construction variables will be appended to the beginning and end of each item from the dictionary. @@ -575,11 +535,11 @@ then the name is defined without an explicit value. Note that the resulting flags are sorted by keyword to ensure that the order of the options on the command line is consistent each time -scons +scons is run. - + # Will add -DA -DB=2 to POSIX compiler command lines, # and /DA /DB=2 to Microsoft Visual C++ command lines. env = Environment(CPPDEFINES={'B':2, 'A':None}) @@ -588,45 +548,42 @@ env = Environment(CPPDEFINES={'B':2, 'A':None}) CPPDEFPREFIX - - + The prefix used to specify preprocessor definitions on the C compiler command line. This will be appended to the beginning of each definition -in the $CPPDEFINES construction variable -when the $_CPPDEFFLAGS variable is automatically generated. +in the $CPPDEFINES construction variable +when the $_CPPDEFFLAGS variable is automatically generated. CPPDEFSUFFIX - - + The suffix used to specify preprocessor definitions on the C compiler command line. This will be appended to the end of each definition -in the $CPPDEFINES construction variable -when the $_CPPDEFFLAGS variable is automatically generated. +in the $CPPDEFINES construction variable +when the $_CPPDEFFLAGS variable is automatically generated. CPPFLAGS - - + User-specified C preprocessor options. These will be included in any command that uses the C preprocessor, including not just compilation of C and C++ source files -via the $CCCOM, -$SHCCCOM, -$CXXCOM and -$SHCXXCOM command lines, -but also the $FORTRANPPCOM, -$SHFORTRANPPCOM, -$F77PPCOM and -$SHF77PPCOM command lines +via the $CCCOM, +$SHCCCOM, +$CXXCOM and +$SHCXXCOM command lines, +but also the $FORTRANPPCOM, +$SHFORTRANPPCOM, +$F77PPCOM and +$SHF77PPCOM command lines used to compile a Fortran source file, -and the $ASPPCOM command line +and the $ASPPCOM command line used to assemble an assembly language source file, after first running each file through the C preprocessor. Note that this variable does @@ -634,30 +591,28 @@ Note that this variable does contain (or similar) include search path options -that scons generates automatically from $CPPPATH. -See $_CPPINCFLAGS, below, +that scons generates automatically from $CPPPATH. +See $_CPPINCFLAGS, below, for the variable that expands to those options. _CPPINCFLAGS - - + An automatically-generated construction variable containing the C preprocessor command-line options for specifying directories to be searched for include files. -The value of $_CPPINCFLAGS is created -by appending $INCPREFIX and $INCSUFFIX +The value of $_CPPINCFLAGS is created +by appending $INCPREFIX and $INCSUFFIX to the beginning and end -of each directory in $CPPPATH. +of each directory in $CPPPATH. CPPPATH - - + The list of directories that the C preprocessor will search for include directories. The C/C++ implicit dependency scanner will search these directories for include files. Don't explicitly put include directory @@ -665,57 +620,56 @@ arguments in CCFLAGS or CXXFLAGS because the result will be non-portable and the directories will not be searched by the dependency scanner. Note: directory names in CPPPATH will be looked-up relative to the SConscript directory when they are used in a command. To force -scons +scons to look-up a directory relative to the root of the source tree use #: - + env = Environment(CPPPATH='#/include') - + The directory look-up can also be forced using the -Dir() +Dir() function: - + include = Dir('include') env = Environment(CPPPATH=include) - + The directory list will be added to command lines through the automatically-generated -$_CPPINCFLAGS +$_CPPINCFLAGS construction variable, which is constructed by appending the values of the -$INCPREFIX and $INCSUFFIX +$INCPREFIX and $INCSUFFIX construction variables to the beginning and end -of each directory in $CPPPATH. +of each directory in $CPPPATH. Any command lines you define that need the CPPPATH directory list should -include $_CPPINCFLAGS: +include $_CPPINCFLAGS: - + env = Environment(CCCOM="my_compiler $_CPPINCFLAGS -c -o $TARGET $SOURCE") CPPSUFFIXES - - + The list of suffixes of files that will be scanned for C preprocessor implicit dependencies (#include lines). The default list is: - + [".c", ".C", ".cxx", ".cpp", ".c++", ".cc", ".h", ".H", ".hxx", ".hpp", ".hh", ".F", ".fpp", ".FPP", @@ -726,24 +680,21 @@ The default list is: CVS - - + The CVS executable. CVSCOFLAGS - - + Options that are passed to the CVS checkout subcommand. CVSCOM - - + The command line used to fetch source files from a CVS repository. @@ -751,19 +702,17 @@ fetch source files from a CVS repository. CVSCOMSTR - - + The string displayed when fetching a source file from a CVS repository. -If this is not set, then $CVSCOM +If this is not set, then $CVSCOM (the command line) is displayed. CVSFLAGS - - + General options that are passed to CVS. By default, this is set to -d $CVSREPOSITORY @@ -773,51 +722,46 @@ to specify from where the files must be fetched. CVSREPOSITORY - - + The path to the CVS repository. This is referenced in the default -$CVSFLAGS value. +$CVSFLAGS value. CXX - - + The C++ compiler. CXXCOM - - + The command line used to compile a C++ source file to an object file. -Any options specified in the $CXXFLAGS and -$CPPFLAGS construction variables +Any options specified in the $CXXFLAGS and +$CPPFLAGS construction variables are included on this command line. CXXCOMSTR - - + The string displayed when a C++ source file is compiled to a (static) object file. -If this is not set, then $CXXCOM (the command line) is displayed. +If this is not set, then $CXXCOM (the command line) is displayed. - + env = Environment(CXXCOMSTR = "Compiling static object $TARGET") CXXFILESUFFIX - - + The suffix for C++ source files. This is used by the internal CXXFile builder when generating C++ files from Lex (.ll) or YACC (.yy) input files. @@ -843,20 +787,18 @@ as C++ files. CXXFLAGS - - + General options that are passed to the C++ compiler. -By default, this includes the value of $CCFLAGS, -so that setting $CCFLAGS affects both C and C++ compilation. +By default, this includes the value of $CCFLAGS, +so that setting $CCFLAGS affects both C and C++ compilation. If you want to add C++-specific flags, -you must set or override the value of $CXXFLAGS. +you must set or override the value of $CXXFLAGS. CXXVERSION - - + The version number of the C++ compiler. This may or may not be set, depending on the specific C++ compiler being used. @@ -865,56 +807,49 @@ depending on the specific C++ compiler being used. DC - - + DC. DCOM - - + DCOM. DDEBUG - - + DDEBUG. _DDEBUGFLAGS - - + _DDEBUGFLAGS. DDEBUGPREFIX - - + DDEBUGPREFIX. DDEBUGSUFFIX - - + DDEBUGSUFFIX. DESCRIPTION - - + A long description of the project being packaged. This is included in the relevant section of the file that controls the packaging build. @@ -923,8 +858,7 @@ of the file that controls the packaging build. DESCRIPTION_lang - - + A language-specific long description for the specified lang. This is used to populate a @@ -936,77 +870,67 @@ section of an RPM DFILESUFFIX - - + DFILESUFFIX. DFLAGPREFIX - - + DFLAGPREFIX. - - DFLAGS - - -DFLAGS. - - - _DFLAGS - - + _DFLAGS. + + DFLAGS + +DFLAGS. + + + DFLAGSUFFIX - - + DFLAGSUFFIX. _DINCFLAGS - - + _DINCFLAGS. DINCPREFIX - - + DINCPREFIX. DINCSUFFIX - - + DINCSUFFIX. Dir - - + A function that converts a string into a Dir instance relative to the target being built. - - + A function that converts a string into a Dir instance relative to the target being built. @@ -1014,8 +938,7 @@ into a Dir instance relative to the target being built. Dirs - - + A function that converts a list of strings into a list of Dir instances relative to the target being built. @@ -1023,200 +946,176 @@ into a list of Dir instances relative to the target being built. DLIB - - + DLIB. DLIBCOM - - + DLIBCOM. _DLIBDIRFLAGS - - + _DLIBDIRFLAGS. DLIBDIRPREFIX - - + DLIBDIRPREFIX. DLIBDIRSUFFIX - - + DLIBDIRSUFFIX. DLIBFLAGPREFIX - - + DLIBFLAGPREFIX. _DLIBFLAGS - - + _DLIBFLAGS. DLIBFLAGSUFFIX - - + DLIBFLAGSUFFIX. DLIBLINKPREFIX - - + DLIBLINKPREFIX. DLIBLINKSUFFIX - - + DLIBLINKSUFFIX. DLINK - - + DLINK. DLINKCOM - - + DLINKCOM. DLINKFLAGPREFIX - - + DLINKFLAGPREFIX. DLINKFLAGS - - + DLINKFLAGS. DLINKFLAGSUFFIX - - + DLINKFLAGSUFFIX. DOCBOOK_DEFAULT_XSL_EPUB - - -The default XSLT file for the DocbookEpub builder within the + +The default XSLT file for the DocbookEpub builder within the current environment, if no other XSLT gets specified via keyword. DOCBOOK_DEFAULT_XSL_HTML - - -The default XSLT file for the DocbookHtml builder within the + +The default XSLT file for the DocbookHtml builder within the current environment, if no other XSLT gets specified via keyword. DOCBOOK_DEFAULT_XSL_HTMLCHUNKED - - -The default XSLT file for the DocbookHtmlChunked builder within the + +The default XSLT file for the DocbookHtmlChunked builder within the current environment, if no other XSLT gets specified via keyword. DOCBOOK_DEFAULT_XSL_HTMLHELP - - -The default XSLT file for the DocbookHtmlhelp builder within the + +The default XSLT file for the DocbookHtmlhelp builder within the current environment, if no other XSLT gets specified via keyword. DOCBOOK_DEFAULT_XSL_MAN - - -The default XSLT file for the DocbookMan builder within the + +The default XSLT file for the DocbookMan builder within the current environment, if no other XSLT gets specified via keyword. DOCBOOK_DEFAULT_XSL_PDF - - -The default XSLT file for the DocbookPdf builder within the + +The default XSLT file for the DocbookPdf builder within the current environment, if no other XSLT gets specified via keyword. DOCBOOK_DEFAULT_XSL_SLIDESHTML - - -The default XSLT file for the DocbookSlidesHtml builder within the + +The default XSLT file for the DocbookSlidesHtml builder within the current environment, if no other XSLT gets specified via keyword. DOCBOOK_DEFAULT_XSL_SLIDESPDF - - -The default XSLT file for the DocbookSlidesPdf builder within the + +The default XSLT file for the DocbookSlidesPdf builder within the current environment, if no other XSLT gets specified via keyword. DOCBOOK_FOP - - + The path to the PDF renderer fop or xep, if one of them is installed (fop gets checked first). @@ -1224,8 +1123,7 @@ if one of them is installed (fop gets checked first). DOCBOOK_FOPCOM - - + The full command-line for the PDF renderer fop or xep. @@ -1233,8 +1131,7 @@ PDF renderer fop or xep. DOCBOOK_FOPCOMSTR - - + The string displayed when a renderer like fop or xep is used to create PDF output from an XML file. @@ -1242,8 +1139,7 @@ The string displayed when a renderer like fop or DOCBOOK_FOPFLAGS - - + Additonal command-line flags for the PDF renderer fop or xep. @@ -1251,8 +1147,7 @@ PDF renderer fop or xep. DOCBOOK_XMLLINT - - + The path to the external executable xmllint, if it's installed. Note, that this is only used as last fallback for resolving XIncludes, if no libxml2 or lxml Python binding can be imported @@ -1262,8 +1157,7 @@ in the current system. DOCBOOK_XMLLINTCOM - - + The full command-line for the external executable xmllint. @@ -1271,8 +1165,7 @@ The full command-line for the external executable DOCBOOK_XMLLINTCOMSTR - - + The string displayed when xmllint is used to resolve XIncludes for a given XML file. @@ -1280,8 +1173,7 @@ XIncludes for a given XML file. DOCBOOK_XMLLINTFLAGS - - + Additonal command-line flags for the external executable xmllint. @@ -1289,8 +1181,7 @@ Additonal command-line flags for the external executable DOCBOOK_XSLTPROC - - + The path to the external executable xsltproc (or saxon, xalan), if one of them is installed. @@ -1301,8 +1192,7 @@ no libxml2 or lxml Python binding can be imported in the current system. DOCBOOK_XSLTPROCCOM - - + The full command-line for the external executable xsltproc (or saxon, xalan). @@ -1311,8 +1201,7 @@ The full command-line for the external executable DOCBOOK_XSLTPROCCOMSTR - - + The string displayed when xsltproc is used to transform an XML file via a given XSLT stylesheet. @@ -1320,8 +1209,7 @@ an XML file via a given XSLT stylesheet. DOCBOOK_XSLTPROCFLAGS - - + Additonal command-line flags for the external executable xsltproc (or saxon, xalan). @@ -1330,8 +1218,7 @@ Additonal command-line flags for the external executable DOCBOOK_XSLTPROCPARAMS - - + Additonal parameters that are not intended for the XSLT processor executable, but the XSL processing itself. By default, they get appended at the end of the command line for saxon and saxon-xslt, respectively. @@ -1340,133 +1227,120 @@ for saxon and saxon-xslt, respectively. DPATH - - + DPATH. DSUFFIXES - - + The list of suffixes of files that will be scanned for imported D package files. The default list is: - + ['.d'] _DVERFLAGS - - + _DVERFLAGS. DVERPREFIX - - + DVERPREFIX. DVERSIONS - - + DVERSIONS. DVERSUFFIX - - + DVERSUFFIX. DVIPDF - - + The TeX DVI file to PDF file converter. DVIPDFCOM - - + The command line used to convert TeX DVI files into a PDF file. DVIPDFCOMSTR - - + The string displayed when a TeX DVI file is converted into a PDF file. -If this is not set, then $DVIPDFCOM (the command line) is displayed. +If this is not set, then $DVIPDFCOM (the command line) is displayed. DVIPDFFLAGS - - + General options passed to the TeX DVI file to PDF file converter. DVIPS - - + The TeX DVI file to PostScript converter. DVIPSFLAGS - - + General options passed to the TeX DVI file to PostScript converter. ENV - - + A dictionary of environment variables to use when invoking commands. When -$ENV is used in a command all list +$ENV is used in a command all list values will be joined using the path separator and any other non-string values will simply be coerced to a string. Note that, by default, -scons +scons does not propagate the environment in force when you execute -scons +scons to the commands used to build target files. This is so that builds will be guaranteed repeatable regardless of the environment variables set at the time -scons +scons is invoked. - + If you want to propagate your environment variables to the commands executed @@ -1474,12 +1348,12 @@ to build target files, you must do so explicitly: - + import os env = Environment(ENV = os.environ) - + Note that you can choose only to propagate certain environment variables. A common example is @@ -1487,12 +1361,12 @@ the system PATH environment variable, so that -scons +scons uses the same utilities as the invoking shell (or other process): - + import os env = Environment(ENV = {'PATH' : os.environ['PATH']}) @@ -1500,8 +1374,7 @@ env = Environment(ENV = {'PATH' : os.environ['PATH']}) ESCAPE - - + A function that will be called to escape shell special characters in command lines. The function should take one argument: the command line string to escape; and should return the escaped command line. @@ -1510,25 +1383,23 @@ string to escape; and should return the escaped command line. F03 - - + The Fortran 03 compiler. -You should normally set the $FORTRAN variable, +You should normally set the $FORTRAN variable, which specifies the default Fortran compiler for all Fortran versions. -You only need to set $F03 if you need to use a specific compiler +You only need to set $F03 if you need to use a specific compiler or compiler version for Fortran 03 files. F03COM - - + The command line used to compile a Fortran 03 source file to an object file. -You only need to set $F03COM if you need to use a specific +You only need to set $F03COM if you need to use a specific command line for Fortran 03 files. -You should normally set the $FORTRANCOM variable, +You should normally set the $FORTRANCOM variable, which specifies the default command line for all Fortran versions. @@ -1536,19 +1407,17 @@ for all Fortran versions. F03COMSTR - - + The string displayed when a Fortran 03 source file is compiled to an object file. -If this is not set, then $F03COM or $FORTRANCOM +If this is not set, then $F03COM or $FORTRANCOM (the command line) is displayed. F03FILESUFFIXES - - + The list of file extensions for which the F03 dialect will be used. By default, this is ['.f03'] @@ -1556,22 +1425,21 @@ default, this is ['.f03'] F03FLAGS - - + General user-specified options that are passed to the Fortran 03 compiler. Note that this variable does not contain (or similar) include search path options -that scons generates automatically from $F03PATH. +that scons generates automatically from $F03PATH. See -$_F03INCFLAGS +$_F03INCFLAGS below, for the variable that expands to those options. -You only need to set $F03FLAGS if you need to define specific +You only need to set $F03FLAGS if you need to define specific user options for Fortran 03 files. -You should normally set the $FORTRANFLAGS variable, +You should normally set the $FORTRANFLAGS variable, which specifies the user-specified options passed to the default Fortran compiler for all Fortran versions. @@ -1580,86 +1448,83 @@ for all Fortran versions. _F03INCFLAGS - - + An automatically-generated construction variable containing the Fortran 03 compiler command-line options for specifying directories to be searched for include files. -The value of $_F03INCFLAGS is created -by appending $INCPREFIX and $INCSUFFIX +The value of $_F03INCFLAGS is created +by appending $INCPREFIX and $INCSUFFIX to the beginning and end -of each directory in $F03PATH. +of each directory in $F03PATH. F03PATH - - + The list of directories that the Fortran 03 compiler will search for include directories. The implicit dependency scanner will search these directories for include files. Don't explicitly put include directory -arguments in $F03FLAGS because the result will be non-portable +arguments in $F03FLAGS because the result will be non-portable and the directories will not be searched by the dependency scanner. Note: -directory names in $F03PATH will be looked-up relative to the SConscript +directory names in $F03PATH will be looked-up relative to the SConscript directory when they are used in a command. To force -scons +scons to look-up a directory relative to the root of the source tree use #: -You only need to set $F03PATH if you need to define a specific +You only need to set $F03PATH if you need to define a specific include path for Fortran 03 files. -You should normally set the $FORTRANPATH variable, +You should normally set the $FORTRANPATH variable, which specifies the include path for the default Fortran compiler for all Fortran versions. - + env = Environment(F03PATH='#/include') - + The directory look-up can also be forced using the -Dir() +Dir() function: - + include = Dir('include') env = Environment(F03PATH=include) - + The directory list will be added to command lines through the automatically-generated -$_F03INCFLAGS +$_F03INCFLAGS construction variable, which is constructed by appending the values of the -$INCPREFIX and $INCSUFFIX +$INCPREFIX and $INCSUFFIX construction variables to the beginning and end -of each directory in $F03PATH. +of each directory in $F03PATH. Any command lines you define that need the F03PATH directory list should -include $_F03INCFLAGS: +include $_F03INCFLAGS: - + env = Environment(F03COM="my_compiler $_F03INCFLAGS -c -o $TARGET $SOURCE") F03PPCOM - - + The command line used to compile a Fortran 03 source file to an object file after first running the file through the C preprocessor. -Any options specified in the $F03FLAGS and $CPPFLAGS construction variables +Any options specified in the $F03FLAGS and $CPPFLAGS construction variables are included on this command line. -You only need to set $F03PPCOM if you need to use a specific +You only need to set $F03PPCOM if you need to use a specific C-preprocessor command line for Fortran 03 files. -You should normally set the $FORTRANPPCOM variable, +You should normally set the $FORTRANPPCOM variable, which specifies the default C-preprocessor command line for all Fortran versions. @@ -1667,20 +1532,18 @@ for all Fortran versions. F03PPCOMSTR - - + The string displayed when a Fortran 03 source file is compiled to an object file after first running the file through the C preprocessor. -If this is not set, then $F03PPCOM or $FORTRANPPCOM +If this is not set, then $F03PPCOM or $FORTRANPPCOM (the command line) is displayed. F03PPFILESUFFIXES - - + The list of file extensions for which the compilation + preprocessor pass for F03 dialect will be used. By default, this is empty @@ -1688,25 +1551,23 @@ F03 dialect will be used. By default, this is empty F08 - - + The Fortran 08 compiler. -You should normally set the $FORTRAN variable, +You should normally set the $FORTRAN variable, which specifies the default Fortran compiler for all Fortran versions. -You only need to set $F08 if you need to use a specific compiler +You only need to set $F08 if you need to use a specific compiler or compiler version for Fortran 08 files. F08COM - - + The command line used to compile a Fortran 08 source file to an object file. -You only need to set $F08COM if you need to use a specific +You only need to set $F08COM if you need to use a specific command line for Fortran 08 files. -You should normally set the $FORTRANCOM variable, +You should normally set the $FORTRANCOM variable, which specifies the default command line for all Fortran versions. @@ -1714,19 +1575,17 @@ for all Fortran versions. F08COMSTR - - + The string displayed when a Fortran 08 source file is compiled to an object file. -If this is not set, then $F08COM or $FORTRANCOM +If this is not set, then $F08COM or $FORTRANCOM (the command line) is displayed. F08FILESUFFIXES - - + The list of file extensions for which the F08 dialect will be used. By default, this is ['.f08'] @@ -1734,22 +1593,21 @@ default, this is ['.f08'] F08FLAGS - - + General user-specified options that are passed to the Fortran 08 compiler. Note that this variable does not contain (or similar) include search path options -that scons generates automatically from $F08PATH. +that scons generates automatically from $F08PATH. See -$_F08INCFLAGS +$_F08INCFLAGS below, for the variable that expands to those options. -You only need to set $F08FLAGS if you need to define specific +You only need to set $F08FLAGS if you need to define specific user options for Fortran 08 files. -You should normally set the $FORTRANFLAGS variable, +You should normally set the $FORTRANFLAGS variable, which specifies the user-specified options passed to the default Fortran compiler for all Fortran versions. @@ -1758,86 +1616,83 @@ for all Fortran versions. _F08INCFLAGS - - + An automatically-generated construction variable containing the Fortran 08 compiler command-line options for specifying directories to be searched for include files. -The value of $_F08INCFLAGS is created -by appending $INCPREFIX and $INCSUFFIX +The value of $_F08INCFLAGS is created +by appending $INCPREFIX and $INCSUFFIX to the beginning and end -of each directory in $F08PATH. +of each directory in $F08PATH. F08PATH - - + The list of directories that the Fortran 08 compiler will search for include directories. The implicit dependency scanner will search these directories for include files. Don't explicitly put include directory -arguments in $F08FLAGS because the result will be non-portable +arguments in $F08FLAGS because the result will be non-portable and the directories will not be searched by the dependency scanner. Note: -directory names in $F08PATH will be looked-up relative to the SConscript +directory names in $F08PATH will be looked-up relative to the SConscript directory when they are used in a command. To force -scons +scons to look-up a directory relative to the root of the source tree use #: -You only need to set $F08PATH if you need to define a specific +You only need to set $F08PATH if you need to define a specific include path for Fortran 08 files. -You should normally set the $FORTRANPATH variable, +You should normally set the $FORTRANPATH variable, which specifies the include path for the default Fortran compiler for all Fortran versions. - + env = Environment(F08PATH='#/include') - + The directory look-up can also be forced using the -Dir() +Dir() function: - + include = Dir('include') env = Environment(F08PATH=include) - + The directory list will be added to command lines through the automatically-generated -$_F08INCFLAGS +$_F08INCFLAGS construction variable, which is constructed by appending the values of the -$INCPREFIX and $INCSUFFIX +$INCPREFIX and $INCSUFFIX construction variables to the beginning and end -of each directory in $F08PATH. +of each directory in $F08PATH. Any command lines you define that need the F08PATH directory list should -include $_F08INCFLAGS: +include $_F08INCFLAGS: - + env = Environment(F08COM="my_compiler $_F08INCFLAGS -c -o $TARGET $SOURCE") F08PPCOM - - + The command line used to compile a Fortran 08 source file to an object file after first running the file through the C preprocessor. -Any options specified in the $F08FLAGS and $CPPFLAGS construction variables +Any options specified in the $F08FLAGS and $CPPFLAGS construction variables are included on this command line. -You only need to set $F08PPCOM if you need to use a specific +You only need to set $F08PPCOM if you need to use a specific C-preprocessor command line for Fortran 08 files. -You should normally set the $FORTRANPPCOM variable, +You should normally set the $FORTRANPPCOM variable, which specifies the default C-preprocessor command line for all Fortran versions. @@ -1845,20 +1700,18 @@ for all Fortran versions. F08PPCOMSTR - - + The string displayed when a Fortran 08 source file is compiled to an object file after first running the file through the C preprocessor. -If this is not set, then $F08PPCOM or $FORTRANPPCOM +If this is not set, then $F08PPCOM or $FORTRANPPCOM (the command line) is displayed. F08PPFILESUFFIXES - - + The list of file extensions for which the compilation + preprocessor pass for F08 dialect will be used. By default, this is empty @@ -1866,25 +1719,23 @@ F08 dialect will be used. By default, this is empty F77 - - + The Fortran 77 compiler. -You should normally set the $FORTRAN variable, +You should normally set the $FORTRAN variable, which specifies the default Fortran compiler for all Fortran versions. -You only need to set $F77 if you need to use a specific compiler +You only need to set $F77 if you need to use a specific compiler or compiler version for Fortran 77 files. F77COM - - + The command line used to compile a Fortran 77 source file to an object file. -You only need to set $F77COM if you need to use a specific +You only need to set $F77COM if you need to use a specific command line for Fortran 77 files. -You should normally set the $FORTRANCOM variable, +You should normally set the $FORTRANCOM variable, which specifies the default command line for all Fortran versions. @@ -1892,19 +1743,17 @@ for all Fortran versions. F77COMSTR - - + The string displayed when a Fortran 77 source file is compiled to an object file. -If this is not set, then $F77COM or $FORTRANCOM +If this is not set, then $F77COM or $FORTRANCOM (the command line) is displayed. F77FILESUFFIXES - - + The list of file extensions for which the F77 dialect will be used. By default, this is ['.f77'] @@ -1912,22 +1761,21 @@ default, this is ['.f77'] F77FLAGS - - + General user-specified options that are passed to the Fortran 77 compiler. Note that this variable does not contain (or similar) include search path options -that scons generates automatically from $F77PATH. +that scons generates automatically from $F77PATH. See -$_F77INCFLAGS +$_F77INCFLAGS below, for the variable that expands to those options. -You only need to set $F77FLAGS if you need to define specific +You only need to set $F77FLAGS if you need to define specific user options for Fortran 77 files. -You should normally set the $FORTRANFLAGS variable, +You should normally set the $FORTRANFLAGS variable, which specifies the user-specified options passed to the default Fortran compiler for all Fortran versions. @@ -1936,86 +1784,83 @@ for all Fortran versions. _F77INCFLAGS - - + An automatically-generated construction variable containing the Fortran 77 compiler command-line options for specifying directories to be searched for include files. -The value of $_F77INCFLAGS is created -by appending $INCPREFIX and $INCSUFFIX +The value of $_F77INCFLAGS is created +by appending $INCPREFIX and $INCSUFFIX to the beginning and end -of each directory in $F77PATH. +of each directory in $F77PATH. F77PATH - - + The list of directories that the Fortran 77 compiler will search for include directories. The implicit dependency scanner will search these directories for include files. Don't explicitly put include directory -arguments in $F77FLAGS because the result will be non-portable +arguments in $F77FLAGS because the result will be non-portable and the directories will not be searched by the dependency scanner. Note: -directory names in $F77PATH will be looked-up relative to the SConscript +directory names in $F77PATH will be looked-up relative to the SConscript directory when they are used in a command. To force -scons +scons to look-up a directory relative to the root of the source tree use #: -You only need to set $F77PATH if you need to define a specific +You only need to set $F77PATH if you need to define a specific include path for Fortran 77 files. -You should normally set the $FORTRANPATH variable, +You should normally set the $FORTRANPATH variable, which specifies the include path for the default Fortran compiler for all Fortran versions. - + env = Environment(F77PATH='#/include') - + The directory look-up can also be forced using the -Dir() +Dir() function: - + include = Dir('include') env = Environment(F77PATH=include) - + The directory list will be added to command lines through the automatically-generated -$_F77INCFLAGS +$_F77INCFLAGS construction variable, which is constructed by appending the values of the -$INCPREFIX and $INCSUFFIX +$INCPREFIX and $INCSUFFIX construction variables to the beginning and end -of each directory in $F77PATH. +of each directory in $F77PATH. Any command lines you define that need the F77PATH directory list should -include $_F77INCFLAGS: +include $_F77INCFLAGS: - + env = Environment(F77COM="my_compiler $_F77INCFLAGS -c -o $TARGET $SOURCE") F77PPCOM - - + The command line used to compile a Fortran 77 source file to an object file after first running the file through the C preprocessor. -Any options specified in the $F77FLAGS and $CPPFLAGS construction variables +Any options specified in the $F77FLAGS and $CPPFLAGS construction variables are included on this command line. -You only need to set $F77PPCOM if you need to use a specific +You only need to set $F77PPCOM if you need to use a specific C-preprocessor command line for Fortran 77 files. -You should normally set the $FORTRANPPCOM variable, +You should normally set the $FORTRANPPCOM variable, which specifies the default C-preprocessor command line for all Fortran versions. @@ -2023,20 +1868,18 @@ for all Fortran versions. F77PPCOMSTR - - + The string displayed when a Fortran 77 source file is compiled to an object file after first running the file through the C preprocessor. -If this is not set, then $F77PPCOM or $FORTRANPPCOM +If this is not set, then $F77PPCOM or $FORTRANPPCOM (the command line) is displayed. F77PPFILESUFFIXES - - + The list of file extensions for which the compilation + preprocessor pass for F77 dialect will be used. By default, this is empty @@ -2044,25 +1887,23 @@ F77 dialect will be used. By default, this is empty F90 - - + The Fortran 90 compiler. -You should normally set the $FORTRAN variable, +You should normally set the $FORTRAN variable, which specifies the default Fortran compiler for all Fortran versions. -You only need to set $F90 if you need to use a specific compiler +You only need to set $F90 if you need to use a specific compiler or compiler version for Fortran 90 files. F90COM - - + The command line used to compile a Fortran 90 source file to an object file. -You only need to set $F90COM if you need to use a specific +You only need to set $F90COM if you need to use a specific command line for Fortran 90 files. -You should normally set the $FORTRANCOM variable, +You should normally set the $FORTRANCOM variable, which specifies the default command line for all Fortran versions. @@ -2070,19 +1911,17 @@ for all Fortran versions. F90COMSTR - - + The string displayed when a Fortran 90 source file is compiled to an object file. -If this is not set, then $F90COM or $FORTRANCOM +If this is not set, then $F90COM or $FORTRANCOM (the command line) is displayed. F90FILESUFFIXES - - + The list of file extensions for which the F90 dialect will be used. By default, this is ['.f90'] @@ -2090,22 +1929,21 @@ default, this is ['.f90'] F90FLAGS - - + General user-specified options that are passed to the Fortran 90 compiler. Note that this variable does not contain (or similar) include search path options -that scons generates automatically from $F90PATH. +that scons generates automatically from $F90PATH. See -$_F90INCFLAGS +$_F90INCFLAGS below, for the variable that expands to those options. -You only need to set $F90FLAGS if you need to define specific +You only need to set $F90FLAGS if you need to define specific user options for Fortran 90 files. -You should normally set the $FORTRANFLAGS variable, +You should normally set the $FORTRANFLAGS variable, which specifies the user-specified options passed to the default Fortran compiler for all Fortran versions. @@ -2114,86 +1952,83 @@ for all Fortran versions. _F90INCFLAGS - - + An automatically-generated construction variable containing the Fortran 90 compiler command-line options for specifying directories to be searched for include files. -The value of $_F90INCFLAGS is created -by appending $INCPREFIX and $INCSUFFIX +The value of $_F90INCFLAGS is created +by appending $INCPREFIX and $INCSUFFIX to the beginning and end -of each directory in $F90PATH. +of each directory in $F90PATH. F90PATH - - + The list of directories that the Fortran 90 compiler will search for include directories. The implicit dependency scanner will search these directories for include files. Don't explicitly put include directory -arguments in $F90FLAGS because the result will be non-portable +arguments in $F90FLAGS because the result will be non-portable and the directories will not be searched by the dependency scanner. Note: -directory names in $F90PATH will be looked-up relative to the SConscript +directory names in $F90PATH will be looked-up relative to the SConscript directory when they are used in a command. To force -scons +scons to look-up a directory relative to the root of the source tree use #: -You only need to set $F90PATH if you need to define a specific +You only need to set $F90PATH if you need to define a specific include path for Fortran 90 files. -You should normally set the $FORTRANPATH variable, +You should normally set the $FORTRANPATH variable, which specifies the include path for the default Fortran compiler for all Fortran versions. - + env = Environment(F90PATH='#/include') - + The directory look-up can also be forced using the -Dir() +Dir() function: - + include = Dir('include') env = Environment(F90PATH=include) - + The directory list will be added to command lines through the automatically-generated -$_F90INCFLAGS +$_F90INCFLAGS construction variable, which is constructed by appending the values of the -$INCPREFIX and $INCSUFFIX +$INCPREFIX and $INCSUFFIX construction variables to the beginning and end -of each directory in $F90PATH. +of each directory in $F90PATH. Any command lines you define that need the F90PATH directory list should -include $_F90INCFLAGS: +include $_F90INCFLAGS: - + env = Environment(F90COM="my_compiler $_F90INCFLAGS -c -o $TARGET $SOURCE") F90PPCOM - - + The command line used to compile a Fortran 90 source file to an object file after first running the file through the C preprocessor. -Any options specified in the $F90FLAGS and $CPPFLAGS construction variables +Any options specified in the $F90FLAGS and $CPPFLAGS construction variables are included on this command line. -You only need to set $F90PPCOM if you need to use a specific +You only need to set $F90PPCOM if you need to use a specific C-preprocessor command line for Fortran 90 files. -You should normally set the $FORTRANPPCOM variable, +You should normally set the $FORTRANPPCOM variable, which specifies the default C-preprocessor command line for all Fortran versions. @@ -2201,19 +2036,17 @@ for all Fortran versions. F90PPCOMSTR - - + The string displayed when a Fortran 90 source file is compiled after first running the file through the C preprocessor. -If this is not set, then $F90PPCOM or $FORTRANPPCOM +If this is not set, then $F90PPCOM or $FORTRANPPCOM (the command line) is displayed. F90PPFILESUFFIXES - - + The list of file extensions for which the compilation + preprocessor pass for F90 dialect will be used. By default, this is empty @@ -2221,25 +2054,23 @@ F90 dialect will be used. By default, this is empty F95 - - + The Fortran 95 compiler. -You should normally set the $FORTRAN variable, +You should normally set the $FORTRAN variable, which specifies the default Fortran compiler for all Fortran versions. -You only need to set $F95 if you need to use a specific compiler +You only need to set $F95 if you need to use a specific compiler or compiler version for Fortran 95 files. F95COM - - + The command line used to compile a Fortran 95 source file to an object file. -You only need to set $F95COM if you need to use a specific +You only need to set $F95COM if you need to use a specific command line for Fortran 95 files. -You should normally set the $FORTRANCOM variable, +You should normally set the $FORTRANCOM variable, which specifies the default command line for all Fortran versions. @@ -2247,19 +2078,17 @@ for all Fortran versions. F95COMSTR - - + The string displayed when a Fortran 95 source file is compiled to an object file. -If this is not set, then $F95COM or $FORTRANCOM +If this is not set, then $F95COM or $FORTRANCOM (the command line) is displayed. F95FILESUFFIXES - - + The list of file extensions for which the F95 dialect will be used. By default, this is ['.f95'] @@ -2267,22 +2096,21 @@ default, this is ['.f95'] F95FLAGS - - + General user-specified options that are passed to the Fortran 95 compiler. Note that this variable does not contain (or similar) include search path options -that scons generates automatically from $F95PATH. +that scons generates automatically from $F95PATH. See -$_F95INCFLAGS +$_F95INCFLAGS below, for the variable that expands to those options. -You only need to set $F95FLAGS if you need to define specific +You only need to set $F95FLAGS if you need to define specific user options for Fortran 95 files. -You should normally set the $FORTRANFLAGS variable, +You should normally set the $FORTRANFLAGS variable, which specifies the user-specified options passed to the default Fortran compiler for all Fortran versions. @@ -2291,86 +2119,83 @@ for all Fortran versions. _F95INCFLAGS - - + An automatically-generated construction variable containing the Fortran 95 compiler command-line options for specifying directories to be searched for include files. -The value of $_F95INCFLAGS is created -by appending $INCPREFIX and $INCSUFFIX +The value of $_F95INCFLAGS is created +by appending $INCPREFIX and $INCSUFFIX to the beginning and end -of each directory in $F95PATH. +of each directory in $F95PATH. F95PATH - - + The list of directories that the Fortran 95 compiler will search for include directories. The implicit dependency scanner will search these directories for include files. Don't explicitly put include directory -arguments in $F95FLAGS because the result will be non-portable +arguments in $F95FLAGS because the result will be non-portable and the directories will not be searched by the dependency scanner. Note: -directory names in $F95PATH will be looked-up relative to the SConscript +directory names in $F95PATH will be looked-up relative to the SConscript directory when they are used in a command. To force -scons +scons to look-up a directory relative to the root of the source tree use #: -You only need to set $F95PATH if you need to define a specific +You only need to set $F95PATH if you need to define a specific include path for Fortran 95 files. -You should normally set the $FORTRANPATH variable, +You should normally set the $FORTRANPATH variable, which specifies the include path for the default Fortran compiler for all Fortran versions. - + env = Environment(F95PATH='#/include') - + The directory look-up can also be forced using the -Dir() +Dir() function: - + include = Dir('include') env = Environment(F95PATH=include) - + The directory list will be added to command lines through the automatically-generated -$_F95INCFLAGS +$_F95INCFLAGS construction variable, which is constructed by appending the values of the -$INCPREFIX and $INCSUFFIX +$INCPREFIX and $INCSUFFIX construction variables to the beginning and end -of each directory in $F95PATH. +of each directory in $F95PATH. Any command lines you define that need the F95PATH directory list should -include $_F95INCFLAGS: +include $_F95INCFLAGS: - + env = Environment(F95COM="my_compiler $_F95INCFLAGS -c -o $TARGET $SOURCE") F95PPCOM - - + The command line used to compile a Fortran 95 source file to an object file after first running the file through the C preprocessor. -Any options specified in the $F95FLAGS and $CPPFLAGS construction variables +Any options specified in the $F95FLAGS and $CPPFLAGS construction variables are included on this command line. -You only need to set $F95PPCOM if you need to use a specific +You only need to set $F95PPCOM if you need to use a specific C-preprocessor command line for Fortran 95 files. -You should normally set the $FORTRANPPCOM variable, +You should normally set the $FORTRANPPCOM variable, which specifies the default C-preprocessor command line for all Fortran versions. @@ -2378,20 +2203,18 @@ for all Fortran versions. F95PPCOMSTR - - + The string displayed when a Fortran 95 source file is compiled to an object file after first running the file through the C preprocessor. -If this is not set, then $F95PPCOM or $FORTRANPPCOM +If this is not set, then $F95PPCOM or $FORTRANPPCOM (the command line) is displayed. F95PPFILESUFFIXES - - + The list of file extensions for which the compilation + preprocessor pass for F95 dialect will be used. By default, this is empty @@ -2399,13 +2222,11 @@ F95 dialect will be used. By default, this is empty File - - + A function that converts a string into a File instance relative to the target being built. - - + A function that converts a string into a File instance relative to the target being built. @@ -2413,8 +2234,7 @@ target being built. FORTRAN - - + The default Fortran compiler for all versions of Fortran. @@ -2422,34 +2242,31 @@ for all versions of Fortran. FORTRANCOM - - + The command line used to compile a Fortran source file to an object file. By default, any options specified -in the $FORTRANFLAGS, -$CPPFLAGS, -$_CPPDEFFLAGS, -$_FORTRANMODFLAG, and -$_FORTRANINCFLAGS construction variables +in the $FORTRANFLAGS, +$CPPFLAGS, +$_CPPDEFFLAGS, +$_FORTRANMODFLAG, and +$_FORTRANINCFLAGS construction variables are included on this command line. FORTRANCOMSTR - - + The string displayed when a Fortran source file is compiled to an object file. -If this is not set, then $FORTRANCOM +If this is not set, then $FORTRANCOM (the command line) is displayed. FORTRANFILESUFFIXES - - + The list of file extensions for which the FORTRAN dialect will be used. By default, this is ['.f', '.for', '.ftn'] @@ -2457,17 +2274,16 @@ default, this is ['.f', '.for', '.ftn'] FORTRANFLAGS - - + General user-specified options that are passed to the Fortran compiler. Note that this variable does not contain (or similar) include or module search path options -that scons generates automatically from $FORTRANPATH. +that scons generates automatically from $FORTRANPATH. See -$_FORTRANINCFLAGS and $_FORTRANMODFLAG, +$_FORTRANINCFLAGS and $_FORTRANMODFLAG, below, for the variables that expand those options. @@ -2475,23 +2291,21 @@ for the variables that expand those options. _FORTRANINCFLAGS - - + An automatically-generated construction variable containing the Fortran compiler command-line options for specifying directories to be searched for include files and module files. -The value of $_FORTRANINCFLAGS is created -by prepending/appending $INCPREFIX and $INCSUFFIX +The value of $_FORTRANINCFLAGS is created +by prepending/appending $INCPREFIX and $INCSUFFIX to the beginning and end -of each directory in $FORTRANPATH. +of each directory in $FORTRANPATH. FORTRANMODDIR - - + Directory location where the Fortran compiler should place any module files it generates. This variable is empty, by default. Some Fortran compilers will internally append this directory in the search path @@ -2501,48 +2315,44 @@ for module files, as well. FORTRANMODDIRPREFIX - - + The prefix used to specify a module directory on the Fortran compiler command line. This will be appended to the beginning of the directory -in the $FORTRANMODDIR construction variables -when the $_FORTRANMODFLAG variables is automatically generated. +in the $FORTRANMODDIR construction variables +when the $_FORTRANMODFLAG variables is automatically generated. FORTRANMODDIRSUFFIX - - + The suffix used to specify a module directory on the Fortran compiler command line. This will be appended to the beginning of the directory -in the $FORTRANMODDIR construction variables -when the $_FORTRANMODFLAG variables is automatically generated. +in the $FORTRANMODDIR construction variables +when the $_FORTRANMODFLAG variables is automatically generated. _FORTRANMODFLAG - - + An automatically-generated construction variable containing the Fortran compiler command-line option for specifying the directory location where the Fortran compiler should place any module files that happen to get generated during compilation. -The value of $_FORTRANMODFLAG is created -by prepending/appending $FORTRANMODDIRPREFIX and -$FORTRANMODDIRSUFFIX -to the beginning and end of the directory in $FORTRANMODDIR. +The value of $_FORTRANMODFLAG is created +by prepending/appending $FORTRANMODDIRPREFIX and +$FORTRANMODDIRSUFFIX +to the beginning and end of the directory in $FORTRANMODDIR. FORTRANMODPREFIX - - + The module file prefix used by the Fortran compiler. SCons assumes that the Fortran compiler follows the quasi-standard naming convention for module files of @@ -2556,8 +2366,7 @@ module file name as scons attempts to resolve dependencies. FORTRANMODSUFFIX - - + The module file suffix used by the Fortran compiler. SCons assumes that the Fortran compiler follows the quasi-standard naming convention for module files of @@ -2571,8 +2380,7 @@ module file name as scons attempts to resolve dependencies. FORTRANPATH - - + The list of directories that the Fortran compiler will search for include files and (for some compilers) module files. The Fortran implicit dependency scanner will search these directories for include files (but @@ -2582,77 +2390,74 @@ include directory arguments in FORTRANFLAGS because the result will be non-portable and the directories will not be searched by the dependency scanner. Note: directory names in FORTRANPATH will be looked-up relative to the SConscript directory when they are used in a command. To force -scons +scons to look-up a directory relative to the root of the source tree use #: - + env = Environment(FORTRANPATH='#/include') - + The directory look-up can also be forced using the -Dir() +Dir() function: - + include = Dir('include') env = Environment(FORTRANPATH=include) - + The directory list will be added to command lines through the automatically-generated -$_FORTRANINCFLAGS +$_FORTRANINCFLAGS construction variable, which is constructed by appending the values of the -$INCPREFIX and $INCSUFFIX +$INCPREFIX and $INCSUFFIX construction variables to the beginning and end -of each directory in $FORTRANPATH. +of each directory in $FORTRANPATH. Any command lines you define that need the FORTRANPATH directory list should -include $_FORTRANINCFLAGS: +include $_FORTRANINCFLAGS: - + env = Environment(FORTRANCOM="my_compiler $_FORTRANINCFLAGS -c -o $TARGET $SOURCE") FORTRANPPCOM - - + The command line used to compile a Fortran source file to an object file after first running the file through the C preprocessor. -By default, any options specified in the $FORTRANFLAGS, -$CPPFLAGS, -$_CPPDEFFLAGS, -$_FORTRANMODFLAG, and -$_FORTRANINCFLAGS +By default, any options specified in the $FORTRANFLAGS, +$CPPFLAGS, +$_CPPDEFFLAGS, +$_FORTRANMODFLAG, and +$_FORTRANINCFLAGS construction variables are included on this command line. FORTRANPPCOMSTR - - + The string displayed when a Fortran source file is compiled to an object file after first running the file through the C preprocessor. -If this is not set, then $FORTRANPPCOM +If this is not set, then $FORTRANPPCOM (the command line) is displayed. FORTRANPPFILESUFFIXES - - + The list of file extensions for which the compilation + preprocessor pass for FORTRAN dialect will be used. By default, this is ['.fpp', '.FPP'] @@ -2660,15 +2465,14 @@ FORTRAN dialect will be used. By default, this is ['.fpp', '.FPP'] FORTRANSUFFIXES - - + The list of suffixes of files that will be scanned for Fortran implicit dependencies (INCLUDE lines and USE statements). The default list is: - + [".f", ".F", ".for", ".FOR", ".ftn", ".FTN", ".fpp", ".FPP", ".f77", ".F77", ".f90", ".F90", ".f95", ".F95"] @@ -2676,50 +2480,47 @@ The default list is: FRAMEWORKPATH - - + On Mac OS X with gcc, a list containing the paths to search for frameworks. Used by the compiler to find framework-style includes like #include <Fmwk/Header.h>. Used by the linker to find user-specified frameworks when linking (see -$FRAMEWORKS). +$FRAMEWORKS). For example: - + env.AppendUnique(FRAMEWORKPATH='#myframeworkdir') - + will add - + ... -Fmyframeworkdir - + to the compiler and linker command lines. _FRAMEWORKPATH - - + On Mac OS X with gcc, an automatically-generated construction variable containing the linker command-line options corresponding to -$FRAMEWORKPATH. +$FRAMEWORKPATH. FRAMEWORKPATHPREFIX - - + On Mac OS X with gcc, the prefix to be used for the FRAMEWORKPATH entries. -(see $FRAMEWORKPATH). +(see $FRAMEWORKPATH). The default value is . @@ -2727,11 +2528,10 @@ The default value is FRAMEWORKPREFIX - - + On Mac OS X with gcc, the prefix to be used for linking in frameworks -(see $FRAMEWORKS). +(see $FRAMEWORKS). The default value is . @@ -2739,8 +2539,7 @@ The default value is _FRAMEWORKS - - + On Mac OS X with gcc, an automatically-generated construction variable containing the linker command-line options @@ -2750,15 +2549,14 @@ for linking with FRAMEWORKS. FRAMEWORKS - - + On Mac OS X with gcc, a list of the framework names to be linked into a program or shared library or bundle. The default value is the empty list. For example: - + env.AppendUnique(FRAMEWORKS=Split('System Cocoa SystemConfiguration')) @@ -2766,31 +2564,28 @@ For example: FRAMEWORKSFLAGS - - + On Mac OS X with gcc, general user-supplied frameworks options to be added at the end of a command line building a loadable module. (This has been largely superseded by -the $FRAMEWORKPATH, $FRAMEWORKPATHPREFIX, -$FRAMEWORKPREFIX and $FRAMEWORKS variables +the $FRAMEWORKPATH, $FRAMEWORKPATHPREFIX, +$FRAMEWORKPREFIX and $FRAMEWORKS variables described above.) GS - - + The Ghostscript program used, e.g. to convert PostScript to PDF files. GSCOM - - + The full Ghostscript command line used for the conversion process. Its default value is $GS $GSFLAGS -sOutputFile=$TARGET $SOURCES. @@ -2798,18 +2593,16 @@ value is $GS $GSFLAGS -sOutputFile=$TARGET $SOURCES GSCOMSTR - - + The string displayed when Ghostscript is called for the conversion process. -If this is not set (the default), then $GSCOM (the command line) is displayed. +If this is not set (the default), then $GSCOM (the command line) is displayed. GSFLAGS - - + General options passed to the Ghostscript program, when converting PostScript to PDF files for example. Its default value is -dNOPAUSE -dBATCH -sDEVICE=pdfwrite @@ -2818,8 +2611,15 @@ is -dNOPAUSE -dBATCH -sDEVICE=pdfwrite HOST_ARCH - - + + The name of the host hardware architecture used to create the Environment. + If a platform is specified when creating the Environment, then + that Platform's logic will handle setting this value. + This value is immutable, and should not be changed by the user after + the Environment is initialized. + Currently only set for Win32. + + Sets the host architecture for Visual Studio compiler. If not set, default to the detected host architecture: note that this may depend on the python you are using. @@ -2827,29 +2627,19 @@ This variable must be passed as an argument to the Environment() constructor; setting it later has no effect. - -Valid values are the same as for $TARGET_ARCH. + +Valid values are the same as for $TARGET_ARCH. - + This is currently only used on Windows, but in the future it will be used on other OSes as well. - - - The name of the host hardware architecture used to create the Environment. - If a platform is specified when creating the Environment, then - that Platform's logic will handle setting this value. - This value is immutable, and should not be changed by the user after - the Environment is initialized. - Currently only set for Win32. - - + HOST_OS - - + The name of the host operating system used to create the Environment. If a platform is specified when creating the Environment, then that Platform's logic will handle setting this value. @@ -2861,29 +2651,27 @@ used on other OSes as well. IDLSUFFIXES - - + The list of suffixes of files that will be scanned for IDL implicit dependencies (#include or import lines). The default list is: - + [".idl", ".IDL"] IMPLICIT_COMMAND_DEPENDENCIES - - + Controls whether or not SCons will add implicit dependencies for the commands executed to build targets. - + By default, SCons will add to each target an implicit dependency on the command @@ -2897,9 +2685,9 @@ variable in the environment used to execute the command. - + If the construction variable -$IMPLICIT_COMMAND_DEPENDENCIES +$IMPLICIT_COMMAND_DEPENDENCIES is set to a false value (None, False, @@ -2910,41 +2698,38 @@ not be added to the targets built with that construction environment. - + env = Environment(IMPLICIT_COMMAND_DEPENDENCIES = 0) INCPREFIX - - + The prefix used to specify an include directory on the C compiler command line. This will be appended to the beginning of each directory -in the $CPPPATH and $FORTRANPATH construction variables -when the $_CPPINCFLAGS and $_FORTRANINCFLAGS +in the $CPPPATH and $FORTRANPATH construction variables +when the $_CPPINCFLAGS and $_FORTRANINCFLAGS variables are automatically generated. INCSUFFIX - - + The suffix used to specify an include directory on the C compiler command line. This will be appended to the end of each directory -in the $CPPPATH and $FORTRANPATH construction variables -when the $_CPPINCFLAGS and $_FORTRANINCFLAGS +in the $CPPPATH and $FORTRANPATH construction variables +when the $_CPPINCFLAGS and $_FORTRANINCFLAGS variables are automatically generated. INSTALL - - + A function to be called to install a file into a destination file name. The default function copies the file into the destination @@ -2953,11 +2738,11 @@ to match the source file's). The function takes the following arguments: - + def install(dest, source, env): - + dest is the path name of the destination file. source @@ -2971,21 +2756,19 @@ in force for this file installation. INSTALLSTR - - + The string displayed when a file is installed into a destination file name. The default is: - + Install file: "$SOURCE" as "$TARGET" INTEL_C_COMPILER_VERSION - - + Set by the "intelc" Tool to the major version number of the Intel C compiler selected for use. @@ -2994,27 +2777,23 @@ selected for use. JAR - - + The Java archive tool. - - + The Java archive tool. JARCHDIR - - + The directory to which the Java archive tool should change (using the option). - - + The directory to which the Java archive tool should change (using the @@ -3024,44 +2803,39 @@ option). JARCOM - - + The command line used to call the Java archive tool. - - + The command line used to call the Java archive tool. JARCOMSTR - - + The string displayed when the Java archive tool is called -If this is not set, then $JARCOM (the command line) is displayed. +If this is not set, then $JARCOM (the command line) is displayed. - + env = Environment(JARCOMSTR = "JARchiving $SOURCES into $TARGET") - - + The string displayed when the Java archive tool is called -If this is not set, then $JARCOM (the command line) is displayed. +If this is not set, then $JARCOM (the command line) is displayed. - + env = Environment(JARCOMSTR = "JARchiving $SOURCES into $TARGET") JARFLAGS - - + General options passed to the Java archive tool. By default this is set to @@ -3069,8 +2843,7 @@ to create the necessary jar file. - - + General options passed to the Java archive tool. By default this is set to @@ -3082,14 +2855,12 @@ file. JARSUFFIX - - + The suffix for Java archives: .jar by default. - - + The suffix for Java archives: .jar by default. @@ -3098,11 +2869,10 @@ by default. JAVABOOTCLASSPATH - - + Specifies the list of directories that will be added to the -javac command line +javac command line via the option. The individual directory names will be separated by the operating system's path separate character @@ -3113,51 +2883,46 @@ separated by the operating system's path separate character JAVAC - - + The Java compiler. JAVACCOM - - + The command line used to compile a directory tree containing Java source files to corresponding Java class files. -Any options specified in the $JAVACFLAGS construction variable +Any options specified in the $JAVACFLAGS construction variable are included on this command line. JAVACCOMSTR - - + The string displayed when compiling a directory tree of Java source files to corresponding Java class files. -If this is not set, then $JAVACCOM (the command line) is displayed. +If this is not set, then $JAVACCOM (the command line) is displayed. - + env = Environment(JAVACCOMSTR = "Compiling class files $TARGETS from $SOURCES") JAVACFLAGS - - + General options that are passed to the Java compiler. JAVACLASSDIR - - + The directory in which Java class files may be found. This is stripped from the beginning of any Java .class file names supplied to the @@ -3168,13 +2933,12 @@ builder. JAVACLASSPATH - - + Specifies the list of directories that will be searched for Java .class file. The directories in this list will be added to the -javac and javah command lines +javac and javah command lines via the option. The individual directory names will be separated by the operating system's path separate character @@ -3182,19 +2946,18 @@ separated by the operating system's path separate character ; on Windows). - + Note that this currently just adds the specified directory via the option. -SCons does not currently search the -$JAVACLASSPATH directories for dependency +SCons does not currently search the +$JAVACLASSPATH directories for dependency .class files. JAVACLASSSUFFIX - - + The suffix for Java class files; .class by default. @@ -3203,41 +2966,37 @@ by default. JAVAH - - + The Java generator for C header and stub files. JAVAHCOM - - + The command line used to generate C header and stub files from Java classes. -Any options specified in the $JAVAHFLAGS construction variable +Any options specified in the $JAVAHFLAGS construction variable are included on this command line. JAVAHCOMSTR - - + The string displayed when C header and stub files are generated from Java classes. -If this is not set, then $JAVAHCOM (the command line) is displayed. +If this is not set, then $JAVAHCOM (the command line) is displayed. - + env = Environment(JAVAHCOMSTR = "Generating header/stub file(s) $TARGETS from $SOURCES") JAVAHFLAGS - - + General options passed to the C header and stub file generator for Java classes. @@ -3245,13 +3004,12 @@ for Java classes. JAVASOURCEPATH - - + Specifies the list of directories that will be searched for input .java file. The directories in this list will be added to the -javac command line +javac command line via the option. The individual directory names will be separated by the operating system's path separate character @@ -3259,19 +3017,18 @@ separated by the operating system's path separate character ; on Windows). - + Note that this currently just adds the specified directory via the option. -SCons does not currently search the -$JAVASOURCEPATH directories for dependency +SCons does not currently search the +$JAVASOURCEPATH directories for dependency .java files. JAVASUFFIX - - + The suffix for Java files; .java by default. @@ -3280,75 +3037,69 @@ by default. JAVAVERSION - - -Specifies the Java version being used by the Java builder. + +Specifies the Java version being used by the Java builder. This is not currently used to select one version of the Java compiler vs. another. Instead, you should set this to specify the version of Java -supported by your javac compiler. +supported by your javac compiler. The default is 1.4. - + This is sometimes necessary because Java 1.5 changed the file names that are created for nested anonymous inner classes, which can cause a mismatch with the files -that SCons expects will be generated by the javac compiler. -Setting $JAVAVERSION to 1.5 +that SCons expects will be generated by the javac compiler. +Setting $JAVAVERSION to 1.5 (or 1.6, as appropriate) -can make SCons realize that a Java 1.5 or 1.6 +can make SCons realize that a Java 1.5 or 1.6 build is actually up to date. LATEX - - + The LaTeX structured formatter and typesetter. LATEXCOM - - + The command line used to call the LaTeX structured formatter and typesetter. LATEXCOMSTR - - + The string displayed when calling the LaTeX structured formatter and typesetter. -If this is not set, then $LATEXCOM (the command line) is displayed. +If this is not set, then $LATEXCOM (the command line) is displayed. - + env = Environment(LATEXCOMSTR = "Building $TARGET from LaTeX input $SOURCES") LATEXFLAGS - - + General options passed to the LaTeX structured formatter and typesetter. LATEXRETRIES - - + The maximum number of times that LaTeX will be re-run if the .log -generated by the $LATEXCOM command +generated by the $LATEXCOM command indicates that there are undefined references. The default is to try to resolve undefined references by re-running LaTeX up to three times. @@ -3357,72 +3108,65 @@ by re-running LaTeX up to three times. LATEXSUFFIXES - - + The list of suffixes of files that will be scanned for LaTeX implicit dependencies (\include or \import files). The default list is: - + [".tex", ".ltx", ".latex"] LDMODULE - - + The linker for building loadable modules. -By default, this is the same as $SHLINK. +By default, this is the same as $SHLINK. LDMODULECOM - - + The command line for building loadable modules. -On Mac OS X, this uses the $LDMODULE, -$LDMODULEFLAGS and -$FRAMEWORKSFLAGS variables. -On other systems, this is the same as $SHLINK. +On Mac OS X, this uses the $LDMODULE, +$LDMODULEFLAGS and +$FRAMEWORKSFLAGS variables. +On other systems, this is the same as $SHLINK. LDMODULECOMSTR - - + The string displayed when building loadable modules. -If this is not set, then $LDMODULECOM (the command line) is displayed. +If this is not set, then $LDMODULECOM (the command line) is displayed. LDMODULEFLAGS - - + General user options passed to the linker for building loadable modules. LDMODULEPREFIX - - + The prefix used for loadable module file names. On Mac OS X, this is null; on other systems, this is -the same as $SHLIBPREFIX. +the same as $SHLIBPREFIX. LDMODULESUFFIX - - + The suffix used for loadable module file names. On Mac OS X, this is null; on other systems, this is @@ -3432,16 +3176,14 @@ the same as $SHLIBSUFFIX. LEX - - + The lexical analyzer generator. LEXCOM - - + The command line used to call the lexical analyzer generator to generate a source file. @@ -3449,162 +3191,151 @@ to generate a source file. LEXCOMSTR - - + The string displayed when generating a source file using the lexical analyzer generator. -If this is not set, then $LEXCOM (the command line) is displayed. +If this is not set, then $LEXCOM (the command line) is displayed. - + env = Environment(LEXCOMSTR = "Lex'ing $TARGET from $SOURCES") LEXFLAGS - - + General options passed to the lexical analyzer generator. _LIBDIRFLAGS - - + An automatically-generated construction variable containing the linker command-line options for specifying directories to be searched for library. -The value of $_LIBDIRFLAGS is created -by appending $LIBDIRPREFIX and $LIBDIRSUFFIX +The value of $_LIBDIRFLAGS is created +by appending $LIBDIRPREFIX and $LIBDIRSUFFIX to the beginning and end -of each directory in $LIBPATH. +of each directory in $LIBPATH. LIBDIRPREFIX - - + The prefix used to specify a library directory on the linker command line. This will be appended to the beginning of each directory -in the $LIBPATH construction variable -when the $_LIBDIRFLAGS variable is automatically generated. +in the $LIBPATH construction variable +when the $_LIBDIRFLAGS variable is automatically generated. LIBDIRSUFFIX - - + The suffix used to specify a library directory on the linker command line. This will be appended to the end of each directory -in the $LIBPATH construction variable -when the $_LIBDIRFLAGS variable is automatically generated. +in the $LIBPATH construction variable +when the $_LIBDIRFLAGS variable is automatically generated. LIBEMITTER - - + TODO _LIBFLAGS - - + An automatically-generated construction variable containing the linker command-line options for specifying libraries to be linked with the resulting target. -The value of $_LIBFLAGS is created -by appending $LIBLINKPREFIX and $LIBLINKSUFFIX +The value of $_LIBFLAGS is created +by appending $LIBLINKPREFIX and $LIBLINKSUFFIX to the beginning and end -of each filename in $LIBS. +of each filename in $LIBS. LIBLINKPREFIX - - + The prefix used to specify a library to link on the linker command line. This will be appended to the beginning of each library -in the $LIBS construction variable -when the $_LIBFLAGS variable is automatically generated. +in the $LIBS construction variable +when the $_LIBFLAGS variable is automatically generated. LIBLINKSUFFIX - - + The suffix used to specify a library to link on the linker command line. This will be appended to the end of each library -in the $LIBS construction variable -when the $_LIBFLAGS variable is automatically generated. +in the $LIBS construction variable +when the $_LIBFLAGS variable is automatically generated. LIBPATH - - + The list of directories that will be searched for libraries. The implicit dependency scanner will search these directories for include files. Don't explicitly put include directory -arguments in $LINKFLAGS or $SHLINKFLAGS +arguments in $LINKFLAGS or $SHLINKFLAGS because the result will be non-portable and the directories will not be searched by the dependency scanner. Note: directory names in LIBPATH will be looked-up relative to the SConscript directory when they are used in a command. To force -scons +scons to look-up a directory relative to the root of the source tree use #: - + env = Environment(LIBPATH='#/libs') - + The directory look-up can also be forced using the -Dir() +Dir() function: - + libs = Dir('libs') env = Environment(LIBPATH=libs) - + The directory list will be added to command lines through the automatically-generated -$_LIBDIRFLAGS +$_LIBDIRFLAGS construction variable, which is constructed by appending the values of the -$LIBDIRPREFIX and $LIBDIRSUFFIX +$LIBDIRPREFIX and $LIBDIRSUFFIX construction variables to the beginning and end -of each directory in $LIBPATH. +of each directory in $LIBPATH. Any command lines you define that need the LIBPATH directory list should -include $_LIBDIRFLAGS: +include $_LIBDIRFLAGS: - + env = Environment(LINKCOM="my_linker $_LIBDIRFLAGS $_LIBFLAGS -o $TARGET $SOURCE") LIBPREFIX - - + The prefix used for (static) library file names. A default value is set for each platform (posix, win32, os2, etc.), @@ -3616,65 +3347,63 @@ to reflect the names of the libraries they create. LIBPREFIXES - - + A list of all legal prefixes for library file names. When searching for library dependencies, SCons will look for files with these prefixes, the base library name, -and suffixes in the $LIBSUFFIXES list. +and suffixes in the $LIBSUFFIXES list. LIBS - - + A list of one or more libraries that will be linked with any executable programs created by this environment. - + The library list will be added to command lines through the automatically-generated -$_LIBFLAGS +$_LIBFLAGS construction variable, which is constructed by appending the values of the -$LIBLINKPREFIX and $LIBLINKSUFFIX +$LIBLINKPREFIX and $LIBLINKSUFFIX construction variables to the beginning and end -of each filename in $LIBS. +of each filename in $LIBS. Any command lines you define that need the LIBS library list should -include $_LIBFLAGS: +include $_LIBFLAGS: - + env = Environment(LINKCOM="my_linker $_LIBDIRFLAGS $_LIBFLAGS -o $TARGET $SOURCE") - + If you add a File object to the -$LIBS +$LIBS list, the name of that file will be added to -$_LIBFLAGS, +$_LIBFLAGS, and thus the link line, as is, without -$LIBLINKPREFIX +$LIBLINKPREFIX or -$LIBLINKSUFFIX. +$LIBLINKSUFFIX. For example: - + env.Append(LIBS=File('/tmp/mylib.so')) - + In all cases, scons will add dependencies from the executable program to all the libraries in this list. @@ -3682,8 +3411,7 @@ all the libraries in this list. LIBSUFFIX - - + The suffix used for (static) library file names. A default value is set for each platform (posix, win32, os2, etc.), @@ -3695,11 +3423,10 @@ to reflect the names of the libraries they create. LIBSUFFIXES - - + A list of all legal suffixes for library file names. When searching for library dependencies, -SCons will look for files with prefixes, in the $LIBPREFIXES list, +SCons will look for files with prefixes, in the $LIBPREFIXES list, the base library name, and these suffixes. @@ -3707,8 +3434,7 @@ and these suffixes. LICENSE - - + The abbreviated name of the license under which this project is released (gpl, lpgl, bsd etc.). See http://www.opensource.org/licenses/alphabetical @@ -3718,9 +3444,8 @@ for a list of license names. LINESEPARATOR - - -The separator used by the Substfile and Textfile builders. + +The separator used by the Substfile and Textfile builders. This value is used between sources when constructing the target. It defaults to the current system line separator. @@ -3728,13 +3453,12 @@ It defaults to the current system line separator. LINGUAS_FILE - - -The $LINGUAS_FILE defines file(s) containing list of additional linguas -to be processed by POInit, POUpdate or MOFiles -builders. It also affects Translate builder. If the variable contains -a string, it defines name of the list file. The $LINGUAS_FILE may be a -list of file names as well. If $LINGUAS_FILE is set to + +The $LINGUAS_FILE defines file(s) containing list of additional linguas +to be processed by POInit, POUpdate or MOFiles +builders. It also affects Translate builder. If the variable contains +a string, it defines name of the list file. The $LINGUAS_FILE may be a +list of file names as well. If $LINGUAS_FILE is set to True (or non-zero numeric value), the list will be read from default file named LINGUAS. @@ -3744,54 +3468,50 @@ default file named LINK - - + The linker. LINKCOM - - + The command line used to link object files into an executable. LINKCOMSTR - - + The string displayed when object files are linked into an executable. -If this is not set, then $LINKCOM (the command line) is displayed. +If this is not set, then $LINKCOM (the command line) is displayed. - + env = Environment(LINKCOMSTR = "Linking $TARGET") LINKFLAGS - - + General user options passed to the linker. Note that this variable should not contain -(or similar) options for linking with the libraries listed in $LIBS, +(or similar) options for linking with the libraries listed in $LIBS, nor (or similar) library search path options -that scons generates automatically from $LIBPATH. +that scons generates automatically from $LIBPATH. See -$_LIBFLAGS +$_LIBFLAGS above, for the variable that expands to library-link options, and -$_LIBDIRFLAGS +$_LIBDIRFLAGS above, for the variable that expands to library search path options. @@ -3799,42 +3519,37 @@ for the variable that expands to library search path options. M4 - - + The M4 macro preprocessor. M4COM - - + The command line used to pass files through the M4 macro preprocessor. M4COMSTR - - + The string displayed when a file is passed through the M4 macro preprocessor. -If this is not set, then $M4COM (the command line) is displayed. +If this is not set, then $M4COM (the command line) is displayed. M4FLAGS - - + General options passed to the M4 macro preprocessor. MAKEINDEX - - + The makeindex generator for the TeX formatter and typesetter and the LaTeX structured formatter and typesetter. @@ -3842,8 +3557,7 @@ LaTeX structured formatter and typesetter. MAKEINDEXCOM - - + The command line used to call the makeindex generator for the TeX formatter and typesetter and the LaTeX structured formatter and typesetter. @@ -3852,19 +3566,17 @@ typesetter. MAKEINDEXCOMSTR - - + The string displayed when calling the makeindex generator for the TeX formatter and typesetter and the LaTeX structured formatter and typesetter. -If this is not set, then $MAKEINDEXCOM (the command line) is displayed. +If this is not set, then $MAKEINDEXCOM (the command line) is displayed. MAKEINDEXFLAGS - - + General options passed to the makeindex generator for the TeX formatter and typesetter and the LaTeX structured formatter and typesetter. @@ -3872,8 +3584,7 @@ and typesetter and the LaTeX structured formatter and typesetter. MAXLINELENGTH - - + The maximum number of characters allowed on an external command line. On Win32 systems, link lines longer than this many characters @@ -3883,178 +3594,159 @@ are linked via a temporary file name. MIDL - - + The Microsoft IDL compiler. MIDLCOM - - + The command line used to pass files to the Microsoft IDL compiler. MIDLCOMSTR - - + The string displayed when the Microsoft IDL copmiler is called. -If this is not set, then $MIDLCOM (the command line) is displayed. +If this is not set, then $MIDLCOM (the command line) is displayed. MIDLFLAGS - - + General options passed to the Microsoft IDL compiler. MOSUFFIX - - + Suffix used for MO files (default: '.mo'). -See msgfmt tool and MOFiles builder. +See msgfmt tool and MOFiles builder. MSGFMT - - + Absolute path to msgfmt(1) binary, found by Detect(). -See msgfmt tool and MOFiles builder. +See msgfmt tool and MOFiles builder. MSGFMTCOM - - + Complete command line to run msgfmt(1) program. -See msgfmt tool and MOFiles builder. +See msgfmt tool and MOFiles builder. MSGFMTCOMSTR - - + String to display when msgfmt(1) is invoked -(default: '', which means ``print $MSGFMTCOM''). -See msgfmt tool and MOFiles builder. +(default: '', which means ``print $MSGFMTCOM''). +See msgfmt tool and MOFiles builder. MSGFMTFLAGS - - + Additional flags to msgfmt(1). -See msgfmt tool and MOFiles builder. +See msgfmt tool and MOFiles builder. MSGINIT - - + Path to msginit(1) program (found via Detect()). -See msginit tool and POInit builder. +See msginit tool and POInit builder. MSGINITCOM - - + Complete command line to run msginit(1) program. -See msginit tool and POInit builder. +See msginit tool and POInit builder. MSGINITCOMSTR - - + String to display when msginit(1) is invoked -(default: '', which means ``print $MSGINITCOM''). -See msginit tool and POInit builder. +(default: '', which means ``print $MSGINITCOM''). +See msginit tool and POInit builder. MSGINITFLAGS - - + List of additional flags to msginit(1) (default: []). -See msginit tool and POInit builder. +See msginit tool and POInit builder. _MSGINITLOCALE - - + Internal ``macro''. Computes locale (language) name based on target filename (default: '${TARGET.filebase}' ). - -See msginit tool and POInit builder. + +See msginit tool and POInit builder. MSGMERGE - - + Absolute path to msgmerge(1) binary as found by Detect(). -See msgmerge tool and POUpdate builder. +See msgmerge tool and POUpdate builder. MSGMERGECOM - - + Complete command line to run msgmerge(1) command. -See msgmerge tool and POUpdate builder. +See msgmerge tool and POUpdate builder. MSGMERGECOMSTR - - + String to be displayed when msgmerge(1) is invoked -(default: '', which means ``print $MSGMERGECOM''). -See msgmerge tool and POUpdate builder. +(default: '', which means ``print $MSGMERGECOM''). +See msgmerge tool and POUpdate builder. MSGMERGEFLAGS - - + Additional flags to msgmerge(1) command. -See msgmerge tool and POUpdate builder. +See msgmerge tool and POUpdate builder. MSSDK_DIR - - + The directory containing the Microsoft SDK (either Platform SDK or Windows SDK) to be used for compilation. @@ -4063,8 +3755,7 @@ to be used for compilation. MSSDK_VERSION - - + The version string of the Microsoft SDK (either Platform SDK or Windows SDK) to be used for compilation. @@ -4080,8 +3771,7 @@ and MSVC_BATCH - - + When set to any true value, specifies that SCons should batch compilation of object files @@ -4092,7 +3782,7 @@ and were configured in SCons using the same construction environment will be built in a single call to the compiler. Only source files that have changed since their object files were built will be passed to each compiler invocation -(via the $CHANGED_SOURCES construction variable). +(via the $CHANGED_SOURCES construction variable). Any compilations where the object (target) file base name (minus the .obj) does not match the source file base name @@ -4102,13 +3792,12 @@ will be compiled separately. MSVC_USE_SCRIPT - - + Use a batch script to set up Microsoft Visual Studio compiler - -$MSVC_USE_SCRIPT overrides $MSVC_VERSION and $TARGET_ARCH. + +$MSVC_USE_SCRIPT overrides $MSVC_VERSION and $TARGET_ARCH. If set to the name of a Visual Studio .bat file (e.g. vcvars.bat), SCons will run that bat file and extract the relevant variables from the result (typically %INCLUDE%, %LIB%, and %PATH%). Setting @@ -4120,20 +3809,19 @@ window and importing the shell's environment variables. MSVC_VERSION - - + Sets the preferred version of Microsoft Visual C/C++ to use. - -If $MSVC_VERSION is not set, SCons will (by default) select the + +If $MSVC_VERSION is not set, SCons will (by default) select the latest version of Visual C/C++ installed on your system. If the specified version isn't installed, tool initialization will fail. This variable must be passed as an argument to the Environment() constructor; setting it later has no effect. - + Valid values for Windows are 12.0, 12.0Exp, @@ -4156,59 +3844,58 @@ Versions ending in Exp refer to "Express" or MSVS - - + When the Microsoft Visual Studio tools are initialized, they set up this dictionary with the following keys: - + VERSION: the version of MSVS being used (can be set via -$MSVS_VERSION) +$MSVS_VERSION) - + VERSIONS: the available versions of MSVS installed - + VCINSTALLDIR: installed directory of Visual C++ - + VSINSTALLDIR: installed directory of Visual Studio - + FRAMEWORKDIR: installed directory of the .NET framework - + FRAMEWORKVERSIONS: list of installed versions of the .NET framework, sorted latest to oldest. - + FRAMEWORKVERSION: latest installed version of the .NET framework - + FRAMEWORKSDKDIR: installed location of the .NET SDK. - + PLATFORMSDKDIR: installed location of the Platform SDK. - + PLATFORMSDK_MODULES: dictionary of installed Platform SDK modules, where the dictionary keys are keywords for the various modules, and @@ -4216,23 +3903,22 @@ the values are 2-tuples where the first is the release date, and the second is the version number. - + If a value isn't set, it wasn't available in the registry. MSVS_ARCH - - + Sets the architecture for which the generated project(s) should build. - + The default value is x86. amd64 is also supported -by SCons for some Visual Studio versions. -Trying to set $MSVS_ARCH to an architecture that's not +by SCons for some Visual Studio versions. +Trying to set $MSVS_ARCH to an architecture that's not supported for a given Visual Studio version will generate an error. @@ -4240,8 +3926,7 @@ will generate an error. MSVS_PROJECT_GUID - - + The string placed in a generated Microsoft Visual Studio project file as the value of the @@ -4253,8 +3938,7 @@ There is no default value. If not defined, a new GUID is generated. MSVS_SCC_AUX_PATH - - + The path name placed in a generated Microsoft Visual Studio project file as the value of the @@ -4269,8 +3953,7 @@ There is no default value. MSVS_SCC_CONNECTION_ROOT - - + The root path of projects in your SCC workspace, i.e the path under which all project and solution files will be generated. It is used as a reference path from which the relative paths of the generated @@ -4301,8 +3984,7 @@ The default value is the current working directory. MSVS_SCC_PROJECT_NAME - - + The project name placed in a generated Microsoft Visual Studio project file as the value of the @@ -4322,8 +4004,7 @@ There is no default value. MSVS_SCC_PROVIDER - - + The string placed in a generated Microsoft Visual Studio project file as the value of the @@ -4340,14 +4021,13 @@ There is no default value. MSVS_VERSION - - + Sets the preferred version of Microsoft Visual Studio to use. - -If $MSVS_VERSION is not set, -SCons will (by default) select the latest version + +If $MSVS_VERSION is not set, +SCons will (by default) select the latest version of Visual Studio installed on your system. So, if you have version 6 and version 7 (MSVS .NET) installed, it will prefer version 7. @@ -4360,17 +4040,16 @@ If the specified version isn't installed, tool initialization will fail. - -This is obsolete: use $MSVC_VERSION instead. If $MSVS_VERSION is set and -$MSVC_VERSION is not, $MSVC_VERSION will be set automatically to $MSVS_VERSION. + +This is obsolete: use $MSVC_VERSION instead. If $MSVS_VERSION is set and +$MSVC_VERSION is not, $MSVC_VERSION will be set automatically to $MSVS_VERSION. If both are set to different values, scons will raise an error. MSVSBUILDCOM - - + The build command line placed in a generated Microsoft Visual Studio project file. The default is to have Visual Studio invoke SCons with any specified @@ -4380,8 +4059,7 @@ build targets. MSVSCLEANCOM - - + The clean command line placed in a generated Microsoft Visual Studio project file. The default is to have Visual Studio invoke SCons with the -c option @@ -4391,8 +4069,7 @@ to remove any specified targets. MSVSENCODING - - + The encoding string placed in a generated Microsoft Visual Studio project file. The default is encoding @@ -4402,16 +4079,14 @@ The default is encoding MSVSPROJECTCOM - - + The action used to generate Microsoft Visual Studio project files. MSVSPROJECTSUFFIX - - + The suffix used for Microsoft Visual Studio project (DSP) files. The default value is .vcproj @@ -4425,8 +4100,7 @@ when using earlier versions of Visual Studio. MSVSREBUILDCOM - - + The rebuild command line placed in a generated Microsoft Visual Studio project file. The default is to have Visual Studio invoke SCons with any specified @@ -4436,8 +4110,7 @@ rebuild targets. MSVSSCONS - - + The SCons used in generated Microsoft Visual Studio project files. The default is the version of SCons being used to generate the project file. @@ -4446,8 +4119,7 @@ used to generate the project file. MSVSSCONSCOM - - + The default SCons command used in generated Microsoft Visual Studio project files. @@ -4455,30 +4127,28 @@ project files. MSVSSCONSCRIPT - - + The sconscript file (that is, -SConstruct +SConstruct or -SConscript +SConscript file) that will be invoked by Visual Studio project files (through the -$MSVSSCONSCOM +$MSVSSCONSCOM variable). The default is the same sconscript file that contains the call to -MSVSProject +MSVSProject to build the project file. MSVSSCONSFLAGS - - + The SCons flags used in generated Microsoft Visual Studio project files. @@ -4486,16 +4156,14 @@ project files. MSVSSOLUTIONCOM - - + The action used to generate Microsoft Visual Studio solution files. MSVSSOLUTIONSUFFIX - - + The suffix used for Microsoft Visual Studio solution (DSW) files. The default value is .sln @@ -4508,43 +4176,38 @@ when using earlier versions of Visual Studio. MT - - + The program used on Windows systems to embed manifests into DLLs and EXEs. -See also $WINDOWS_EMBED_MANIFEST. +See also $WINDOWS_EMBED_MANIFEST. MTEXECOM - - + The Windows command line used to embed manifests into executables. -See also $MTSHLIBCOM. +See also $MTSHLIBCOM. MTFLAGS - - -Flags passed to the $MT manifest embedding program (Windows only). + +Flags passed to the $MT manifest embedding program (Windows only). MTSHLIBCOM - - + The Windows command line used to embed manifests into shared libraries (DLLs). -See also $MTEXECOM. +See also $MTEXECOM. MWCW_VERSION - - + The version number of the MetroWerks CodeWarrior C compiler to be used. @@ -4552,8 +4215,7 @@ to be used. MWCW_VERSIONS - - + A list of installed versions of the MetroWerks CodeWarrior C compiler on this system. @@ -4561,16 +4223,14 @@ on this system. NAME - - + Specfies the name of the project to package. no_import_lib - - + When set to non-zero, suppresses creation of a corresponding Windows static import lib by the SharedLibrary @@ -4584,32 +4244,28 @@ when using Microsoft Visual Studio. OBJPREFIX - - + The prefix used for (static) object file names. OBJSUFFIX - - + The suffix used for (static) object file names. P4 - - + The Perforce executable. P4COM - - + The command line used to fetch source files from Perforce. @@ -4617,26 +4273,23 @@ fetch source files from Perforce. P4COMSTR - - + The string displayed when fetching a source file from Perforce. -If this is not set, then $P4COM (the command line) is displayed. +If this is not set, then $P4COM (the command line) is displayed. P4FLAGS - - + General options that are passed to Perforce. PACKAGEROOT - - + Specifies the directory where all files in resulting archive will be placed if applicable. The default value is "$NAME-$VERSION". @@ -4644,12 +4297,11 @@ placed if applicable. The default value is "$NAME-$VERSION". PACKAGETYPE - - + Selects the package type to build. Currently these are available: - + * msi - Microsoft Installer * rpm - Redhat Package Manger * ipkg - Itsy Package Management System @@ -4661,15 +4313,14 @@ Selects the package type to build. Currently these are available: * src_zip - zip file source - + This may be overridden with the "package_type" command line option. PACKAGEVERSION - - + The version of the package (not the underlying project). This is currently only used by the rpm packager and should reflect changes in the packaging, @@ -4679,8 +4330,7 @@ not the underlying project code itself. PCH - - + The Microsoft Visual C++ precompiled header that will be used when compiling object files. This variable is ignored by tools other than Microsoft Visual C++. When this variable is @@ -4690,44 +4340,40 @@ dependencies for the PCH file. Example: - + env['PCH'] = 'StdAfx.pch' PCHCOM - - + The command line used by the -PCH +PCH builder to generated a precompiled header. PCHCOMSTR - - + The string displayed when generating a precompiled header. -If this is not set, then $PCHCOM (the command line) is displayed. +If this is not set, then $PCHCOM (the command line) is displayed. PCHPDBFLAGS - - + A construction variable that, when expanded, adds the /yD flag to the command line -only if the $PDB construction variable is set. +only if the $PDB construction variable is set. PCHSTOP - - + This variable specifies how much of a source file is precompiled. This variable is ignored by tools other than Microsoft Visual C++, or when the PCH variable is not being used. When this variable is define it @@ -4736,15 +4382,14 @@ is included at the end of the precompiled portion of the source files, or the empty string if the "#pragma hrdstop" construct is being used: - + env['PCHSTOP'] = 'StdAfx.h' PDB - - + The Microsoft Visual C++ PDB file that will store debugging information for object files, shared libraries, and programs. This variable is ignored by tools other than Microsoft Visual C++. @@ -4755,11 +4400,11 @@ dependencies for the PDB file. Example: - + env['PDB'] = 'hello.pdb' - + The Visual C++ compiler switch that SCons uses by default to generate PDB information is . This works correctly with parallel () builds @@ -4771,116 +4416,104 @@ Using the instead may yield improved link-time performance, although parallel builds will no longer work. You can generate PDB files with the -switch by overriding the default $CCPDBFLAGS variable; +switch by overriding the default $CCPDBFLAGS variable; see the entry for that variable for specific examples. PDFCOM - - -A deprecated synonym for $DVIPDFCOM. + +A deprecated synonym for $DVIPDFCOM. PDFLATEX - - -The pdflatex utility. + +The pdflatex utility. PDFLATEXCOM - - -The command line used to call the pdflatex utility. + +The command line used to call the pdflatex utility. PDFLATEXCOMSTR - - -The string displayed when calling the pdflatex utility. -If this is not set, then $PDFLATEXCOM (the command line) is displayed. + +The string displayed when calling the pdflatex utility. +If this is not set, then $PDFLATEXCOM (the command line) is displayed. - + env = Environment(PDFLATEX;COMSTR = "Building $TARGET from LaTeX input $SOURCES") PDFLATEXFLAGS - - -General options passed to the pdflatex utility. + +General options passed to the pdflatex utility. PDFPREFIX - - + The prefix used for PDF file names. PDFSUFFIX - - + The suffix used for PDF file names. PDFTEX - - -The pdftex utility. + +The pdftex utility. PDFTEXCOM - - -The command line used to call the pdftex utility. + +The command line used to call the pdftex utility. PDFTEXCOMSTR - - -The string displayed when calling the pdftex utility. -If this is not set, then $PDFTEXCOM (the command line) is displayed. + +The string displayed when calling the pdftex utility. +If this is not set, then $PDFTEXCOM (the command line) is displayed. - + env = Environment(PDFTEXCOMSTR = "Building $TARGET from TeX input $SOURCES") PDFTEXFLAGS - - -General options passed to the pdftex utility. + +General options passed to the pdftex utility. PKGCHK - - + On Solaris systems, the package-checking program that will -be used (along with $PKGINFO) +be used (along with $PKGINFO) to look for installed versions of the Sun PRO C++ compiler. The default is @@ -4890,11 +4523,10 @@ The default is PKGINFO - - + On Solaris systems, the package information program that will -be used (along with $PKGCHK) +be used (along with $PKGCHK) to look for installed versions of the Sun PRO C++ compiler. The default is @@ -4904,15 +4536,14 @@ The default is PLATFORM - - + The name of the platform used to create the Environment. If no platform is specified when the Environment is created, -scons +scons autodetects the platform. - + env = Environment(tools = []) if env['PLATFORM'] == 'cygwin': Tool('mingw')(env) @@ -4923,45 +4554,41 @@ else: POAUTOINIT - - -The $POAUTOINIT variable, if set to True (on non-zero -numeric value), let the msginit tool to automatically initialize + +The $POAUTOINIT variable, if set to True (on non-zero +numeric value), let the msginit tool to automatically initialize missing PO files with msginit(1). This applies to both, -POInit and POUpdate builders (and others that use any of +POInit and POUpdate builders (and others that use any of them). POCREATE_ALIAS - - -Common alias for all PO files created with POInit + +Common alias for all PO files created with POInit builder (default: 'po-create'). -See msginit tool and POInit builder. +See msginit tool and POInit builder. POSUFFIX - - + Suffix used for PO files (default: '.po') -See msginit tool and POInit builder. +See msginit tool and POInit builder. POTDOMAIN - - -The $POTDOMAIN defines default domain, used to generate -POT filename as $POTDOMAIN.pot when + +The $POTDOMAIN defines default domain, used to generate +POT filename as $POTDOMAIN.pot when no POT file name is provided by the user. This applies to -POTUpdate, POInit and POUpdate builders (and -builders, that use them, e.g. Translate). Normally (if $POTDOMAIN is +POTUpdate, POInit and POUpdate builders (and +builders, that use them, e.g. Translate). Normally (if $POTDOMAIN is not defined), the builders use messages.pot as default POT file name. @@ -4969,37 +4596,33 @@ not defined), the builders use messages.pot as default POTSUFFIX - - + Suffix used for PO Template files (default: '.pot'). -See xgettext tool and POTUpdate builder. +See xgettext tool and POTUpdate builder. POTUPDATE_ALIAS - - + Name of the common phony target for all PO Templates created with -POUpdate (default: 'pot-update'). -See xgettext tool and POTUpdate builder. +POUpdate (default: 'pot-update'). +See xgettext tool and POTUpdate builder. POUPDATE_ALIAS - - + Common alias for all PO files being defined with -POUpdate builder (default: 'po-update'). -See msgmerge tool and POUpdate builder. +POUpdate builder (default: 'po-update'). +See msgmerge tool and POUpdate builder. PRINT_CMD_LINE_FUNC - - + A Python function used to print the command lines as they are executed (assuming command printing is not disabled by the @@ -5017,20 +4640,20 @@ the source(s) used (file node, list, or string name(s)), and the environment being used. - + The function must do the printing itself. The default implementation, used if this variable is not set or is None, is: - + def print_cmd_line(s, target, source, env): sys.stdout.write(s + "\n") - + Here's an example of a more interesting function: - + def print_cmd_line(s, target, source, env): sys.stdout.write("Building %s -> %s...\n" % (' and '.join([str(x) for x in source]), @@ -5039,7 +4662,7 @@ env=Environment(PRINT_CMD_LINE_FUNC=print_cmd_line) env.Program('foo', 'foo.c') - + This just prints "Building targetname from sourcename..." instead of the actual commands. Such a function could also log the actual commands to a log file, @@ -5049,66 +4672,58 @@ for example. PROGEMITTER - - + TODO PROGPREFIX - - + The prefix used for executable file names. PROGSUFFIX - - + The suffix used for executable file names. PSCOM - - + The command line used to convert TeX DVI files into a PostScript file. PSCOMSTR - - + The string displayed when a TeX DVI file is converted into a PostScript file. -If this is not set, then $PSCOM (the command line) is displayed. +If this is not set, then $PSCOM (the command line) is displayed. PSPREFIX - - + The prefix used for PostScript file names. PSSUFFIX - - + The prefix used for PostScript file names. QT_AUTOSCAN - - + Turn off scanning for mocable files. Use the Moc Builder to explicitly specify files to run moc on. @@ -5116,74 +4731,66 @@ specify files to run moc on. QT_BINPATH - - + The path where the qt binaries are installed. -The default value is '$QTDIR/bin'. +The default value is '$QTDIR/bin'. QT_CPPPATH - - + The path where the qt header files are installed. -The default value is '$QTDIR/include'. +The default value is '$QTDIR/include'. Note: If you set this variable to None, -the tool won't change the $CPPPATH +the tool won't change the $CPPPATH construction variable. QT_DEBUG - - + Prints lots of debugging information while scanning for moc files. QT_LIB - - + Default value is 'qt'. You may want to set this to 'qt-mt'. Note: If you set -this variable to None, the tool won't change the $LIBS variable. +this variable to None, the tool won't change the $LIBS variable. QT_LIBPATH - - + The path where the qt libraries are installed. -The default value is '$QTDIR/lib'. +The default value is '$QTDIR/lib'. Note: If you set this variable to None, -the tool won't change the $LIBPATH +the tool won't change the $LIBPATH construction variable. QT_MOC - - -Default value is '$QT_BINPATH/moc'. + +Default value is '$QT_BINPATH/moc'. QT_MOCCXXPREFIX - - + Default value is ''. Prefix for moc output files, when source is a cxx file. QT_MOCCXXSUFFIX - - + Default value is '.moc'. Suffix for moc output files, when source is a cxx file. @@ -5191,25 +4798,22 @@ file. QT_MOCFROMCXXCOM - - + Command to generate a moc file from a cpp file. QT_MOCFROMCXXCOMSTR - - + The string displayed when generating a moc file from a cpp file. -If this is not set, then $QT_MOCFROMCXXCOM (the command line) is displayed. +If this is not set, then $QT_MOCFROMCXXCOM (the command line) is displayed. QT_MOCFROMCXXFLAGS - - + Default value is '-i'. These flags are passed to moc, when moccing a C++ file. @@ -5217,25 +4821,22 @@ C++ file. QT_MOCFROMHCOM - - + Command to generate a moc file from a header. QT_MOCFROMHCOMSTR - - + The string displayed when generating a moc file from a cpp file. -If this is not set, then $QT_MOCFROMHCOM (the command line) is displayed. +If this is not set, then $QT_MOCFROMHCOM (the command line) is displayed. QT_MOCFROMHFLAGS - - + Default value is ''. These flags are passed to moc, when moccing a header file. @@ -5243,50 +4844,44 @@ file. QT_MOCHPREFIX - - + Default value is 'moc_'. Prefix for moc output files, when source is a header. QT_MOCHSUFFIX - - -Default value is '$CXXFILESUFFIX'. Suffix for moc output files, when source is + +Default value is '$CXXFILESUFFIX'. Suffix for moc output files, when source is a header. QT_UIC - - -Default value is '$QT_BINPATH/uic'. + +Default value is '$QT_BINPATH/uic'. QT_UICCOM - - + Command to generate header files from .ui files. QT_UICCOMSTR - - + The string displayed when generating header files from .ui files. -If this is not set, then $QT_UICCOM (the command line) is displayed. +If this is not set, then $QT_UICCOM (the command line) is displayed. QT_UICDECLFLAGS - - + Default value is ''. These flags are passed to uic, when creating a a h file from a .ui file. @@ -5294,24 +4889,21 @@ file from a .ui file. QT_UICDECLPREFIX - - + Default value is ''. Prefix for uic generated header files. QT_UICDECLSUFFIX - - + Default value is '.h'. Suffix for uic generated header files. QT_UICIMPLFLAGS - - + Default value is ''. These flags are passed to uic, when creating a cxx file from a .ui file. @@ -5319,33 +4911,29 @@ file from a .ui file. QT_UICIMPLPREFIX - - + Default value is 'uic_'. Prefix for uic generated implementation files. QT_UICIMPLSUFFIX - - -Default value is '$CXXFILESUFFIX'. Suffix for uic generated implementation + +Default value is '$CXXFILESUFFIX'. Suffix for uic generated implementation files. QT_UISUFFIX - - + Default value is '.ui'. Suffix of designer input files. QTDIR - - + The qt tool tries to take this from os.environ. It also initializes all QT_* construction variables listed below. @@ -5354,24 +4942,24 @@ with python's os.path.join() method, but are listed here with the '/' separator for easier reading.) In addition, the construction environment -variables $CPPPATH, -$LIBPATH and -$LIBS may be modified +variables $CPPPATH, +$LIBPATH and +$LIBS may be modified and the variables -$PROGEMITTER, $SHLIBEMITTER and $LIBEMITTER +$PROGEMITTER, $SHLIBEMITTER and $LIBEMITTER are modified. Because the build-performance is affected when using this tool, you have to explicitly specify it at Environment creation: - + Environment(tools=['default','qt']) - + The qt tool supports the following operations: - + Automatic moc file generation from header files. You do not have to specify moc files explicitly, the tool does it for you. However, there are a few preconditions to do so: Your header file must have @@ -5379,11 +4967,11 @@ the same filebase as your implementation file and must stay in the same directory. It must have one of the suffixes .h, .hpp, .H, .hxx, .hh. You can turn off automatic moc file generation by setting QT_AUTOSCAN to 0. See also the corresponding -Moc() +Moc() builder method. - + Automatic moc file generation from cxx files. As stated in the qt documentation, include the moc file at the end of the cxx file. Note that you have to include the file, which is generated @@ -5392,11 +4980,11 @@ by the transformation ${QT_MOCCXXPREFIX}<basename>${QT_MOCCXXSUFFIX}, by d do not include the correct file. If you are using VariantDir, you may need to specify duplicate=1. You can turn off automatic moc file generation by setting QT_AUTOSCAN to 0. See also the corresponding -Moc +Moc builder method. - + Automatic handling of .ui files. The implementation files generated from .ui files are handled much the same as yacc or lex files. Each .ui file given as a source of Program, Library or @@ -5404,52 +4992,47 @@ SharedLibrary will generate three files, the declaration file, the implementation file and a moc file. Because there are also generated headers, you may need to specify duplicate=1 in calls to VariantDir. See also the corresponding -Uic +Uic builder method. RANLIB - - + The archive indexer. RANLIBCOM - - + The command line used to index a static library archive. RANLIBCOMSTR - - + The string displayed when a static library archive is indexed. -If this is not set, then $RANLIBCOM (the command line) is displayed. +If this is not set, then $RANLIBCOM (the command line) is displayed. - + env = Environment(RANLIBCOMSTR = "Indexing $TARGET") RANLIBFLAGS - - + General options passed to the archive indexer. RC - - + The resource compiler used to build a Microsoft Visual C++ resource file. @@ -5457,8 +5040,7 @@ a Microsoft Visual C++ resource file. RCCOM - - + The command line used to build a Microsoft Visual C++ resource file. @@ -5466,78 +5048,71 @@ a Microsoft Visual C++ resource file. RCCOMSTR - - + The string displayed when invoking the resource compiler to build a Microsoft Visual C++ resource file. -If this is not set, then $RCCOM (the command line) is displayed. +If this is not set, then $RCCOM (the command line) is displayed. RCFLAGS - - + The flags passed to the resource compiler by the RES builder. RCINCFLAGS - - + An automatically-generated construction variable containing the command-line options for specifying directories to be searched by the resource compiler. -The value of $RCINCFLAGS is created -by appending $RCINCPREFIX and $RCINCSUFFIX +The value of $RCINCFLAGS is created +by appending $RCINCPREFIX and $RCINCSUFFIX to the beginning and end -of each directory in $CPPPATH. +of each directory in $CPPPATH. RCINCPREFIX - - + The prefix (flag) used to specify an include directory on the resource compiler command line. This will be appended to the beginning of each directory -in the $CPPPATH construction variable -when the $RCINCFLAGS variable is expanded. +in the $CPPPATH construction variable +when the $RCINCFLAGS variable is expanded. RCINCSUFFIX - - + The suffix used to specify an include directory on the resource compiler command line. This will be appended to the end of each directory -in the $CPPPATH construction variable -when the $RCINCFLAGS variable is expanded. +in the $CPPPATH construction variable +when the $RCINCFLAGS variable is expanded. RCS - - + The RCS executable. Note that this variable is not actually used for the command to fetch source files from RCS; see the -$RCS_CO +$RCS_CO construction variable, below. RCS_CO - - + The RCS "checkout" executable, used to fetch source files from RCS. @@ -5545,8 +5120,7 @@ used to fetch source files from RCS. RCS_COCOM - - + The command line used to fetch (checkout) source files from RCS. @@ -5554,27 +5128,24 @@ fetch (checkout) source files from RCS. RCS_COCOMSTR - - + The string displayed when fetching a source file from RCS. -If this is not set, then $RCS_COCOM +If this is not set, then $RCS_COCOM (the command line) is displayed. RCS_COFLAGS - - -Options that are passed to the $RCS_CO command. + +Options that are passed to the $RCS_CO command. RDirs - - + A function that converts a string into a list of Dir instances by searching the repositories. @@ -5582,39 +5153,35 @@ searching the repositories. REGSVR - - + The program used on Windows systems to register a newly-built DLL library -whenever the SharedLibrary builder +whenever the SharedLibrary builder is passed a keyword argument of register=1. REGSVRCOM - - + The command line used on Windows systems to register a newly-built DLL library -whenever the SharedLibrary builder +whenever the SharedLibrary builder is passed a keyword argument of register=1. REGSVRCOMSTR - - + The string displayed when registering a newly-built DLL file. -If this is not set, then $REGSVRCOM (the command line) is displayed. +If this is not set, then $REGSVRCOM (the command line) is displayed. REGSVRFLAGS - - + Flags passed to the DLL registration program on Windows systems when a newly-built DLL library is registered. By default, @@ -5626,72 +5193,66 @@ and requiring user attention. RMIC - - + The Java RMI stub compiler. RMICCOM - - + The command line used to compile stub and skeleton class files from Java classes that contain RMI implementations. -Any options specified in the $RMICFLAGS construction variable +Any options specified in the $RMICFLAGS construction variable are included on this command line. RMICCOMSTR - - + The string displayed when compiling stub and skeleton class files from Java classes that contain RMI implementations. -If this is not set, then $RMICCOM (the command line) is displayed. +If this is not set, then $RMICCOM (the command line) is displayed. - + env = Environment(RMICCOMSTR = "Generating stub/skeleton class files $TARGETS from $SOURCES") RMICFLAGS - - + General options passed to the Java RMI stub compiler. _RPATH - - + An automatically-generated construction variable containing the rpath flags to be used when linking a program with shared libraries. -The value of $_RPATH is created -by appending $RPATHPREFIX and $RPATHSUFFIX +The value of $_RPATH is created +by appending $RPATHPREFIX and $RPATHSUFFIX to the beginning and end -of each directory in $RPATH. +of each directory in $RPATH. RPATH - - + A list of paths to search for shared libraries when running programs. Currently only used in the GNU (gnulink), IRIX (sgilink) and Sun (sunlink) linkers. Ignored on platforms and toolchains that don't support it. Note that the paths added to RPATH are not transformed by -scons +scons in any way: if you want an absolute path, you must make it absolute yourself. @@ -5699,96 +5260,87 @@ path, you must make it absolute yourself. RPATHPREFIX - - + The prefix used to specify a directory to be searched for shared libraries when running programs. This will be appended to the beginning of each directory -in the $RPATH construction variable -when the $_RPATH variable is automatically generated. +in the $RPATH construction variable +when the $_RPATH variable is automatically generated. RPATHSUFFIX - - + The suffix used to specify a directory to be searched for shared libraries when running programs. This will be appended to the end of each directory -in the $RPATH construction variable -when the $_RPATH variable is automatically generated. +in the $RPATH construction variable +when the $_RPATH variable is automatically generated. RPCGEN - - + The RPC protocol compiler. RPCGENCLIENTFLAGS - - + Options passed to the RPC protocol compiler when generating client side stubs. These are in addition to any flags specified in the -$RPCGENFLAGS +$RPCGENFLAGS construction variable. RPCGENFLAGS - - + General options passed to the RPC protocol compiler. RPCGENHEADERFLAGS - - + Options passed to the RPC protocol compiler when generating a header file. These are in addition to any flags specified in the -$RPCGENFLAGS +$RPCGENFLAGS construction variable. RPCGENSERVICEFLAGS - - + Options passed to the RPC protocol compiler when generating server side stubs. These are in addition to any flags specified in the -$RPCGENFLAGS +$RPCGENFLAGS construction variable. RPCGENXDRFLAGS - - + Options passed to the RPC protocol compiler when generating XDR routines. These are in addition to any flags specified in the -$RPCGENFLAGS +$RPCGENFLAGS construction variable. SCANNERS - - + A list of the available implicit dependency scanners. New file scanners may be added by appending to this list, @@ -5803,16 +5355,14 @@ below, for more information. SCCS - - + The SCCS executable. SCCSCOM - - + The command line used to fetch source files from SCCS. @@ -5820,27 +5370,24 @@ fetch source files from SCCS. SCCSCOMSTR - - + The string displayed when fetching a source file from a CVS repository. -If this is not set, then $SCCSCOM +If this is not set, then $SCCSCOM (the command line) is displayed. SCCSFLAGS - - + General options that are passed to SCCS. SCCSGETFLAGS - - + Options that are passed specifically to the SCCS "get" subcommand. This can be set, for example, to @@ -5850,13 +5397,12 @@ to check out editable files from SCCS. SCONS_HOME - - + The (optional) path to the SCons library directory, initialized from the external environment. If set, this is used to construct a shorter and more efficient search path in the -$MSVSSCONS +$MSVSSCONS command line executed from Microsoft Visual Studio project files. @@ -5864,43 +5410,39 @@ from Microsoft Visual Studio project files. SHCC - - + The C compiler used for generating shared-library objects. SHCCCOM - - + The command line used to compile a C source file to a shared-library object file. -Any options specified in the $SHCFLAGS, -$SHCCFLAGS and -$CPPFLAGS construction variables +Any options specified in the $SHCFLAGS, +$SHCCFLAGS and +$CPPFLAGS construction variables are included on this command line. SHCCCOMSTR - - + The string displayed when a C source file is compiled to a shared object file. -If this is not set, then $SHCCCOM (the command line) is displayed. +If this is not set, then $SHCCCOM (the command line) is displayed. - + env = Environment(SHCCCOMSTR = "Compiling shared object $TARGET") SHCCFLAGS - - + Options that are passed to the C and C++ compilers to generate shared-library objects. @@ -5908,8 +5450,7 @@ to generate shared-library objects. SHCFLAGS - - + Options that are passed to the C compiler (only; not C++) to generate shared-library objects. @@ -5917,42 +5458,38 @@ to generate shared-library objects. SHCXX - - + The C++ compiler used for generating shared-library objects. SHCXXCOM - - + The command line used to compile a C++ source file to a shared-library object file. -Any options specified in the $SHCXXFLAGS and -$CPPFLAGS construction variables +Any options specified in the $SHCXXFLAGS and +$CPPFLAGS construction variables are included on this command line. SHCXXCOMSTR - - + The string displayed when a C++ source file is compiled to a shared object file. -If this is not set, then $SHCXXCOM (the command line) is displayed. +If this is not set, then $SHCXXCOM (the command line) is displayed. - + env = Environment(SHCXXCOMSTR = "Compiling shared object $TARGET") SHCXXFLAGS - - + Options that are passed to the C++ compiler to generate shared-library objects. @@ -5960,79 +5497,71 @@ to generate shared-library objects. SHDC - - + SHDC. SHDCOM - - + SHDCOM. SHDLINK - - + SHDLINK. SHDLINKCOM - - + SHDLINKCOM. SHDLINKFLAGS - - + SHDLINKFLAGS. SHELL - - + A string naming the shell program that will be passed to the -$SPAWN +$SPAWN function. See the -$SPAWN +$SPAWN construction variable for more information. SHF03 - - + The Fortran 03 compiler used for generating shared-library objects. -You should normally set the $SHFORTRAN variable, +You should normally set the $SHFORTRAN variable, which specifies the default Fortran compiler for all Fortran versions. -You only need to set $SHF03 if you need to use a specific compiler +You only need to set $SHF03 if you need to use a specific compiler or compiler version for Fortran 03 files. SHF03COM - - + The command line used to compile a Fortran 03 source file to a shared-library object file. -You only need to set $SHF03COM if you need to use a specific +You only need to set $SHF03COM if you need to use a specific command line for Fortran 03 files. -You should normally set the $SHFORTRANCOM variable, +You should normally set the $SHFORTRANCOM variable, which specifies the default command line for all Fortran versions. @@ -6040,24 +5569,22 @@ for all Fortran versions. SHF03COMSTR - - + The string displayed when a Fortran 03 source file is compiled to a shared-library object file. -If this is not set, then $SHF03COM or $SHFORTRANCOM +If this is not set, then $SHF03COM or $SHFORTRANCOM (the command line) is displayed. SHF03FLAGS - - + Options that are passed to the Fortran 03 compiler to generated shared-library objects. -You only need to set $SHF03FLAGS if you need to define specific +You only need to set $SHF03FLAGS if you need to define specific user options for Fortran 03 files. -You should normally set the $SHFORTRANFLAGS variable, +You should normally set the $SHFORTRANFLAGS variable, which specifies the user-specified options passed to the default Fortran compiler for all Fortran versions. @@ -6066,16 +5593,15 @@ for all Fortran versions. SHF03PPCOM - - + The command line used to compile a Fortran 03 source file to a shared-library object file after first running the file through the C preprocessor. -Any options specified in the $SHF03FLAGS and $CPPFLAGS construction variables +Any options specified in the $SHF03FLAGS and $CPPFLAGS construction variables are included on this command line. -You only need to set $SHF03PPCOM if you need to use a specific +You only need to set $SHF03PPCOM if you need to use a specific C-preprocessor command line for Fortran 03 files. -You should normally set the $SHFORTRANPPCOM variable, +You should normally set the $SHFORTRANPPCOM variable, which specifies the default C-preprocessor command line for all Fortran versions. @@ -6083,38 +5609,35 @@ for all Fortran versions. SHF03PPCOMSTR - - + The string displayed when a Fortran 03 source file is compiled to a shared-library object file after first running the file through the C preprocessor. -If this is not set, then $SHF03PPCOM or $SHFORTRANPPCOM +If this is not set, then $SHF03PPCOM or $SHFORTRANPPCOM (the command line) is displayed. SHF08 - - + The Fortran 08 compiler used for generating shared-library objects. -You should normally set the $SHFORTRAN variable, +You should normally set the $SHFORTRAN variable, which specifies the default Fortran compiler for all Fortran versions. -You only need to set $SHF08 if you need to use a specific compiler +You only need to set $SHF08 if you need to use a specific compiler or compiler version for Fortran 08 files. SHF08COM - - + The command line used to compile a Fortran 08 source file to a shared-library object file. -You only need to set $SHF08COM if you need to use a specific +You only need to set $SHF08COM if you need to use a specific command line for Fortran 08 files. -You should normally set the $SHFORTRANCOM variable, +You should normally set the $SHFORTRANCOM variable, which specifies the default command line for all Fortran versions. @@ -6122,24 +5645,22 @@ for all Fortran versions. SHF08COMSTR - - + The string displayed when a Fortran 08 source file is compiled to a shared-library object file. -If this is not set, then $SHF08COM or $SHFORTRANCOM +If this is not set, then $SHF08COM or $SHFORTRANCOM (the command line) is displayed. SHF08FLAGS - - + Options that are passed to the Fortran 08 compiler to generated shared-library objects. -You only need to set $SHF08FLAGS if you need to define specific +You only need to set $SHF08FLAGS if you need to define specific user options for Fortran 08 files. -You should normally set the $SHFORTRANFLAGS variable, +You should normally set the $SHFORTRANFLAGS variable, which specifies the user-specified options passed to the default Fortran compiler for all Fortran versions. @@ -6148,16 +5669,15 @@ for all Fortran versions. SHF08PPCOM - - + The command line used to compile a Fortran 08 source file to a shared-library object file after first running the file through the C preprocessor. -Any options specified in the $SHF08FLAGS and $CPPFLAGS construction variables +Any options specified in the $SHF08FLAGS and $CPPFLAGS construction variables are included on this command line. -You only need to set $SHF08PPCOM if you need to use a specific +You only need to set $SHF08PPCOM if you need to use a specific C-preprocessor command line for Fortran 08 files. -You should normally set the $SHFORTRANPPCOM variable, +You should normally set the $SHFORTRANPPCOM variable, which specifies the default C-preprocessor command line for all Fortran versions. @@ -6165,38 +5685,35 @@ for all Fortran versions. SHF08PPCOMSTR - - + The string displayed when a Fortran 08 source file is compiled to a shared-library object file after first running the file through the C preprocessor. -If this is not set, then $SHF08PPCOM or $SHFORTRANPPCOM +If this is not set, then $SHF08PPCOM or $SHFORTRANPPCOM (the command line) is displayed. SHF77 - - + The Fortran 77 compiler used for generating shared-library objects. -You should normally set the $SHFORTRAN variable, +You should normally set the $SHFORTRAN variable, which specifies the default Fortran compiler for all Fortran versions. -You only need to set $SHF77 if you need to use a specific compiler +You only need to set $SHF77 if you need to use a specific compiler or compiler version for Fortran 77 files. SHF77COM - - + The command line used to compile a Fortran 77 source file to a shared-library object file. -You only need to set $SHF77COM if you need to use a specific +You only need to set $SHF77COM if you need to use a specific command line for Fortran 77 files. -You should normally set the $SHFORTRANCOM variable, +You should normally set the $SHFORTRANCOM variable, which specifies the default command line for all Fortran versions. @@ -6204,24 +5721,22 @@ for all Fortran versions. SHF77COMSTR - - + The string displayed when a Fortran 77 source file is compiled to a shared-library object file. -If this is not set, then $SHF77COM or $SHFORTRANCOM +If this is not set, then $SHF77COM or $SHFORTRANCOM (the command line) is displayed. SHF77FLAGS - - + Options that are passed to the Fortran 77 compiler to generated shared-library objects. -You only need to set $SHF77FLAGS if you need to define specific +You only need to set $SHF77FLAGS if you need to define specific user options for Fortran 77 files. -You should normally set the $SHFORTRANFLAGS variable, +You should normally set the $SHFORTRANFLAGS variable, which specifies the user-specified options passed to the default Fortran compiler for all Fortran versions. @@ -6230,16 +5745,15 @@ for all Fortran versions. SHF77PPCOM - - + The command line used to compile a Fortran 77 source file to a shared-library object file after first running the file through the C preprocessor. -Any options specified in the $SHF77FLAGS and $CPPFLAGS construction variables +Any options specified in the $SHF77FLAGS and $CPPFLAGS construction variables are included on this command line. -You only need to set $SHF77PPCOM if you need to use a specific +You only need to set $SHF77PPCOM if you need to use a specific C-preprocessor command line for Fortran 77 files. -You should normally set the $SHFORTRANPPCOM variable, +You should normally set the $SHFORTRANPPCOM variable, which specifies the default C-preprocessor command line for all Fortran versions. @@ -6247,38 +5761,35 @@ for all Fortran versions. SHF77PPCOMSTR - - + The string displayed when a Fortran 77 source file is compiled to a shared-library object file after first running the file through the C preprocessor. -If this is not set, then $SHF77PPCOM or $SHFORTRANPPCOM +If this is not set, then $SHF77PPCOM or $SHFORTRANPPCOM (the command line) is displayed. SHF90 - - + The Fortran 90 compiler used for generating shared-library objects. -You should normally set the $SHFORTRAN variable, +You should normally set the $SHFORTRAN variable, which specifies the default Fortran compiler for all Fortran versions. -You only need to set $SHF90 if you need to use a specific compiler +You only need to set $SHF90 if you need to use a specific compiler or compiler version for Fortran 90 files. SHF90COM - - + The command line used to compile a Fortran 90 source file to a shared-library object file. -You only need to set $SHF90COM if you need to use a specific +You only need to set $SHF90COM if you need to use a specific command line for Fortran 90 files. -You should normally set the $SHFORTRANCOM variable, +You should normally set the $SHFORTRANCOM variable, which specifies the default command line for all Fortran versions. @@ -6286,24 +5797,22 @@ for all Fortran versions. SHF90COMSTR - - + The string displayed when a Fortran 90 source file is compiled to a shared-library object file. -If this is not set, then $SHF90COM or $SHFORTRANCOM +If this is not set, then $SHF90COM or $SHFORTRANCOM (the command line) is displayed. SHF90FLAGS - - + Options that are passed to the Fortran 90 compiler to generated shared-library objects. -You only need to set $SHF90FLAGS if you need to define specific +You only need to set $SHF90FLAGS if you need to define specific user options for Fortran 90 files. -You should normally set the $SHFORTRANFLAGS variable, +You should normally set the $SHFORTRANFLAGS variable, which specifies the user-specified options passed to the default Fortran compiler for all Fortran versions. @@ -6312,16 +5821,15 @@ for all Fortran versions. SHF90PPCOM - - + The command line used to compile a Fortran 90 source file to a shared-library object file after first running the file through the C preprocessor. -Any options specified in the $SHF90FLAGS and $CPPFLAGS construction variables +Any options specified in the $SHF90FLAGS and $CPPFLAGS construction variables are included on this command line. -You only need to set $SHF90PPCOM if you need to use a specific +You only need to set $SHF90PPCOM if you need to use a specific C-preprocessor command line for Fortran 90 files. -You should normally set the $SHFORTRANPPCOM variable, +You should normally set the $SHFORTRANPPCOM variable, which specifies the default C-preprocessor command line for all Fortran versions. @@ -6329,38 +5837,35 @@ for all Fortran versions. SHF90PPCOMSTR - - + The string displayed when a Fortran 90 source file is compiled to a shared-library object file after first running the file through the C preprocessor. -If this is not set, then $SHF90PPCOM or $SHFORTRANPPCOM +If this is not set, then $SHF90PPCOM or $SHFORTRANPPCOM (the command line) is displayed. SHF95 - - + The Fortran 95 compiler used for generating shared-library objects. -You should normally set the $SHFORTRAN variable, +You should normally set the $SHFORTRAN variable, which specifies the default Fortran compiler for all Fortran versions. -You only need to set $SHF95 if you need to use a specific compiler +You only need to set $SHF95 if you need to use a specific compiler or compiler version for Fortran 95 files. SHF95COM - - + The command line used to compile a Fortran 95 source file to a shared-library object file. -You only need to set $SHF95COM if you need to use a specific +You only need to set $SHF95COM if you need to use a specific command line for Fortran 95 files. -You should normally set the $SHFORTRANCOM variable, +You should normally set the $SHFORTRANCOM variable, which specifies the default command line for all Fortran versions. @@ -6368,24 +5873,22 @@ for all Fortran versions. SHF95COMSTR - - + The string displayed when a Fortran 95 source file is compiled to a shared-library object file. -If this is not set, then $SHF95COM or $SHFORTRANCOM +If this is not set, then $SHF95COM or $SHFORTRANCOM (the command line) is displayed. SHF95FLAGS - - + Options that are passed to the Fortran 95 compiler to generated shared-library objects. -You only need to set $SHF95FLAGS if you need to define specific +You only need to set $SHF95FLAGS if you need to define specific user options for Fortran 95 files. -You should normally set the $SHFORTRANFLAGS variable, +You should normally set the $SHFORTRANFLAGS variable, which specifies the user-specified options passed to the default Fortran compiler for all Fortran versions. @@ -6394,16 +5897,15 @@ for all Fortran versions. SHF95PPCOM - - + The command line used to compile a Fortran 95 source file to a shared-library object file after first running the file through the C preprocessor. -Any options specified in the $SHF95FLAGS and $CPPFLAGS construction variables +Any options specified in the $SHF95FLAGS and $CPPFLAGS construction variables are included on this command line. -You only need to set $SHF95PPCOM if you need to use a specific +You only need to set $SHF95PPCOM if you need to use a specific C-preprocessor command line for Fortran 95 files. -You should normally set the $SHFORTRANPPCOM variable, +You should normally set the $SHFORTRANPPCOM variable, which specifies the default C-preprocessor command line for all Fortran versions. @@ -6411,28 +5913,25 @@ for all Fortran versions. SHF95PPCOMSTR - - + The string displayed when a Fortran 95 source file is compiled to a shared-library object file after first running the file through the C preprocessor. -If this is not set, then $SHF95PPCOM or $SHFORTRANPPCOM +If this is not set, then $SHF95PPCOM or $SHFORTRANPPCOM (the command line) is displayed. SHFORTRAN - - + The default Fortran compiler used for generating shared-library objects. SHFORTRANCOM - - + The command line used to compile a Fortran source file to a shared-library object file. @@ -6440,19 +5939,17 @@ to a shared-library object file. SHFORTRANCOMSTR - - + The string displayed when a Fortran source file is compiled to a shared-library object file. -If this is not set, then $SHFORTRANCOM +If this is not set, then $SHFORTRANCOM (the command line) is displayed. SHFORTRANFLAGS - - + Options that are passed to the Fortran compiler to generate shared-library objects. @@ -6460,62 +5957,56 @@ to generate shared-library objects. SHFORTRANPPCOM - - + The command line used to compile a Fortran source file to a shared-library object file after first running the file through the C preprocessor. Any options specified -in the $SHFORTRANFLAGS and -$CPPFLAGS construction variables +in the $SHFORTRANFLAGS and +$CPPFLAGS construction variables are included on this command line. SHFORTRANPPCOMSTR - - + The string displayed when a Fortran source file is compiled to a shared-library object file after first running the file through the C preprocessor. -If this is not set, then $SHFORTRANPPCOM +If this is not set, then $SHFORTRANPPCOM (the command line) is displayed. SHLIBEMITTER - - + TODO SHLIBPREFIX - - + The prefix used for shared library file names. SHLIBSUFFIX - - + The suffix used for shared library file names. SHLIBVERSION - - + When this construction variable is defined, a versioned shared library -is created. This modifies the $SHLINKFLAGS as required, adds +is created. This modifies the $SHLINKFLAGS as required, adds the version number to the library name, and creates the symlinks that -are needed. $SHLIBVERSION needs to be of the form X.Y.Z, +are needed. $SHLIBVERSION needs to be of the form X.Y.Z, where X and Y are numbers, and Z is a number but can also contain letters to designate alpha, beta, or release candidate patch levels. @@ -6523,53 +6014,49 @@ letters to designate alpha, beta, or release candidate patch levels. SHLINK - - + The linker for programs that use shared libraries. SHLINKCOM - - + The command line used to link programs using shared libraries. SHLINKCOMSTR - - + The string displayed when programs using shared libraries are linked. -If this is not set, then $SHLINKCOM (the command line) is displayed. +If this is not set, then $SHLINKCOM (the command line) is displayed. - + env = Environment(SHLINKCOMSTR = "Linking shared $TARGET") SHLINKFLAGS - - + General user options passed to the linker for programs using shared libraries. Note that this variable should not contain -(or similar) options for linking with the libraries listed in $LIBS, +(or similar) options for linking with the libraries listed in $LIBS, nor (or similar) include search path options -that scons generates automatically from $LIBPATH. +that scons generates automatically from $LIBPATH. See -$_LIBFLAGS +$_LIBFLAGS above, for the variable that expands to library-link options, and -$_LIBDIRFLAGS +$_LIBDIRFLAGS above, for the variable that expands to library search path options. @@ -6577,24 +6064,21 @@ for the variable that expands to library search path options. SHOBJPREFIX - - + The prefix used for shared object file names. SHOBJSUFFIX - - + The suffix used for shared object file names. SOURCE - - + A reserved variable name that may not be set or used in a construction environment. (See "Variable Substitution," below.) @@ -6603,8 +6087,7 @@ that may not be set or used in a construction environment. SOURCE_URL - - + The URL (web address) of the location from which the project was retrieved. @@ -6616,8 +6099,7 @@ field in the controlling information for Ipkg and RPM packages. SOURCES - - + A reserved variable name that may not be set or used in a construction environment. (See "Variable Substitution," below.) @@ -6626,17 +6108,16 @@ that may not be set or used in a construction environment. SPAWN - - + A command interpreter function that will be called to execute command line strings. The function must expect the following arguments: - + def spawn(shell, escape, cmd, args, env): - + sh is a string naming the shell program to use. escape @@ -6654,17 +6135,15 @@ in which the command should be executed. STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME - - + When this variable is true, static objects and shared objects are assumed to be the same; that is, SCons does not check for linking static objects into a shared library. SUBST_DICT - - -The dictionary used by the Substfile or Textfile builders + +The dictionary used by the Substfile or Textfile builders for substitution values. It can be anything acceptable to the dict() constructor, so in addition to a dictionary, @@ -6674,26 +6153,23 @@ lists of tuples are also acceptable. SUBSTFILEPREFIX - - -The prefix used for Substfile file names, + +The prefix used for Substfile file names, the null string by default. SUBSTFILESUFFIX - - -The suffix used for Substfile file names, + +The suffix used for Substfile file names, the null string by default. SUMMARY - - + A short summary of what the project is about. This is used to fill in the Summary: @@ -6706,35 +6182,32 @@ field in MSI packages. SWIG - - + The scripting language wrapper and interface generator. SWIGCFILESUFFIX - - + The suffix that will be used for intermediate C source files generated by the scripting language wrapper and interface generator. The default value is -_wrap$CFILESUFFIX. +_wrap$CFILESUFFIX. By default, this value is used whenever the option is not specified as part of the -$SWIGFLAGS +$SWIGFLAGS construction variable. SWIGCOM - - + The command line used to call the scripting language wrapper and interface generator. @@ -6742,35 +6215,32 @@ the scripting language wrapper and interface generator. SWIGCOMSTR - - + The string displayed when calling the scripting language wrapper and interface generator. -If this is not set, then $SWIGCOM (the command line) is displayed. +If this is not set, then $SWIGCOM (the command line) is displayed. SWIGCXXFILESUFFIX - - + The suffix that will be used for intermediate C++ source files generated by the scripting language wrapper and interface generator. The default value is -_wrap$CFILESUFFIX. +_wrap$CFILESUFFIX. By default, this value is used whenever the -c++ option is specified as part of the -$SWIGFLAGS +$SWIGFLAGS construction variable. SWIGDIRECTORSUFFIX - - + The suffix that will be used for intermediate C++ header files generated by the scripting language wrapper and interface generator. These are only generated for C++ code when the SWIG 'directors' feature is @@ -6782,8 +6252,7 @@ The default value is SWIGFLAGS - - + General options passed to the scripting language wrapper and interface generator. This is where you should set @@ -6794,60 +6263,56 @@ or whatever other options you want to specify to SWIG. If you set the option in this variable, -scons +scons will, by default, generate a C++ intermediate source file with the extension that is specified as the -$CXXFILESUFFIX +$CXXFILESUFFIX variable. _SWIGINCFLAGS - - + An automatically-generated construction variable containing the SWIG command-line options for specifying directories to be searched for included files. -The value of $_SWIGINCFLAGS is created -by appending $SWIGINCPREFIX and $SWIGINCSUFFIX +The value of $_SWIGINCFLAGS is created +by appending $SWIGINCPREFIX and $SWIGINCSUFFIX to the beginning and end -of each directory in $SWIGPATH. +of each directory in $SWIGPATH. SWIGINCPREFIX - - + The prefix used to specify an include directory on the SWIG command line. This will be appended to the beginning of each directory -in the $SWIGPATH construction variable -when the $_SWIGINCFLAGS variable is automatically generated. +in the $SWIGPATH construction variable +when the $_SWIGINCFLAGS variable is automatically generated. SWIGINCSUFFIX - - + The suffix used to specify an include directory on the SWIG command line. This will be appended to the end of each directory -in the $SWIGPATH construction variable -when the $_SWIGINCFLAGS variable is automatically generated. +in the $SWIGPATH construction variable +when the $_SWIGINCFLAGS variable is automatically generated. SWIGOUTDIR - - + Specifies the output directory in which the scripting language wrapper and interface generator should place generated language-specific files. This will be used by SCons to identify -the files that will be generated by the swig call, +the files that will be generated by the swig call, and translated into the swig -outdir option on the command line. @@ -6855,17 +6320,16 @@ and translated into the SWIGPATH - - + The list of directories that the scripting language wrapper and interface generate will search for included files. The SWIG implicit dependency scanner will search these directories for include files. The default is to use the same path -specified as $CPPPATH. +specified as $CPPPATH. - + Don't explicitly put include directory arguments in SWIGFLAGS; the result will be non-portable @@ -6873,96 +6337,90 @@ and the directories will not be searched by the dependency scanner. Note: directory names in SWIGPATH will be looked-up relative to the SConscript directory when they are used in a command. To force -scons +scons to look-up a directory relative to the root of the source tree use #: - + env = Environment(SWIGPATH='#/include') - + The directory look-up can also be forced using the -Dir() +Dir() function: - + include = Dir('include') env = Environment(SWIGPATH=include) - + The directory list will be added to command lines through the automatically-generated -$_SWIGINCFLAGS +$_SWIGINCFLAGS construction variable, which is constructed by appending the values of the -$SWIGINCPREFIX and $SWIGINCSUFFIX +$SWIGINCPREFIX and $SWIGINCSUFFIX construction variables to the beginning and end -of each directory in $SWIGPATH. +of each directory in $SWIGPATH. Any command lines you define that need the SWIGPATH directory list should -include $_SWIGINCFLAGS: +include $_SWIGINCFLAGS: - + env = Environment(SWIGCOM="my_swig -o $TARGET $_SWIGINCFLAGS $SORUCES") SWIGVERSION - - + The version number of the SWIG tool. TAR - - + The tar archiver. TARCOM - - + The command line used to call the tar archiver. TARCOMSTR - - + The string displayed when archiving files using the tar archiver. -If this is not set, then $TARCOM (the command line) is displayed. +If this is not set, then $TARCOM (the command line) is displayed. - + env = Environment(TARCOMSTR = "Archiving $TARGET") TARFLAGS - - + General options passed to the tar archiver. TARGET - - + A reserved variable name that may not be set or used in a construction environment. (See "Variable Substitution," below.) @@ -6971,11 +6429,16 @@ that may not be set or used in a construction environment. TARGET_ARCH - - + + The name of the target hardware architecture for the compiled objects + created by this Environment. + This defaults to the value of HOST_ARCH, and the user can override it. + Currently only set for Win32. + + Sets the target architecture for Visual Studio compiler (i.e. the arch of the binaries generated by the compiler). If not set, default to -$HOST_ARCH, or, if that is unset, to the architecture of the +$HOST_ARCH, or, if that is unset, to the architecture of the running machine's OS (note that the python build or architecture has no effect). This variable must be passed as an argument to the Environment() @@ -6984,7 +6447,7 @@ This is currently only used on Windows, but in the future it will be used on other OSes as well. - + Valid values for Windows are x86, i386 @@ -6997,19 +6460,11 @@ and ia64 (Itanium). For example, if you want to compile 64-bit binaries, you would set TARGET_ARCH='x86_64' in your SCons environment. - - - The name of the target hardware architecture for the compiled objects - created by this Environment. - This defaults to the value of HOST_ARCH, and the user can override it. - Currently only set for Win32. - - + TARGET_OS - - + The name of the target operating system for the compiled objects created by this Environment. This defaults to the value of HOST_OS, and the user can override it. @@ -7019,8 +6474,7 @@ For example, if you want to compile 64-bit binaries, you would set TARGETS - - + A reserved variable name that may not be set or used in a construction environment. (See "Variable Substitution," below.) @@ -7029,16 +6483,14 @@ that may not be set or used in a construction environment. TARSUFFIX - - + The suffix used for tar file names. TEMPFILEPREFIX - - + The prefix for a temporary file used to execute lines longer than $MAXLINELENGTH. The default is '@'. @@ -7050,46 +6502,41 @@ or '-via' for ARM toolchain. TEX - - + The TeX formatter and typesetter. TEXCOM - - + The command line used to call the TeX formatter and typesetter. TEXCOMSTR - - + The string displayed when calling the TeX formatter and typesetter. -If this is not set, then $TEXCOM (the command line) is displayed. +If this is not set, then $TEXCOM (the command line) is displayed. - + env = Environment(TEXCOMSTR = "Building $TARGET from TeX input $SOURCES") TEXFLAGS - - + General options passed to the TeX formatter and typesetter. TEXINPUTS - - + List of directories that the LaTeX program will search for include directories. The LaTeX implicit dependency scanner will search these @@ -7099,26 +6546,23 @@ directories for \include and \import files. TEXTFILEPREFIX - - -The prefix used for Textfile file names, + +The prefix used for Textfile file names, the null string by default. TEXTFILESUFFIX - - -The suffix used for Textfile file names; + +The suffix used for Textfile file names; .txt by default. TOOLS - - + A list of the names of the Tool specifications that are part of this construction environment. @@ -7126,8 +6570,7 @@ that are part of this construction environment. UNCHANGED_SOURCES - - + A reserved variable name that may not be set or used in a construction environment. (See "Variable Substitution," below.) @@ -7136,8 +6579,7 @@ that may not be set or used in a construction environment. UNCHANGED_TARGETS - - + A reserved variable name that may not be set or used in a construction environment. (See "Variable Substitution," below.) @@ -7146,8 +6588,7 @@ that may not be set or used in a construction environment. VENDOR - - + The person or organization who supply the packaged software. This is used to fill in the Vendor: @@ -7160,68 +6601,60 @@ field in the controlling information for MSI packages. VERSION - - + The version of the project, specified as a string. WIN32_INSERT_DEF - - -A deprecated synonym for $WINDOWS_INSERT_DEF. + +A deprecated synonym for $WINDOWS_INSERT_DEF. WIN32DEFPREFIX - - -A deprecated synonym for $WINDOWSDEFPREFIX. + +A deprecated synonym for $WINDOWSDEFPREFIX. WIN32DEFSUFFIX - - -A deprecated synonym for $WINDOWSDEFSUFFIX. + +A deprecated synonym for $WINDOWSDEFSUFFIX. WIN32EXPPREFIX - - -A deprecated synonym for $WINDOWSEXPSUFFIX. + +A deprecated synonym for $WINDOWSEXPSUFFIX. WIN32EXPSUFFIX - - -A deprecated synonym for $WINDOWSEXPSUFFIX. + +A deprecated synonym for $WINDOWSEXPSUFFIX. WINDOWS_EMBED_MANIFEST - - + Set this variable to True or 1 to embed the compiler-generated manifest (normally ${TARGET}.manifest) into all Windows exes and DLLs built with this environment, as a resource during their link step. -This is done using $MT and $MTEXECOM and $MTSHLIBCOM. +This is done using $MT and $MTEXECOM and $MTSHLIBCOM. WINDOWS_INSERT_DEF - - + When this is set to true, a library build of a Windows shared library (.dll file) @@ -7235,10 +6668,9 @@ The default is 0 (do not build a .def file). WINDOWS_INSERT_MANIFEST - - + When this is set to true, -scons +scons will be aware of the .manifest files generated by Microsoft Visua C/C++ 8. @@ -7247,40 +6679,35 @@ files generated by Microsoft Visua C/C++ 8. WINDOWSDEFPREFIX - - + The prefix used for Windows .def file names. WINDOWSDEFSUFFIX - - + The suffix used for Windows .def file names. WINDOWSEXPPREFIX - - + The prefix used for Windows .exp file names. WINDOWSEXPSUFFIX - - + The suffix used for Windows .exp file names. WINDOWSPROGMANIFESTPREFIX - - + The prefix used for executable program .manifest files generated by Microsoft Visual C/C++. @@ -7288,8 +6715,7 @@ generated by Microsoft Visual C/C++. WINDOWSPROGMANIFESTSUFFIX - - + The suffix used for executable program .manifest files generated by Microsoft Visual C/C++. @@ -7297,8 +6723,7 @@ generated by Microsoft Visual C/C++. WINDOWSSHLIBMANIFESTPREFIX - - + The prefix used for shared library .manifest files generated by Microsoft Visual C/C++. @@ -7306,8 +6731,7 @@ generated by Microsoft Visual C/C++. WINDOWSSHLIBMANIFESTSUFFIX - - + The suffix used for shared library .manifest files generated by Microsoft Visual C/C++. @@ -7315,8 +6739,7 @@ generated by Microsoft Visual C/C++. X_IPK_DEPENDS - - + This is used to fill in the Depends: field in the controlling information for Ipkg packages. @@ -7325,8 +6748,7 @@ field in the controlling information for Ipkg packages. X_IPK_DESCRIPTION - - + This is used to fill in the Description: field in the controlling information for Ipkg packages. @@ -7337,8 +6759,7 @@ The default value is X_IPK_MAINTAINER - - + This is used to fill in the Maintainer: field in the controlling information for Ipkg packages. @@ -7347,8 +6768,7 @@ field in the controlling information for Ipkg packages. X_IPK_PRIORITY - - + This is used to fill in the Priority: field in the controlling information for Ipkg packages. @@ -7357,8 +6777,7 @@ field in the controlling information for Ipkg packages. X_IPK_SECTION - - + This is used to fill in the Section: field in the controlling information for Ipkg packages. @@ -7367,8 +6786,7 @@ field in the controlling information for Ipkg packages. X_MSI_LANGUAGE - - + This is used to fill in the Language: attribute in the controlling information for MSI packages. @@ -7377,8 +6795,7 @@ attribute in the controlling information for MSI packages. X_MSI_LICENSE_TEXT - - + The text of the software license in RTF format. Carriage return characters will be replaced with the RTF equivalent \\par. @@ -7387,16 +6804,14 @@ replaced with the RTF equivalent \\par. X_MSI_UPGRADE_CODE - - + TODO X_RPM_AUTOREQPROV - - + This is used to fill in the AutoReqProv: field in the RPM @@ -7406,16 +6821,14 @@ field in the RPM X_RPM_BUILD - - + internal, but overridable X_RPM_BUILDREQUIRES - - + This is used to fill in the BuildRequires: field in the RPM @@ -7425,24 +6838,21 @@ field in the RPM X_RPM_BUILDROOT - - + internal, but overridable X_RPM_CLEAN - - + internal, but overridable X_RPM_CONFLICTS - - + This is used to fill in the Conflicts: field in the RPM @@ -7452,8 +6862,7 @@ field in the RPM X_RPM_DEFATTR - - + This value is used as the default attributes for the files in the RPM package. The default value is @@ -7463,8 +6872,7 @@ The default value is X_RPM_DISTRIBUTION - - + This is used to fill in the Distribution: field in the RPM @@ -7474,8 +6882,7 @@ field in the RPM X_RPM_EPOCH - - + This is used to fill in the Epoch: field in the controlling information for RPM packages. @@ -7484,8 +6891,7 @@ field in the controlling information for RPM packages. X_RPM_EXCLUDEARCH - - + This is used to fill in the ExcludeArch: field in the RPM @@ -7495,8 +6901,7 @@ field in the RPM X_RPM_EXLUSIVEARCH - - + This is used to fill in the ExclusiveArch: field in the RPM @@ -7506,8 +6911,7 @@ field in the RPM X_RPM_GROUP - - + This is used to fill in the Group: field in the RPM @@ -7517,8 +6921,7 @@ field in the RPM X_RPM_GROUP_lang - - + This is used to fill in the Group(lang): field in the RPM @@ -7533,8 +6936,7 @@ the appropriate language code. X_RPM_ICON - - + This is used to fill in the Icon: field in the RPM @@ -7544,16 +6946,14 @@ field in the RPM X_RPM_INSTALL - - + internal, but overridable X_RPM_PACKAGER - - + This is used to fill in the Packager: field in the RPM @@ -7563,8 +6963,7 @@ field in the RPM X_RPM_POSTINSTALL - - + This is used to fill in the %post: section in the RPM @@ -7574,8 +6973,7 @@ section in the RPM X_RPM_POSTUNINSTALL - - + This is used to fill in the %postun: section in the RPM @@ -7585,8 +6983,7 @@ section in the RPM X_RPM_PREFIX - - + This is used to fill in the Prefix: field in the RPM @@ -7596,8 +6993,7 @@ field in the RPM X_RPM_PREINSTALL - - + This is used to fill in the %pre: section in the RPM @@ -7607,16 +7003,14 @@ section in the RPM X_RPM_PREP - - + internal, but overridable X_RPM_PREUNINSTALL - - + This is used to fill in the %preun: section in the RPM @@ -7626,8 +7020,7 @@ section in the RPM X_RPM_PROVIDES - - + This is used to fill in the Provides: field in the RPM @@ -7637,8 +7030,7 @@ field in the RPM X_RPM_REQUIRES - - + This is used to fill in the Requires: field in the RPM @@ -7648,8 +7040,7 @@ field in the RPM X_RPM_SERIAL - - + This is used to fill in the Serial: field in the RPM @@ -7659,8 +7050,7 @@ field in the RPM X_RPM_URL - - + This is used to fill in the Url: field in the RPM @@ -7670,37 +7060,33 @@ field in the RPM XGETTEXT - - + Path to xgettext(1) program (found via Detect()). -See xgettext tool and POTUpdate builder. +See xgettext tool and POTUpdate builder. XGETTEXTCOM - - + Complete xgettext command line. -See xgettext tool and POTUpdate builder. +See xgettext tool and POTUpdate builder. XGETTEXTCOMSTR - - + A string that is shown when xgettext(1) command is invoked -(default: '', which means "print $XGETTEXTCOM"). -See xgettext tool and POTUpdate builder. +(default: '', which means "print $XGETTEXTCOM"). +See xgettext tool and POTUpdate builder. _XGETTEXTDOMAIN - - + Internal "macro". Generates xgettext domain name form source and target (default: '${TARGET.filebase}'). @@ -7708,40 +7094,36 @@ form source and target (default: '${TARGET.filebase}'). XGETTEXTFLAGS - - + Additional flags to xgettext(1). -See xgettext tool and POTUpdate builder. +See xgettext tool and POTUpdate builder. XGETTEXTFROM - - + Name of file containing list of xgettext(1)'s source files. Autotools' users know this as POTFILES.in so they will in most cases set XGETTEXTFROM="POTFILES.in" here. -The $XGETTEXTFROM files have same syntax and semantics as the well known +The $XGETTEXTFROM files have same syntax and semantics as the well known GNU POTFILES.in. -See xgettext tool and POTUpdate builder. +See xgettext tool and POTUpdate builder. _XGETTEXTFROMFLAGS - - + Internal "macro". Genrates list of -D<dir> flags -from the $XGETTEXTPATH list. +from the $XGETTEXTPATH list. XGETTEXTFROMPREFIX - - -This flag is used to add single $XGETTEXTFROM file to + +This flag is used to add single $XGETTEXTFROM file to xgettext(1)'s commandline (default: '-f'). @@ -7749,38 +7131,34 @@ This flag is used to add single XGETTEXTFROMSUFFIX - - + (default: '') XGETTEXTPATH - - + List of directories, there xgettext(1) will look for source files (default: []). -This variable works only together with $XGETTEXTFROM +This variable works only together with $XGETTEXTFROM -See also xgettext tool and POTUpdate builder. +See also xgettext tool and POTUpdate builder. _XGETTEXTPATHFLAGS - - + Internal "macro". Generates list of -f<file> flags -from $XGETTEXTFROM. +from $XGETTEXTFROM. XGETTEXTPATHPREFIX - - + This flag is used to add single search path to xgettext(1)'s commandline (default: '-D'). @@ -7789,24 +7167,21 @@ This flag is used to add single search path to XGETTEXTPATHSUFFIX - - + (default: '') YACC - - + The parser generator. YACCCOM - - + The command line used to call the parser generator to generate a source file. @@ -7814,24 +7189,22 @@ to generate a source file. YACCCOMSTR - - + The string displayed when generating a source file using the parser generator. -If this is not set, then $YACCCOM (the command line) is displayed. +If this is not set, then $YACCCOM (the command line) is displayed. - + env = Environment(YACCCOMSTR = "Yacc'ing $TARGET from $SOURCES") YACCFLAGS - - + General options passed to the parser generator. -If $YACCFLAGS contains a option, +If $YACCFLAGS contains a option, SCons assumes that the call will also create a .h file (if the yacc source file ends in a .y suffix) or a .hpp file @@ -7841,8 +7214,7 @@ or a .hpp file YACCHFILESUFFIX - - + The suffix of the C header file generated by the parser generator when the @@ -7860,8 +7232,7 @@ The default value is YACCHXXFILESUFFIX - - + The suffix of the C++ header file generated by the parser generator when the @@ -7877,7 +7248,7 @@ The default value is except on Mac OS X, where the default is ${TARGET.suffix}.h. -because the default bison parser generator just +because the default bison parser generator just appends .h to the name of the generated C++ file. @@ -7885,8 +7256,7 @@ to the name of the generated C++ file. YACCVCGFILESUFFIX - - + The suffix of the file containing the VCG grammar automaton definition when the @@ -7904,16 +7274,14 @@ The default value is ZIP - - + The zip compression and file packaging utility. ZIPCOM - - + The command line used to call the zip utility, or the internal Python function used to create a zip archive. @@ -7922,8 +7290,7 @@ zip archive. ZIPCOMPRESSION - - + The compression flag @@ -7943,42 +7310,39 @@ module is unavailable. ZIPCOMSTR - - + The string displayed when archiving files using the zip utility. -If this is not set, then $ZIPCOM +If this is not set, then $ZIPCOM (the command line or internal Python function) is displayed. - + env = Environment(ZIPCOMSTR = "Zipping $TARGET") ZIPFLAGS - - + General options passed to the zip utility. ZIPROOT - - + An optional zip root directory (default empty). The filenames stored in the zip file will be relative to this directory, if given. Otherwise the filenames are relative to the current directory of the command. For instance: - + env = Environment() env.Zip('foo.zip', 'subdir1/subdir2/file1', ZIPROOT='subdir1') - + will produce a zip file foo.zip containing a file with the name subdir2/file1 rather than @@ -7988,8 +7352,7 @@ containing a file with the name ZIPSUFFIX - - + The suffix used for zip file names. diff --git a/doc/generated/variables.mod b/doc/generated/variables.mod index 3f254a5..fc12a92 100644 --- a/doc/generated/variables.mod +++ b/doc/generated/variables.mod @@ -76,8 +76,8 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. $DESCRIPTION_lang"> $DFILESUFFIX"> $DFLAGPREFIX"> -$DFLAGS"> $_DFLAGS"> +$DFLAGS"> $DFLAGSUFFIX"> $_DINCFLAGS"> $DINCPREFIX"> @@ -714,8 +714,8 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. $DESCRIPTION_lang"> $DFILESUFFIX"> $DFLAGPREFIX"> -$DFLAGS"> $_DFLAGS"> +$DFLAGS"> $DFLAGSUFFIX"> $_DINCFLAGS"> $DINCPREFIX"> diff --git a/src/engine/SCons/Tool/install.xml b/src/engine/SCons/Tool/install.xml index da82c6e..0aa9384 100644 --- a/src/engine/SCons/Tool/install.xml +++ b/src/engine/SCons/Tool/install.xml @@ -85,7 +85,7 @@ env.InstallAs(target = ['../lib/libfoo.a', '../lib/libbar.a'], Installs a versioned shared library. The &cv-link-SHLIBVERSION; construction variable should be defined in the environment to confirm the version number in the library name. -If &cv-link-SHLIBVERSION is not defined a warning will be issued +If &cv-link-SHLIBVERSION; is not defined a warning will be issued and the name of the library will be parsed to derive the version. The symlinks appropriate to the architecture will be generated. -- cgit v0.12 From 61a64ab9015bcd4f70b467eab182cb04141e9cb6 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Tue, 24 Mar 2015 19:16:05 -0700 Subject: updated copyright date on man pages --- doc/man/scons.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/man/scons.xml b/doc/man/scons.xml index 08a942b..c3abb64 100644 --- a/doc/man/scons.xml +++ b/doc/man/scons.xml @@ -54,10 +54,10 @@ Steven Knight and the SCons Development Team - 2004 - 2014 + 2004 - 2015 - 2004 - 2014 + 2004 - 2015 The SCons Foundation -- cgit v0.12 From e2deb3e686eac9f36a413778ce08110e8acf5c33 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Thu, 26 Mar 2015 16:59:30 -0700 Subject: add SKIP_WIN_PACKAGES bootstrap.py flag to allow skipping building win packages. Debian seems to skip shipping the wininst*.exe files and so will fail when trying to build these --- SConstruct | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/SConstruct b/SConstruct index ae1a06e..e47908d 100644 --- a/SConstruct +++ b/SConstruct @@ -172,6 +172,8 @@ if build_id is None: else: build_id = '' +skip_win_packages = ARGUMENTS.get('SKIP_WIN_PACKAGES',False) + python_ver = sys.version[0:3] # @@ -235,6 +237,8 @@ command_line_variables = [ ("VERSION=", "The SCons version being packaged. The default " + "is the hard-coded value '%s' " % default_version + "from this SConstruct file."), + + ("SKIP_WIN_PACKAGES=", "If set, skip building win32 and win64 packages."), ] Default('.', build_dir) @@ -495,10 +499,13 @@ Version_values = [Value(version), Value(build_id)] # separate packages. # +from distutils.sysconfig import get_python_lib; + + python_scons = { 'pkg' : 'python-' + project, 'src_subdir' : 'engine', - 'inst_subdir' : os.path.join('lib', 'python1.5', 'site-packages'), + 'inst_subdir' : get_python_lib(), 'rpm_dir' : '/usr/lib/scons', 'debian_deps' : [ @@ -737,8 +744,6 @@ for p in [ scons ]: 'dist', "%s.%s.zip" % (pkg_version, platform)) - win64_exe = os.path.join(build, 'dist', "%s.win-amd64.exe" % pkg_version) - win32_exe = os.path.join(build, 'dist', "%s.win32.exe" % pkg_version) # # Update the environment with the relevant information @@ -849,8 +854,13 @@ for p in [ scons ]: Local(*build_src_files) distutils_formats = [] + distutils_targets = [] + + if not skip_win_packages: + win64_exe = os.path.join(build, 'dist', "%s.win-amd64.exe" % pkg_version) + win32_exe = os.path.join(build, 'dist', "%s.win32.exe" % pkg_version) + distutils_targets.extend([ win32_exe , win64_exe ]) - distutils_targets = [ win32_exe , win64_exe ] dist_distutils_targets = [] for target in distutils_targets: @@ -1088,9 +1098,10 @@ for p in [ scons ]: commands.append("$PYTHON $PYTHONFLAGS $SETUP_PY sdist --formats=%s" % \ ','.join(distutils_formats)) - commands.append("$PYTHON $PYTHONFLAGS $SETUP_PY bdist_wininst --plat-name=win32 --user-access-control auto") + if not skip_win_packages: + commands.append("$PYTHON $PYTHONFLAGS $SETUP_PY bdist_wininst --plat-name=win32 --user-access-control auto") - commands.append("$PYTHON $PYTHONFLAGS $SETUP_PY bdist_wininst --plat-name=win-amd64 --user-access-control auto") + commands.append("$PYTHON $PYTHONFLAGS $SETUP_PY bdist_wininst --plat-name=win-amd64 --user-access-control auto") env.Command(distutils_targets, build_src_files, commands) -- cgit v0.12 From 1560d9e8fda849f09b74dab27e285af35f850da2 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Thu, 26 Mar 2015 17:41:17 -0700 Subject: some debug code to figure out why failing --- SConstruct | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SConstruct b/SConstruct index e47908d..9063869 100644 --- a/SConstruct +++ b/SConstruct @@ -861,6 +861,8 @@ for p in [ scons ]: win32_exe = os.path.join(build, 'dist', "%s.win32.exe" % pkg_version) distutils_targets.extend([ win32_exe , win64_exe ]) + print "distutils_targets :%s"%distutils_targets + dist_distutils_targets = [] for target in distutils_targets: -- cgit v0.12 From 61977094ad7569d2a594bd8a9538d0e99079b6b1 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Thu, 26 Mar 2015 17:42:44 -0700 Subject: some debug code to figure out why failing --- SConstruct | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SConstruct b/SConstruct index 9063869..3639de8 100644 --- a/SConstruct +++ b/SConstruct @@ -1105,6 +1105,8 @@ for p in [ scons ]: commands.append("$PYTHON $PYTHONFLAGS $SETUP_PY bdist_wininst --plat-name=win-amd64 --user-access-control auto") + print "Commands:%s"%commands + env.Command(distutils_targets, build_src_files, commands) # -- cgit v0.12 From 46536adb150648780c0f79cc26390376a386894f Mon Sep 17 00:00:00 2001 From: William Deegan Date: Thu, 26 Mar 2015 20:19:41 -0700 Subject: logic to automatically detect if the wininst*.exe is in the python install, and skip building windows packages if it's not possible on this platform --- SConstruct | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/SConstruct b/SConstruct index 3639de8..fbc8419 100644 --- a/SConstruct +++ b/SConstruct @@ -173,6 +173,11 @@ if build_id is None: build_id = '' skip_win_packages = ARGUMENTS.get('SKIP_WIN_PACKAGES',False) +import os.path +import distutils.command + +skip_win_packages = not os.path.exists(os.path.join(os.path.split(distutils.command.__file__)[0],'wininst-9.0.exe')) +print "Skip_win_packages:%s"%skip_win_packages python_ver = sys.version[0:3] -- cgit v0.12 From aa0b7546c613ca2d3fff226815c94e3484b3f098 Mon Sep 17 00:00:00 2001 From: Dirk Baechle Date: Sat, 28 Mar 2015 19:25:52 +0100 Subject: - added backward compatibility layer for the Node attributes abspath, labspath, path, tpath and path_elements --- src/engine/SCons/Node/FS.py | 137 +++++++++++++++++++++++++++----------------- 1 file changed, 84 insertions(+), 53 deletions(-) diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py index 2402fac..4084d56 100644 --- a/src/engine/SCons/Node/FS.py +++ b/src/engine/SCons/Node/FS.py @@ -588,11 +588,11 @@ class Base(SCons.Node.Node): __slots__ = ['name', 'fs', - 'abspath', - 'labspath', - 'path', - 'tpath', - 'path_elements', + '_abspath', + '_labspath', + '_path', + '_tpath', + '_path_elements', 'dir', 'cwd', 'duplicate', @@ -621,11 +621,11 @@ class Base(SCons.Node.Node): assert directory, "A directory must be provided" - self.abspath = None - self.labspath = None - self.path = None - self.tpath = None - self.path_elements = None + self._abspath = None + self._labspath = None + self._path = None + self._tpath = None + self._path_elements = None self.dir = directory self.cwd = None # will hold the SConscript directory for target nodes @@ -660,6 +660,27 @@ class Base(SCons.Node.Node): def rfile(self): return self + def __getattr__(self, attr): + """ Together with the node_bwcomp dict defined below, + this method provides a simple backward compatibility + layer for the Node attributes 'abspath', 'labspath', + 'path', 'tpath' and 'path_elements'. These Node attributes + used to be directly available in v2.3 and earlier, but + have been replaced by getter methods that initialize the + single variables lazily when required, in order to save memory. + The redirection to the getters lets older Tools and + SConstruct continue to work without any additional changes, + fully transparent to the user. + Note, that __getattr__ is only called as fallback when the + requested attribute can't be found, so there should be no + speed performance penalty involved for standard builds. + """ + if attr in node_bwcomp: + return node_bwcomp[attr](self) + + raise AttributeError("%r object has no attribute %r" % + (self.__class__, attr)) + def __str__(self): """A Node.FS.Base object's string representation is its path name.""" @@ -815,19 +836,19 @@ class Base(SCons.Node.Node): return self.dir.entry_labspath(self.name) def get_internal_path(self): - if self.dir.path == '.': + if self.dir._path == '.': return self.name else: return self.dir.entry_path(self.name) def get_tpath(self): - if self.dir.tpath == '.': + if self.dir._tpath == '.': return self.name else: return self.dir.entry_tpath(self.name) def get_path_elements(self): - return self.dir.path_elements + [self] + return self.dir._path_elements + [self] def for_signature(self): # Return just our name. Even an absolute path would not work, @@ -919,6 +940,16 @@ class Base(SCons.Node.Node): def _glob1(self, pattern, ondisk=True, source=False, strings=False): return [] +# Dict that provides a simple backward compatibility +# layer for the Node attributes 'abspath', 'labspath', +# 'path', 'tpath' and 'path_elements'. +# @see Base.__getattr__ above +node_bwcomp = {'abspath' : Base.get_abspath, + 'labspath' : Base.get_labspath, + 'path' : Base.get_internal_path, + 'tpath' : Base.get_tpath, + 'path_elements' : Base.get_path_elements} + class Entry(Base): """This is the class for generic Node.FS entries--that is, things that could be a File or a Dir, but we're just not sure yet. @@ -1169,8 +1200,8 @@ class FS(LocalFS): self.defaultDrive = _my_normcase(_my_splitdrive(self.pathTop)[0]) self.Top = self.Dir(self.pathTop) - self.Top.path = '.' - self.Top.tpath = '.' + self.Top._path = '.' + self.Top._tpath = '.' self._cwd = self.Top DirNodeInfo.fs = self @@ -1434,7 +1465,7 @@ class FS(LocalFS): if start_dir.is_under(bd): # If already in the build-dir location, don't reflect return [orig], fmt % str(orig) - p = os.path.join(bd.path, *tail) + p = os.path.join(bd._path, *tail) targets.append(self.Entry(p)) tail = [dir.name] + tail dir = dir.up() @@ -1533,17 +1564,17 @@ class Dir(Base): self._func_exists = 2 self._func_get_contents = 2 - self.abspath = SCons.Util.silent_intern(self.dir.entry_abspath(self.name)) - self.labspath = SCons.Util.silent_intern(self.dir.entry_labspath(self.name)) - if self.dir.path == '.': - self.path = SCons.Util.silent_intern(self.name) + self._abspath = SCons.Util.silent_intern(self.dir.entry_abspath(self.name)) + self._labspath = SCons.Util.silent_intern(self.dir.entry_labspath(self.name)) + if self.dir._path == '.': + self._path = SCons.Util.silent_intern(self.name) else: - self.path = SCons.Util.silent_intern(self.dir.entry_path(self.name)) - if self.dir.tpath == '.': - self.tpath = SCons.Util.silent_intern(self.name) + self._path = SCons.Util.silent_intern(self.dir.entry_path(self.name)) + if self.dir._tpath == '.': + self._tpath = SCons.Util.silent_intern(self.name) else: - self.tpath = SCons.Util.silent_intern(self.dir.entry_tpath(self.name)) - self.path_elements = self.dir.path_elements + [self] + self._tpath = SCons.Util.silent_intern(self.dir.entry_tpath(self.name)) + self._path_elements = self.dir._path_elements + [self] # For directories, we make a difference between the directory # 'name' and the directory 'dirname'. The 'name' attribute is @@ -1662,7 +1693,7 @@ class Dir(Base): def addRepository(self, dir): if dir != self and not dir in self.repositories: self.repositories.append(dir) - dir.tpath = '.' + dir._tpath = '.' self.__clearRepositoryCache() def up(self): @@ -1700,7 +1731,7 @@ class Dir(Base): if self is other: result = '.' - elif not other in self.path_elements: + elif not other in self._path_elements: try: other_dir = other.get_dir() except AttributeError: @@ -1715,10 +1746,10 @@ class Dir(Base): else: result = dir_rel_path + OS_SEP + other.name else: - i = self.path_elements.index(other) + 1 + i = self._path_elements.index(other) + 1 - path_elems = ['..'] * (len(self.path_elements) - i) \ - + [n.name for n in other.path_elements[i:]] + path_elems = ['..'] * (len(self._path_elements) - i) \ + + [n.name for n in other._path_elements[i:]] result = OS_SEP.join(path_elems) @@ -1882,32 +1913,32 @@ class Dir(Base): def get_abspath(self): """Get the absolute path of the file.""" - return self.abspath + return self._abspath def get_labspath(self): """Get the absolute path of the file.""" - return self.labspath + return self._labspath def get_internal_path(self): - return self.path + return self._path def get_tpath(self): - return self.tpath + return self._tpath def get_path_elements(self): - return self.path_elements + return self._path_elements def entry_abspath(self, name): - return self.abspath + OS_SEP + name + return self._abspath + OS_SEP + name def entry_labspath(self, name): - return self.labspath + '/' + name + return self._labspath + '/' + name def entry_path(self, name): - return self.path + OS_SEP + name + return self._path + OS_SEP + name def entry_tpath(self, name): - return self.tpath + OS_SEP + name + return self._tpath + OS_SEP + name def entry_exists_on_disk(self, name): """ Searches through the file/dir entries of the current @@ -1921,7 +1952,7 @@ class Dir(Base): except AttributeError: d = {} try: - entries = os.listdir(self.abspath) + entries = os.listdir(self._abspath) except OSError: pass else: @@ -1934,7 +1965,7 @@ class Dir(Base): if result is None: # Belt-and-suspenders for Windows: check directly for # 8.3 file names that don't show up in os.listdir(). - result = os.path.exists(self.abspath + OS_SEP + name) + result = os.path.exists(self._abspath + OS_SEP + name) d[name] = result return result else: @@ -2177,7 +2208,7 @@ class Dir(Base): for name in node_names: selfEntry(name) if ondisk: try: - disk_names = os.listdir(dir.abspath) + disk_names = os.listdir(dir._abspath) except os.error: continue names.extend(disk_names) @@ -2251,7 +2282,7 @@ class RootDir(Dir): self.name = SCons.Util.silent_intern(name) self.fs = fs #: Reference to parent Node.FS object - self.path_elements = [self] + self._path_elements = [self] self.dir = self self._func_rexists = 2 self._func_target_from_source = 1 @@ -2262,10 +2293,10 @@ class RootDir(Dir): # as the initial drive letter (the name) plus the directory # separator, except for the "lookup abspath," which does not # have the drive letter. - self.abspath = dirname - self.labspath = '' - self.path = dirname - self.tpath = dirname + self._abspath = dirname + self._labspath = '' + self._path = dirname + self._tpath = dirname self.dirname = dirname self._morph() @@ -2373,19 +2404,19 @@ class RootDir(Dir): return result def __str__(self): - return self.abspath + return self._abspath def entry_abspath(self, name): - return self.abspath + name + return self._abspath + name def entry_labspath(self, name): return '/' + name def entry_path(self, name): - return self.path + name + return self._path + name def entry_tpath(self, name): - return self.tpath + name + return self._tpath + name def is_under(self, dir): if self is dir: @@ -3080,7 +3111,7 @@ class File(Base): Unlink(self, None, None) e = Link(self, src, None) if isinstance(e, SCons.Errors.BuildError): - desc = "Cannot duplicate `%s' in `%s': %s." % (src.get_internal_path(), self.dir.path, e.errstr) + desc = "Cannot duplicate `%s' in `%s': %s." % (src.get_internal_path(), self.dir._path, e.errstr) raise SCons.Errors.StopError(desc) self.linked = 1 # The Link() action may or may not have actually @@ -3193,7 +3224,7 @@ class File(Base): SCons.Node.store_info_map[self.store_info](self) # ... then release some more variables. self._specific_sources = False - self.labspath = None + self._labspath = None self._save_str() self.cwd = None -- cgit v0.12 From 2dd443706e2c6a2f85e9ac40a237fc2c73aab345 Mon Sep 17 00:00:00 2001 From: Dirk Baechle Date: Sat, 28 Mar 2015 22:34:58 +0100 Subject: - replaced wrong Node attribute with its new name --- src/engine/SCons/Node/FS.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py index 4084d56..1a6f7e5 100644 --- a/src/engine/SCons/Node/FS.py +++ b/src/engine/SCons/Node/FS.py @@ -1816,7 +1816,7 @@ class Dir(Base): if p is None: # Don't use while: - else: for this condition because # if so, then parent is None and has no .path attribute. - raise SCons.Errors.StopError(parent.path) + raise SCons.Errors.StopError(parent._path) parent = p listDirs.reverse() for dirnode in listDirs: -- cgit v0.12 From 9508091845949b4bbb181a46b11032ecab8178c6 Mon Sep 17 00:00:00 2001 From: Alexandre Feblot Date: Sat, 25 Apr 2015 14:23:26 +0200 Subject: VC11 needs PCH objects added to the link line. Update msvc linker emitter to add the PCH object to shared libraries if not already present. --- src/engine/SCons/Tool/mslink.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/engine/SCons/Tool/mslink.py b/src/engine/SCons/Tool/mslink.py index 37af34e..827161e 100644 --- a/src/engine/SCons/Tool/mslink.py +++ b/src/engine/SCons/Tool/mslink.py @@ -129,6 +129,14 @@ def _dllEmitter(target, source, env, paramtp): 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) + if not no_import_lib and \ not env.FindIxes(target, "LIBPREFIX", "LIBSUFFIX"): # Append an import library to the list of targets. -- cgit v0.12 From ac9335aac3ad4c320257a865711a4dfeaa23866c Mon Sep 17 00:00:00 2001 From: Alexandre Feblot Date: Sat, 25 Apr 2015 17:41:47 +0200 Subject: Fix C typo error in a test --- test/option/tree-lib.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/option/tree-lib.py b/test/option/tree-lib.py index 2721344..2dc5fb0 100644 --- a/test/option/tree-lib.py +++ b/test/option/tree-lib.py @@ -52,7 +52,7 @@ test.write('main.c', """\ #include #include int -main(int argc, char *argv) +main(int argc, char **argv) { printf("#define FOO_H \\"foo.h\\"\\n"); return (0); -- cgit v0.12 From a9c8d39ed653a54ed99086aeef0fa716787dc73b Mon Sep 17 00:00:00 2001 From: Alexandre Feblot Date: Sat, 25 Apr 2015 17:43:10 +0200 Subject: Add an exclude parameter to Glob(), to allow excluding some elements matching the main pattern --- doc/user/less-simple.xml | 1 + src/engine/SCons/Environment.py | 4 +- src/engine/SCons/Environment.xml | 13 ++++++- src/engine/SCons/Node/FS.py | 36 ++++++++++-------- test/Glob/exclude.py | 82 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 117 insertions(+), 19 deletions(-) create mode 100644 test/Glob/exclude.py diff --git a/doc/user/less-simple.xml b/doc/user/less-simple.xml index cca6033..9f27738 100644 --- a/doc/user/less-simple.xml +++ b/doc/user/less-simple.xml @@ -257,6 +257,7 @@ Program('program', Glob('*.c')) (see , below) and repositories (see , below), + excluding some files and returning strings rather than Nodes. diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py index 5f2c9ff..6886e85 100644 --- a/src/engine/SCons/Environment.py +++ b/src/engine/SCons/Environment.py @@ -2080,8 +2080,8 @@ class Base(SubstitutionEnvironment): else: return result[0] - def Glob(self, pattern, ondisk=True, source=False, strings=False): - return self.fs.Glob(self.subst(pattern), ondisk, source, strings) + def Glob(self, pattern, ondisk=True, source=False, strings=False, exclude=None): + return self.fs.Glob(self.subst(pattern), ondisk, source, strings, exclude) def Ignore(self, target, dependency): """Ignore a dependency.""" diff --git a/src/engine/SCons/Environment.xml b/src/engine/SCons/Environment.xml index b3b132e..6de2669 100644 --- a/src/engine/SCons/Environment.xml +++ b/src/engine/SCons/Environment.xml @@ -1697,7 +1697,7 @@ Nodes or strings representing path names. -(pattern, [ondisk, source, strings]) +(pattern, [ondisk, source, strings, exclude]) @@ -1811,12 +1811,23 @@ directory.) +The +exclude +argument may be set to a list of patterns +(following the same Unix shell semantics) +which must be filtered out of returned elements. +Elements matching a least one pattern of +this list will be excluded. + + + Examples: Program('foo', Glob('*.c')) Zip('/tmp/everything', Glob('.??*') + Glob('*')) +sources = Glob('*.cpp', exlude=['os_*_specific_*.cpp']) + Glob('os_%s_specific_*.cpp'%currentOS) diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py index 4db1cb3..0156e27 100644 --- a/src/engine/SCons/Node/FS.py +++ b/src/engine/SCons/Node/FS.py @@ -1401,7 +1401,7 @@ class FS(LocalFS): message = fmt % ' '.join(map(str, targets)) return targets, message - def Glob(self, pathname, ondisk=True, source=True, strings=False, cwd=None): + def Glob(self, pathname, ondisk=True, source=True, strings=False, exclude=None, cwd=None): """ Globs @@ -1409,7 +1409,7 @@ class FS(LocalFS): """ if cwd is None: cwd = self.getcwd() - return cwd.glob(pathname, ondisk, source, strings) + return cwd.glob(pathname, ondisk, source, strings, exclude) class DirNodeInfo(SCons.Node.NodeInfoBase): # This should get reset by the FS initialization. @@ -2020,7 +2020,7 @@ class Dir(Base): for dirname in [n for n in names if isinstance(entries[n], Dir)]: entries[dirname].walk(func, arg) - def glob(self, pathname, ondisk=True, source=False, strings=False): + def glob(self, pathname, ondisk=True, source=False, strings=False, exclude=None): """ Returns a list of Nodes (or strings) matching a specified pathname pattern. @@ -2048,24 +2048,30 @@ class Dir(Base): The "strings" argument, when true, returns the matches as strings, not Nodes. The strings are path names relative to this directory. + The "exclude" argument, if not None, must be a list of patterns + following the same UNIX shell semantics. Elements matching a least + one pattern of this list will be excluded from the result. + The underlying algorithm is adapted from the glob.glob() function in the Python library (but heavily modified), and uses fnmatch() under the covers. """ dirname, basename = os.path.split(pathname) if not dirname: - return sorted(self._glob1(basename, ondisk, source, strings), - key=lambda t: str(t)) - if has_glob_magic(dirname): - list = self.glob(dirname, ondisk, source, strings=False) + result = self._glob1(basename, ondisk, source, strings) else: - list = [self.Dir(dirname, create=True)] - result = [] - for dir in list: - r = dir._glob1(basename, ondisk, source, strings) - if strings: - r = [os.path.join(str(dir), x) for x in r] - result.extend(r) + if has_glob_magic(dirname): + list = self.glob(dirname, ondisk, source, False, exclude) + else: + list = [self.Dir(dirname, create=True)] + result = [] + for dir in list: + r = dir._glob1(basename, ondisk, source, strings) + if strings: + r = [os.path.join(str(dir), x) for x in r] + result.extend(r) + if exclude: + result = filter(lambda x: not any(fnmatch.fnmatch(str(x), e) for e in exclude), result) return sorted(result, key=lambda a: str(a)) def _glob1(self, pattern, ondisk=True, source=False, strings=False): @@ -2128,14 +2134,12 @@ class Dir(Base): names = set(names) if pattern[0] != '.': - #names = [ n for n in names if n[0] != '.' ] names = [x for x in names if x[0] != '.'] names = fnmatch.filter(names, pattern) if strings: return names - #return [ self.entries[_my_normcase(n)] for n in names ] return [self.entries[_my_normcase(n)] for n in names] class RootDir(Dir): diff --git a/test/Glob/exclude.py b/test/Glob/exclude.py new file mode 100644 index 0000000..7ef06df --- /dev/null +++ b/test/Glob/exclude.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Verify the "exclude" parameter usage of the Glob() function. + - with or without subdir + - with or without returning strings + - a file in a subdir is not excluded by a pattern without this subdir +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.write('SConstruct', """\ +env = Environment() + +def concatenate(target, source, env): + fp = open(str(target[0]), 'wb') + for s in source: + fp.write(open(str(s), 'rb').read()) + fp.close() + +env['BUILDERS']['Concatenate'] = Builder(action=concatenate) + +env.Concatenate('fa.out', sorted(Glob('f*.in' , exclude=['f2.in', 'f4.*'] , strings=False), key=lambda t: t.path)) +env.Concatenate('fb.out', sorted(Glob('f*.in' , exclude=['f2.in', 'f4.*'] , strings=True))) +env.Concatenate('fc.out', sorted(Glob('d?/f*.in', exclude=['d?/f1.*', 'f2.in'], strings=False), key=lambda t: t.path)) +env.Concatenate('fd.out', sorted(Glob('d?/f*.in', exclude=['d?/f1.*', 'f2.in'], strings=True))) +""") + +test.write('f1.in', "f1.in\n") +test.write('f2.in', "f2.in\n") +test.write('f3.in', "f3.in\n") +test.write('f4.in', "f4.in\n") +test.write('f5.in', "f5.in\n") + +test.subdir('d1', 'd2') +test.write(['d1', 'f1.in'], "d1/f1.in\n") +test.write(['d1', 'f2.in'], "d1/f2.in\n") +test.write(['d1', 'f3.in'], "d1/f3.in\n") +test.write(['d2', 'f1.in'], "d2/f1.in\n") +test.write(['d2', 'f2.in'], "d2/f2.in\n") +test.write(['d2', 'f3.in'], "d2/f3.in\n") + +test.run(arguments = '.') + +test.must_match('fa.out', "f1.in\nf3.in\nf5.in\n") +test.must_match('fb.out', "f1.in\nf3.in\nf5.in\n") +test.must_match('fc.out', "d1/f2.in\nd1/f3.in\nd2/f2.in\nd2/f3.in\n") +test.must_match('fd.out', "d1/f2.in\nd1/f3.in\nd2/f2.in\nd2/f3.in\n") + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: -- cgit v0.12 From 141f6eebdf3619bef3b8665e2cf997667026d20d Mon Sep 17 00:00:00 2001 From: Alexandre Feblot Date: Sat, 25 Apr 2015 18:24:35 +0200 Subject: Fix typo in the doc --- src/engine/SCons/Environment.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/SCons/Environment.xml b/src/engine/SCons/Environment.xml index 6de2669..069ad87 100644 --- a/src/engine/SCons/Environment.xml +++ b/src/engine/SCons/Environment.xml @@ -1827,7 +1827,7 @@ Examples: Program('foo', Glob('*.c')) Zip('/tmp/everything', Glob('.??*') + Glob('*')) -sources = Glob('*.cpp', exlude=['os_*_specific_*.cpp']) + Glob('os_%s_specific_*.cpp'%currentOS) +sources = Glob('*.cpp', exclude=['os_*_specific_*.cpp']) + Glob('os_%s_specific_*.cpp'%currentOS) -- cgit v0.12 From df36b18d410042510239fe10b00022a88a1095d7 Mon Sep 17 00:00:00 2001 From: Alexandre Feblot Date: Wed, 29 Apr 2015 21:03:04 +0200 Subject: Add a test on basic PCH behavior: bulid a simple executable and a simple shared lib --- test/MSVC/pch-basics.py | 79 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 test/MSVC/pch-basics.py diff --git a/test/MSVC/pch-basics.py b/test/MSVC/pch-basics.py new file mode 100644 index 0000000..45735ed --- /dev/null +++ b/test/MSVC/pch-basics.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Verify PCH works to build a simple exe and a simple dll. +""" + +import time + +import TestSCons + +test = TestSCons.TestSCons(match = TestSCons.match_re) + +test.skip_if_not_msvc() + +test.write('Main.cpp', """\ +#include "Precompiled.h" + +int main() +{ + return testf(); +} +""") + +test.write('Precompiled.cpp', """\ +#include "Precompiled.h" +""") + +test.write('Precompiled.h', """\ +#pragma once + +static int testf() +{ + return 0; +} +""") + +test.write('SConstruct', """\ +env = Environment() + +env['PCHSTOP'] = 'Precompiled.h' +env['PCH'] = env.PCH('Precompiled.cpp')[0] + +env.SharedLibrary('pch_dll', 'Main.cpp') +env.Program('pch_exe', 'Main.cpp') +""") + +test.run(arguments='.', stderr=None) + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: -- cgit v0.12 From 442d6edefdd962f282549b933e2c8323e0809044 Mon Sep 17 00:00:00 2001 From: Alexandre Feblot Date: Wed, 29 Apr 2015 22:58:22 +0200 Subject: Additional Glob exlude tests --- test/Glob/exclude.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/Glob/exclude.py b/test/Glob/exclude.py index 7ef06df..2348cc2 100644 --- a/test/Glob/exclude.py +++ b/test/Glob/exclude.py @@ -50,6 +50,8 @@ env.Concatenate('fa.out', sorted(Glob('f*.in' , exclude=['f2.in', 'f4.*'] , env.Concatenate('fb.out', sorted(Glob('f*.in' , exclude=['f2.in', 'f4.*'] , strings=True))) env.Concatenate('fc.out', sorted(Glob('d?/f*.in', exclude=['d?/f1.*', 'f2.in'], strings=False), key=lambda t: t.path)) env.Concatenate('fd.out', sorted(Glob('d?/f*.in', exclude=['d?/f1.*', 'f2.in'], strings=True))) +env.Concatenate('fe.out', sorted(Glob('f*.in', exclude=['f1.in'] , strings=True))) +env.Concatenate('ff.out', sorted(Glob('f*.in', exclude=['other'] , strings=True))) """) test.write('f1.in', "f1.in\n") @@ -72,6 +74,8 @@ test.must_match('fa.out', "f1.in\nf3.in\nf5.in\n") test.must_match('fb.out', "f1.in\nf3.in\nf5.in\n") test.must_match('fc.out', "d1/f2.in\nd1/f3.in\nd2/f2.in\nd2/f3.in\n") test.must_match('fd.out', "d1/f2.in\nd1/f3.in\nd2/f2.in\nd2/f3.in\n") +test.must_match('fe.out', "f2.in\nf3.in\nf4.in\nf5.in\n") +test.must_match('ff.out', "f1.in\nf2.in\nf3.in\nf4.in\nf5.in\n") test.pass_test() -- cgit v0.12 From 96b03f5736c84dc01b9de3b19a108c1f7846c89d Mon Sep 17 00:00:00 2001 From: Alexandre Feblot Date: Thu, 30 Apr 2015 00:19:55 +0200 Subject: Glob exclude parameter can now be a string or a list of strings --- src/engine/SCons/Environment.xml | 2 +- src/engine/SCons/Node/FS.py | 9 +++++---- test/Glob/exclude.py | 4 ++-- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/engine/SCons/Environment.xml b/src/engine/SCons/Environment.xml index 069ad87..b90f1d8 100644 --- a/src/engine/SCons/Environment.xml +++ b/src/engine/SCons/Environment.xml @@ -1813,7 +1813,7 @@ directory.) The exclude -argument may be set to a list of patterns +argument may be set to a pattern or a list of patterns (following the same Unix shell semantics) which must be filtered out of returned elements. Elements matching a least one pattern of diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py index 0156e27..eec4e42 100644 --- a/src/engine/SCons/Node/FS.py +++ b/src/engine/SCons/Node/FS.py @@ -2048,9 +2048,10 @@ class Dir(Base): The "strings" argument, when true, returns the matches as strings, not Nodes. The strings are path names relative to this directory. - The "exclude" argument, if not None, must be a list of patterns - following the same UNIX shell semantics. Elements matching a least - one pattern of this list will be excluded from the result. + The "exclude" argument, if not None, must be a pattern or a list + of patterns following the same UNIX shell semantics. + Elements matching a least one pattern of this list will be excluded + from the result. The underlying algorithm is adapted from the glob.glob() function in the Python library (but heavily modified), and uses fnmatch() @@ -2071,7 +2072,7 @@ class Dir(Base): r = [os.path.join(str(dir), x) for x in r] result.extend(r) if exclude: - result = filter(lambda x: not any(fnmatch.fnmatch(str(x), e) for e in exclude), result) + result = filter(lambda x: not any(fnmatch.fnmatch(str(x), e) for e in SCons.Util.flatten(exclude)), result) return sorted(result, key=lambda a: str(a)) def _glob1(self, pattern, ondisk=True, source=False, strings=False): diff --git a/test/Glob/exclude.py b/test/Glob/exclude.py index 2348cc2..56b58a8 100644 --- a/test/Glob/exclude.py +++ b/test/Glob/exclude.py @@ -50,8 +50,8 @@ env.Concatenate('fa.out', sorted(Glob('f*.in' , exclude=['f2.in', 'f4.*'] , env.Concatenate('fb.out', sorted(Glob('f*.in' , exclude=['f2.in', 'f4.*'] , strings=True))) env.Concatenate('fc.out', sorted(Glob('d?/f*.in', exclude=['d?/f1.*', 'f2.in'], strings=False), key=lambda t: t.path)) env.Concatenate('fd.out', sorted(Glob('d?/f*.in', exclude=['d?/f1.*', 'f2.in'], strings=True))) -env.Concatenate('fe.out', sorted(Glob('f*.in', exclude=['f1.in'] , strings=True))) -env.Concatenate('ff.out', sorted(Glob('f*.in', exclude=['other'] , strings=True))) +env.Concatenate('fe.out', sorted(Glob('f*.in', exclude='f1.in' , strings=True))) +env.Concatenate('ff.out', sorted(Glob('f*.in', exclude='other' , strings=True))) """) test.write('f1.in', "f1.in\n") -- cgit v0.12 From 0b350d60762e6a369a739fccd246e7fdbef093f8 Mon Sep 17 00:00:00 2001 From: Alexandre Feblot Date: Thu, 30 Apr 2015 00:51:56 +0200 Subject: Update README --- src/CHANGES.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 45c8a8c..7b384d2 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -33,6 +33,8 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER From Alexandre Feblot: - Fix for VersionedSharedLibrary under 'sunos' platform. + - Fixed dll link with precompiled headers on MSVC 2012 + - Added an 'exclude' parameter to Glob() From Laurent Marchelli: - Support for multiple cmdargs (one per variant) in VS project files. -- cgit v0.12 From 1ec87674971081f7bf1018985254feb7ab52fcd4 Mon Sep 17 00:00:00 2001 From: Stephen Pollard Date: Sat, 2 May 2015 09:58:56 -0600 Subject: Fixed a sentence in libraries.xml in response to issue 2989. --- doc/user/libraries.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/user/libraries.xml b/doc/user/libraries.xml index 626e939..d7983c9 100644 --- a/doc/user/libraries.xml +++ b/doc/user/libraries.xml @@ -123,7 +123,7 @@ void f3() { printf("f3.c\n"); } list of source files. You can, however, also give the &b-link-Library; call object files, - and it will correctly realize + and it will correctly realize they are object files. In fact, you can arbitrarily mix source code files and object files in the source list: -- cgit v0.12 From 21a6b1c09608f361ddf64141c97b18cb6b1a96ec Mon Sep 17 00:00:00 2001 From: Stephen Pollard Date: Sat, 2 May 2015 10:08:03 -0600 Subject: Fixed minor punctuation issue 2990 --- doc/user/builders-writing.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/user/builders-writing.xml b/doc/user/builders-writing.xml index f3713f2..dec176a 100644 --- a/doc/user/builders-writing.xml +++ b/doc/user/builders-writing.xml @@ -502,7 +502,7 @@ def build_function(target, source, env): The builder function may raise an exception or return any non-zero value - to indicate that the build is unsuccessful, + to indicate that the build is unsuccessful. -- cgit v0.12 From 7ac97ed9d43883d1322dc1d3a775ccc6da049b26 Mon Sep 17 00:00:00 2001 From: Dirk Baechle Date: Tue, 5 May 2015 23:06:20 +0200 Subject: Updated CHANGES.txt --- src/CHANGES.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 7b384d2..ef4e016 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -6,6 +6,10 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER + From Stephen Pollard: + - Documentation fixes for libraries.xml and + builders-writing.xml (#2989 and #2990) + From William Deegan: - Extended docs for InstallVersionedLib/SharedLibrary, and added SKIP_WIN_PACKAGES argument to build script -- cgit v0.12 From ed3930b3474f5b407ccf40d273f4bc2ac35ad9eb Mon Sep 17 00:00:00 2001 From: Andrew Featherstone Date: Tue, 12 May 2015 08:09:48 +0100 Subject: Corrects SWIGPATH documentation as per http://scons.tigris.org/issues/show_bug.cgi?id=2504. Corrects a minor typo in the SWIGPATH description. --- src/engine/SCons/Tool/swig.xml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/engine/SCons/Tool/swig.xml b/src/engine/SCons/Tool/swig.xml index 2b817dc..1160804 100644 --- a/src/engine/SCons/Tool/swig.xml +++ b/src/engine/SCons/Tool/swig.xml @@ -202,9 +202,7 @@ and translated into the The list of directories that the scripting language wrapper and interface generate will search for included files. The SWIG implicit dependency scanner will search these -directories for include files. -The default is to use the same path -specified as &cv-CPPPATH;. +directories for include files. The default value is an empty list. @@ -251,7 +249,7 @@ include &cv-_SWIGINCFLAGS;: -env = Environment(SWIGCOM="my_swig -o $TARGET $_SWIGINCFLAGS $SORUCES") +env = Environment(SWIGCOM="my_swig -o $TARGET $_SWIGINCFLAGS $SOURCES") -- cgit v0.12 From 654e4414d80324b2a4c2edf3c685a38feec514f6 Mon Sep 17 00:00:00 2001 From: William Blevins Date: Wed, 13 May 2015 00:06:05 -0400 Subject: Issue 2264: Added SWIG recursive dependency tests. --- QMTest/TestCommon.py | 32 ++++++++++ test/SWIG/recursive-includes-cpp.py | 123 ++++++++++++++++++++++++++++++++++++ 2 files changed, 155 insertions(+) create mode 100644 test/SWIG/recursive-includes-cpp.py diff --git a/QMTest/TestCommon.py b/QMTest/TestCommon.py index 4e90e16..275d4f2 100644 --- a/QMTest/TestCommon.py +++ b/QMTest/TestCommon.py @@ -36,6 +36,8 @@ provided by the TestCommon class: test.must_contain('file', 'required text\n') + test.must_contain_all(output, lines, ['title', find]) + test.must_contain_all_lines(output, lines, ['title', find]) test.must_contain_any_line(output, lines, ['title', find]) @@ -305,6 +307,36 @@ class TestCommon(TestCmd): print file_contents self.fail_test(not contains) + def must_contain_all(self, output, input, title=None, find=None): + """Ensures that the specified output string (first argument) + contains all of the specified input as a block (second argument). + + An optional third argument can be used to describe the type + of output being searched, and only shows up in failure output. + + An optional fourth argument can be used to supply a different + function, of the form "find(line, output), to use when searching + for lines in the output. + """ + if find is None: + def find(o, i): + try: + return o.index(i) + except ValueError: + return None + + if is_List(output): + output = os.newline.join(output) + + if find(output, input) is None: + if title is None: + title = 'output' + print 'Missing expected input from %s:' % title + print input + print self.banner(title + ' ') + print output + self.fail_test() + def must_contain_all_lines(self, output, lines, title=None, find=None): """Ensures that the specified output string (first argument) contains all of the specified lines (second argument). diff --git a/test/SWIG/recursive-includes-cpp.py b/test/SWIG/recursive-includes-cpp.py new file mode 100644 index 0000000..364bd73 --- /dev/null +++ b/test/SWIG/recursive-includes-cpp.py @@ -0,0 +1,123 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Verify that SWIG include directives produce the correct dependencies +in cases of recursive inclusion. +""" + +import os +import TestSCons +from SCons.Defaults import DefaultEnvironment + +DefaultEnvironment( tools = [ 'swig' ] ) + +test = TestSCons.TestSCons() + +# Check for prerequisites of this test. +for pre_req in ['swig', 'python']: + if not test.where_is(pre_req): + test.skip_test('Can not find installed "' + pre_req + '", skipping test.%s' % os.linesep) + +test.write("recursive.h", """\ +/* An empty header file. */ +""") + +test.write("main.h", """\ +#include "recursive.h" +""") + +test.write("main.c", """\ +#include "main.h" +""") + +test.write("mod.i", """\ +%module mod + +%include "main.h" + +#include "main.h" +""") + +test.write('SConstruct', """\ +import distutils.sysconfig + +DefaultEnvironment( tools = [ 'swig' ] ) + +env = Environment( + SWIGFLAGS = [ + '-python' + ], + CPPPATH = [ + distutils.sysconfig.get_python_inc() + ], + SHLIBPREFIX = "" +) + +env.SharedLibrary( + 'mod.so', + [ + "mod.i", + "main.c", + ] +) +""") + +expectMain = """\ ++-main.os + +-main.c + +-main.h + +-recursive.h""" + +expectMod = """\ ++-mod_wrap.os + +-mod_wrap.c + | +-mod.i + | +-main.h + | +-recursive.h""" + +# Validate that the recursive dependencies are found with SWIG scanning first. +test.run( arguments = '--tree=all mod_wrap.os main.os' ) + +test.must_contain_all( test.stdout(), expectMain ) +test.must_contain_all( test.stdout(), expectMod ) + +# Validate that the recursive dependencies are found consistently. +test.run( arguments = '--tree=all main.os mod_wrap.os' ) + +test.must_contain_all( test.stdout(), expectMain ) +test.must_contain_all( test.stdout(), expectMod ) + +test.run() +test.up_to_date() + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: -- cgit v0.12 From 6af468c642134c73c70820b17cad562c35785fdd Mon Sep 17 00:00:00 2001 From: Andrew Featherstone Date: Fri, 15 May 2015 21:02:10 +0100 Subject: Corrects comparison of actions from different environments. --- src/engine/SCons/Builder.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engine/SCons/Builder.py b/src/engine/SCons/Builder.py index c82f6ac..4e8aee9 100644 --- a/src/engine/SCons/Builder.py +++ b/src/engine/SCons/Builder.py @@ -292,8 +292,8 @@ def _node_errors(builder, env, tlist, slist): if t.has_explicit_builder(): if not t.env is None and not t.env is env: action = t.builder.action - t_contents = action.get_contents(tlist, slist, t.env) - contents = action.get_contents(tlist, slist, env) + t_contents = t.builder.action.get_contents(tlist, slist, t.env) + contents = builder.action.get_contents(tlist, slist, env) if t_contents == contents: msg = "Two different environments were specified for target %s,\n\tbut they appear to have the same action: %s" % (t, action.genstring(tlist, slist, t.env)) -- cgit v0.12 From b27b2316842dfa291feef332c80f676fd097d809 Mon Sep 17 00:00:00 2001 From: William Blevins Date: Sun, 17 May 2015 19:57:44 -0400 Subject: Issue 2264: Added cross-language scanner support. --- src/engine/SCons/Defaults.py | 2 +- src/engine/SCons/Executor.py | 26 ++++++---------------- src/engine/SCons/Node/__init__.py | 26 +++++++++++++--------- src/engine/SCons/Scanner/SWIG.py | 45 +++++++++++++++++++++++++++++++++++++++ src/engine/SCons/Tool/__init__.py | 7 ++++++ src/engine/SCons/Tool/swig.py | 6 ------ 6 files changed, 75 insertions(+), 37 deletions(-) create mode 100644 src/engine/SCons/Scanner/SWIG.py diff --git a/src/engine/SCons/Defaults.py b/src/engine/SCons/Defaults.py index 6500443..3e37fa5 100644 --- a/src/engine/SCons/Defaults.py +++ b/src/engine/SCons/Defaults.py @@ -484,7 +484,7 @@ class Variable_Method_Caller(object): ConstructionEnvironment = { 'BUILDERS' : {}, - 'SCANNERS' : [], + 'SCANNERS' : [ SCons.Tool.SourceFileScanner ], 'CONFIGUREDIR' : '#/.sconf_temp', 'CONFIGURELOG' : '#/config.log', 'CPPSUFFIXES' : SCons.Tool.CSuffixes, diff --git a/src/engine/SCons/Executor.py b/src/engine/SCons/Executor.py index 98ed758..59e57e3 100644 --- a/src/engine/SCons/Executor.py +++ b/src/engine/SCons/Executor.py @@ -486,29 +486,15 @@ class Executor(object): each individual target, which is a hell of a lot more efficient. """ env = self.get_build_env() + path = self.get_build_scanner_path + kw = self.get_kw() # TODO(batch): scan by batches) deps = [] - if scanner: - for node in node_list: - node.disambiguate() - s = scanner.select(node) - if not s: - continue - path = self.get_build_scanner_path(s) - deps.extend(node.get_implicit_deps(env, s, path)) - else: - kw = self.get_kw() - for node in node_list: - node.disambiguate() - scanner = node.get_env_scanner(env, kw) - if not scanner: - continue - scanner = scanner.select(node) - if not scanner: - continue - path = self.get_build_scanner_path(scanner) - deps.extend(node.get_implicit_deps(env, scanner, path)) + + for node in node_list: + node.disambiguate() + deps.extend(node.get_implicit_deps(env, scanner, path, kw)) deps.extend(self.get_implicit_deps()) diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py index f2d37c2..5721442 100644 --- a/src/engine/SCons/Node/__init__.py +++ b/src/engine/SCons/Node/__init__.py @@ -916,32 +916,38 @@ class Node(object): """ return [] - def get_implicit_deps(self, env, scanner, path): + def get_implicit_deps(self, env, scanner, path, kw = {}): """Return a list of implicit dependencies for this node. This method exists to handle recursive invocation of the scanner on the implicit dependencies returned by the scanner, if the scanner's recursive flag says that we should. """ - if not scanner: - return [] - - # Give the scanner a chance to select a more specific scanner - # for this Node. - #scanner = scanner.select(self) - nodes = [self] seen = {} seen[self] = 1 deps = [] while nodes: n = nodes.pop(0) - d = [x for x in n.get_found_includes(env, scanner, path) if x not in seen] + + if not scanner: + s = n.get_env_scanner(env, kw) + if s: + s = s.select(n) + else: + s = scanner.select(n) + + if not s: + continue + + p = path(s) + + d = [x for x in n.get_found_includes(env, s, p) if x not in seen] if d: deps.extend(d) for n in d: seen[n] = 1 - nodes.extend(scanner.recurse_nodes(d)) + nodes.extend(s.recurse_nodes(d)) return deps diff --git a/src/engine/SCons/Scanner/SWIG.py b/src/engine/SCons/Scanner/SWIG.py new file mode 100644 index 0000000..2650e4b --- /dev/null +++ b/src/engine/SCons/Scanner/SWIG.py @@ -0,0 +1,45 @@ +"""SCons.Scanner.SWIG + +This module implements the dependency scanner for SWIG code. + +""" + +# +# __COPYRIGHT__ +# +# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import SCons.Scanner + +SWIGSuffixes = [ '.i' ] + +def SWIGScanner(): + expr = '^[ \t]*%[ \t]*(?:include|import|extern)[ \t]*(<|"?)([^>\s"]+)(?:>|"?)' + scanner = SCons.Scanner.ClassicCPP("SWIGScanner", ".i", "SWIGPATH", expr) + return scanner + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py index efd2e33..6002d72 100644 --- a/src/engine/SCons/Tool/__init__.py +++ b/src/engine/SCons/Tool/__init__.py @@ -51,6 +51,7 @@ import SCons.Scanner.C import SCons.Scanner.D import SCons.Scanner.LaTeX import SCons.Scanner.Prog +import SCons.Scanner.SWIG DefaultToolpath=[] @@ -60,6 +61,7 @@ LaTeXScanner = SCons.Scanner.LaTeX.LaTeXScanner() PDFLaTeXScanner = SCons.Scanner.LaTeX.PDFLaTeXScanner() ProgramScanner = SCons.Scanner.Prog.ProgramScanner() SourceFileScanner = SCons.Scanner.Base({}, name='SourceFileScanner') +SWIGScanner = SCons.Scanner.SWIG.SWIGScanner() CSuffixes = [".c", ".C", ".cxx", ".cpp", ".c++", ".cc", ".h", ".H", ".hxx", ".hpp", ".hh", @@ -73,12 +75,17 @@ IDLSuffixes = [".idl", ".IDL"] LaTeXSuffixes = [".tex", ".ltx", ".latex"] +SWIGSuffixes = ['.i'] + for suffix in CSuffixes: SourceFileScanner.add_scanner(suffix, CScanner) for suffix in DSuffixes: SourceFileScanner.add_scanner(suffix, DScanner) +for suffix in SWIGSuffixes: + SourceFileScanner.add_scanner(suffix, SWIGScanner) + # 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 diff --git a/src/engine/SCons/Tool/swig.py b/src/engine/SCons/Tool/swig.py index a315182..959d5fe 100644 --- a/src/engine/SCons/Tool/swig.py +++ b/src/engine/SCons/Tool/swig.py @@ -39,7 +39,6 @@ import subprocess import SCons.Action import SCons.Defaults -import SCons.Scanner import SCons.Tool import SCons.Util import SCons.Node @@ -173,11 +172,6 @@ def generate(env): 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 -- cgit v0.12 From 279caec8f29b92cc569be83eb7b0c7a271136ad4 Mon Sep 17 00:00:00 2001 From: William Blevins Date: Sun, 17 May 2015 23:38:23 -0400 Subject: Issue 2264: Updated tests to reflect Node changes. --- src/engine/SCons/ExecutorTests.py | 4 ++- src/engine/SCons/Node/NodeTests.py | 19 ++++++++----- test/Fortran/FORTRANSUFFIXES.py | 56 +++++++++++++++++++------------------- test/QT/manual.py | 6 ++-- test/Scanner/exception.py | 14 +++++----- test/Scanner/generated.py | 1 + 6 files changed, 55 insertions(+), 45 deletions(-) diff --git a/src/engine/SCons/ExecutorTests.py b/src/engine/SCons/ExecutorTests.py index 9df0b2d..f390319 100644 --- a/src/engine/SCons/ExecutorTests.py +++ b/src/engine/SCons/ExecutorTests.py @@ -83,7 +83,9 @@ class MyNode(object): executor(self) def get_env_scanner(self, env, kw): return MyScanner('dep-') - def get_implicit_deps(self, env, scanner, path): + def get_implicit_deps(self, env, scanner, path, kw={}): + if not scanner: + scanner = self.get_env_scanner(env, kw) return [scanner.prefix + str(self)] def add_to_implicit(self, deps): self.implicit.extend(deps) diff --git a/src/engine/SCons/Node/NodeTests.py b/src/engine/SCons/Node/NodeTests.py index a6471b4..4639cf9 100644 --- a/src/engine/SCons/Node/NodeTests.py +++ b/src/engine/SCons/Node/NodeTests.py @@ -132,7 +132,12 @@ class Environment(object): def get_factory(self, factory): return factory or MyNode def get_scanner(self, scanner_key): - return self._dict['SCANNERS'][0] + try: + return self._dict['SCANNERS'][0] + except: + pass + + return [] class Builder(object): def __init__(self, env=None, is_explicit=1): @@ -185,7 +190,7 @@ class Scanner(object): def __call__(self, node): self.called = 1 return node.GetTag('found_includes') - def path(self, env, dir, target=None, source=None): + def path(self, env, dir=None, target=None, source=None, kw={}): return () def select(self, node): return self @@ -928,7 +933,7 @@ class NodeTestCase(unittest.TestCase): node.Tag('found_includes', [d1, d2]) # Simple return of the found includes - deps = node.get_implicit_deps(env, s, target) + deps = node.get_implicit_deps(env, s, s.path) assert deps == [d1, d2], deps # By default, our fake scanner recurses @@ -938,24 +943,24 @@ class NodeTestCase(unittest.TestCase): d1.Tag('found_includes', [e, f]) d2.Tag('found_includes', [e, f]) f.Tag('found_includes', [g]) - deps = node.get_implicit_deps(env, s, target) + deps = node.get_implicit_deps(env, s, s.path) assert deps == [d1, d2, e, f, g], list(map(str, deps)) # Recursive scanning eliminates duplicates e.Tag('found_includes', [f]) - deps = node.get_implicit_deps(env, s, target) + deps = node.get_implicit_deps(env, s, s.path) assert deps == [d1, d2, e, f, g], list(map(str, deps)) # Scanner method can select specific nodes to recurse def no_fff(nodes): return [n for n in nodes if str(n)[0] != 'f'] s.recurse_nodes = no_fff - deps = node.get_implicit_deps(env, s, target) + deps = node.get_implicit_deps(env, s, s.path) assert deps == [d1, d2, e, f], list(map(str, deps)) # Scanner method can short-circuit recursing entirely s.recurse_nodes = lambda nodes: [] - deps = node.get_implicit_deps(env, s, target) + deps = node.get_implicit_deps(env, s, s.path) assert deps == [d1, d2], list(map(str, deps)) def test_get_env_scanner(self): diff --git a/test/Fortran/FORTRANSUFFIXES.py b/test/Fortran/FORTRANSUFFIXES.py index 583b71b..9673e6f 100644 --- a/test/Fortran/FORTRANSUFFIXES.py +++ b/test/Fortran/FORTRANSUFFIXES.py @@ -56,51 +56,51 @@ env = Environment(FORTRANPATH = ['.'], env.Append(FORTRANSUFFIXES = ['.x']) env.Object(target = 'test1', source = 'test1.f') env.InstallAs('test1_f', 'test1.f') -env.InstallAs('test1_h', 'test1.h') env.InstallAs('test1_x', 'test1.x') +env.InstallAs('test2_f', 'test2.f') """ % locals()) test.write('test1.f', """\ test1.f 1 - INCLUDE 'test1.h' + INCLUDE 'test2.f' INCLUDE 'test1.x' """) -test.write('test1.h', """\ - test1.h 1 - INCLUDE 'foo.h' +test.write('test2.f', """\ + test2.f 1 + INCLUDE 'foo.f' """) test.write('test1.x', """\ test1.x 1 - INCLUDE 'foo.h' + INCLUDE 'foo.f' """) -test.write('foo.h', """\ - foo.h 1 +test.write('foo.f', """\ + foo.f 1 """) expect = test.wrap_stdout("""\ %(_python_)s myfc.py test1.o test1.f Install file: "test1.f" as "test1_f" -Install file: "test1.h" as "test1_h" Install file: "test1.x" as "test1_x" +Install file: "test2.f" as "test2_f" """ % locals()) test.run(arguments='.', stdout=expect) test.must_match('test1.o', """\ test1.f 1 - test1.h 1 - foo.h 1 + test2.f 1 + foo.f 1 test1.x 1 - foo.h 1 + foo.f 1 """) test.up_to_date(arguments='.') -test.write('foo.h', """\ - foo.h 2 +test.write('foo.f', """\ + foo.f 2 """) expect = test.wrap_stdout("""\ @@ -111,17 +111,17 @@ test.run(arguments='.', stdout=expect) test.must_match('test1.o', """\ test1.f 1 - test1.h 1 - foo.h 2 + test2.f 1 + foo.f 2 test1.x 1 - foo.h 2 + foo.f 2 """) test.up_to_date(arguments='.') test.write('test1.x', """\ test1.x 2 - INCLUDE 'foo.h' + INCLUDE 'foo.f' """) expect = test.wrap_stdout("""\ @@ -133,32 +133,32 @@ test.run(arguments='.', stdout=expect) test.must_match('test1.o', """\ test1.f 1 - test1.h 1 - foo.h 2 + test2.f 1 + foo.f 2 test1.x 2 - foo.h 2 + foo.f 2 """) test.up_to_date(arguments='.') -test.write('test1.h', """\ - test1.h 2 - INCLUDE 'foo.h' +test.write('test2.f', """\ + test2.f 2 + INCLUDE 'foo.f' """) expect = test.wrap_stdout("""\ %(_python_)s myfc.py test1.o test1.f -Install file: "test1.h" as "test1_h" +Install file: "test2.f" as "test2_f" """ % locals()) test.run(arguments='.', stdout=expect) test.must_match('test1.o', """\ test1.f 1 - test1.h 2 - foo.h 2 + test2.f 2 + foo.f 2 test1.x 2 - foo.h 2 + foo.f 2 """) test.up_to_date(arguments='.') diff --git a/test/QT/manual.py b/test/QT/manual.py index ff38f32..d911fb3 100644 --- a/test/QT/manual.py +++ b/test/QT/manual.py @@ -46,13 +46,15 @@ sources = ['aaa.cpp', 'bbb.cpp', 'ddd.cpp', 'eee.cpp', 'main.cpp'] # normal invocation sources.append(env.Moc('include/aaa.h')) -env.Moc('bbb.cpp') +moc = env.Moc('bbb.cpp') +env.Ignore( moc, moc ) sources.extend(env.Uic('ui/ccc.ui')[1:]) # manual target specification sources.append(env.Moc('moc-ddd.cpp', 'include/ddd.h', QT_MOCHPREFIX='')) # Watch out ! -env.Moc('moc_eee.cpp', 'eee.cpp') +moc = env.Moc('moc_eee.cpp', 'eee.cpp') +env.Ignore( moc, moc ) sources.extend(env.Uic(['include/uic_fff.hpp', 'fff.cpp', 'fff.moc.cpp'], 'ui/fff.ui')[1:]) diff --git a/test/Scanner/exception.py b/test/Scanner/exception.py index 1a14152..de0a795 100644 --- a/test/Scanner/exception.py +++ b/test/Scanner/exception.py @@ -83,23 +83,23 @@ env.Cat('bar', bar_in) test.write('foo.k', """foo.k 1 line 1 -include xxx -include yyy +include xxx.k +include yyy.k foo.k 1 line 4 """) test.write('bar.in', -"""include yyy +"""include yyy.k bar.in 1 line 2 bar.in 1 line 3 -include zzz +include zzz.k """) -test.write('xxx', "xxx 1\n") +test.write('xxx.k', "xxx 1\n") -test.write('yyy', "exception yyy 1\n") +test.write('yyy.k', "exception yyy 1\n") -test.write('zzz', "zzz 1\n") +test.write('zzz.k', "zzz 1\n") test.run(arguments = '.', status = 2, diff --git a/test/Scanner/generated.py b/test/Scanner/generated.py index 845111c..b41c7c8 100644 --- a/test/Scanner/generated.py +++ b/test/Scanner/generated.py @@ -338,6 +338,7 @@ class CScannerCounter(object): import SCons.Tool MyCScanner = CScannerCounter(SCons.Script.CScanner) SCons.Tool.SourceFileScanner.add_scanner('.c', MyCScanner) +SCons.Tool.SourceFileScanner.add_scanner('.h', MyCScanner) env = Environment(CPPPATH = ".") l = env.StaticLibrary("g", Split("libg_1.c libg_2.c libg_3.c")) -- cgit v0.12 From 6a63deeace54613c91004535bc3d593bb161430e Mon Sep 17 00:00:00 2001 From: anatoly techtonik Date: Mon, 18 May 2015 16:56:04 +0300 Subject: Fix --tree=all print when build tree contains non-ascii Node representation (PR #235) --- src/CHANGES.txt | 2 ++ src/engine/SCons/Util.py | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index ef4e016..42108de 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -34,6 +34,8 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER - Show --config choices if no argument is specified (PR #202). - Fixed build crash when XML toolchain isn't installed, and activated compression for ZIP archives. + - Fixed --tree=all print when build tree contains non-ascii + Node representation (PR #235). From Alexandre Feblot: - Fix for VersionedSharedLibrary under 'sunos' platform. diff --git a/src/engine/SCons/Util.py b/src/engine/SCons/Util.py index 822d524..6dd64ec 100644 --- a/src/engine/SCons/Util.py +++ b/src/engine/SCons/Util.py @@ -264,10 +264,10 @@ def print_tree(root, child_func, prune=0, showtags=0, margin=[0], visited={}): children = child_func(root) if prune and rname in visited and children: - sys.stdout.write(''.join(tags + margins + ['+-[', rname, ']']) + u'\n') + sys.stdout.write(''.join(tags + margins + ['+-[', rname, ']']) + '\n') return - sys.stdout.write(''.join(tags + margins + ['+-', rname]) + u'\n') + sys.stdout.write(''.join(tags + margins + ['+-', rname]) + '\n') visited[rname] = 1 -- cgit v0.12 From f0a8c4f4aea84a6a49ff087b87cc2a6c4a12f148 Mon Sep 17 00:00:00 2001 From: Dirk Baechle Date: Wed, 20 May 2015 21:59:19 +0200 Subject: - updated generated documentation, prior to release of 2.3.5 --- doc/generated/examples/troubleshoot_Dump_2.xml | 4 ++-- doc/generated/functions.gen | 15 +++++++++++++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/doc/generated/examples/troubleshoot_Dump_2.xml b/doc/generated/examples/troubleshoot_Dump_2.xml index 17c9de5..d6fa404 100644 --- a/doc/generated/examples/troubleshoot_Dump_2.xml +++ b/doc/generated/examples/troubleshoot_Dump_2.xml @@ -34,7 +34,7 @@ scons: Reading SConscript files ... '.SPP', '.sx'], 'CXX': '$CC', - 'CXXCOM': '${TEMPFILE("$CXX $_MSVC_OUTPUT_FLAG /c $CHANGED_SOURCES $CXXFLAGS $CCFLAGS $_CCCOMCOM")}', + 'CXXCOM': '${TEMPFILE("$CXX $_MSVC_OUTPUT_FLAG /c $CHANGED_SOURCES $CXXFLAGS $CCFLAGS $_CCCOMCOM","$CXXCOMSTR")}', 'CXXFILESUFFIX': '.cc', 'CXXFLAGS': ['$(', '/TP', '$)'], 'DSUFFIXES': ['.d'], @@ -77,7 +77,7 @@ scons: Reading SConscript files ... 'SHCCFLAGS': ['$CCFLAGS'], 'SHCFLAGS': ['$CFLAGS'], 'SHCXX': '$CXX', - 'SHCXXCOM': '${TEMPFILE("$SHCXX $_MSVC_OUTPUT_FLAG /c $CHANGED_SOURCES $SHCXXFLAGS $SHCCFLAGS $_CCCOMCOM")}', + 'SHCXXCOM': '${TEMPFILE("$SHCXX $_MSVC_OUTPUT_FLAG /c $CHANGED_SOURCES $SHCXXFLAGS $SHCCFLAGS $_CCCOMCOM","$SHCXXCOMSTR")}', 'SHCXXFLAGS': ['$CXXFLAGS'], 'SHELL': None, 'SHLIBPREFIX': '', diff --git a/doc/generated/functions.gen b/doc/generated/functions.gen index 62a9ab3..3ad36e5 100644 --- a/doc/generated/functions.gen +++ b/doc/generated/functions.gen @@ -2426,10 +2426,10 @@ option. - Glob(pattern, [ondisk, source, strings]) + Glob(pattern, [ondisk, source, strings, exclude]) - env.Glob(pattern, [ondisk, source, strings]) + env.Glob(pattern, [ondisk, source, strings, exclude]) @@ -2543,12 +2543,23 @@ directory.) +The +exclude +argument may be set to a pattern or a list of patterns +(following the same Unix shell semantics) +which must be filtered out of returned elements. +Elements matching a least one pattern of +this list will be excluded. + + + Examples: Program('foo', Glob('*.c')) Zip('/tmp/everything', Glob('.??*') + Glob('*')) +sources = Glob('*.cpp', exclude=['os_*_specific_*.cpp']) + Glob('os_%s_specific_*.cpp'%currentOS) -- cgit v0.12 From 7321f4be216986c316891d5280d4811a6257a952 Mon Sep 17 00:00:00 2001 From: Andrew Featherstone Date: Mon, 25 May 2015 13:14:59 +0100 Subject: Issue 2984: Corrected escaping of less-than and greater-than symbols. --- doc/generated/examples/troubleshoot_Dump_1.xml | 26 ++++++++++---------- doc/generated/examples/troubleshoot_Dump_2.xml | 34 +++++++++++++------------- doc/user/repositories.xml | 2 +- doc/user/sconf.xml | 6 ++--- 4 files changed, 34 insertions(+), 34 deletions(-) diff --git a/doc/generated/examples/troubleshoot_Dump_1.xml b/doc/generated/examples/troubleshoot_Dump_1.xml index 248e85c..bbabbd4 100644 --- a/doc/generated/examples/troubleshoot_Dump_1.xml +++ b/doc/generated/examples/troubleshoot_Dump_1.xml @@ -1,7 +1,7 @@ % scons scons: Reading SConscript files ... -{ 'BUILDERS': {'_InternalInstall': <function InstallBuilderWrapper at 0x700000&gt;, '_InternalInstallVersionedLib': <function InstallVersionedBuilderWrapper at 0x700000&gt;, '_InternalInstallAs': <function InstallAsBuilderWrapper at 0x700000&gt;}, +{ 'BUILDERS': {'_InternalInstall': <function InstallBuilderWrapper at 0x700000>, '_InternalInstallVersionedLib': <function InstallVersionedBuilderWrapper at 0x700000>, '_InternalInstallAs': <function InstallAsBuilderWrapper at 0x700000>}, 'CONFIGUREDIR': '#/.sconf_temp', 'CONFIGURELOG': '#/config.log', 'CPPSUFFIXES': [ '.c', @@ -25,16 +25,16 @@ scons: Reading SConscript files ... '.SPP', '.sx'], 'DSUFFIXES': ['.d'], - 'Dir': <SCons.Defaults.Variable_Method_Caller object at 0x700000&gt;, - 'Dirs': <SCons.Defaults.Variable_Method_Caller object at 0x700000&gt;, + 'Dir': <SCons.Defaults.Variable_Method_Caller object at 0x700000>, + 'Dirs': <SCons.Defaults.Variable_Method_Caller object at 0x700000>, 'ENV': { 'PATH': '/usr/local/bin:/opt/bin:/bin:/usr/bin'}, - 'ESCAPE': <function escape at 0x700000&gt;, - 'File': <SCons.Defaults.Variable_Method_Caller object at 0x700000&gt;, + 'ESCAPE': <function escape at 0x700000>, + 'File': <SCons.Defaults.Variable_Method_Caller object at 0x700000>, 'HOST_ARCH': None, 'HOST_OS': None, 'IDLSUFFIXES': ['.idl', '.IDL'], - 'INSTALL': <function copyFunc at 0x700000&gt;, - 'INSTALLVERSIONEDLIB': <function copyFuncVersionedLib at 0x700000&gt;, + 'INSTALL': <function copyFunc at 0x700000>, + 'INSTALLVERSIONEDLIB': <function copyFuncVersionedLib at 0x700000>, 'LIBPREFIX': 'lib', 'LIBPREFIXES': ['$LIBPREFIX'], 'LIBSUFFIX': '.a', @@ -45,15 +45,15 @@ scons: Reading SConscript files ... 'PLATFORM': 'posix', 'PROGPREFIX': '', 'PROGSUFFIX': '', - 'PSPAWN': <function piped_env_spawn at 0x700000&gt;, - 'RDirs': <SCons.Defaults.Variable_Method_Caller object at 0x700000&gt;, + 'PSPAWN': <function piped_env_spawn at 0x700000>, + 'RDirs': <SCons.Defaults.Variable_Method_Caller object at 0x700000>, 'SCANNERS': [], 'SHELL': 'sh', 'SHLIBPREFIX': '$LIBPREFIX', 'SHLIBSUFFIX': '.so', 'SHOBJPREFIX': '$OBJPREFIX', 'SHOBJSUFFIX': '$OBJSUFFIX', - 'SPAWN': <function subprocess_spawn at 0x700000&gt;, + 'SPAWN': <function subprocess_spawn at 0x700000>, 'TARGET_ARCH': None, 'TARGET_OS': None, 'TEMPFILE': <class 'SCons.Platform.TempFileMunge'>, @@ -65,9 +65,9 @@ scons: Reading SConscript files ... '_LIBFLAGS': '${_concat(LIBLINKPREFIX, LIBS, LIBLINKSUFFIX, __env__)}', '__DRPATH': '$_DRPATH', '__RPATH': '$_RPATH', - '_concat': <function _concat at 0x700000&gt;, - '_defines': <function _defines at 0x700000&gt;, - '_stripixes': <function _stripixes at 0x700000&gt;} + '_concat': <function _concat at 0x700000>, + '_defines': <function _defines at 0x700000>, + '_stripixes': <function _stripixes at 0x700000>} scons: done reading SConscript files. scons: Building targets ... scons: `.' is up to date. diff --git a/doc/generated/examples/troubleshoot_Dump_2.xml b/doc/generated/examples/troubleshoot_Dump_2.xml index d6fa404..d6baf5d 100644 --- a/doc/generated/examples/troubleshoot_Dump_2.xml +++ b/doc/generated/examples/troubleshoot_Dump_2.xml @@ -1,9 +1,9 @@ C:\>scons scons: Reading SConscript files ... -{ 'BUILDERS': {'_InternalInstallVersionedLib': <function InstallVersionedBuilderWrapper at 0x700000&gt;, '_InternalInstall': <function InstallBuilderWrapper at 0x700000&gt;, 'Object': <SCons.Builder.CompositeBuilder object at 0x700000&gt;, 'PCH': <SCons.Builder.BuilderBase object at 0x700000&gt;, 'RES': <SCons.Builder.BuilderBase object at 0x700000&gt;, 'SharedObject': <SCons.Builder.CompositeBuilder object at 0x700000&gt;, 'StaticObject': <SCons.Builder.CompositeBuilder object at 0x700000&gt;, '_InternalInstallAs': <function InstallAsBuilderWrapper at 0x700000&gt;}, +{ 'BUILDERS': {'_InternalInstallVersionedLib': <function InstallVersionedBuilderWrapper at 0x700000>, '_InternalInstall': <function InstallBuilderWrapper at 0x700000>, 'Object': <SCons.Builder.CompositeBuilder object at 0x700000>, 'PCH': <SCons.Builder.BuilderBase object at 0x700000>, 'RES': <SCons.Builder.BuilderBase object at 0x700000>, 'SharedObject': <SCons.Builder.CompositeBuilder object at 0x700000>, 'StaticObject': <SCons.Builder.CompositeBuilder object at 0x700000>, '_InternalInstallAs': <function InstallAsBuilderWrapper at 0x700000>}, 'CC': 'cl', - 'CCCOM': <SCons.Action.FunctionAction object at 0x700000&gt;, + 'CCCOM': <SCons.Action.FunctionAction object at 0x700000>, 'CCFLAGS': ['/nologo'], 'CCPCHFLAGS': ['${(PCH and "/Yu%s \\"/Fp%s\\""%(PCHSTOP or "",File(PCH))) or ""}'], 'CCPDBFLAGS': ['${(PDB and "/Z7") or ""}'], @@ -38,20 +38,20 @@ scons: Reading SConscript files ... 'CXXFILESUFFIX': '.cc', 'CXXFLAGS': ['$(', '/TP', '$)'], 'DSUFFIXES': ['.d'], - 'Dir': <SCons.Defaults.Variable_Method_Caller object at 0x700000&gt;, - 'Dirs': <SCons.Defaults.Variable_Method_Caller object at 0x700000&gt;, + 'Dir': <SCons.Defaults.Variable_Method_Caller object at 0x700000>, + 'Dirs': <SCons.Defaults.Variable_Method_Caller object at 0x700000>, 'ENV': { 'PATH': 'C:\\WINDOWS\\System32', 'PATHEXT': '.COM;.EXE;.BAT;.CMD', 'SystemRoot': 'C:\\WINDOWS'}, - 'ESCAPE': <function escape at 0x700000&gt;, - 'File': <SCons.Defaults.Variable_Method_Caller object at 0x700000&gt;, + 'ESCAPE': <function escape at 0x700000>, + 'File': <SCons.Defaults.Variable_Method_Caller object at 0x700000>, 'HOST_ARCH': '', 'HOST_OS': 'win32', 'IDLSUFFIXES': ['.idl', '.IDL'], 'INCPREFIX': '/I', 'INCSUFFIX': '', - 'INSTALL': <function copyFunc at 0x700000&gt;, - 'INSTALLVERSIONEDLIB': <function copyFuncVersionedLib at 0x700000&gt;, + 'INSTALL': <function copyFunc at 0x700000>, + 'INSTALLVERSIONEDLIB': <function copyFuncVersionedLib at 0x700000>, 'LIBPREFIX': '', 'LIBPREFIXES': ['$LIBPREFIX'], 'LIBSUFFIX': '.lib', @@ -65,15 +65,15 @@ scons: Reading SConscript files ... 'PLATFORM': 'win32', 'PROGPREFIX': '', 'PROGSUFFIX': '.exe', - 'PSPAWN': <function piped_spawn at 0x700000&gt;, + 'PSPAWN': <function piped_spawn at 0x700000>, 'RC': 'rc', - 'RCCOM': <SCons.Action.FunctionAction object at 0x700000&gt;, + 'RCCOM': <SCons.Action.FunctionAction object at 0x700000>, 'RCFLAGS': [], 'RCSUFFIXES': ['.rc', '.rc2'], - 'RDirs': <SCons.Defaults.Variable_Method_Caller object at 0x700000&gt;, + 'RDirs': <SCons.Defaults.Variable_Method_Caller object at 0x700000>, 'SCANNERS': [], 'SHCC': '$CC', - 'SHCCCOM': <SCons.Action.FunctionAction object at 0x700000&gt;, + 'SHCCCOM': <SCons.Action.FunctionAction object at 0x700000>, 'SHCCFLAGS': ['$CCFLAGS'], 'SHCFLAGS': ['$CFLAGS'], 'SHCXX': '$CXX', @@ -84,7 +84,7 @@ scons: Reading SConscript files ... 'SHLIBSUFFIX': '.dll', 'SHOBJPREFIX': '$OBJPREFIX', 'SHOBJSUFFIX': '$OBJSUFFIX', - 'SPAWN': <function spawn at 0x700000&gt;, + 'SPAWN': <function spawn at 0x700000>, 'STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME': 1, 'TARGET_ARCH': None, 'TARGET_OS': None, @@ -96,10 +96,10 @@ scons: Reading SConscript files ... '_CPPINCFLAGS': '$( ${_concat(INCPREFIX, CPPPATH, INCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)', '_LIBDIRFLAGS': '$( ${_concat(LIBDIRPREFIX, LIBPATH, LIBDIRSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)', '_LIBFLAGS': '${_concat(LIBLINKPREFIX, LIBS, LIBLINKSUFFIX, __env__)}', - '_MSVC_OUTPUT_FLAG': <function msvc_output_flag at 0x700000&gt;, - '_concat': <function _concat at 0x700000&gt;, - '_defines': <function _defines at 0x700000&gt;, - '_stripixes': <function _stripixes at 0x700000&gt;} + '_MSVC_OUTPUT_FLAG': <function msvc_output_flag at 0x700000>, + '_concat': <function _concat at 0x700000>, + '_defines': <function _defines at 0x700000>, + '_stripixes': <function _stripixes at 0x700000>} scons: done reading SConscript files. scons: Building targets ... scons: `.' is up to date. diff --git a/doc/user/repositories.xml b/doc/user/repositories.xml index 32a0b5b..c91188e 100644 --- a/doc/user/repositories.xml +++ b/doc/user/repositories.xml @@ -423,7 +423,7 @@ int main() { printf("Hello, world!\n"); } Change all occurrences of #include "file.h" - to #include &lt;file.h&gt;. + to #include <file.h>. Use of #include with angle brackets does not have the same behavior--the -I directories are searched first diff --git a/doc/user/sconf.xml b/doc/user/sconf.xml index 214569d..569ab1a 100644 --- a/doc/user/sconf.xml +++ b/doc/user/sconf.xml @@ -275,7 +275,7 @@ env = conf.Finish() env = Environment() conf = Configure(env) -if not conf.CheckType('off_t', '#include &lt;sys/types.h&gt;\n'): +if not conf.CheckType('off_t', '#include <sys/types.h>\n'): print 'Did not find off_t typedef, assuming int' conf.env.Append(CCFLAGS = '-Doff_t=int') env = conf.Finish() @@ -324,7 +324,7 @@ scons: `.' is up to date. mylib_test_source_file = """ -#include &lt;mylib.h&gt; +#include <mylib.h> int main(int argc, char **argv) { MyLibrary mylib(argc, argv); @@ -401,7 +401,7 @@ conf = Configure(env, custom_tests = {'CheckMyLibrary' : CheckMyLibrary}) mylib_test_source_file = """ -#include &lt;mylib.h&gt; +#include <mylib.h> int main(int argc, char **argv) { MyLibrary mylib(argc, argv); -- cgit v0.12 From cd88c2ae35ff11b6565dcb8c7b0a0c1985346f51 Mon Sep 17 00:00:00 2001 From: anatoly techtonik Date: Tue, 26 May 2015 18:50:30 +0300 Subject: Add test for UnicodeDecode failure --- test/option--tree.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/test/option--tree.py b/test/option--tree.py index a50433c..519ebe3 100644 --- a/test/option--tree.py +++ b/test/option--tree.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +# -*- coding: utf-8 -*- # # __COPYRIGHT__ # @@ -51,6 +52,20 @@ scons: warning: The --debug=tree option is deprecated; please use --tree=all ins """, status = 0, match=TestSCons.match_re_dotall) + +# Check that printing nodes won't fail with +# UnicodeDecodeError: 'ascii' codec ... ordinal not in range(128) +# https://bitbucket.org/scons/scons/pull-request/235 + +test.write('SConstruct', """\ +# -*- coding: utf-8 -*- + +Entry('русский юникод') +""") + +test.run(arguments = '-Q --tree=all') + + test.pass_test() # Local Variables: -- cgit v0.12 From d91a18d674dd282467a009707f2ef6c9c9f526e2 Mon Sep 17 00:00:00 2001 From: Andrew Featherstone Date: Wed, 27 May 2015 21:22:52 +0100 Subject: Reverting changes to generated output as requested in PR feedback. --- doc/generated/examples/troubleshoot_Dump_1.xml | 26 ++++++++++---------- doc/generated/examples/troubleshoot_Dump_2.xml | 34 +++++++++++++------------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/doc/generated/examples/troubleshoot_Dump_1.xml b/doc/generated/examples/troubleshoot_Dump_1.xml index bbabbd4..248e85c 100644 --- a/doc/generated/examples/troubleshoot_Dump_1.xml +++ b/doc/generated/examples/troubleshoot_Dump_1.xml @@ -1,7 +1,7 @@ % scons scons: Reading SConscript files ... -{ 'BUILDERS': {'_InternalInstall': <function InstallBuilderWrapper at 0x700000>, '_InternalInstallVersionedLib': <function InstallVersionedBuilderWrapper at 0x700000>, '_InternalInstallAs': <function InstallAsBuilderWrapper at 0x700000>}, +{ 'BUILDERS': {'_InternalInstall': <function InstallBuilderWrapper at 0x700000&gt;, '_InternalInstallVersionedLib': <function InstallVersionedBuilderWrapper at 0x700000&gt;, '_InternalInstallAs': <function InstallAsBuilderWrapper at 0x700000&gt;}, 'CONFIGUREDIR': '#/.sconf_temp', 'CONFIGURELOG': '#/config.log', 'CPPSUFFIXES': [ '.c', @@ -25,16 +25,16 @@ scons: Reading SConscript files ... '.SPP', '.sx'], 'DSUFFIXES': ['.d'], - 'Dir': <SCons.Defaults.Variable_Method_Caller object at 0x700000>, - 'Dirs': <SCons.Defaults.Variable_Method_Caller object at 0x700000>, + 'Dir': <SCons.Defaults.Variable_Method_Caller object at 0x700000&gt;, + 'Dirs': <SCons.Defaults.Variable_Method_Caller object at 0x700000&gt;, 'ENV': { 'PATH': '/usr/local/bin:/opt/bin:/bin:/usr/bin'}, - 'ESCAPE': <function escape at 0x700000>, - 'File': <SCons.Defaults.Variable_Method_Caller object at 0x700000>, + 'ESCAPE': <function escape at 0x700000&gt;, + 'File': <SCons.Defaults.Variable_Method_Caller object at 0x700000&gt;, 'HOST_ARCH': None, 'HOST_OS': None, 'IDLSUFFIXES': ['.idl', '.IDL'], - 'INSTALL': <function copyFunc at 0x700000>, - 'INSTALLVERSIONEDLIB': <function copyFuncVersionedLib at 0x700000>, + 'INSTALL': <function copyFunc at 0x700000&gt;, + 'INSTALLVERSIONEDLIB': <function copyFuncVersionedLib at 0x700000&gt;, 'LIBPREFIX': 'lib', 'LIBPREFIXES': ['$LIBPREFIX'], 'LIBSUFFIX': '.a', @@ -45,15 +45,15 @@ scons: Reading SConscript files ... 'PLATFORM': 'posix', 'PROGPREFIX': '', 'PROGSUFFIX': '', - 'PSPAWN': <function piped_env_spawn at 0x700000>, - 'RDirs': <SCons.Defaults.Variable_Method_Caller object at 0x700000>, + 'PSPAWN': <function piped_env_spawn at 0x700000&gt;, + 'RDirs': <SCons.Defaults.Variable_Method_Caller object at 0x700000&gt;, 'SCANNERS': [], 'SHELL': 'sh', 'SHLIBPREFIX': '$LIBPREFIX', 'SHLIBSUFFIX': '.so', 'SHOBJPREFIX': '$OBJPREFIX', 'SHOBJSUFFIX': '$OBJSUFFIX', - 'SPAWN': <function subprocess_spawn at 0x700000>, + 'SPAWN': <function subprocess_spawn at 0x700000&gt;, 'TARGET_ARCH': None, 'TARGET_OS': None, 'TEMPFILE': <class 'SCons.Platform.TempFileMunge'>, @@ -65,9 +65,9 @@ scons: Reading SConscript files ... '_LIBFLAGS': '${_concat(LIBLINKPREFIX, LIBS, LIBLINKSUFFIX, __env__)}', '__DRPATH': '$_DRPATH', '__RPATH': '$_RPATH', - '_concat': <function _concat at 0x700000>, - '_defines': <function _defines at 0x700000>, - '_stripixes': <function _stripixes at 0x700000>} + '_concat': <function _concat at 0x700000&gt;, + '_defines': <function _defines at 0x700000&gt;, + '_stripixes': <function _stripixes at 0x700000&gt;} scons: done reading SConscript files. scons: Building targets ... scons: `.' is up to date. diff --git a/doc/generated/examples/troubleshoot_Dump_2.xml b/doc/generated/examples/troubleshoot_Dump_2.xml index d6baf5d..d6fa404 100644 --- a/doc/generated/examples/troubleshoot_Dump_2.xml +++ b/doc/generated/examples/troubleshoot_Dump_2.xml @@ -1,9 +1,9 @@ C:\>scons scons: Reading SConscript files ... -{ 'BUILDERS': {'_InternalInstallVersionedLib': <function InstallVersionedBuilderWrapper at 0x700000>, '_InternalInstall': <function InstallBuilderWrapper at 0x700000>, 'Object': <SCons.Builder.CompositeBuilder object at 0x700000>, 'PCH': <SCons.Builder.BuilderBase object at 0x700000>, 'RES': <SCons.Builder.BuilderBase object at 0x700000>, 'SharedObject': <SCons.Builder.CompositeBuilder object at 0x700000>, 'StaticObject': <SCons.Builder.CompositeBuilder object at 0x700000>, '_InternalInstallAs': <function InstallAsBuilderWrapper at 0x700000>}, +{ 'BUILDERS': {'_InternalInstallVersionedLib': <function InstallVersionedBuilderWrapper at 0x700000&gt;, '_InternalInstall': <function InstallBuilderWrapper at 0x700000&gt;, 'Object': <SCons.Builder.CompositeBuilder object at 0x700000&gt;, 'PCH': <SCons.Builder.BuilderBase object at 0x700000&gt;, 'RES': <SCons.Builder.BuilderBase object at 0x700000&gt;, 'SharedObject': <SCons.Builder.CompositeBuilder object at 0x700000&gt;, 'StaticObject': <SCons.Builder.CompositeBuilder object at 0x700000&gt;, '_InternalInstallAs': <function InstallAsBuilderWrapper at 0x700000&gt;}, 'CC': 'cl', - 'CCCOM': <SCons.Action.FunctionAction object at 0x700000>, + 'CCCOM': <SCons.Action.FunctionAction object at 0x700000&gt;, 'CCFLAGS': ['/nologo'], 'CCPCHFLAGS': ['${(PCH and "/Yu%s \\"/Fp%s\\""%(PCHSTOP or "",File(PCH))) or ""}'], 'CCPDBFLAGS': ['${(PDB and "/Z7") or ""}'], @@ -38,20 +38,20 @@ scons: Reading SConscript files ... 'CXXFILESUFFIX': '.cc', 'CXXFLAGS': ['$(', '/TP', '$)'], 'DSUFFIXES': ['.d'], - 'Dir': <SCons.Defaults.Variable_Method_Caller object at 0x700000>, - 'Dirs': <SCons.Defaults.Variable_Method_Caller object at 0x700000>, + 'Dir': <SCons.Defaults.Variable_Method_Caller object at 0x700000&gt;, + 'Dirs': <SCons.Defaults.Variable_Method_Caller object at 0x700000&gt;, 'ENV': { 'PATH': 'C:\\WINDOWS\\System32', 'PATHEXT': '.COM;.EXE;.BAT;.CMD', 'SystemRoot': 'C:\\WINDOWS'}, - 'ESCAPE': <function escape at 0x700000>, - 'File': <SCons.Defaults.Variable_Method_Caller object at 0x700000>, + 'ESCAPE': <function escape at 0x700000&gt;, + 'File': <SCons.Defaults.Variable_Method_Caller object at 0x700000&gt;, 'HOST_ARCH': '', 'HOST_OS': 'win32', 'IDLSUFFIXES': ['.idl', '.IDL'], 'INCPREFIX': '/I', 'INCSUFFIX': '', - 'INSTALL': <function copyFunc at 0x700000>, - 'INSTALLVERSIONEDLIB': <function copyFuncVersionedLib at 0x700000>, + 'INSTALL': <function copyFunc at 0x700000&gt;, + 'INSTALLVERSIONEDLIB': <function copyFuncVersionedLib at 0x700000&gt;, 'LIBPREFIX': '', 'LIBPREFIXES': ['$LIBPREFIX'], 'LIBSUFFIX': '.lib', @@ -65,15 +65,15 @@ scons: Reading SConscript files ... 'PLATFORM': 'win32', 'PROGPREFIX': '', 'PROGSUFFIX': '.exe', - 'PSPAWN': <function piped_spawn at 0x700000>, + 'PSPAWN': <function piped_spawn at 0x700000&gt;, 'RC': 'rc', - 'RCCOM': <SCons.Action.FunctionAction object at 0x700000>, + 'RCCOM': <SCons.Action.FunctionAction object at 0x700000&gt;, 'RCFLAGS': [], 'RCSUFFIXES': ['.rc', '.rc2'], - 'RDirs': <SCons.Defaults.Variable_Method_Caller object at 0x700000>, + 'RDirs': <SCons.Defaults.Variable_Method_Caller object at 0x700000&gt;, 'SCANNERS': [], 'SHCC': '$CC', - 'SHCCCOM': <SCons.Action.FunctionAction object at 0x700000>, + 'SHCCCOM': <SCons.Action.FunctionAction object at 0x700000&gt;, 'SHCCFLAGS': ['$CCFLAGS'], 'SHCFLAGS': ['$CFLAGS'], 'SHCXX': '$CXX', @@ -84,7 +84,7 @@ scons: Reading SConscript files ... 'SHLIBSUFFIX': '.dll', 'SHOBJPREFIX': '$OBJPREFIX', 'SHOBJSUFFIX': '$OBJSUFFIX', - 'SPAWN': <function spawn at 0x700000>, + 'SPAWN': <function spawn at 0x700000&gt;, 'STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME': 1, 'TARGET_ARCH': None, 'TARGET_OS': None, @@ -96,10 +96,10 @@ scons: Reading SConscript files ... '_CPPINCFLAGS': '$( ${_concat(INCPREFIX, CPPPATH, INCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)', '_LIBDIRFLAGS': '$( ${_concat(LIBDIRPREFIX, LIBPATH, LIBDIRSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)', '_LIBFLAGS': '${_concat(LIBLINKPREFIX, LIBS, LIBLINKSUFFIX, __env__)}', - '_MSVC_OUTPUT_FLAG': <function msvc_output_flag at 0x700000>, - '_concat': <function _concat at 0x700000>, - '_defines': <function _defines at 0x700000>, - '_stripixes': <function _stripixes at 0x700000>} + '_MSVC_OUTPUT_FLAG': <function msvc_output_flag at 0x700000&gt;, + '_concat': <function _concat at 0x700000&gt;, + '_defines': <function _defines at 0x700000&gt;, + '_stripixes': <function _stripixes at 0x700000&gt;} scons: done reading SConscript files. scons: Building targets ... scons: `.' is up to date. -- cgit v0.12 From 7a6c84894f9251a6c8751f18eaec50993647afa9 Mon Sep 17 00:00:00 2001 From: Dirk Baechle Date: Tue, 2 Jun 2015 13:21:23 +0200 Subject: Fixed license of SVG titlepage files, resolves #2985. This is required in the Debian packaging context, such that the images allow for commercial use too. See https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=787356 for the original bug description. --- doc/design/titlepage/SConsBuildBricks_path.svg | 22 ++++++++++------------ doc/man/titlepage/SConsBuildBricks_path.svg | 22 ++++++++++------------ doc/reference/titlepage/SConsBuildBricks_path.svg | 22 ++++++++++------------ doc/user/titlepage/SConsBuildBricks_path.svg | 22 ++++++++++------------ src/CHANGES.txt | 2 ++ 5 files changed, 42 insertions(+), 48 deletions(-) diff --git a/doc/design/titlepage/SConsBuildBricks_path.svg b/doc/design/titlepage/SConsBuildBricks_path.svg index ed0c60d..0d7f63e 100644 --- a/doc/design/titlepage/SConsBuildBricks_path.svg +++ b/doc/design/titlepage/SConsBuildBricks_path.svg @@ -14,9 +14,9 @@ height="80.330002" id="svg2" sodipodi:version="0.32" - inkscape:version="0.48.1 r9760" + inkscape:version="0.48.4 r9939" version="1.0" - sodipodi:docname="SConsBuildBricks.svg" + sodipodi:docname="SConsBuildBricks_path.svg" inkscape:export-filename="Constructs-using-SCons.png" inkscape:export-xdpi="100" inkscape:export-ydpi="100"> @@ -77,24 +77,22 @@ + rdf:resource="http://creativecommons.org/licenses/by-sa/3.0/" /> + rdf:about="http://creativecommons.org/licenses/by-sa/3.0/"> + rdf:resource="http://creativecommons.org/ns#Reproduction" /> + rdf:resource="http://creativecommons.org/ns#Distribution" /> + rdf:resource="http://creativecommons.org/ns#Notice" /> - + rdf:resource="http://creativecommons.org/ns#Attribution" /> + rdf:resource="http://creativecommons.org/ns#DerivativeWorks" /> + rdf:resource="http://creativecommons.org/ns#ShareAlike" /> diff --git a/doc/man/titlepage/SConsBuildBricks_path.svg b/doc/man/titlepage/SConsBuildBricks_path.svg index ed0c60d..0d7f63e 100644 --- a/doc/man/titlepage/SConsBuildBricks_path.svg +++ b/doc/man/titlepage/SConsBuildBricks_path.svg @@ -14,9 +14,9 @@ height="80.330002" id="svg2" sodipodi:version="0.32" - inkscape:version="0.48.1 r9760" + inkscape:version="0.48.4 r9939" version="1.0" - sodipodi:docname="SConsBuildBricks.svg" + sodipodi:docname="SConsBuildBricks_path.svg" inkscape:export-filename="Constructs-using-SCons.png" inkscape:export-xdpi="100" inkscape:export-ydpi="100"> @@ -77,24 +77,22 @@ + rdf:resource="http://creativecommons.org/licenses/by-sa/3.0/" /> + rdf:about="http://creativecommons.org/licenses/by-sa/3.0/"> + rdf:resource="http://creativecommons.org/ns#Reproduction" /> + rdf:resource="http://creativecommons.org/ns#Distribution" /> + rdf:resource="http://creativecommons.org/ns#Notice" /> - + rdf:resource="http://creativecommons.org/ns#Attribution" /> + rdf:resource="http://creativecommons.org/ns#DerivativeWorks" /> + rdf:resource="http://creativecommons.org/ns#ShareAlike" /> diff --git a/doc/reference/titlepage/SConsBuildBricks_path.svg b/doc/reference/titlepage/SConsBuildBricks_path.svg index ed0c60d..0d7f63e 100644 --- a/doc/reference/titlepage/SConsBuildBricks_path.svg +++ b/doc/reference/titlepage/SConsBuildBricks_path.svg @@ -14,9 +14,9 @@ height="80.330002" id="svg2" sodipodi:version="0.32" - inkscape:version="0.48.1 r9760" + inkscape:version="0.48.4 r9939" version="1.0" - sodipodi:docname="SConsBuildBricks.svg" + sodipodi:docname="SConsBuildBricks_path.svg" inkscape:export-filename="Constructs-using-SCons.png" inkscape:export-xdpi="100" inkscape:export-ydpi="100"> @@ -77,24 +77,22 @@ + rdf:resource="http://creativecommons.org/licenses/by-sa/3.0/" /> + rdf:about="http://creativecommons.org/licenses/by-sa/3.0/"> + rdf:resource="http://creativecommons.org/ns#Reproduction" /> + rdf:resource="http://creativecommons.org/ns#Distribution" /> + rdf:resource="http://creativecommons.org/ns#Notice" /> - + rdf:resource="http://creativecommons.org/ns#Attribution" /> + rdf:resource="http://creativecommons.org/ns#DerivativeWorks" /> + rdf:resource="http://creativecommons.org/ns#ShareAlike" /> diff --git a/doc/user/titlepage/SConsBuildBricks_path.svg b/doc/user/titlepage/SConsBuildBricks_path.svg index ed0c60d..0d7f63e 100644 --- a/doc/user/titlepage/SConsBuildBricks_path.svg +++ b/doc/user/titlepage/SConsBuildBricks_path.svg @@ -14,9 +14,9 @@ height="80.330002" id="svg2" sodipodi:version="0.32" - inkscape:version="0.48.1 r9760" + inkscape:version="0.48.4 r9939" version="1.0" - sodipodi:docname="SConsBuildBricks.svg" + sodipodi:docname="SConsBuildBricks_path.svg" inkscape:export-filename="Constructs-using-SCons.png" inkscape:export-xdpi="100" inkscape:export-ydpi="100"> @@ -77,24 +77,22 @@ + rdf:resource="http://creativecommons.org/licenses/by-sa/3.0/" /> + rdf:about="http://creativecommons.org/licenses/by-sa/3.0/"> + rdf:resource="http://creativecommons.org/ns#Reproduction" /> + rdf:resource="http://creativecommons.org/ns#Distribution" /> + rdf:resource="http://creativecommons.org/ns#Notice" /> - + rdf:resource="http://creativecommons.org/ns#Attribution" /> + rdf:resource="http://creativecommons.org/ns#DerivativeWorks" /> + rdf:resource="http://creativecommons.org/ns#ShareAlike" /> diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 42108de..2a2c21f 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -25,6 +25,8 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER From Dirk Baechle: - Added new method rentry_exists_on_disk to Node.FS (PR #193). + - Fixed license of SVG titlepage files in the context of Debian + packaging, such that they allow for commercial use too (#2985). From Russel Winder: - Fixed several D tests under the different OS. -- cgit v0.12 From 29da60b30f4a33e836594b6249a8d1508d3d4ebc Mon Sep 17 00:00:00 2001 From: William Deegan Date: Sun, 14 Jun 2015 16:33:24 -0700 Subject: rolling back unicode --tree=all patch --- test/option--tree.py | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/test/option--tree.py b/test/option--tree.py index 519ebe3..a50433c 100644 --- a/test/option--tree.py +++ b/test/option--tree.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- # # __COPYRIGHT__ # @@ -52,20 +51,6 @@ scons: warning: The --debug=tree option is deprecated; please use --tree=all ins """, status = 0, match=TestSCons.match_re_dotall) - -# Check that printing nodes won't fail with -# UnicodeDecodeError: 'ascii' codec ... ordinal not in range(128) -# https://bitbucket.org/scons/scons/pull-request/235 - -test.write('SConstruct', """\ -# -*- coding: utf-8 -*- - -Entry('русский юникод') -""") - -test.run(arguments = '-Q --tree=all') - - test.pass_test() # Local Variables: -- cgit v0.12 From 9d12770921fa229ce4716f4a210a467582f0920d Mon Sep 17 00:00:00 2001 From: William Deegan Date: Sun, 14 Jun 2015 16:33:38 -0700 Subject: rolling back unicode --tree=all patch --- src/CHANGES.txt | 2 -- src/engine/SCons/Util.py | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 42108de..ef4e016 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -34,8 +34,6 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER - Show --config choices if no argument is specified (PR #202). - Fixed build crash when XML toolchain isn't installed, and activated compression for ZIP archives. - - Fixed --tree=all print when build tree contains non-ascii - Node representation (PR #235). From Alexandre Feblot: - Fix for VersionedSharedLibrary under 'sunos' platform. diff --git a/src/engine/SCons/Util.py b/src/engine/SCons/Util.py index 6dd64ec..822d524 100644 --- a/src/engine/SCons/Util.py +++ b/src/engine/SCons/Util.py @@ -264,10 +264,10 @@ def print_tree(root, child_func, prune=0, showtags=0, margin=[0], visited={}): children = child_func(root) if prune and rname in visited and children: - sys.stdout.write(''.join(tags + margins + ['+-[', rname, ']']) + '\n') + sys.stdout.write(''.join(tags + margins + ['+-[', rname, ']']) + u'\n') return - sys.stdout.write(''.join(tags + margins + ['+-', rname]) + '\n') + sys.stdout.write(''.join(tags + margins + ['+-', rname]) + u'\n') visited[rname] = 1 -- cgit v0.12 From 3fac0a432e7d5f37678b27d0acdcf9024b2ff9a9 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 15 Jun 2015 10:59:50 -0700 Subject: Release 2.3.5.final.0 Important changes -- Extended docs for InstallVersionedLib/SharedLibrary, -- Fixed symlink support (PR #227, #2395). -- Fixed incomplete LIBS flattening and substitution in Program scanner(PR #205, #2954). -- Added new method rentry_exists_on_disk to Node.FS (PR #193). -- Add support for f08 file extensions for Fortran 2008 code. -- Show --config choices if no argument is specified (PR #202). -- Fixed build crash when XML toolchain isn't installed, and activated compression for ZIP archives. -- Fix for VersionedSharedLibrary under 'sunos' platform. -- Fixed dll link with precompiled headers on MSVC 2012 -- Added an 'exclude' parameter to Glob() -- Support for multiple cmdargs (one per variant) in VS project files. -- Various improvements for TempFileMunge class. -- Added an implementation for Visual Studio users files (PR #209). -- Added support for the 'PlatformToolset' tag in VS project files (#2978). -- Added support for '-isystem' to ParseFlags. --- QMTest/TestSCons.py | 2 +- README.rst | 16 ++++++++-------- ReleaseConfig | 4 ++-- SConstruct | 6 +++--- doc/user/main.xml | 4 ++-- src/Announce.txt | 22 +++++++++++++++++++++- src/CHANGES.txt | 2 +- src/RELEASE.txt | 2 +- 8 files changed, 39 insertions(+), 19 deletions(-) diff --git a/QMTest/TestSCons.py b/QMTest/TestSCons.py index 923e319..bf8f9fe 100644 --- a/QMTest/TestSCons.py +++ b/QMTest/TestSCons.py @@ -34,7 +34,7 @@ from TestCmd import PIPE # here provides some independent verification that what we packaged # conforms to what we expect. -default_version = '2.3.4' +default_version = '2.3.5.final.0' python_version_unsupported = (2, 3, 0) python_version_deprecated = (2, 7, 0) diff --git a/README.rst b/README.rst index 599abaf..fa832a0 100644 --- a/README.rst +++ b/README.rst @@ -480,14 +480,14 @@ following packages will be built:: build/dist/scons-2.3.3-1.noarch.rpm build/dist/scons-2.3.3-1.src.rpm build/dist/scons-2.3.3.linux-i686.tar.gz - build/dist/scons-2.3.4.tar.gz - build/dist/scons-2.3.4.win32.exe - build/dist/scons-2.3.4.zip - build/dist/scons-doc-2.3.4.tar.gz - build/dist/scons-local-2.3.4.tar.gz - build/dist/scons-local-2.3.4.zip - build/dist/scons-src-2.3.4.tar.gz - build/dist/scons-src-2.3.4.zip + build/dist/scons-2.3.5.final.0.tar.gz + build/dist/scons-2.3.5.final.0.win32.exe + build/dist/scons-2.3.5.final.0.zip + build/dist/scons-doc-2.3.5.final.0.tar.gz + build/dist/scons-local-2.3.5.final.0.tar.gz + build/dist/scons-local-2.3.5.final.0.zip + build/dist/scons-src-2.3.5.final.0.tar.gz + build/dist/scons-src-2.3.5.final.0.zip build/dist/scons_2.3.3-1_all.deb The SConstruct file is supposed to be smart enough to avoid trying to build diff --git a/ReleaseConfig b/ReleaseConfig index 0735012..70af3e4 100644 --- a/ReleaseConfig +++ b/ReleaseConfig @@ -32,7 +32,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" # 'final', the patchlevel is set to the release date. This value is # mandatory and must be present in this file. #version_tuple = (2, 2, 0, 'final', 0) -version_tuple = (2, 3, 5, 'alpha', 0) +version_tuple = (2, 3, 5, 'final', 0) # Python versions prior to unsupported_python_version cause a fatal error # when that version is used. Python versions prior to deprecate_python_version @@ -51,7 +51,7 @@ deprecated_python_version = (2, 7, 0) #month_year = 'December 2012' # If copyright years is not given, the release year is used as the end. -copyright_years = '2001 - 2014' +copyright_years = '2001 - 2015' # Local Variables: # tab-width:4 diff --git a/SConstruct b/SConstruct index abf5fa8..f5a3e7f 100644 --- a/SConstruct +++ b/SConstruct @@ -3,10 +3,10 @@ # # See the README.rst file for an overview of how SCons is built and tested. -copyright_years = '2001 - 2014' +copyright_years = '2001 - 2015' # This gets inserted into the man pages to reflect the month of release. -month_year = 'September 2014' +month_year = 'June 2015' # # __COPYRIGHT__ @@ -43,7 +43,7 @@ import tempfile import bootstrap project = 'scons' -default_version = '2.3.4' +default_version = '2.3.5.final.0' copyright = "Copyright (c) %s The SCons Foundation" % copyright_years platform = distutils.util.get_platform() diff --git a/doc/user/main.xml b/doc/user/main.xml index a165777..d2c4c18 100644 --- a/doc/user/main.xml +++ b/doc/user/main.xml @@ -74,10 +74,10 @@ Steven Knight and the SCons Development Team - 2004 - 2014 + 2004 - 2015 - 2004 - 2014 + 2004 - 2015 The SCons Foundation diff --git a/src/Announce.txt b/src/Announce.txt index 7c6fdd5..882ab45 100644 --- a/src/Announce.txt +++ b/src/Announce.txt @@ -19,13 +19,33 @@ effectively, please go to http://scons.org/lists.php#users to sign up for the scons-users mailing list. -RELEASE VERSION/DATE TO BE FILLED IN LATER +RELEASE 2.3.5.final.0 - Mon, 15 Jun 2015 09:38:27 -0700 Please consult the RELEASE.txt file for a summary of changes since the last release and consult the CHANGES.txt file for complete a list of changes since last release. This announcement highlights only the important changes. + Please note the following important changes since release 2.3.4: + + -- Extended docs for InstallVersionedLib/SharedLibrary, + -- Fixed symlink support (PR #227, #2395). + -- Fixed incomplete LIBS flattening and substitution in + Program scanner(PR #205, #2954). + -- Added new method rentry_exists_on_disk to Node.FS (PR #193). + -- Add support for f08 file extensions for Fortran 2008 code. + -- Show --config choices if no argument is specified (PR #202). + -- Fixed build crash when XML toolchain isn't installed, and + activated compression for ZIP archives. + -- Fix for VersionedSharedLibrary under 'sunos' platform. + -- Fixed dll link with precompiled headers on MSVC 2012 + -- Added an 'exclude' parameter to Glob() + -- Support for multiple cmdargs (one per variant) in VS project files. + -- Various improvements for TempFileMunge class. + -- Added an implementation for Visual Studio users files (PR #209). + -- Added support for the 'PlatformToolset' tag in VS project files (#2978). + -- Added support for '-isystem' to ParseFlags. + Please note the following important changes since release 2.3.3: -- Fix for EnsureSConsVersion regression in 2.3.3. diff --git a/src/CHANGES.txt b/src/CHANGES.txt index ef4e016..90769ff 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -4,7 +4,7 @@ Change Log -RELEASE VERSION/DATE TO BE FILLED IN LATER +RELEASE 2.3.5.final.0 - Mon, 15 Jun 2015 09:38:27 -0700 From Stephen Pollard: - Documentation fixes for libraries.xml and diff --git a/src/RELEASE.txt b/src/RELEASE.txt index 1fa033b..3506b12 100644 --- a/src/RELEASE.txt +++ b/src/RELEASE.txt @@ -1,4 +1,4 @@ - A new SCons checkpoint release, 2.3.5.alpha.yyyymmdd, is now available + A new SCons checkpoint release, 2.3.5.final.0, is now available on the SCons download page: http://www.scons.org/download.php -- cgit v0.12 From 51ff963a5ae273484addabdc64c4828c7fc4a595 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 15 Jun 2015 14:05:50 -0700 Subject: Release 2.3.5.final.0 Important changes -- Extended docs for InstallVersionedLib/SharedLibrary, -- Fixed symlink support (PR #227, #2395). -- Fixed incomplete LIBS flattening and substitution in Program scanner(PR #205, #2954). -- Added new method rentry_exists_on_disk to Node.FS (PR #193). -- Add support for f08 file extensions for Fortran 2008 code. -- Show --config choices if no argument is specified (PR #202). -- Fixed build crash when XML toolchain isn't installed, and activated compression for ZIP archives. -- Fix for VersionedSharedLibrary under 'sunos' platform. -- Fixed dll link with precompiled headers on MSVC 2012 -- Added an 'exclude' parameter to Glob() -- Support for multiple cmdargs (one per variant) in VS project files. -- Various improvements for TempFileMunge class. -- Added an implementation for Visual Studio users files (PR #209). -- Added support for the 'PlatformToolset' tag in VS project files (#2978). -- Added support for '-isystem' to ParseFlags. --- QMTest/TestSCons.py | 2 +- README.rst | 16 ++++++++-------- ReleaseConfig | 3 ++- SConstruct | 2 +- src/Announce.txt | 2 +- src/CHANGES.txt | 2 +- src/RELEASE.txt | 2 +- 7 files changed, 15 insertions(+), 14 deletions(-) diff --git a/QMTest/TestSCons.py b/QMTest/TestSCons.py index bf8f9fe..bae96e6 100644 --- a/QMTest/TestSCons.py +++ b/QMTest/TestSCons.py @@ -34,7 +34,7 @@ from TestCmd import PIPE # here provides some independent verification that what we packaged # conforms to what we expect. -default_version = '2.3.5.final.0' +default_version = '2.3.5' python_version_unsupported = (2, 3, 0) python_version_deprecated = (2, 7, 0) diff --git a/README.rst b/README.rst index fa832a0..5e9dcb8 100644 --- a/README.rst +++ b/README.rst @@ -480,14 +480,14 @@ following packages will be built:: build/dist/scons-2.3.3-1.noarch.rpm build/dist/scons-2.3.3-1.src.rpm build/dist/scons-2.3.3.linux-i686.tar.gz - build/dist/scons-2.3.5.final.0.tar.gz - build/dist/scons-2.3.5.final.0.win32.exe - build/dist/scons-2.3.5.final.0.zip - build/dist/scons-doc-2.3.5.final.0.tar.gz - build/dist/scons-local-2.3.5.final.0.tar.gz - build/dist/scons-local-2.3.5.final.0.zip - build/dist/scons-src-2.3.5.final.0.tar.gz - build/dist/scons-src-2.3.5.final.0.zip + build/dist/scons-2.3.5.tar.gz + build/dist/scons-2.3.5.win32.exe + build/dist/scons-2.3.5.zip + build/dist/scons-doc-2.3.5.tar.gz + build/dist/scons-local-2.3.5.tar.gz + build/dist/scons-local-2.3.5.zip + build/dist/scons-src-2.3.5.tar.gz + build/dist/scons-src-2.3.5.zip build/dist/scons_2.3.3-1_all.deb The SConstruct file is supposed to be smart enough to avoid trying to build diff --git a/ReleaseConfig b/ReleaseConfig index 70af3e4..e899d93 100644 --- a/ReleaseConfig +++ b/ReleaseConfig @@ -32,7 +32,8 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" # 'final', the patchlevel is set to the release date. This value is # mandatory and must be present in this file. #version_tuple = (2, 2, 0, 'final', 0) -version_tuple = (2, 3, 5, 'final', 0) +#version_tuple = (2, 3, 5, 'final', 0) +version_tuple = (2, 3, 5 ) # Python versions prior to unsupported_python_version cause a fatal error # when that version is used. Python versions prior to deprecate_python_version diff --git a/SConstruct b/SConstruct index f5a3e7f..bbddd98 100644 --- a/SConstruct +++ b/SConstruct @@ -43,7 +43,7 @@ import tempfile import bootstrap project = 'scons' -default_version = '2.3.5.final.0' +default_version = '2.3.5' copyright = "Copyright (c) %s The SCons Foundation" % copyright_years platform = distutils.util.get_platform() diff --git a/src/Announce.txt b/src/Announce.txt index 882ab45..c9c379a 100644 --- a/src/Announce.txt +++ b/src/Announce.txt @@ -19,7 +19,7 @@ effectively, please go to http://scons.org/lists.php#users to sign up for the scons-users mailing list. -RELEASE 2.3.5.final.0 - Mon, 15 Jun 2015 09:38:27 -0700 +RELEASE 2.3.5 - Mon, 15 Jun 2015 11:53:37 -0700 Please consult the RELEASE.txt file for a summary of changes since the last release and consult the CHANGES.txt file for complete a list of changes diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 90769ff..d54d83e 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -4,7 +4,7 @@ Change Log -RELEASE 2.3.5.final.0 - Mon, 15 Jun 2015 09:38:27 -0700 +RELEASE 2.3.5 - Mon, 15 Jun 2015 11:53:37 -0700 From Stephen Pollard: - Documentation fixes for libraries.xml and diff --git a/src/RELEASE.txt b/src/RELEASE.txt index 3506b12..587c01e 100644 --- a/src/RELEASE.txt +++ b/src/RELEASE.txt @@ -1,4 +1,4 @@ - A new SCons checkpoint release, 2.3.5.final.0, is now available + A new SCons checkpoint release, 2.3.5, is now available on the SCons download page: http://www.scons.org/download.php -- cgit v0.12 -- cgit v0.12 -- cgit v0.12 From 6fbeaab0d682a9e6d74a36ae546e2f4b0edea36f Mon Sep 17 00:00:00 2001 From: William Deegan Date: Wed, 17 Jun 2015 21:05:34 -0700 Subject: reverting 3321 --- QMTest/TestSCons.py | 2 +- README.rst | 16 ++++++++-------- ReleaseConfig | 3 +-- SConstruct | 2 +- src/Announce.txt | 2 +- src/CHANGES.txt | 2 +- src/RELEASE.txt | 2 +- 7 files changed, 14 insertions(+), 15 deletions(-) diff --git a/QMTest/TestSCons.py b/QMTest/TestSCons.py index bae96e6..bf8f9fe 100644 --- a/QMTest/TestSCons.py +++ b/QMTest/TestSCons.py @@ -34,7 +34,7 @@ from TestCmd import PIPE # here provides some independent verification that what we packaged # conforms to what we expect. -default_version = '2.3.5' +default_version = '2.3.5.final.0' python_version_unsupported = (2, 3, 0) python_version_deprecated = (2, 7, 0) diff --git a/README.rst b/README.rst index 5e9dcb8..fa832a0 100644 --- a/README.rst +++ b/README.rst @@ -480,14 +480,14 @@ following packages will be built:: build/dist/scons-2.3.3-1.noarch.rpm build/dist/scons-2.3.3-1.src.rpm build/dist/scons-2.3.3.linux-i686.tar.gz - build/dist/scons-2.3.5.tar.gz - build/dist/scons-2.3.5.win32.exe - build/dist/scons-2.3.5.zip - build/dist/scons-doc-2.3.5.tar.gz - build/dist/scons-local-2.3.5.tar.gz - build/dist/scons-local-2.3.5.zip - build/dist/scons-src-2.3.5.tar.gz - build/dist/scons-src-2.3.5.zip + build/dist/scons-2.3.5.final.0.tar.gz + build/dist/scons-2.3.5.final.0.win32.exe + build/dist/scons-2.3.5.final.0.zip + build/dist/scons-doc-2.3.5.final.0.tar.gz + build/dist/scons-local-2.3.5.final.0.tar.gz + build/dist/scons-local-2.3.5.final.0.zip + build/dist/scons-src-2.3.5.final.0.tar.gz + build/dist/scons-src-2.3.5.final.0.zip build/dist/scons_2.3.3-1_all.deb The SConstruct file is supposed to be smart enough to avoid trying to build diff --git a/ReleaseConfig b/ReleaseConfig index e899d93..70af3e4 100644 --- a/ReleaseConfig +++ b/ReleaseConfig @@ -32,8 +32,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" # 'final', the patchlevel is set to the release date. This value is # mandatory and must be present in this file. #version_tuple = (2, 2, 0, 'final', 0) -#version_tuple = (2, 3, 5, 'final', 0) -version_tuple = (2, 3, 5 ) +version_tuple = (2, 3, 5, 'final', 0) # Python versions prior to unsupported_python_version cause a fatal error # when that version is used. Python versions prior to deprecate_python_version diff --git a/SConstruct b/SConstruct index bbddd98..f5a3e7f 100644 --- a/SConstruct +++ b/SConstruct @@ -43,7 +43,7 @@ import tempfile import bootstrap project = 'scons' -default_version = '2.3.5' +default_version = '2.3.5.final.0' copyright = "Copyright (c) %s The SCons Foundation" % copyright_years platform = distutils.util.get_platform() diff --git a/src/Announce.txt b/src/Announce.txt index c9c379a..882ab45 100644 --- a/src/Announce.txt +++ b/src/Announce.txt @@ -19,7 +19,7 @@ effectively, please go to http://scons.org/lists.php#users to sign up for the scons-users mailing list. -RELEASE 2.3.5 - Mon, 15 Jun 2015 11:53:37 -0700 +RELEASE 2.3.5.final.0 - Mon, 15 Jun 2015 09:38:27 -0700 Please consult the RELEASE.txt file for a summary of changes since the last release and consult the CHANGES.txt file for complete a list of changes diff --git a/src/CHANGES.txt b/src/CHANGES.txt index d54d83e..90769ff 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -4,7 +4,7 @@ Change Log -RELEASE 2.3.5 - Mon, 15 Jun 2015 11:53:37 -0700 +RELEASE 2.3.5.final.0 - Mon, 15 Jun 2015 09:38:27 -0700 From Stephen Pollard: - Documentation fixes for libraries.xml and diff --git a/src/RELEASE.txt b/src/RELEASE.txt index 587c01e..3506b12 100644 --- a/src/RELEASE.txt +++ b/src/RELEASE.txt @@ -1,4 +1,4 @@ - A new SCons checkpoint release, 2.3.5, is now available + A new SCons checkpoint release, 2.3.5.final.0, is now available on the SCons download page: http://www.scons.org/download.php -- cgit v0.12 From 33e3dffd49e51008a5f35f0710deafd64e1e3b8b Mon Sep 17 00:00:00 2001 From: William Deegan Date: Wed, 17 Jun 2015 21:05:56 -0700 Subject: reverting 3320 --- QMTest/TestSCons.py | 2 +- README.rst | 16 ++++++++-------- ReleaseConfig | 4 ++-- SConstruct | 6 +++--- doc/user/main.xml | 4 ++-- src/Announce.txt | 22 +--------------------- src/CHANGES.txt | 2 +- src/RELEASE.txt | 2 +- 8 files changed, 19 insertions(+), 39 deletions(-) diff --git a/QMTest/TestSCons.py b/QMTest/TestSCons.py index bf8f9fe..923e319 100644 --- a/QMTest/TestSCons.py +++ b/QMTest/TestSCons.py @@ -34,7 +34,7 @@ from TestCmd import PIPE # here provides some independent verification that what we packaged # conforms to what we expect. -default_version = '2.3.5.final.0' +default_version = '2.3.4' python_version_unsupported = (2, 3, 0) python_version_deprecated = (2, 7, 0) diff --git a/README.rst b/README.rst index fa832a0..599abaf 100644 --- a/README.rst +++ b/README.rst @@ -480,14 +480,14 @@ following packages will be built:: build/dist/scons-2.3.3-1.noarch.rpm build/dist/scons-2.3.3-1.src.rpm build/dist/scons-2.3.3.linux-i686.tar.gz - build/dist/scons-2.3.5.final.0.tar.gz - build/dist/scons-2.3.5.final.0.win32.exe - build/dist/scons-2.3.5.final.0.zip - build/dist/scons-doc-2.3.5.final.0.tar.gz - build/dist/scons-local-2.3.5.final.0.tar.gz - build/dist/scons-local-2.3.5.final.0.zip - build/dist/scons-src-2.3.5.final.0.tar.gz - build/dist/scons-src-2.3.5.final.0.zip + build/dist/scons-2.3.4.tar.gz + build/dist/scons-2.3.4.win32.exe + build/dist/scons-2.3.4.zip + build/dist/scons-doc-2.3.4.tar.gz + build/dist/scons-local-2.3.4.tar.gz + build/dist/scons-local-2.3.4.zip + build/dist/scons-src-2.3.4.tar.gz + build/dist/scons-src-2.3.4.zip build/dist/scons_2.3.3-1_all.deb The SConstruct file is supposed to be smart enough to avoid trying to build diff --git a/ReleaseConfig b/ReleaseConfig index 70af3e4..0735012 100644 --- a/ReleaseConfig +++ b/ReleaseConfig @@ -32,7 +32,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" # 'final', the patchlevel is set to the release date. This value is # mandatory and must be present in this file. #version_tuple = (2, 2, 0, 'final', 0) -version_tuple = (2, 3, 5, 'final', 0) +version_tuple = (2, 3, 5, 'alpha', 0) # Python versions prior to unsupported_python_version cause a fatal error # when that version is used. Python versions prior to deprecate_python_version @@ -51,7 +51,7 @@ deprecated_python_version = (2, 7, 0) #month_year = 'December 2012' # If copyright years is not given, the release year is used as the end. -copyright_years = '2001 - 2015' +copyright_years = '2001 - 2014' # Local Variables: # tab-width:4 diff --git a/SConstruct b/SConstruct index f5a3e7f..abf5fa8 100644 --- a/SConstruct +++ b/SConstruct @@ -3,10 +3,10 @@ # # See the README.rst file for an overview of how SCons is built and tested. -copyright_years = '2001 - 2015' +copyright_years = '2001 - 2014' # This gets inserted into the man pages to reflect the month of release. -month_year = 'June 2015' +month_year = 'September 2014' # # __COPYRIGHT__ @@ -43,7 +43,7 @@ import tempfile import bootstrap project = 'scons' -default_version = '2.3.5.final.0' +default_version = '2.3.4' copyright = "Copyright (c) %s The SCons Foundation" % copyright_years platform = distutils.util.get_platform() diff --git a/doc/user/main.xml b/doc/user/main.xml index d2c4c18..a165777 100644 --- a/doc/user/main.xml +++ b/doc/user/main.xml @@ -74,10 +74,10 @@ Steven Knight and the SCons Development Team - 2004 - 2015 + 2004 - 2014 - 2004 - 2015 + 2004 - 2014 The SCons Foundation diff --git a/src/Announce.txt b/src/Announce.txt index 882ab45..7c6fdd5 100644 --- a/src/Announce.txt +++ b/src/Announce.txt @@ -19,33 +19,13 @@ effectively, please go to http://scons.org/lists.php#users to sign up for the scons-users mailing list. -RELEASE 2.3.5.final.0 - Mon, 15 Jun 2015 09:38:27 -0700 +RELEASE VERSION/DATE TO BE FILLED IN LATER Please consult the RELEASE.txt file for a summary of changes since the last release and consult the CHANGES.txt file for complete a list of changes since last release. This announcement highlights only the important changes. - Please note the following important changes since release 2.3.4: - - -- Extended docs for InstallVersionedLib/SharedLibrary, - -- Fixed symlink support (PR #227, #2395). - -- Fixed incomplete LIBS flattening and substitution in - Program scanner(PR #205, #2954). - -- Added new method rentry_exists_on_disk to Node.FS (PR #193). - -- Add support for f08 file extensions for Fortran 2008 code. - -- Show --config choices if no argument is specified (PR #202). - -- Fixed build crash when XML toolchain isn't installed, and - activated compression for ZIP archives. - -- Fix for VersionedSharedLibrary under 'sunos' platform. - -- Fixed dll link with precompiled headers on MSVC 2012 - -- Added an 'exclude' parameter to Glob() - -- Support for multiple cmdargs (one per variant) in VS project files. - -- Various improvements for TempFileMunge class. - -- Added an implementation for Visual Studio users files (PR #209). - -- Added support for the 'PlatformToolset' tag in VS project files (#2978). - -- Added support for '-isystem' to ParseFlags. - Please note the following important changes since release 2.3.3: -- Fix for EnsureSConsVersion regression in 2.3.3. diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 90769ff..ef4e016 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -4,7 +4,7 @@ Change Log -RELEASE 2.3.5.final.0 - Mon, 15 Jun 2015 09:38:27 -0700 +RELEASE VERSION/DATE TO BE FILLED IN LATER From Stephen Pollard: - Documentation fixes for libraries.xml and diff --git a/src/RELEASE.txt b/src/RELEASE.txt index 3506b12..1fa033b 100644 --- a/src/RELEASE.txt +++ b/src/RELEASE.txt @@ -1,4 +1,4 @@ - A new SCons checkpoint release, 2.3.5.final.0, is now available + A new SCons checkpoint release, 2.3.5.alpha.yyyymmdd, is now available on the SCons download page: http://www.scons.org/download.php -- cgit v0.12 From 7de7bbe1e48e51386ec466618fdbf6277ad3f934 Mon Sep 17 00:00:00 2001 From: anatoly techtonik Date: Sat, 20 Jun 2015 17:49:24 +0300 Subject: Fix premature SyntaxError on Python 3 This allows to show correct message for Python 3 users --- src/script/scons.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/script/scons.py b/src/script/scons.py index 0c7b44c..e522f57 100644 --- a/src/script/scons.py +++ b/src/script/scons.py @@ -191,7 +191,7 @@ if __name__ == "__main__": except: print("Import failed. Unable to find SCons files in:") for path in libs: - print " %s" % path + print(" %s" % path) raise # this does all the work, and calls sys.exit -- cgit v0.12 From 0446ed1d72ba7fdabce2b74acccc74cb7bbc9b0f Mon Sep 17 00:00:00 2001 From: William Deegan Date: Sat, 20 Jun 2015 16:36:59 -0700 Subject: merging 2.3.5 changes --- QMTest/TestSCons.py | 2 +- README.rst | 16 ++++++++-------- ReleaseConfig | 4 ++-- SConstruct | 6 +++--- bin/scp-sourceforge | 8 ++++++++ debian/changelog | 6 ++++++ doc/user/main.xml | 4 ++-- doc/version.xml | 4 ++-- src/Announce.txt | 47 ++++++++++++++++++++++++++++++++++++++++++++++- src/CHANGES.txt | 2 +- src/RELEASE.txt | 2 +- 11 files changed, 80 insertions(+), 21 deletions(-) diff --git a/QMTest/TestSCons.py b/QMTest/TestSCons.py index 923e319..bae96e6 100644 --- a/QMTest/TestSCons.py +++ b/QMTest/TestSCons.py @@ -34,7 +34,7 @@ from TestCmd import PIPE # here provides some independent verification that what we packaged # conforms to what we expect. -default_version = '2.3.4' +default_version = '2.3.5' python_version_unsupported = (2, 3, 0) python_version_deprecated = (2, 7, 0) diff --git a/README.rst b/README.rst index 599abaf..5e9dcb8 100644 --- a/README.rst +++ b/README.rst @@ -480,14 +480,14 @@ following packages will be built:: build/dist/scons-2.3.3-1.noarch.rpm build/dist/scons-2.3.3-1.src.rpm build/dist/scons-2.3.3.linux-i686.tar.gz - build/dist/scons-2.3.4.tar.gz - build/dist/scons-2.3.4.win32.exe - build/dist/scons-2.3.4.zip - build/dist/scons-doc-2.3.4.tar.gz - build/dist/scons-local-2.3.4.tar.gz - build/dist/scons-local-2.3.4.zip - build/dist/scons-src-2.3.4.tar.gz - build/dist/scons-src-2.3.4.zip + build/dist/scons-2.3.5.tar.gz + build/dist/scons-2.3.5.win32.exe + build/dist/scons-2.3.5.zip + build/dist/scons-doc-2.3.5.tar.gz + build/dist/scons-local-2.3.5.tar.gz + build/dist/scons-local-2.3.5.zip + build/dist/scons-src-2.3.5.tar.gz + build/dist/scons-src-2.3.5.zip build/dist/scons_2.3.3-1_all.deb The SConstruct file is supposed to be smart enough to avoid trying to build diff --git a/ReleaseConfig b/ReleaseConfig index 0735012..44fe657 100644 --- a/ReleaseConfig +++ b/ReleaseConfig @@ -32,7 +32,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" # 'final', the patchlevel is set to the release date. This value is # mandatory and must be present in this file. #version_tuple = (2, 2, 0, 'final', 0) -version_tuple = (2, 3, 5, 'alpha', 0) +version_tuple = (2, 3, 5) # Python versions prior to unsupported_python_version cause a fatal error # when that version is used. Python versions prior to deprecate_python_version @@ -51,7 +51,7 @@ deprecated_python_version = (2, 7, 0) #month_year = 'December 2012' # If copyright years is not given, the release year is used as the end. -copyright_years = '2001 - 2014' +copyright_years = '2001 - 2015' # Local Variables: # tab-width:4 diff --git a/SConstruct b/SConstruct index abf5fa8..bbddd98 100644 --- a/SConstruct +++ b/SConstruct @@ -3,10 +3,10 @@ # # See the README.rst file for an overview of how SCons is built and tested. -copyright_years = '2001 - 2014' +copyright_years = '2001 - 2015' # This gets inserted into the man pages to reflect the month of release. -month_year = 'September 2014' +month_year = 'June 2015' # # __COPYRIGHT__ @@ -43,7 +43,7 @@ import tempfile import bootstrap project = 'scons' -default_version = '2.3.4' +default_version = '2.3.5' copyright = "Copyright (c) %s The SCons Foundation" % copyright_years platform = distutils.util.get_platform() diff --git a/bin/scp-sourceforge b/bin/scp-sourceforge index ad761d1..07df3ea 100755 --- a/bin/scp-sourceforge +++ b/bin/scp-sourceforge @@ -19,10 +19,14 @@ do sf/$p/$VERSION done +cp -p build/scons/README.txt \ + sf/. + cp -p build/dist/scons-$VERSION-1.noarch.rpm \ build/dist/scons-$VERSION-1.src.rpm \ build/dist/scons-$VERSION.tar.gz \ build/dist/scons-$VERSION.win32.exe \ + build/dist/scons-$VERSION.win-amd64.exe \ build/dist/scons-$VERSION.zip \ sf/scons/$VERSION cp -p build/dist/scons-local-$VERSION.tar.gz \ @@ -35,4 +39,8 @@ cp -p build/dist/scons-src-$VERSION.tar.gz \ # Transmit them in this order, since the most-recent is displayed at the top scp -r sf/scons-local/ sf/scons-src/ sf/scons/ \ $SF_USER,scons@frs.sourceforge.net:/home/pfs/project/s/sc/scons + +scp sf/README.txt \ + $SF_USER,scons@frs.sourceforge.net:/home/pfs/project/s/sc/scons + rm -rf sf diff --git a/debian/changelog b/debian/changelog index a39a73b..9dbb1b3 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +scons (2.3.5) unstable; urgency=low + + * Maintenance release. + + -- William Deegan Mon, 17 Jun 2015 21:07:32 -0700 + scons (2.3.4) unstable; urgency=low * Maintenance release. diff --git a/doc/user/main.xml b/doc/user/main.xml index a165777..d2c4c18 100644 --- a/doc/user/main.xml +++ b/doc/user/main.xml @@ -74,10 +74,10 @@ Steven Knight and the SCons Development Team - 2004 - 2014 + 2004 - 2015 - 2004 - 2014 + 2004 - 2015 The SCons Foundation diff --git a/doc/version.xml b/doc/version.xml index f6eba1f..172a9ec 100644 --- a/doc/version.xml +++ b/doc/version.xml @@ -2,6 +2,6 @@ - - + + diff --git a/src/Announce.txt b/src/Announce.txt index 7c6fdd5..e8b7fd5 100644 --- a/src/Announce.txt +++ b/src/Announce.txt @@ -18,14 +18,59 @@ So that everyone using SCons can help each other learn how to use it more effectively, please go to http://scons.org/lists.php#users to sign up for the scons-users mailing list. +==============IMPORTANT NOTICE FOR NEXT VERSION V2.4.0=========== -RELEASE VERSION/DATE TO BE FILLED IN LATER +PLEASE READ. CHANGES COMING IN NEXT MAJOR RELEASE V2.4.0 +As has been pre-announced in SCons's mailing lists: + +* https://pairlist4.pair.net/pipermail/scons-users/2014-July/002734.html , +* https://pairlist2.pair.net/pipermail/scons-dev/2014-December/002107.html +* https://pairlist4.pair.net/pipermail/scons-users/2015-February/003454.html + +We're planning to switch the Node class to using "slots" in the core sources, +mainly to reduce memory consumption by up to 35% in large build projects. + +This feature has been tested extensively and we don't expect any problems for you. +However as with all major changes it would be wise to test V2.4.0 when it is +released. Especially if you are directly using the Node class. + +================================================================= + + +RELEASE 2.3.5 - Mon, 17 Jun 2015 21:07:32 -0700 Please consult the RELEASE.txt file for a summary of changes since the last release and consult the CHANGES.txt file for complete a list of changes since last release. This announcement highlights only the important changes. + + Please note the following important changes since release 2.3.4: + - Documentation fixes for libraries.xml and + builders-writing.xml (#2989 and #2990) + - Extended docs for InstallVersionedLib/SharedLibrary, + and added SKIP_WIN_PACKAGES argument to build script + bootstrap.py (PR #230, #3002). + - Fixed symlink support (PR #227, #2395). + - Updated debug-count test case (PR #229). + - Fixed incomplete LIBS flattening and substitution in + Program scanner(PR #205, #2954). + - Added new method rentry_exists_on_disk to Node.FS (PR #193). + - Fixed several D tests under the different OS. + - Add support for f08 file extensions for Fortran 2008 code. + - Show --config choices if no argument is specified (PR #202). + - Fixed build crash when XML toolchain isn't installed, and + activated compression for ZIP archives. + - Fix for VersionedSharedLibrary under 'sunos' platform. + - Fixed dll link with precompiled headers on MSVC 2012 + - Added an 'exclude' parameter to Glob() + - Support for multiple cmdargs (one per variant) in VS project files. + - Various improvements for TempFileMunge class. + - Added an implementation for Visual Studio users files (PR #209). + - Added support for the 'PlatformToolset' tag in VS project files (#2978). + - Added support for '-isystem' to ParseFlags. + + Please note the following important changes since release 2.3.3: -- Fix for EnsureSConsVersion regression in 2.3.3. diff --git a/src/CHANGES.txt b/src/CHANGES.txt index ef4e016..8c764c1 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -4,7 +4,7 @@ Change Log -RELEASE VERSION/DATE TO BE FILLED IN LATER +RELEASE 2.3.5 - Mon, 17 Jun 2015 21:07:32 -0700 From Stephen Pollard: - Documentation fixes for libraries.xml and diff --git a/src/RELEASE.txt b/src/RELEASE.txt index 1fa033b..587c01e 100644 --- a/src/RELEASE.txt +++ b/src/RELEASE.txt @@ -1,4 +1,4 @@ - A new SCons checkpoint release, 2.3.5.alpha.yyyymmdd, is now available + A new SCons checkpoint release, 2.3.5, is now available on the SCons download page: http://www.scons.org/download.php -- cgit v0.12 From 6a841c8066c8a44a5f215e2d88d0e55fb9191e58 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Sat, 20 Jun 2015 16:37:21 -0700 Subject: post release changes back to develop settings --- ReleaseConfig | 2 +- src/Announce.txt | 2 +- src/CHANGES.txt | 7 +++++++ src/RELEASE.txt | 2 +- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/ReleaseConfig b/ReleaseConfig index 44fe657..b5623be 100644 --- a/ReleaseConfig +++ b/ReleaseConfig @@ -32,7 +32,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" # 'final', the patchlevel is set to the release date. This value is # mandatory and must be present in this file. #version_tuple = (2, 2, 0, 'final', 0) -version_tuple = (2, 3, 5) +version_tuple = (2, 3, 6, 'alpha', 0) # Python versions prior to unsupported_python_version cause a fatal error # when that version is used. Python versions prior to deprecate_python_version diff --git a/src/Announce.txt b/src/Announce.txt index e8b7fd5..2d26ab5 100644 --- a/src/Announce.txt +++ b/src/Announce.txt @@ -37,7 +37,7 @@ released. Especially if you are directly using the Node class. ================================================================= -RELEASE 2.3.5 - Mon, 17 Jun 2015 21:07:32 -0700 +RELEASE VERSION/DATE TO BE FILLED IN LATER Please consult the RELEASE.txt file for a summary of changes since the last release and consult the CHANGES.txt file for complete a list of changes diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 8c764c1..dad6307 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -4,6 +4,13 @@ Change Log +RELEASE VERSION/DATE TO BE FILLED IN LATER + + From John Doe: + + - Whatever John Doe did. + + RELEASE 2.3.5 - Mon, 17 Jun 2015 21:07:32 -0700 From Stephen Pollard: diff --git a/src/RELEASE.txt b/src/RELEASE.txt index 587c01e..303776c 100644 --- a/src/RELEASE.txt +++ b/src/RELEASE.txt @@ -1,4 +1,4 @@ - A new SCons checkpoint release, 2.3.5, is now available + A new SCons checkpoint release, 2.3.6.alpha.yyyymmdd, is now available on the SCons download page: http://www.scons.org/download.php -- cgit v0.12 From 888b72ece421a1bad7128b21170cf161ea815bb9 Mon Sep 17 00:00:00 2001 From: Rob Smith Date: Tue, 14 Jul 2015 16:30:40 -0700 Subject: Add Visual Studio 2015 support to SCons --- src/engine/SCons/Tool/MSCommon/arch.py | 6 ++++++ src/engine/SCons/Tool/MSCommon/vc.py | 6 +++++- src/engine/SCons/Tool/MSCommon/vs.py | 22 ++++++++++++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/engine/SCons/Tool/MSCommon/arch.py b/src/engine/SCons/Tool/MSCommon/arch.py index 2c90950..9bcc221 100644 --- a/src/engine/SCons/Tool/MSCommon/arch.py +++ b/src/engine/SCons/Tool/MSCommon/arch.py @@ -51,6 +51,12 @@ SupportedArchitectureList = [ 'ia64', ['IA64'], ), + + ArchitectureDefinition( + 'arm', + ['ARM'], + ), + ] SupportedArchitectureMap = {} diff --git a/src/engine/SCons/Tool/MSCommon/vc.py b/src/engine/SCons/Tool/MSCommon/vc.py index 97cb349..0ee6324 100644 --- a/src/engine/SCons/Tool/MSCommon/vc.py +++ b/src/engine/SCons/Tool/MSCommon/vc.py @@ -134,9 +134,13 @@ def get_host_target(env): # 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 = ["14.0", "14.0Exp", "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 = { + '14.0' : [ + r'Microsoft\VisualStudio\14.0\Setup\VC\ProductDir'], + '14.0Exp' : [ + r'Microsoft\VCExpress\14.0\Setup\VC\ProductDir'], '12.0' : [ r'Microsoft\VisualStudio\12.0\Setup\VC\ProductDir'], '12.0Exp' : [ diff --git a/src/engine/SCons/Tool/MSCommon/vs.py b/src/engine/SCons/Tool/MSCommon/vs.py index 2ec403b..d9eb1e3 100644 --- a/src/engine/SCons/Tool/MSCommon/vs.py +++ b/src/engine/SCons/Tool/MSCommon/vs.py @@ -203,6 +203,28 @@ class VisualStudio(object): # Tool/MSCommon/vc.py, and the MSVC_VERSION documentation in Tool/msvc.xml. SupportedVSList = [ + # Visual Studio 2015 + VisualStudio('14.0', + vc_version='14.0', + sdk_version='10.0A', + hkeys=[r'Microsoft\VisualStudio\14.0\Setup\VS\ProductDir'], + common_tools_var='VS140COMNTOOLS', + executable_path=r'Common7\IDE\devenv.com', + batch_file_path=r'Common7\Tools\vsvars32.bat', + supported_arch=['x86', 'amd64', "arm"], + ), + + # Visual C++ 2015 Express Edition (for Desktop) + VisualStudio('14.0Exp', + vc_version='14.0', + sdk_version='10.0A', + hkeys=[r'Microsoft\VisualStudio\14.0\Setup\VS\ProductDir'], + common_tools_var='VS140COMNTOOLS', + executable_path=r'Common7\IDE\WDExpress.exe', + batch_file_path=r'Common7\Tools\vsvars32.bat', + supported_arch=['x86', 'amd64', "arm"], + ), + # Visual Studio 2013 VisualStudio('12.0', vc_version='12.0', -- cgit v0.12 From 1c4556169cf83f13162bd5dabd3122cd04de56f9 Mon Sep 17 00:00:00 2001 From: Rob Smith Date: Wed, 15 Jul 2015 16:33:36 -0700 Subject: Add VS 2015 tests --- test/MSVS/vs-14.0-exec.py | 109 ++++++++++++++++++++++++++++++++ test/MSVS/vs-14.0-files.py | 110 ++++++++++++++++++++++++++++++++ test/MSVS/vs-14.0-scc-files.py | 115 ++++++++++++++++++++++++++++++++++ test/MSVS/vs-14.0-scc-legacy-files.py | 98 +++++++++++++++++++++++++++++ test/MSVS/vs-14.0Exp-exec.py | 109 ++++++++++++++++++++++++++++++++ 5 files changed, 541 insertions(+) create mode 100644 test/MSVS/vs-14.0-exec.py create mode 100644 test/MSVS/vs-14.0-files.py create mode 100644 test/MSVS/vs-14.0-scc-files.py create mode 100644 test/MSVS/vs-14.0-scc-legacy-files.py create mode 100644 test/MSVS/vs-14.0Exp-exec.py diff --git a/test/MSVS/vs-14.0-exec.py b/test/MSVS/vs-14.0-exec.py new file mode 100644 index 0000000..b96bdab --- /dev/null +++ b/test/MSVS/vs-14.0-exec.py @@ -0,0 +1,109 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Test that we can actually build a simple program using our generated +Visual Studio 14.0 project (.vcxproj) and solution (.sln) files +using Visual Studio 14.0 (Professional edition). +""" + +import os +import sys + +import TestSConsMSVS + +test = TestSConsMSVS.TestSConsMSVS() + +if sys.platform != 'win32': + msg = "Skipping Visual Studio test on non-Windows platform '%s'\n" % sys.platform + test.skip_test(msg) + +msvs_version = '14.0' + +if not msvs_version in test.msvs_versions(): + msg = "Visual Studio %s not installed; skipping test.\n" % msvs_version + test.skip_test(msg) + + + +# Let SCons figure out the Visual Studio environment variables for us and +# print out a statement that we can exec to suck them into our external +# environment so we can execute devenv and really try to build something. + +test.run(arguments = '-n -q -Q -f -', stdin = """\ +env = Environment(tools = ['msvc'], MSVS_VERSION='%(msvs_version)s') +print "os.environ.update(%%s)" %% repr(env['ENV']) +""" % locals()) + +exec(test.stdout()) + + + +test.subdir('sub dir') + +test.write(['sub dir', 'SConstruct'], """\ +env=Environment(MSVS_VERSION = '%(msvs_version)s') + +env.MSVSProject(target = 'foo.vcxproj', + srcs = ['foo.c'], + buildtarget = 'foo.exe', + variant = 'Release') + +env.Program('foo.c') +""" % locals()) + +test.write(['sub dir', 'foo.c'], r""" +int +main(int argc, char *argv) +{ + printf("foo.c\n"); + exit (0); +} +""") + +test.run(chdir='sub dir', arguments='.') + +test.vcproj_sys_path(test.workpath('sub dir', 'foo.vcxproj')) + +import SCons.Platform.win32 +system_dll_path = os.path.join( SCons.Platform.win32.get_system_root(), 'System32' ) +os.environ['PATH'] = os.environ['PATH'] + os.pathsep + system_dll_path + +test.run(chdir='sub dir', + program=[test.get_msvs_executable(msvs_version)], + arguments=['foo.sln', '/build', 'Release']) + +test.run(program=test.workpath('sub dir', 'foo'), stdout="foo.c\n") + + + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/MSVS/vs-14.0-files.py b/test/MSVS/vs-14.0-files.py new file mode 100644 index 0000000..e4ba8e2 --- /dev/null +++ b/test/MSVS/vs-14.0-files.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Test that we can generate Visual Studio 14.0 project (.vcxproj) and +solution (.sln) files that look correct. +""" + +import os + +import TestSConsMSVS + +test = TestSConsMSVS.TestSConsMSVS() +host_arch = test.get_vs_host_arch() + + +# Make the test infrastructure think we have this version of MSVS installed. +test._msvs_versions = ['14.0'] + + + +expected_slnfile = TestSConsMSVS.expected_slnfile_14_0 +expected_vcprojfile = TestSConsMSVS.expected_vcprojfile_14_0 +SConscript_contents = TestSConsMSVS.SConscript_contents_14_0 + + + +test.write('SConstruct', SConscript_contents%{'HOST_ARCH': host_arch}) + +test.run(arguments="Test.vcxproj") + +test.must_exist(test.workpath('Test.vcxproj')) +test.must_exist(test.workpath('Test.vcxproj.filters')) +vcxproj = test.read('Test.vcxproj', 'r') +expect = test.msvs_substitute(expected_vcprojfile, '14.0', None, 'SConstruct') +# don't compare the pickled data +assert vcxproj[:len(expect)] == expect, test.diff_substr(expect, vcxproj) + +test.must_exist(test.workpath('Test.sln')) +sln = test.read('Test.sln', 'r') +expect = test.msvs_substitute(expected_slnfile, '14.0', None, 'SConstruct') +# don't compare the pickled data +assert sln[:len(expect)] == expect, test.diff_substr(expect, sln) + +test.run(arguments='-c .') + +test.must_not_exist(test.workpath('Test.vcxproj')) +test.must_not_exist(test.workpath('Test.vcxproj.filters')) +test.must_not_exist(test.workpath('Test.sln')) + +test.run(arguments='Test.vcxproj') + +test.must_exist(test.workpath('Test.vcxproj')) +test.must_exist(test.workpath('Test.vcxproj.filters')) +test.must_exist(test.workpath('Test.sln')) + +test.run(arguments='-c Test.sln') + +test.must_not_exist(test.workpath('Test.vcxproj')) +test.must_not_exist(test.workpath('Test.vcxproj.filters')) +test.must_not_exist(test.workpath('Test.sln')) + + + +# Test that running SCons with $PYTHON_ROOT in the environment +# changes the .vcxproj output as expected. +os.environ['PYTHON_ROOT'] = 'xyzzy' +python = os.path.join('$(PYTHON_ROOT)', os.path.split(TestSConsMSVS.python)[1]) + +test.run(arguments='Test.vcxproj') + +test.must_exist(test.workpath('Test.vcxproj')) +vcxproj = test.read('Test.vcxproj', 'r') +expect = test.msvs_substitute(expected_vcprojfile, '14.0', None, 'SConstruct', + python=python) +# don't compare the pickled data +assert vcxproj[:len(expect)] == expect, test.diff_substr(expect, vcxproj) + + + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/MSVS/vs-14.0-scc-files.py b/test/MSVS/vs-14.0-scc-files.py new file mode 100644 index 0000000..c934ac9 --- /dev/null +++ b/test/MSVS/vs-14.0-scc-files.py @@ -0,0 +1,115 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Test that we can generate Visual Studio 14.0 project (.vcxproj) and +solution (.sln) files that contain SCC information and look correct. +""" + +import os + +import TestSConsMSVS + +test = TestSConsMSVS.TestSConsMSVS() + +# Make the test infrastructure think we have this version of MSVS installed. +test._msvs_versions = ['14.0'] + + + +expected_slnfile = TestSConsMSVS.expected_slnfile_14_0 +expected_vcprojfile = TestSConsMSVS.expected_vcprojfile_14_0 +SConscript_contents = """\ +env=Environment(platform='win32', tools=['msvs'], MSVS_VERSION='14.0', + CPPDEFINES=['DEF1', 'DEF2',('DEF3','1234')], + CPPPATH=['inc1', 'inc2'], + MSVS_SCC_CONNECTION_ROOT='.', + MSVS_SCC_PROVIDER='MSSCCI:Perforce SCM', + MSVS_SCC_PROJECT_NAME='Perforce Project') + +testsrc = ['test1.cpp', 'test2.cpp'] +testincs = ['sdk_dir\sdk.h'] +testlocalincs = ['test.h'] +testresources = ['test.rc'] +testmisc = ['readme.txt'] + +env.MSVSProject(target = 'Test.vcxproj', + srcs = testsrc, + incs = testincs, + localincs = testlocalincs, + resources = testresources, + misc = testmisc, + buildtarget = 'Test.exe', + variant = 'Release') +""" + +expected_sln_sccinfo = """\ +\tGlobalSection(SourceCodeControl) = preSolution +\t\tSccNumberOfProjects = 2 +\t\tSccProjectName0 = Perforce\u0020Project +\t\tSccLocalPath0 = . +\t\tSccProvider0 = MSSCCI:Perforce\u0020SCM +\t\tCanCheckoutShared = true +\t\tSccProjectUniqueName1 = Test.vcxproj +\t\tSccLocalPath1 = . +\t\tCanCheckoutShared = true +\t\tSccProjectFilePathRelativizedFromConnection1 = .\\\\ +\tEndGlobalSection +""" + +expected_vcproj_sccinfo = """\ +\t\tPerforce Project +\t\t. +\t\tMSSCCI:Perforce SCM +""" + + +test.write('SConstruct', SConscript_contents) + +test.run(arguments="Test.vcxproj") + +test.must_exist(test.workpath('Test.vcxproj')) +vcproj = test.read('Test.vcxproj', 'r') +expect = test.msvs_substitute(expected_vcprojfile, '14.0', None, 'SConstruct', + vcproj_sccinfo=expected_vcproj_sccinfo) +# don't compare the pickled data +assert vcproj[:len(expect)] == expect, test.diff_substr(expect, vcproj) + +test.must_exist(test.workpath('Test.sln')) +sln = test.read('Test.sln', 'r') +expect = test.msvs_substitute(expected_slnfile, '14.0', None, 'SConstruct', + sln_sccinfo=expected_sln_sccinfo) +# don't compare the pickled data +assert sln[:len(expect)] == expect, test.diff_substr(expect, sln) + + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/MSVS/vs-14.0-scc-legacy-files.py b/test/MSVS/vs-14.0-scc-legacy-files.py new file mode 100644 index 0000000..ba6ebad --- /dev/null +++ b/test/MSVS/vs-14.0-scc-legacy-files.py @@ -0,0 +1,98 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Test that we can generate Visual Studio 14.0 project (.vcxproj) and +solution (.sln) files that contain SCC information and look correct. +""" + +import os + +import TestSConsMSVS + +test = TestSConsMSVS.TestSConsMSVS() + +# Make the test infrastructure think we have this version of MSVS installed. +test._msvs_versions = ['14.0'] + + + +expected_slnfile = TestSConsMSVS.expected_slnfile_14_0 +expected_vcprojfile = TestSConsMSVS.expected_vcprojfile_14_0 +SConscript_contents = """\ +env=Environment(platform='win32', tools=['msvs'], MSVS_VERSION='14.0', + CPPDEFINES=['DEF1', 'DEF2',('DEF3','1234')], + CPPPATH=['inc1', 'inc2'], + MSVS_SCC_LOCAL_PATH='C:\\MyMsVsProjects', + MSVS_SCC_PROJECT_NAME='Perforce Project') + +testsrc = ['test1.cpp', 'test2.cpp'] +testincs = ['sdk_dir\sdk.h'] +testlocalincs = ['test.h'] +testresources = ['test.rc'] +testmisc = ['readme.txt'] + +env.MSVSProject(target = 'Test.vcxproj', + srcs = testsrc, + incs = testincs, + localincs = testlocalincs, + resources = testresources, + misc = testmisc, + buildtarget = 'Test.exe', + variant = 'Release') +""" + +expected_vcproj_sccinfo = """\ +\t\tPerforce Project +\t\tC:\\MyMsVsProjects +""" + + +test.write('SConstruct', SConscript_contents) + +test.run(arguments="Test.vcxproj") + +test.must_exist(test.workpath('Test.vcxproj')) +vcproj = test.read('Test.vcxproj', 'r') +expect = test.msvs_substitute(expected_vcprojfile, '14.0', None, 'SConstruct', + vcproj_sccinfo=expected_vcproj_sccinfo) +# don't compare the pickled data +assert vcproj[:len(expect)] == expect, test.diff_substr(expect, vcproj) + +test.must_exist(test.workpath('Test.sln')) +sln = test.read('Test.sln', 'r') +expect = test.msvs_substitute(expected_slnfile, '14.0', None, 'SConstruct') +# don't compare the pickled data +assert sln[:len(expect)] == expect, test.diff_substr(expect, sln) + + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/MSVS/vs-14.0Exp-exec.py b/test/MSVS/vs-14.0Exp-exec.py new file mode 100644 index 0000000..44ebece --- /dev/null +++ b/test/MSVS/vs-14.0Exp-exec.py @@ -0,0 +1,109 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Test that we can actually build a simple program using our generated +Visual Studio 14.0 project (.vcxproj) and solution (.sln) files +using Visual C++ 14.0 Express edition. +""" + +import os +import sys + +import TestSConsMSVS + +test = TestSConsMSVS.TestSConsMSVS() + +if sys.platform != 'win32': + msg = "Skipping Visual Studio test on non-Windows platform '%s'\n" % sys.platform + test.skip_test(msg) + +msvs_version = '14.0Exp' + +if not msvs_version in test.msvs_versions(): + msg = "Visual Studio %s not installed; skipping test.\n" % msvs_version + test.skip_test(msg) + + + +# Let SCons figure out the Visual Studio environment variables for us and +# print out a statement that we can exec to suck them into our external +# environment so we can execute devenv and really try to build something. + +test.run(arguments = '-n -q -Q -f -', stdin = """\ +env = Environment(tools = ['msvc'], MSVS_VERSION='%(msvs_version)s') +print "os.environ.update(%%s)" %% repr(env['ENV']) +""" % locals()) + +exec(test.stdout()) + + + +test.subdir('sub dir') + +test.write(['sub dir', 'SConstruct'], """\ +env=Environment(MSVS_VERSION = '%(msvs_version)s') + +env.MSVSProject(target = 'foo.vcxproj', + srcs = ['foo.c'], + buildtarget = 'foo.exe', + variant = 'Release') + +env.Program('foo.c') +""" % locals()) + +test.write(['sub dir', 'foo.c'], r""" +int +main(int argc, char *argv) +{ + printf("foo.c\n"); + exit (0); +} +""") + +test.run(chdir='sub dir', arguments='.') + +test.vcproj_sys_path(test.workpath('sub dir', 'foo.vcxproj')) + +import SCons.Platform.win32 +system_dll_path = os.path.join( SCons.Platform.win32.get_system_root(), 'System32' ) +os.environ['PATH'] = os.environ['PATH'] + os.pathsep + system_dll_path + +test.run(chdir='sub dir', + program=[test.get_msvs_executable(msvs_version)], + arguments=['foo.sln', '/build', 'Release']) + +test.run(program=test.workpath('sub dir', 'foo'), stdout="foo.c\n") + + + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: -- cgit v0.12 From a4c8f18b9199cbffd7040ec64dcfd6a95eb20d53 Mon Sep 17 00:00:00 2001 From: Rob Smith Date: Fri, 17 Jul 2015 14:07:38 -0700 Subject: Update MSVS project samples in TestSConsMSVS --- QMTest/TestSConsMSVS.py | 108 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/QMTest/TestSConsMSVS.py b/QMTest/TestSConsMSVS.py index 540d24d..50a7956 100644 --- a/QMTest/TestSConsMSVS.py +++ b/QMTest/TestSConsMSVS.py @@ -514,6 +514,26 @@ Global EndGlobal """ +expected_slnfile_14_0 = """\ +Microsoft Visual Studio Solution File, Format Version 14.00 +# Visual Studio 14 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Test.vcxproj", "Test.vcxproj", "{39A97E1F-1A52-8954-A0B1-A10A8487545E}" +EndProject +Global + +\tGlobalSection(SolutionConfigurationPlatforms) = preSolution +\t\tRelease|Win32 = Release|Win32 +\tEndGlobalSection +\tGlobalSection(ProjectConfigurationPlatforms) = postSolution +\t\t{39A97E1F-1A52-8954-A0B1-A10A8487545E}.Release|Win32.ActiveCfg = Release|Win32 +\t\t{39A97E1F-1A52-8954-A0B1-A10A8487545E}.Release|Win32.Build.0 = Release|Win32 +\tEndGlobalSection +\tGlobalSection(SolutionProperties) = preSolution +\t\tHideSolutionNode = FALSE +\tEndGlobalSection +EndGlobal +""" + expected_vcprojfile_8_0 = """\ """ +expected_vcprojfile_14_0 = """\ + + +\t +\t\t +\t\t\tRelease +\t\t\tWin32 +\t\t +\t +\t +\t\t{39A97E1F-1A52-8954-A0B1-A10A8487545E} + +\t\tTest +\t\tMakeFileProj +\t +\t +\t +\t\tMakefile +\t\tfalse +\t\tv140 +\t +\t +\t +\t +\t +\t\t +\t +\t +\t +\t<_ProjectFileVersion>10.0.30319.1 +\t\techo Starting SCons && "" -c "" -C "" -f SConstruct "Test.exe" +\t\techo Starting SCons && "" -c "" -C "" -f SConstruct "Test.exe" +\t\techo Starting SCons && "" -c "" -C "" -f SConstruct -c "Test.exe" +\t\tTest.exe +\t\tDEF1;DEF2;DEF3=1234 +\t\tinc1;inc2 +\t\t$(NMakeForcedIncludes) +\t\t$(NMakeAssemblySearchPath) +\t\t$(NMakeForcedUsingAssemblies) +\t +\t +\t\t +\t +\t +\t\t +\t +\t +\t\t +\t +\t +\t\t +\t +\t +\t\t +\t\t +\t +\t +\t\t +\t +\t +\t +\t + +""" + SConscript_contents_8_0 = """\ env=Environment(platform='win32', tools=['msvs'], MSVS_VERSION='8.0', CPPDEFINES=['DEF1', 'DEF2',('DEF3','1234')], @@ -912,6 +997,29 @@ env.MSVSProject(target = 'Test.vcxproj', variant = 'Release') """ +SConscript_contents_14_0 = """\ +env=Environment(platform='win32', tools=['msvs'], MSVS_VERSION='14.0', + CPPDEFINES=['DEF1', 'DEF2',('DEF3','1234')], + CPPPATH=['inc1', 'inc2'], + HOST_ARCH='%(HOST_ARCH)s') + +testsrc = ['test1.cpp', 'test2.cpp'] +testincs = ['sdk_dir\sdk.h'] +testlocalincs = ['test.h'] +testresources = ['test.rc'] +testmisc = ['readme.txt'] + +env.MSVSProject(target = 'Test.vcxproj', + slnguid = '{SLNGUID}', + srcs = testsrc, + incs = testincs, + localincs = testlocalincs, + resources = testresources, + misc = testmisc, + buildtarget = 'Test.exe', + variant = 'Release') +""" + class TestSConsMSVS(TestSCons): """Subclass for testing MSVS-specific portions of SCons.""" -- cgit v0.12 From 5ffbfecaf01bceed3263b2cd5829e4a5b8424ac6 Mon Sep 17 00:00:00 2001 From: Rob Smith Date: Mon, 20 Jul 2015 15:12:33 -0700 Subject: Add VS14 support to the solution generation code and fix the solution version number (12.0) --- QMTest/TestSConsMSVS.py | 2 +- src/engine/SCons/Tool/msvs.py | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/QMTest/TestSConsMSVS.py b/QMTest/TestSConsMSVS.py index 50a7956..65a09eb 100644 --- a/QMTest/TestSConsMSVS.py +++ b/QMTest/TestSConsMSVS.py @@ -515,7 +515,7 @@ EndGlobal """ expected_slnfile_14_0 = """\ -Microsoft Visual Studio Solution File, Format Version 14.00 +Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Test.vcxproj", "Test.vcxproj", "{39A97E1F-1A52-8954-A0B1-A10A8487545E}" EndProject diff --git a/src/engine/SCons/Tool/msvs.py b/src/engine/SCons/Tool/msvs.py index d00413d..8b74cf4 100644 --- a/src/engine/SCons/Tool/msvs.py +++ b/src/engine/SCons/Tool/msvs.py @@ -1535,7 +1535,9 @@ class _GenerateV7DSW(_DSWGenerator): 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: + if self.version_num >= 12.0: + self.file.write('# Visual Studio 14\n') + elif 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') -- cgit v0.12 From 1c3e0ef0c5392db9a23dc766e8cae598aeb178ad Mon Sep 17 00:00:00 2001 From: Rob Smith Date: Mon, 20 Jul 2015 15:24:38 -0700 Subject: Update CHANGES.txt for VS2015 support --- src/CHANGES.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index dad6307..b3a46b8 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -9,7 +9,9 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER From John Doe: - Whatever John Doe did. - + + From Rob Smith: + - Added support for Visual Studio 2015 RELEASE 2.3.5 - Mon, 17 Jun 2015 21:07:32 -0700 -- cgit v0.12 From 85f7e408f935ab89e0b1bdafa80aa28da6b09e2e Mon Sep 17 00:00:00 2001 From: William Deegan Date: Thu, 23 Jul 2015 18:19:27 -0400 Subject: Kick buildbot --- README.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/README.rst b/README.rst index 5e9dcb8..64e8748 100644 --- a/README.rst +++ b/README.rst @@ -750,4 +750,3 @@ many contributors, including but not at all limited to: __COPYRIGHT__ - -- cgit v0.12 From 3be61c5b90e24835f7cd86e07d230e99edf0ca31 Mon Sep 17 00:00:00 2001 From: William Blevins Date: Mon, 29 Jun 2015 07:04:53 -0400 Subject: Issue 3004: Updated Environment.Dump pydoc. --- src/engine/SCons/Environment.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py index 6886e85..973c109 100644 --- a/src/engine/SCons/Environment.py +++ b/src/engine/SCons/Environment.py @@ -1528,8 +1528,8 @@ class Base(SubstitutionEnvironment): def Dump(self, key = None): """ - Using the standard Python pretty printer, dump the contents of the - scons build environment to stdout. + Using the standard Python pretty printer, return the contents of the + scons build environment as a string. If the key passed in is anything other than None, then that will be used as an index into the build environment dictionary and -- cgit v0.12 From 5260437c85052289702664c6a1025202eaf7111a Mon Sep 17 00:00:00 2001 From: William Blevins Date: Mon, 29 Jun 2015 16:12:02 -0400 Subject: Issue 2264: Corrected comment description of new output validation function. --- QMTest/TestCommon.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/QMTest/TestCommon.py b/QMTest/TestCommon.py index 275d4f2..c4a5373 100644 --- a/QMTest/TestCommon.py +++ b/QMTest/TestCommon.py @@ -36,7 +36,7 @@ provided by the TestCommon class: test.must_contain('file', 'required text\n') - test.must_contain_all(output, lines, ['title', find]) + test.must_contain_all(output, input, ['title', find]) test.must_contain_all_lines(output, lines, ['title', find]) -- cgit v0.12 From e5ac090e378fd5cda31dd70f762ea2792eed7dc7 Mon Sep 17 00:00:00 2001 From: William Blevins Date: Mon, 29 Jun 2015 23:32:45 -0400 Subject: Issue 2264: Updated behaviour when scanning included dependencies for nodes without scanner_key mappings. --- src/engine/SCons/Node/NodeTests.py | 2 ++ src/engine/SCons/Node/__init__.py | 63 +++++++++++++++++++++++++++----------- test/Scanner/exception.py | 14 ++++----- 3 files changed, 54 insertions(+), 25 deletions(-) diff --git a/src/engine/SCons/Node/NodeTests.py b/src/engine/SCons/Node/NodeTests.py index 4639cf9..1478419 100644 --- a/src/engine/SCons/Node/NodeTests.py +++ b/src/engine/SCons/Node/NodeTests.py @@ -121,6 +121,8 @@ class Environment(object): self._dict.update(kw) def __getitem__(self, key): return self._dict[key] + def get(self, key, default = None): + return self._dict.get(key, default) def Dictionary(self, *args): return {} def Override(self, overrides): diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py index 5721442..64a513b 100644 --- a/src/engine/SCons/Node/__init__.py +++ b/src/engine/SCons/Node/__init__.py @@ -916,7 +916,7 @@ class Node(object): """ return [] - def get_implicit_deps(self, env, scanner, path, kw = {}): + def get_implicit_deps(self, env, initial_scanner, path_func, kw = {}): """Return a list of implicit dependencies for this node. This method exists to handle recursive invocation of the scanner @@ -926,31 +926,58 @@ class Node(object): nodes = [self] seen = {} seen[self] = 1 - deps = [] + dependencies = [] + + root_node_scanner = self._get_scanner(env, initial_scanner, None, kw) + while nodes: - n = nodes.pop(0) + node = nodes.pop(0) - if not scanner: - s = n.get_env_scanner(env, kw) - if s: - s = s.select(n) - else: - s = scanner.select(n) + scanner = node._get_scanner(env, initial_scanner, root_node_scanner, kw) - if not s: + if not scanner: continue - p = path(s) + path = path_func(scanner) - d = [x for x in n.get_found_includes(env, s, p) if x not in seen] - if d: - deps.extend(d) - for n in d: - seen[n] = 1 - nodes.extend(s.recurse_nodes(d)) + included_deps = [x for x in node.get_found_includes(env, scanner, path) if x not in seen] + if included_deps: + dependencies.extend(included_deps) + for dep in included_deps: + seen[dep] = 1 + nodes.extend(scanner.recurse_nodes(included_deps)) - return deps + return dependencies + def _get_scanner(self, env, initial_scanner, root_node_scanner, kw): + if not initial_scanner: + # handle implicit scanner case + scanner = self.get_env_scanner(env, kw) + if scanner: + scanner = scanner.select(self) + else: + # handle explicit scanner case + scanner = initial_scanner.select(self) + + if not scanner: + # no scanner could be found for the given node's scanner key; + # thus, make an attempt at using a default. + + # check for a user specified scanner hint + scanner = env.get( 'SCANNER_HINT' ) + + if scanner: + # Ensure scanner hint returned a valid Scanner object + if not instanceof( scanner, SCons.Scanner.Base ): + raise SCons.Error.UserError( + 'SCANNER_HINT object must be instance of ' + str(SCons.Scanner.Base) + ) + else: + # no scanner hint, so do best guess (IE. return the root's scanner). + scanner = root_node_scanner + + return scanner + def get_env_scanner(self, env, kw={}): return env.get_scanner(self.scanner_key()) diff --git a/test/Scanner/exception.py b/test/Scanner/exception.py index de0a795..1a14152 100644 --- a/test/Scanner/exception.py +++ b/test/Scanner/exception.py @@ -83,23 +83,23 @@ env.Cat('bar', bar_in) test.write('foo.k', """foo.k 1 line 1 -include xxx.k -include yyy.k +include xxx +include yyy foo.k 1 line 4 """) test.write('bar.in', -"""include yyy.k +"""include yyy bar.in 1 line 2 bar.in 1 line 3 -include zzz.k +include zzz """) -test.write('xxx.k', "xxx 1\n") +test.write('xxx', "xxx 1\n") -test.write('yyy.k', "exception yyy 1\n") +test.write('yyy', "exception yyy 1\n") -test.write('zzz.k', "zzz 1\n") +test.write('zzz', "zzz 1\n") test.run(arguments = '.', status = 2, -- cgit v0.12 From 829492d37c7b85e22c169e1171265abdf4841af6 Mon Sep 17 00:00:00 2001 From: William Blevins Date: Tue, 30 Jun 2015 01:12:48 -0400 Subject: Issue 2264: Added test for SCANNER_HINT support, plus bug fixes. --- src/engine/SCons/Node/__init__.py | 4 +- test/Scanner/ScannerHint.py | 119 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+), 2 deletions(-) create mode 100644 test/Scanner/ScannerHint.py diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py index 64a513b..d709f11 100644 --- a/src/engine/SCons/Node/__init__.py +++ b/src/engine/SCons/Node/__init__.py @@ -968,8 +968,8 @@ class Node(object): if scanner: # Ensure scanner hint returned a valid Scanner object - if not instanceof( scanner, SCons.Scanner.Base ): - raise SCons.Error.UserError( + if not isinstance( scanner, SCons.Scanner.Base ): + raise SCons.Errors.UserError( 'SCANNER_HINT object must be instance of ' + str(SCons.Scanner.Base) ) else: diff --git a/test/Scanner/ScannerHint.py b/test/Scanner/ScannerHint.py new file mode 100644 index 0000000..b12b847 --- /dev/null +++ b/test/Scanner/ScannerHint.py @@ -0,0 +1,119 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import TestSCons + +_python_ = TestSCons._python_ + +test = TestSCons.TestSCons() + +# Test behavior of Scanners when evaluating implicit dependencies +# for nodes that do not have mappings from their scanner_key +# to a scanner instance + +test.write('SConstruct', """ +import re + +include_re = re.compile(r'^include\s+(\S+)$', re.M) + +def scan(node, env, scanpaths, arg): + contents = node.get_text_contents() + includes = include_re.findall(contents) + return includes + +def kfile_scan(node, env, scanpaths, arg): + print 'kscan: ' + str(node) + return scan(node, env, scanpaths, arg) + +def k2file_scan(node, env, scanpaths, arg): + print 'k2scan: ' + str(node) + return scan(node, env, scanpaths, arg) + +kscan = Scanner(name = 'kfile', + function = kfile_scan, + argument = None, + skeys = ['.k'], + recursive = True) + +k2scan = Scanner(name = 'k2', + function = k2file_scan, + argument = None, + skeys = ['.k2']) + +env1 = Environment() +env1.Append(SCANNERS = [ kscan, k2scan ] ) +env1.Command( 'k', 'foo.k', Copy( '$TARGET', '$SOURCE' ) ) + +env2 = env1.Clone() +env2.Replace(SCANNER_HINT = k2scan) +env2.Command( 'k2', 'foo.k', Copy( '$TARGET', '$SOURCE' ) ) + +env3 = env1.Clone() +env3.Replace(SCANNER_HINT = 'raise') +env3.Command( 'raise', 'foo.k', Copy( '$TARGET', '$SOURCE' ) ) +""") + +test.write('foo.k', +"""foo.k 1 line 1 +include xxx.k +include yyy +foo.k 1 line 4 +""") + +test.write('xxx.k', "xxx.k 1\n") +test.write('yyy', "yyy 1\n") +test.write('yyy.k2', "yyy.k2 1\n") + +expected_stdout = test.wrap_stdout("""\ +kscan: foo.k +kscan: xxx.k +kscan: yyy +Copy("k", "foo.k") +kscan: foo.k +kscan: xxx.k +k2scan: yyy +Copy("k2", "foo.k") +""") + +test.run(arguments='k k2', stdout=expected_stdout) + +expected_stdout = test.wrap_stdout("""\ +kscan: foo.k +kscan: xxx.k +""", error = True) + +expected_stderr = """\ +scons: *** [raise] SCANNER_HINT object must be instance of +""" + +test.run(arguments='raise', stderr=expected_stderr, stdout=expected_stdout, status = 2) +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: -- cgit v0.12 From 097978017a9e65a5037d8ed37a0acba8c3fd066e Mon Sep 17 00:00:00 2001 From: William Deegan Date: Wed, 29 Jul 2015 19:45:19 -0700 Subject: Remove obsolete aegis revision control scripts --- bin/ae-cvs-ci | 204 --------------------- bin/ae-svn-ci | 240 ------------------------ bin/ae2cvs | 579 ---------------------------------------------------------- 3 files changed, 1023 deletions(-) delete mode 100755 bin/ae-cvs-ci delete mode 100755 bin/ae-svn-ci delete mode 100644 bin/ae2cvs diff --git a/bin/ae-cvs-ci b/bin/ae-cvs-ci deleted file mode 100755 index 47c8073..0000000 --- a/bin/ae-cvs-ci +++ /dev/null @@ -1,204 +0,0 @@ -# -# aegis - project change supervisor -# Copyright (C) 2004 Peter Miller; -# All rights reserved. -# -# As a specific exception to the GPL, you are allowed to copy -# this source file into your own project and modify it, without -# releasing your project under the GPL, unless there is some other -# file or condition which would require it. -# -# MANIFEST: shell script to commit changes to CVS -# -# It is assumed that your CVSROOT and CVS_RSH environment variables have -# already been set appropriately. -# -# This script is expected to be run as by integrate_pass_notify_command -# and as such the baseline has already assumed the shape asked for by -# the change. -# -# integrate_pass_notify_command = -# "$bin/ae-cvs-ci $project $change"; -# -# Alternatively, you may wish to tailor this script to the individual -# needs of your project. Make it a source file, e.g. "etc/ae-cvs-ci.sh" -# and then use the following: -# -# integrate_pass_notify_command = -# "$sh ${s etc/ae-cvs-ci} $project $change"; -# - -USAGE="Usage: $0 " - -PRINT="echo" -EXECUTE="eval" - -while getopts "hnq" FLAG -do - case ${FLAG} in - h ) - echo "${USAGE}" - exit 0 - ;; - n ) - EXECUTE=":" - ;; - q ) - PRINT=":" - ;; - * ) - echo "$0: unknown option ${FLAG}" >&2 - exit 1 - ;; - esac -done - -shift `expr ${OPTIND} - 1` - -case $# in -2) - project=$1 - change=$2 - ;; -*) - echo "${USAGE}" 1>&2 - exit 1 - ;; -esac - -here=`pwd` - -AEGIS_PROJECT=$project -export AEGIS_PROJECT -AEGIS_CHANGE=$change -export AEGIS_CHANGE - -module=`echo $project | sed 's|[.].*||'` - -baseline=`aegis -cd -bl` - -if test X${TMPDIR} = X; then TMPDIR=/var/tmp; fi - -TMP=${TMPDIR}/ae-cvs-ci.$$ -mkdir ${TMP} -cd ${TMP} - -PWD=`pwd` -if test X${PWD} != X${TMP}; then - echo "$0: ended up in ${PWD}, not ${TMP}" >&2 - exit 1 -fi - -fail() -{ - set +x - cd $here - rm -rf ${TMP} - echo "FAILED" 1>&2 - exit 1 -} -trap "fail" 1 2 3 15 - -Command() -{ - ${PRINT} "$*" - ${EXECUTE} "$*" -} - -# -# Create a new CVS work area. -# -# Note: this assumes the module is checked-out into a directory of the -# same name. Is there a way to ask CVS where is is going to put a -# modules, so we can always get the "cd" right? -# -${PRINT} cvs co $module -${EXECUTE} cvs co $module > LOG 2>&1 -if test $? -ne 0; then cat LOG; fail; fi -${EXECUTE} cd $module - -# -# Now we need to extract the sources from Aegis and drop them into the -# CVS work area. There are two ways to do this. -# -# The first way is to use the generated tarball. -# This has the advantage that it has the Makefile.in file in it, and -# will work immediately. -# -# The second way is to use aetar, which will give exact sources, and -# omit all derived files. This will *not* include the Makefile.in, -# and so will not be readily compilable. -# -# gunzip < $baseline/export/${project}.tar.gz | tardy -rp ${project} | tar xf - -aetar -send -comp-alg=gzip -o - | tar xzf - - -# -# If any new directories have been created we will need to add them -# to CVS before we can add the new files which we know are in them, -# or they would not have been created. Do this only if the -n option -# isn't used, because if it is, we won't have actually checked out the -# source and we'd erroneously report that all of them need to be added. -# -if test "X${EXECUTE}" != "X:" -then - find . \( -name CVS -o -name Attic \) -prune -o -type d -print | - xargs --max-args=1 | - while read dir - do - if [ ! -d "$dir/CVS" ] - then - Command cvs add "$dir" - fi - done -fi - -# -# Use the Aegis meta-data to perform some CVS commands that CVS can't -# figure out for itself. -# -aegis -l cf -unf | sed 's| -> [0-9][0-9.]*||' | -while read usage action rev filename -do - if test "x$filename" = "x" - then - filename="$rev" - fi - case $action in - create) - Command cvs add $filename - ;; - remove) - Command rm -f $filename - Command cvs remove $filename - ;; - *) - ;; - esac -done - -# -# Extract the brief description. We'd like to do this using aesub -# or something, like so: -# -# message=`aesub '${version} - ${change description}'` -# -# but the expansion of ${change description} has a lame hard-coded max of -# 80 characters, so we have to do this by hand. (This has the slight -# benefit of preserving backslashes in front of any double-quotes in -# the text; that will have to be handled if we go back to using aesub.) -# -description=`aegis -ca -l | sed -n 's/brief_description = "\(.*\)";$/\1/p'` -version=`aesub '${version}'` -message="$version - $description" - -# -# Now commit all the changes. -# -Command cvs -q commit -m \"$message\" - -# -# All done. Clean up and go home. -# -cd $here -rm -rf ${TMP} -exit 0 diff --git a/bin/ae-svn-ci b/bin/ae-svn-ci deleted file mode 100755 index 301d890..0000000 --- a/bin/ae-svn-ci +++ /dev/null @@ -1,240 +0,0 @@ -# -# aegis - project change supervisor -# Copyright (C) 2004 Peter Miller; -# All rights reserved. -# -# As a specific exception to the GPL, you are allowed to copy -# this source file into your own project and modify it, without -# releasing your project under the GPL, unless there is some other -# file or condition which would require it. -# -# MANIFEST: shell script to commit changes to Subversion -# -# This script is expected to be run by the integrate_pass_notify_command -# and as such the baseline has already assumed the shape asked for by -# the change. -# -# integrate_pass_notify_command = -# "$bin/ae-svn-ci $project $change http://svn.site.com/svn/trunk --username svn_user"; -# -# Alternatively, you may wish to tailor this script to the individual -# needs of your project. Make it a source file, e.g. "etc/ae-svn-ci.sh" -# and then use the following: -# -# integrate_pass_notify_command = -# "$sh ${s etc/ae-svn-ci} $project $change http://svn.site.com/svn/trunk --username svn_user"; -# - -USAGE="Usage: $0 [-hnq] []" - -PRINT="echo" -EXECUTE="eval" - -while getopts "hnq" FLAG -do - case ${FLAG} in - h ) - echo "${USAGE}" - exit 0 - ;; - n ) - EXECUTE=":" - ;; - q ) - PRINT=":" - ;; - * ) - echo "$0: unknown option ${FLAG}" >&2 - exit 1 - ;; - esac -done - -shift `expr ${OPTIND} - 1` - -case $# in -[012]) - echo "${USAGE}" 1>&2 - exit 1 - ;; -*) - project=$1 - change=$2 - svn_url=$3 - shift 3 - svn_co_flags=$* - ;; -esac - -here=`pwd` - -AEGIS_PROJECT=$project -export AEGIS_PROJECT -AEGIS_CHANGE=$change -export AEGIS_CHANGE - -module=`echo $project | sed 's|[.].*||'` - -baseline=`aegis -cd -bl` - -if test X${TMPDIR} = X; then TMPDIR=/var/tmp; fi - -TMP=${TMPDIR}/ae-svn-ci.$$ -mkdir ${TMP} -cd ${TMP} - -PWD=`pwd` -if test X${PWD} != X${TMP}; then - echo "$0: ended up in ${PWD}, not ${TMP}" >&2 - exit 1 -fi - -fail() -{ - set +x - cd $here - rm -rf ${TMP} - echo "FAILED" 1>&2 - exit 1 -} -trap "fail" 1 2 3 15 - -Command() -{ - ${PRINT} "$*" - ${EXECUTE} "$*" -} - -# -# Create a new Subversion work area. -# -# Note: this assumes the module is checked-out into a directory of the -# same name. Is there a way to ask Subversion where it is going to put a -# module, so we can always get the "cd" right? -# -${PRINT} svn co $svn_url $module $svn_co_flags -${EXECUTE} svn co $svn_url $module $svn_co_flags > LOG 2>&1 -if test $? -ne 0; then cat LOG; fail; fi -${EXECUTE} cd $module - -# -# Now we need to extract the sources from Aegis and drop them into the -# Subversion work area. There are two ways to do this. -# -# The first way is to use the generated tarball. -# This has the advantage that it has the Makefile.in file in it, and -# will work immediately. -# -# The second way is to use aetar, which will give exact sources, and -# omit all derived files. This will *not* include the Makefile.in, -# and so will not be readily compilable. -# -# gunzip < $baseline/export/${project}.tar.gz | tardy -rp ${project} | tar xf - -aetar -send -comp-alg=gzip -o - | tar xzf - - -# -# If any new directories have been created we will need to add them -# to Subversion before we can add the new files which we know are in them, -# or they would not have been created. Do this only if the -n option -# isn't used, because if it is, we won't have actually checked out the -# source and we'd erroneously report that all of them need to be added. -# -if test "X${EXECUTE}" != "X:" -then - find . -name .svn -prune -o -type d -print | - xargs --max-args=1 | - while read dir - do - if [ ! -d "$dir/.svn" ] - then - Command svn add -N "$dir" - fi - done -fi - -# -# Use the Aegis meta-data to perform some commands that Subversion can't -# figure out for itself. We use an inline "aer" report script to identify -# when a remove-create pair are actually due to a move. -# -aegis -rpt -nph -f - <<_EOF_ | -auto cs; -cs = project[project_name()].state.branch.change[change_number()]; - -columns({width = 1000;}); - -auto file, moved; -for (file in cs.src) -{ - if (file.move != "") - moved[file.move] = 1; -} - -auto action; -for (file in cs.src) -{ - if (file.action == "remove" && file.move != "") - action = "move"; - else - action = file.action; - /* - * Suppress printing of any files created as the result of a move. - * These are printed as the destination when printing the line for - * the file that was *removed* as a result of the move. - */ - if (action != "create" || ! moved[file.file_name]) - print(sprintf("%s %s \\"%s\\" \\"%s\\"", file.usage, action, file.file_name, file.move)); -} -_EOF_ -while read line -do - eval set -- "$line" - usage="$1" - action="$2" - srcfile="$3" - dstfile="$4" - case $action in - create) - Command svn add $srcfile - ;; - remove) - Command rm -f $srcfile - Command svn remove $srcfile - ;; - move) - Command mv $dstfile $dstfile.move - Command svn move $srcfile $dstfile - Command cp $dstfile.move $dstfile - Command rm -f $dstfile.move - ;; - *) - ;; - esac -done - -# -# Extract the brief description. We'd like to do this using aesub -# or something, like so: -# -# message=`aesub '${version} - ${change description}'` -# -# but the expansion of ${change description} has a lame hard-coded max of -# 80 characters, so we have to do this by hand. (This has the slight -# benefit of preserving backslashes in front of any double-quotes in -# the text; that will have to be handled if we go back to using aesub.) -# -description=`aegis -ca -l | sed -n 's/brief_description = "\(.*\)";$/\1/p'` -version=`aesub '${version}'` -message="$version - $description" - -# -# Now commit all the changes. -# -Command svn commit -m \"$message\" - -# -# All done. Clean up and go home. -# -cd $here -rm -rf ${TMP} -exit 0 diff --git a/bin/ae2cvs b/bin/ae2cvs deleted file mode 100644 index e7cb22b..0000000 --- a/bin/ae2cvs +++ /dev/null @@ -1,579 +0,0 @@ -#! /usr/bin/env perl - -$revision = "src/ae2cvs.pl 0.04.D001 2005/08/14 15:13:36 knight"; - -$copyright = "Copyright 2001, 2002, 2003, 2004, 2005 Steven Knight."; - -# -# All rights reserved. This program is free software; you can -# redistribute and/or modify under the same terms as Perl itself. -# - -use strict; -use File::Find; -use File::Spec; -use Pod::Usage (); - -use vars qw( @add_list @args @cleanup @copy_list @libraries - @mkdir_list @remove_list - %seen_dir - $ae_copy $aedir $aedist - $cnum $comment $commit $common $copyright - $cvs_command $cvsmod $cvsroot - $delta $description $exec $help $indent $infile - $proj $pwd $quiet $revision - $summary $usedir $usepath ); - -$aedist = 1; -$cvsroot = undef; -$exec = undef; -$indent = ""; - -sub version { - print "ae2cvs: $revision\n"; - print "$copyright\n"; - exit 0; -} - -{ - use Getopt::Long; - - Getopt::Long::Configure('no_ignore_case'); - - my $ret = GetOptions ( - "aedist" => sub { $aedist = 1 }, - "aegis" => sub { $aedist = 0 }, - "change=i" => \$cnum, - "d=s" => \$cvsroot, - "file=s" => \$infile, - "help|?" => \$help, - "library=s" => \@libraries, - "module=s" => \$cvsmod, - "noexecute" => sub { $exec = 0 }, - "project=s" => \$proj, - "quiet" => \$quiet, - "usedir=s" => \$usedir, - "v|version" => \&version, - "x|execute" => sub { $exec++ if ! defined $exec || $exec != 0 }, - "X|EXECUTE" => sub { $exec = 2 if ! defined $exec || $exec != 0 }, - ); - - Pod::Usage::pod2usage(-verbose => 0) if $help || ! $ret; - - $exec = 0 if ! defined $exec; -} - -$cvs_command = $cvsroot ? "cvs -d $cvsroot -Q" : "cvs -Q"; - -# -# Wrap up the $quiet logic in one place. -# -sub printit { - return if $quiet; - my $string = join('', @_); - $string =~ s/^/$indent/msg if $indent; - print $string; -} - -# -# Wrappers for executing various builtin Perl functions in -# accordance with the -n, -q and -x options. -# -sub execute { - my $cmd = shift; - printit "$cmd\n"; - if (! $exec) { - return 1; - } - ! system($cmd); -} - -sub _copy { - my ($source, $dest) = @_; - printit "cp $source $dest\n"; - if ($exec) { - use File::Copy; - copy($source, $dest); - } -} - -sub _chdir { - my $dir = shift; - printit "cd $dir\n"; - if ($exec) { - chdir($dir) || die "ae2cvs: could not chdir($dir): $!"; - } -} - -sub _mkdir { - my $dir = shift; - printit "mkdir $dir\n"; - if ($exec) { - mkdir($dir); - } -} - -# -# Put some input data through an external filter and capture the output. -# -sub filter { - my ($cmd, $input) = @_; - - use FileHandle; - use IPC::Open2; - - my $pid = open2(*READ, *WRITE, $cmd) || die "Cannot exec '$cmd': $!\n"; - print WRITE $input; - close(WRITE); - my $output = join('', ); - close(READ); - return $output; -} - -# -# Parse a change description, in both 'aegis -l cd" and "aedist" formats. -# -# Returns an array containing the project name, the change number -# (if any), the delta number (if any), the SUMMARY, the DESCRIPTION -# and the lines describing the files in the change. -# -sub parse_change { - my $output = shift; - - my ($p, $c, $d, $c_or_d, $sum, $desc, $filesection, @flines); - - # The project name line comes after NAME in "aegis -l cd" format, - # and PROJECT in "aedist" format. In both cases, the project name - # and the change/delta name are separated a comma. - ($p = $output) =~ s/(?:NAME|PROJECT)\n([^\n]*)\n.*/$1/ms; - ($p, $c_or_d) = (split(/,/, $p)); - - # In "aegis -l cd" format, the project name actually comes after - # the string "Project" and is itself enclosed in double quotes. - $p =~ s/Project "([^"]*)"/$1/; - - # The change or delta string was the right-hand side of the comma. - # "aegis -l cd" format spells it "Change 123." or "Delta 123." while - # "aedist" format spells it "change 123." - if ($c_or_d =~ /\s*[Cc]hange (\d+).*/) { $c = $1 }; - if ($c_or_d =~ /\s*[Dd]elta (\d+).*/) { $d = $1 }; - - # The SUMMARY line is always followed the DESCRIPTION section. - # It seems to always be a single line, but we grab everything in - # between just in case. - ($sum = $output) =~ s/.*\nSUMMARY\n//ms; - $sum =~ s/\nDESCRIPTION\n.*//ms; - - # The DESCRIPTION section is followed ARCHITECTURE in "aegis -l cd" - # format and by CAUSE in "aedist" format. Explicitly under it if the - # string is only "none," which means they didn't supply a description. - ($desc = $output) =~ s/.*\nDESCRIPTION\n//ms; - $desc =~ s/\n(ARCHITECTURE|CAUSE)\n.*//ms; - chomp($desc); - if ($desc eq "none" || $desc eq "none\n") { $desc = undef } - - # The FILES section is followed by HISTORY in "aegis -l cd" format. - # It seems to be the last section in "aedist" format, but stripping - # a non-existent HISTORY section doesn't hurt. - ($filesection = $output) =~ s/.*\nFILES\n//ms; - $filesection =~ s/\nHISTORY\n.*//ms; - - @flines = split(/\n/, $filesection); - - ($p, $c, $d, $sum, $desc, \@flines) -} - -# -# -# -$pwd = Cwd::cwd(); - -# -# Fetch the file list either from our aedist input -# or directly from the project itself. -# -my @filelines; -if ($aedist) { - local ($/); - undef $/; - my $infile_redir = ""; - my $contents; - if (! $infile || $infile eq "-") { - $contents = join('', ); - } else { - open(FILE, "<$infile") || die "Cannot open '$infile': $!\n"; - binmode(FILE); - $contents = join('', ); - close(FILE); - if (! File::Spec->file_name_is_absolute($infile)) { - $infile = File::Spec->catfile($pwd, $infile); - } - $infile_redir = " < $infile"; - } - - my $output = filter("aedist -l -unf", $contents); - my ($p, $c, $d, $s, $desc, $fl) = parse_change($output); - - $proj = $p if ! defined $proj; - $summary = $s; - $description = $desc; - @filelines = @$fl; - - if (! $exec) { - printit qq(MYTMP="/tmp/ae2cvs-ae.\$\$"\n), - qq(mkdir \$MYTMP\n), - qq(cd \$MYTMP\n); - printit q(perl -MMIME::Base64 -e 'undef $/; ($c = <>) =~ s/.*\n\n//ms; print decode_base64($c)'), - $infile_redir, - qq( | zcat), - qq( | cpio -i -d --quiet\n); - $aedir = '$MYTMP'; - push(@cleanup, $aedir); - } else { - $aedir = File::Spec->catfile(File::Spec->tmpdir, "ae2cvs-ae.$$"); - _mkdir($aedir); - push(@cleanup, $aedir); - _chdir($aedir); - - use MIME::Base64; - - $contents =~ s/.*\n\n//ms; - $contents = filter("zcat", decode_base64($contents)); - - open(CPIO, "|cpio -i -d --quiet"); - print CPIO $contents; - close(CPIO); - } - - $ae_copy = sub { - foreach my $dest (@_) { - my $source = File::Spec->catfile($aedir, "src", $dest); - execute(qq(cp $source $dest)); - } - } -} else { - $cnum = $ENV{AEGIS_CHANGE} if ! defined $cnum; - $proj = $ENV{AEGIS_PROJECT} if ! defined $proj; - - $common = "-lib " . join(" -lib ", @libraries) if @libraries; - $common = "$common -proj $proj" if $proj; - - my $output = `aegis -l cd $cnum -unf $common`; - my ($p, $c, $d, $s, $desc, $fl) = parse_change($output); - - $delta = $d; - $summary = $s; - $description = $desc; - @filelines = @$fl; - - if (! $delta) { - print STDERR "ae2cvs: No delta number, exiting.\n"; - exit 1; - } - - $ae_copy = sub { - execute(qq(aegis -cp -ind -delta $delta $common @_)); - } -} - -if (! $usedir) { - $usedir = File::Spec->catfile(File::Spec->tmpdir, "ae2cvs.$$"); - _mkdir($usedir); - push(@cleanup, $usedir); -} - -_chdir($usedir); - -$usepath = $usedir; -if (! File::Spec->file_name_is_absolute($usepath)) { - $usepath = File::Spec->catfile($pwd, $usepath); -} - -if (! -d File::Spec->catfile($usedir, "CVS")) { - $cvsmod = (split(/\./, $proj))[0] if ! defined $cvsmod; - - execute(qq($cvs_command co $cvsmod)); - - _chdir($cvsmod); - - $usepath = File::Spec->catfile($usepath, $cvsmod); -} - -# -# Figure out what we have to do to accomplish everything. -# -foreach (@filelines) { - my @arr = split(/\s+/, $_); - my $type = shift @arr; # source / test - my $act = shift @arr; # modify / create - my $file = pop @arr; - - if ($act eq "create" or $act eq "modify") { - # XXX Do we really only need to do this for - # ($act eq "create") files? - my (undef, $dirs, undef) = File::Spec->splitpath($file); - my $absdir = $usepath; - my $reldir; - my $d; - foreach $d (File::Spec->splitdir($dirs)) { - next if ! $d; - $absdir = File::Spec->catdir($absdir, $d); - $reldir = $reldir ? File::Spec->catdir($reldir, $d) : $d; - if (! -d $absdir && ! $seen_dir{$reldir}) { - $seen_dir{$reldir} = 1; - push(@mkdir_list, $reldir); - } - } - - push(@copy_list, $file); - - if ($act eq "create") { - push(@add_list, $file); - } - } elsif ($act eq "remove") { - push(@remove_list, $file); - } else { - print STDERR "Unsure how to '$act' the '$file' file.\n"; - } -} - -# Now go through and mkdir() the directories, -# adding them to the CVS tree as we do. -if (@mkdir_list) { - if (! $exec) { - printit qq(# The following "mkdir" and "cvs -Q add" calls are not\n), - qq(# necessary for any directories that already exist in the\n), - qq(# CVS tree but which aren't present locally.\n); - } - foreach (@mkdir_list) { - if (! $exec) { - printit qq(if test ! -d $_; then\n); - $indent = " "; - } - _mkdir($_); - execute(qq($cvs_command add $_)); - if (! $exec) { - $indent = ""; - printit qq(fi\n); - } - } - if (! $exec) { - printit qq(# End of directory creation.\n); - } -} - -# Copy in any files in the change, before we try to "cvs add" them. -$ae_copy->(@copy_list) if @copy_list; - -if (@add_list) { - execute(qq($cvs_command add @add_list)); -} - -if (@remove_list) { - execute(qq(rm -f @remove_list)); - execute(qq($cvs_command remove @remove_list)); -} - -# Last, commit the whole bunch. -$comment = $summary; -$comment .= "\n" . $description if $description; -$commit = qq($cvs_command commit -m '$comment' .); -if ($exec == 1) { - printit qq(# Execute the following to commit the changes:\n), - qq(# $commit\n); -} else { - execute($commit); -} - -_chdir($pwd); - -# -# Directory cleanup. -# -sub END { - my $dir; - foreach $dir (@cleanup) { - printit "rm -rf $dir\n"; - if ($exec) { - finddepth(sub { - # print STDERR "unlink($_)\n" if (!-d $_); - # print STDERR "rmdir($_)\n" if (-d $_ && $_ ne "."); - unlink($_) if (!-d $_); - rmdir($_) if (-d $_ && $_ ne "."); - 1; - }, $dir); - rmdir($dir) || print STDERR "Could not remove $dir: $!\n"; - } - } -} - -__END__; - -=head1 NAME - -ae2cvs - convert an Aegis change set to CVS commands - -=head1 SYNOPSIS - -ae2cvs [-aedist|-aegis] [-c change] [-d cvs_root] [-f file] [-l lib] - [-m module] [-n] [-p proj] [-q] [-u dir] [-v] [-x] [-X] - - -aedist use aedist format from input (default) - -aegis query aegis repository directly - -c change change number - -d cvs_root CVS root directory - -f file read aedist from file ('-' == stdin) - -l lib Aegis library directory - -m module CVS module - -n no execute - -p proj project name - -q quiet, don't print commands - -u dir use dir for CVS checkin - -v print version string and exit - -x execute the commands, but don't commit; - two or more -x options commit changes - -X execute the commands and commit changes - -=head1 DESCRIPTION - -The C utility can convert an Aegis change into a set of CVS (and -other) commands to make the corresponding change(s) to a carbon-copy CVS -repository. This can be used to keep a front-end CVS repository in sync -with changes made to an Aegis project, either manually or automatically -using the C attribute of the Aegis -project. - -By default, C makes no changes to any software, and only prints -out the necessary commands. These commands can be examined first for -safety, and then fed to any Bourne shell variant (sh, ksh, or bash) to -make the actual CVS changes. - -An option exists to have C execute the commands directly. - -=head1 OPTIONS - -The C utility supports the following options: - -=over 4 - -=item -aedist - -Reads an aedist change set. -By default, the change set is read from standard input, -or a file specified with the C<-f> option. - -=item -aegis - -Reads the change directly from the Aegis repository -by executing the proper C commands. - -=item -c change - -Specify the Aegis change number to be used. -The value of the C environment variable -is used by default. - -=item -d cvsroot - -Specify the CVS root directory to be used. -This option is passed explicitly to each executed C command. -The default behavior is to omit any C<-d> options -and let the executed C commands use the -C environment variable as they normally would. - -=item -f file - -Reads the aedist change set from the specified C, -or from standard input if C is C<'-'>. - -=item -l lib - -Specifies an Aegis library directory to be searched for global states -files and user state files. - -=item -m module - -Specifies the name of the CVS module to be brought up-to-date. -The default is to use the Aegis project name, -minus any branch numbers; -for example, given an Aegis project name of C, -the default CVS module name is C. - -=item -n - -No execute. Commands are printed (including a command for a final -commit of changes), but not executed. This is the default. - -=item -p proj - -Specifies the name of the Aegis project from which this change is taken. -The value of the C environment variable -is used by default. - -=item -q - -Quiet. Commands are not printed. - -=item -u dir - -Use the already checked-out CVS tree that exists at C -for the checkins and commits. -The default is to use a separately-created temporary directory. - -=item -v - -Print the version string and exit. - -=item -x - -Execute the commands to bring the CVS repository up to date, -except for the final commit of the changes. Two or more -C<-x> options will cause the change to be committed. - -=item -X - -Execute the commands to bring the CVS repository up to date, -including the final commit of the changes. - -=back - -=head1 ENVIRONMENT VARIABLES - -=over 4 - -=item AE2CVS_FLAGS - -Specifies any options to be used to initialize -the C utility. -Options on the command line override these values. - -=back - -=head1 AUTHOR - -Steven Knight (knight at baldmt dot com) - -=head1 BUGS - -If errors occur during the execution of the Aegis or CVS commands, and -the -X option is used, a partial change (consisting of those files for -which the command(s) succeeded) will be committed. It would be safer to -generate code to detect the error and print a warning. - -When a file has been deleted in Aegis, the standard whiteout file can -cause a regex failure in this script. It doesn't necessarily happen all -the time, though, so this needs more investigation. - -=head1 TODO - -Add an explicit test for using ae2cvs in the Aegis -integrate_pass_notify_command field to support fully keeping a -repository in sync automatically. - -=head1 COPYRIGHT - -Copyright 2001, 2002, 2003, 2004, 2005 Steven Knight. - -=head1 SEE ALSO - -aegis(1), cvs(1) -- cgit v0.12 From fa5c62b33d842413b9dda4596c76d9b25d7afa03 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Wed, 29 Jul 2015 20:19:11 -0700 Subject: Call scons-proc.py with the same python executable that the docs-update-generated is being run by. --- bin/docs-update-generated.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/bin/docs-update-generated.py b/bin/docs-update-generated.py index 66b22c0..55f0035 100644 --- a/bin/docs-update-generated.py +++ b/bin/docs-update-generated.py @@ -8,6 +8,7 @@ # import os +import sys import SConsDoc # Directory where all generated files are stored @@ -41,8 +42,8 @@ def generate_all(): print "Couldn't create destination folder %s! Exiting..." % gen_folder return # Call scons-proc.py - os.system('python %s -b %s -f %s -t %s -v %s %s' % - (os.path.join('bin','scons-proc.py'), + os.system('%s %s -b %s -f %s -t %s -v %s %s' % + (sys.executable, os.path.join('bin','scons-proc.py'), argpair('builders'), argpair('functions'), argpair('tools'), argpair('variables'), ' '.join(flist))) -- cgit v0.12 From b63ae0f3e4d5ef95c6bceb3d61a331d652ab8f49 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Fri, 31 Jul 2015 13:41:41 -0700 Subject: update docs for 2.3.5 release --- doc/generated/examples/caching_ex-random_1.xml | 6 +-- doc/generated/examples/troubleshoot_explain1_3.xml | 2 +- doc/generated/variables.gen | 48 +++++++++++----------- doc/generated/variables.mod | 4 +- 4 files changed, 30 insertions(+), 30 deletions(-) diff --git a/doc/generated/examples/caching_ex-random_1.xml b/doc/generated/examples/caching_ex-random_1.xml index b864ef4..6f64f8f 100644 --- a/doc/generated/examples/caching_ex-random_1.xml +++ b/doc/generated/examples/caching_ex-random_1.xml @@ -1,9 +1,9 @@ % scons -Q -cc -o f1.o -c f1.c -cc -o f3.o -c f3.c -cc -o f4.o -c f4.c cc -o f2.o -c f2.c +cc -o f4.o -c f4.c +cc -o f3.o -c f3.c cc -o f5.o -c f5.c +cc -o f1.o -c f1.c cc -o prog f1.o f2.o f3.o f4.o f5.o diff --git a/doc/generated/examples/troubleshoot_explain1_3.xml b/doc/generated/examples/troubleshoot_explain1_3.xml index 0a5299b..246ee56 100644 --- a/doc/generated/examples/troubleshoot_explain1_3.xml +++ b/doc/generated/examples/troubleshoot_explain1_3.xml @@ -3,5 +3,5 @@ cp file.in file.oout scons: warning: Cannot find target file.out after building -File "/home/garyo/src/scons-scons/src/script/scons.py", line 199, in <module> +File "/home/bdbaddog/scons/as_scons/bootstrap/src/script/scons.py", line 199, in <module> diff --git a/doc/generated/variables.gen b/doc/generated/variables.gen index 120b4a3..bf18796 100644 --- a/doc/generated/variables.gen +++ b/doc/generated/variables.gen @@ -950,19 +950,19 @@ DFLAGPREFIX. - - DFLAGS + + _DFLAGS -DFLAGS. +_DFLAGS. - - _DFLAGS + + DFLAGS -_DFLAGS. +DFLAGS. @@ -2820,6 +2820,15 @@ is -dNOPAUSE -dBATCH -sDEVICE=pdfwrite HOST_ARCH + The name of the host hardware architecture used to create the Environment. + If a platform is specified when creating the Environment, then + that Platform's logic will handle setting this value. + This value is immutable, and should not be changed by the user after + the Environment is initialized. + Currently only set for Win32. + + + Sets the host architecture for Visual Studio compiler. If not set, default to the detected host architecture: note that this may depend on the python you are using. @@ -2835,16 +2844,7 @@ Valid values are the same as for This is currently only used on Windows, but in the future it will be used on other OSes as well. - - - The name of the host hardware architecture used to create the Environment. - If a platform is specified when creating the Environment, then - that Platform's logic will handle setting this value. - This value is immutable, and should not be changed by the user after - the Environment is initialized. - Currently only set for Win32. - - + HOST_OS @@ -6866,6 +6866,13 @@ that may not be set or used in a construction environment. TARGET_ARCH + The name of the target hardware architecture for the compiled objects + created by this Environment. + This defaults to the value of HOST_ARCH, and the user can override it. + Currently only set for Win32. + + + Sets the target architecture for Visual Studio compiler (i.e. the arch of the binaries generated by the compiler). If not set, default to $HOST_ARCH, or, if that is unset, to the architecture of the @@ -6890,14 +6897,7 @@ and ia64 (Itanium). For example, if you want to compile 64-bit binaries, you would set TARGET_ARCH='x86_64' in your SCons environment. - - - The name of the target hardware architecture for the compiled objects - created by this Environment. - This defaults to the value of HOST_ARCH, and the user can override it. - Currently only set for Win32. - - + TARGET_OS diff --git a/doc/generated/variables.mod b/doc/generated/variables.mod index 3f254a5..fc12a92 100644 --- a/doc/generated/variables.mod +++ b/doc/generated/variables.mod @@ -76,8 +76,8 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. $DESCRIPTION_lang"> $DFILESUFFIX"> $DFLAGPREFIX"> -$DFLAGS"> $_DFLAGS"> +$DFLAGS"> $DFLAGSUFFIX"> $_DINCFLAGS"> $DINCPREFIX"> @@ -714,8 +714,8 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. $DESCRIPTION_lang"> $DFILESUFFIX"> $DFLAGPREFIX"> -$DFLAGS"> $_DFLAGS"> +$DFLAGS"> $DFLAGSUFFIX"> $_DINCFLAGS"> $DINCPREFIX"> -- cgit v0.12 From 5d3694daa2fb40c82307f9221a2bea58befd3db7 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Fri, 31 Jul 2015 14:15:27 -0700 Subject: Changes for 2.3.6 --- debian/changelog | 6 ++++++ src/Announce.txt | 3 +++ src/CHANGES.txt | 4 ---- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/debian/changelog b/debian/changelog index 9dbb1b3..b161db1 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +scons (2.3.6) unstable; urgency=low + + * Maintenance release. + + -- William Deegan Mon, 17 Jun 2015 21:07:32 -0700 + scons (2.3.5) unstable; urgency=low * Maintenance release. diff --git a/src/Announce.txt b/src/Announce.txt index 2d26ab5..f96e703 100644 --- a/src/Announce.txt +++ b/src/Announce.txt @@ -45,6 +45,9 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER changes. + Please note the following important changes since release 2.3.5: + - Support for Visual Studio 2015 + Please note the following important changes since release 2.3.4: - Documentation fixes for libraries.xml and builders-writing.xml (#2989 and #2990) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index b3a46b8..906ccfc 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -6,10 +6,6 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER - From John Doe: - - - Whatever John Doe did. - From Rob Smith: - Added support for Visual Studio 2015 -- cgit v0.12 From 0e917c316284acc6856d0e5cff81945050c4648d Mon Sep 17 00:00:00 2001 From: William Deegan Date: Fri, 31 Jul 2015 20:33:34 -0700 Subject: post 2.3.6 release changes --- QMTest/TestSCons.py | 2 +- README.rst | 16 ++++++++-------- ReleaseConfig | 2 +- SConstruct | 4 ++-- src/CHANGES.txt | 7 +++++++ src/RELEASE.txt | 2 +- 6 files changed, 20 insertions(+), 13 deletions(-) diff --git a/QMTest/TestSCons.py b/QMTest/TestSCons.py index bae96e6..a9b4e3e 100644 --- a/QMTest/TestSCons.py +++ b/QMTest/TestSCons.py @@ -34,7 +34,7 @@ from TestCmd import PIPE # here provides some independent verification that what we packaged # conforms to what we expect. -default_version = '2.3.5' +default_version = '2.3.6' python_version_unsupported = (2, 3, 0) python_version_deprecated = (2, 7, 0) diff --git a/README.rst b/README.rst index 64e8748..9ed0ccc 100644 --- a/README.rst +++ b/README.rst @@ -480,14 +480,14 @@ following packages will be built:: build/dist/scons-2.3.3-1.noarch.rpm build/dist/scons-2.3.3-1.src.rpm build/dist/scons-2.3.3.linux-i686.tar.gz - build/dist/scons-2.3.5.tar.gz - build/dist/scons-2.3.5.win32.exe - build/dist/scons-2.3.5.zip - build/dist/scons-doc-2.3.5.tar.gz - build/dist/scons-local-2.3.5.tar.gz - build/dist/scons-local-2.3.5.zip - build/dist/scons-src-2.3.5.tar.gz - build/dist/scons-src-2.3.5.zip + build/dist/scons-2.3.6.tar.gz + build/dist/scons-2.3.6.win32.exe + build/dist/scons-2.3.6.zip + build/dist/scons-doc-2.3.6.tar.gz + build/dist/scons-local-2.3.6.tar.gz + build/dist/scons-local-2.3.6.zip + build/dist/scons-src-2.3.6.tar.gz + build/dist/scons-src-2.3.6.zip build/dist/scons_2.3.3-1_all.deb The SConstruct file is supposed to be smart enough to avoid trying to build diff --git a/ReleaseConfig b/ReleaseConfig index b5623be..5a191ba 100644 --- a/ReleaseConfig +++ b/ReleaseConfig @@ -32,7 +32,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" # 'final', the patchlevel is set to the release date. This value is # mandatory and must be present in this file. #version_tuple = (2, 2, 0, 'final', 0) -version_tuple = (2, 3, 6, 'alpha', 0) +version_tuple = (2, 3, 8, 'alpha', 0) # Python versions prior to unsupported_python_version cause a fatal error # when that version is used. Python versions prior to deprecate_python_version diff --git a/SConstruct b/SConstruct index bbddd98..e8b6c9a 100644 --- a/SConstruct +++ b/SConstruct @@ -6,7 +6,7 @@ copyright_years = '2001 - 2015' # This gets inserted into the man pages to reflect the month of release. -month_year = 'June 2015' +month_year = 'July 2015' # # __COPYRIGHT__ @@ -43,7 +43,7 @@ import tempfile import bootstrap project = 'scons' -default_version = '2.3.5' +default_version = '2.3.6' copyright = "Copyright (c) %s The SCons Foundation" % copyright_years platform = distutils.util.get_platform() diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 906ccfc..7cbfe8b 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -6,6 +6,13 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER + From John Doe: + + - Whatever John Doe did. + + +RELEASE 2.3.6 - Mon, 31 Jul 2015 14:35:03 -0700 + From Rob Smith: - Added support for Visual Studio 2015 diff --git a/src/RELEASE.txt b/src/RELEASE.txt index 303776c..83212a7 100644 --- a/src/RELEASE.txt +++ b/src/RELEASE.txt @@ -1,4 +1,4 @@ - A new SCons checkpoint release, 2.3.6.alpha.yyyymmdd, is now available + A new SCons checkpoint release, 2.3.8.alpha.yyyymmdd, is now available on the SCons download page: http://www.scons.org/download.php -- cgit v0.12 From d152e4ce442ae724084c9304c9e36e882fa5850d Mon Sep 17 00:00:00 2001 From: Dirk Baechle Date: Thu, 6 Aug 2015 23:50:31 +0200 Subject: - fixed several tests and tools that still used Node attributes directly (found by disabling the __getattr__ in Node/FS.py) --- src/engine/SCons/Tool/link.py | 2 +- src/engine/SCons/Tool/msvs.py | 2 +- test/Glob/Repository.py | 2 +- test/Glob/exclude.py | 4 ++-- test/Interactive/variant_dir.py | 4 ++-- test/option/md5-chunksize.py | 4 ++-- test/site_scons/sysdirs.py | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/engine/SCons/Tool/link.py b/src/engine/SCons/Tool/link.py index 2624946..a084bc4 100644 --- a/src/engine/SCons/Tool/link.py +++ b/src/engine/SCons/Tool/link.py @@ -86,7 +86,7 @@ def shlib_emitter(target, source, env): # the version number target[0].attributes.shlibname = version_names[0] shlib = env.File(version_names[0], directory=target[0].get_dir()) - target[0].attributes.shlibpath = shlib.path + target[0].attributes.shlibpath = shlib.get_internal_path() for name in version_names[1:]: env.SideEffect(name, shlib) env.Clean(shlib, name) diff --git a/src/engine/SCons/Tool/msvs.py b/src/engine/SCons/Tool/msvs.py index 8b74cf4..355eeed 100644 --- a/src/engine/SCons/Tool/msvs.py +++ b/src/engine/SCons/Tool/msvs.py @@ -1983,7 +1983,7 @@ def generate(env): env['MSVSSCONSCRIPT'] = default_MSVS_SConscript env['MSVSSCONS'] = '"%s" -c "%s"' % (python_executable, getExecScriptMain(env)) - env['MSVSSCONSFLAGS'] = '-C "${MSVSSCONSCRIPT.dir.abspath}" -f ${MSVSSCONSCRIPT.name}' + env['MSVSSCONSFLAGS'] = '-C "${MSVSSCONSCRIPT.dir.get_abspath()}" -f ${MSVSSCONSCRIPT.name}' env['MSVSSCONSCOM'] = '$MSVSSCONS $MSVSSCONSFLAGS' env['MSVSBUILDCOM'] = '$MSVSSCONSCOM "$MSVSBUILDTARGET"' env['MSVSREBUILDCOM'] = '$MSVSSCONSCOM "$MSVSBUILDTARGET"' diff --git a/test/Glob/Repository.py b/test/Glob/Repository.py index 0a2e326..22a7f88 100644 --- a/test/Glob/Repository.py +++ b/test/Glob/Repository.py @@ -75,7 +75,7 @@ test.write(['repository', 'src', 'SConscript'], """ Import("env") env.Build('xxx.out', Glob('x*.in')) env.Build('yyy.out', Glob('yy?.in')) -env.Build('zzz.out', sorted(Glob('*/zzz.in'), key=lambda t: t.abspath)) +env.Build('zzz.out', sorted(Glob('*/zzz.in'), key=lambda t: t.get_abspath())) """) test.write(['repository', 'src', 'xxx.in'], "repository/src/xxx.in\n") diff --git a/test/Glob/exclude.py b/test/Glob/exclude.py index 56b58a8..fe93b82 100644 --- a/test/Glob/exclude.py +++ b/test/Glob/exclude.py @@ -46,9 +46,9 @@ def concatenate(target, source, env): env['BUILDERS']['Concatenate'] = Builder(action=concatenate) -env.Concatenate('fa.out', sorted(Glob('f*.in' , exclude=['f2.in', 'f4.*'] , strings=False), key=lambda t: t.path)) +env.Concatenate('fa.out', sorted(Glob('f*.in' , exclude=['f2.in', 'f4.*'] , strings=False), key=lambda t: t.get_internal_path())) env.Concatenate('fb.out', sorted(Glob('f*.in' , exclude=['f2.in', 'f4.*'] , strings=True))) -env.Concatenate('fc.out', sorted(Glob('d?/f*.in', exclude=['d?/f1.*', 'f2.in'], strings=False), key=lambda t: t.path)) +env.Concatenate('fc.out', sorted(Glob('d?/f*.in', exclude=['d?/f1.*', 'f2.in'], strings=False), key=lambda t: t.get_internal_path())) env.Concatenate('fd.out', sorted(Glob('d?/f*.in', exclude=['d?/f1.*', 'f2.in'], strings=True))) env.Concatenate('fe.out', sorted(Glob('f*.in', exclude='f1.in' , strings=True))) env.Concatenate('ff.out', sorted(Glob('f*.in', exclude='other' , strings=True))) diff --git a/test/Interactive/variant_dir.py b/test/Interactive/variant_dir.py index f36bd0a..7f2c42f 100644 --- a/test/Interactive/variant_dir.py +++ b/test/Interactive/variant_dir.py @@ -41,10 +41,10 @@ marker_2 = test.workpath('markers', '2') test.write(['work', 'SConstruct'], """\ # build the plugin binaries -basepath = str(Dir('#').abspath) +basepath = str(Dir('#').get_abspath()) env = Environment() env.Append(BASEPATH=basepath) -env.Append(ENV = {'BASEPATH' : str(Dir('#').abspath)}) +env.Append(ENV = {'BASEPATH' : str(Dir('#').get_abspath())}) SConscript( 'sub1/SConscript', variant_dir = 'build', duplicate=False, diff --git a/test/option/md5-chunksize.py b/test/option/md5-chunksize.py index 375208d..dbb2615 100644 --- a/test/option/md5-chunksize.py +++ b/test/option/md5-chunksize.py @@ -104,8 +104,8 @@ get_stat(["test.stat"], ["test.big"]) test2.write('SConstruct', """ import os def get_stat(target, source, env): - stat = os.stat(source[0].abspath) - dest = open(target[0].abspath,'w') + stat = os.stat(source[0].get_abspath()) + dest = open(target[0].get_abspath(),'w') dest.write(str(stat)) dest.close() env = Environment() diff --git a/test/site_scons/sysdirs.py b/test/site_scons/sysdirs.py index c05ef67..f50485a 100644 --- a/test/site_scons/sysdirs.py +++ b/test/site_scons/sysdirs.py @@ -39,7 +39,7 @@ test = TestSCons.TestSCons() test.write('SConstruct', """ import SCons.Script -SCons.Script.Main.test_load_all_site_scons_dirs(Dir('.').path) +SCons.Script.Main.test_load_all_site_scons_dirs(Dir('.').get_internal_path()) """) test.run(arguments = '-Q .') -- cgit v0.12 From 27ae977d3fa04e29166e172fa64f7b5439d9f0c8 Mon Sep 17 00:00:00 2001 From: William Blevins Date: Fri, 7 Aug 2015 00:25:40 -0400 Subject: Issue 2264: Removed redundant SCANNER_HINT for preference of SCANNERS. Also possibly SCons.Tool.SourceFileScanner (global only). Updated test to reflect with case using SCANNERS plus root node default. --- src/engine/SCons/Node/__init__.py | 14 +--- test/Scanner/CrossLanguageNoExtension.py | 110 ++++++++++++++++++++++++++++ test/Scanner/ScannerHint.py | 119 ------------------------------- 3 files changed, 111 insertions(+), 132 deletions(-) create mode 100644 test/Scanner/CrossLanguageNoExtension.py delete mode 100644 test/Scanner/ScannerHint.py diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py index d709f11..5aa9600 100644 --- a/src/engine/SCons/Node/__init__.py +++ b/src/engine/SCons/Node/__init__.py @@ -962,19 +962,7 @@ class Node(object): if not scanner: # no scanner could be found for the given node's scanner key; # thus, make an attempt at using a default. - - # check for a user specified scanner hint - scanner = env.get( 'SCANNER_HINT' ) - - if scanner: - # Ensure scanner hint returned a valid Scanner object - if not isinstance( scanner, SCons.Scanner.Base ): - raise SCons.Errors.UserError( - 'SCANNER_HINT object must be instance of ' + str(SCons.Scanner.Base) - ) - else: - # no scanner hint, so do best guess (IE. return the root's scanner). - scanner = root_node_scanner + scanner = root_node_scanner return scanner diff --git a/test/Scanner/CrossLanguageNoExtension.py b/test/Scanner/CrossLanguageNoExtension.py new file mode 100644 index 0000000..5bf205f --- /dev/null +++ b/test/Scanner/CrossLanguageNoExtension.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import TestSCons + +_python_ = TestSCons._python_ + +test = TestSCons.TestSCons() + +# Test behavior of Scanners when evaluating implicit dependencies +# for nodes that do not have mappings from their scanner_key +# to a scanner instance + +test.write('SConstruct', """ +import re + +include_re = re.compile(r'^include\s+(\S+)$', re.M) + +def scan(node, env, scanpaths, arg): + contents = node.get_text_contents() + includes = include_re.findall(contents) + return includes + +def kfile_scan(node, env, scanpaths, arg): + print 'kscan: ' + str(node) + return scan(node, env, scanpaths, arg) + +def k2file_scan(node, env, scanpaths, arg): + print 'k2scan: ' + str(node) + return scan(node, env, scanpaths, arg) + +kscan = Scanner(name = 'kfile', + function = kfile_scan, + argument = None, + skeys = ['.k'], + recursive = True) + +k2scan = Scanner(name = 'k2', + function = k2file_scan, + argument = None, + skeys = ['.k2']) + +k2scan2 = Scanner(name = 'k2', + function = k2file_scan, + argument = None, + skeys = ['']) + +env1 = Environment() +env1.Append(SCANNERS = [ kscan, k2scan ] ) +env1.Command( 'k', 'foo.k', Copy( '$TARGET', '$SOURCE' ) ) + +env2 = env1.Clone() +env2.Append(SCANNERS = [ k2scan2 ] ) +env2.Command( 'k2', 'foo.k', Copy( '$TARGET', '$SOURCE' ) ) +""") + +test.write('foo.k', +"""foo.k 1 line 1 +include xxx.k +include yyy +foo.k 1 line 4 +""") + +test.write('xxx.k', "xxx.k 1\n") +test.write('yyy', "yyy 1\n") +test.write('yyy.k2', "yyy.k2 1\n") + +expected_stdout = test.wrap_stdout("""\ +kscan: foo.k +kscan: xxx.k +kscan: yyy +Copy("k", "foo.k") +kscan: foo.k +kscan: xxx.k +k2scan: yyy +Copy("k2", "foo.k") +""") + +test.run(arguments='k k2', stdout=expected_stdout) + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/Scanner/ScannerHint.py b/test/Scanner/ScannerHint.py deleted file mode 100644 index b12b847..0000000 --- a/test/Scanner/ScannerHint.py +++ /dev/null @@ -1,119 +0,0 @@ -#!/usr/bin/env python -# -# __COPYRIGHT__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import TestSCons - -_python_ = TestSCons._python_ - -test = TestSCons.TestSCons() - -# Test behavior of Scanners when evaluating implicit dependencies -# for nodes that do not have mappings from their scanner_key -# to a scanner instance - -test.write('SConstruct', """ -import re - -include_re = re.compile(r'^include\s+(\S+)$', re.M) - -def scan(node, env, scanpaths, arg): - contents = node.get_text_contents() - includes = include_re.findall(contents) - return includes - -def kfile_scan(node, env, scanpaths, arg): - print 'kscan: ' + str(node) - return scan(node, env, scanpaths, arg) - -def k2file_scan(node, env, scanpaths, arg): - print 'k2scan: ' + str(node) - return scan(node, env, scanpaths, arg) - -kscan = Scanner(name = 'kfile', - function = kfile_scan, - argument = None, - skeys = ['.k'], - recursive = True) - -k2scan = Scanner(name = 'k2', - function = k2file_scan, - argument = None, - skeys = ['.k2']) - -env1 = Environment() -env1.Append(SCANNERS = [ kscan, k2scan ] ) -env1.Command( 'k', 'foo.k', Copy( '$TARGET', '$SOURCE' ) ) - -env2 = env1.Clone() -env2.Replace(SCANNER_HINT = k2scan) -env2.Command( 'k2', 'foo.k', Copy( '$TARGET', '$SOURCE' ) ) - -env3 = env1.Clone() -env3.Replace(SCANNER_HINT = 'raise') -env3.Command( 'raise', 'foo.k', Copy( '$TARGET', '$SOURCE' ) ) -""") - -test.write('foo.k', -"""foo.k 1 line 1 -include xxx.k -include yyy -foo.k 1 line 4 -""") - -test.write('xxx.k', "xxx.k 1\n") -test.write('yyy', "yyy 1\n") -test.write('yyy.k2', "yyy.k2 1\n") - -expected_stdout = test.wrap_stdout("""\ -kscan: foo.k -kscan: xxx.k -kscan: yyy -Copy("k", "foo.k") -kscan: foo.k -kscan: xxx.k -k2scan: yyy -Copy("k2", "foo.k") -""") - -test.run(arguments='k k2', stdout=expected_stdout) - -expected_stdout = test.wrap_stdout("""\ -kscan: foo.k -kscan: xxx.k -""", error = True) - -expected_stderr = """\ -scons: *** [raise] SCANNER_HINT object must be instance of -""" - -test.run(arguments='raise', stderr=expected_stderr, stdout=expected_stdout, status = 2) -test.pass_test() - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: -- cgit v0.12 From 352c0ef0203f0f09de077d1662f95d896f08ff1c Mon Sep 17 00:00:00 2001 From: William Blevins Date: Fri, 7 Aug 2015 10:29:05 -0400 Subject: Issue 2264: removed implicit dependency recursion from install targets. Resolves performance issue with implicit dependencies (without builders) reinstalling. Example (C++): A.h includes B.h and both are installed somewhere. B.h is updated so both A.h and B.h would be reinstalled because B.h changed. A.h didn't need to be reinstalled for obvious reasons. Background info: this was already an issue for any scanner added to SCANNERS environment. Did not occur originally because default scanners not in SCANNERS environment. --- src/engine/SCons/Tool/install.py | 1 + test/IDL/IDLSUFFIXES.py | 5 ----- test/explain/basic.py | 25 +++++++++++-------------- test/explain/save-info.py | 7 ++----- 4 files changed, 14 insertions(+), 24 deletions(-) diff --git a/src/engine/SCons/Tool/install.py b/src/engine/SCons/Tool/install.py index 9f2e937..847af34 100644 --- a/src/engine/SCons/Tool/install.py +++ b/src/engine/SCons/Tool/install.py @@ -447,6 +447,7 @@ def generate(env): source_factory = env.fs.Entry, multi = 1, emitter = [ add_targets_to_INSTALLED_FILES, ], + source_scanner = SCons.Scanner.Base( {}, name = 'Install', recursive = False ), name = 'InstallBuilder') global BaseVersionedInstallBuilder diff --git a/test/IDL/IDLSUFFIXES.py b/test/IDL/IDLSUFFIXES.py index f71ceba..0a9a50c 100644 --- a/test/IDL/IDLSUFFIXES.py +++ b/test/IDL/IDLSUFFIXES.py @@ -60,11 +60,6 @@ test.up_to_date(arguments='.') test.write('foo.h', "foo.h 2\n") -test.run(arguments='.', stdout=test.wrap_stdout("""\ -Install file: "foo.idl" as "foo_idl" -Install file: "foo.x" as "foo_x" -""")) - test.up_to_date(arguments='.') test.pass_test() diff --git a/test/explain/basic.py b/test/explain/basic.py index 5e31cfd..1072ac4 100644 --- a/test/explain/basic.py +++ b/test/explain/basic.py @@ -169,10 +169,18 @@ test.write(['src', 'file6.in'], "file6.in 1\n") test.write(['src', 'subdir', 'file7.in'], "subdir/file7.in 1\n") -args = '--debug=explain .' +args = '--debug=explain ..' expect = test.wrap_stdout("""\ +scons: building `%(inc_aaa)s' because it doesn't exist +Install file: "aaa" as "%(inc_aaa)s" +scons: building `%(inc_bbb_k)s' because it doesn't exist +Install file: "bbb.k" as "%(inc_bbb_k)s" +scons: building `%(inc_ddd)s' because it doesn't exist +Install file: "ddd" as "%(inc_ddd)s" +scons: building `%(inc_eee)s' because it doesn't exist +Install file: "eee.in" as "%(inc_eee)s" scons: building `file1' because it doesn't exist %(_python_)s %(cat_py)s file1 file1.in scons: building `file2' because it doesn't exist @@ -181,14 +189,6 @@ scons: building `file3' because it doesn't exist %(_python_)s %(cat_py)s file3 xxx yyy zzz scons: building `file4' because it doesn't exist %(_python_)s %(cat_py)s file4 - file4.in -scons: building `%(inc_aaa)s' because it doesn't exist -Install file: "aaa" as "%(inc_aaa)s" -scons: building `%(inc_ddd)s' because it doesn't exist -Install file: "ddd" as "%(inc_ddd)s" -scons: building `%(inc_eee)s' because it doesn't exist -Install file: "eee.in" as "%(inc_eee)s" -scons: building `%(inc_bbb_k)s' because it doesn't exist -Install file: "bbb.k" as "%(inc_bbb_k)s" scons: building `file5' because it doesn't exist %(_python_)s %(cat_py)s file5 file5.k scons: building `file6' because it doesn't exist @@ -236,6 +236,8 @@ test_value = '"second"' WriteInitialTest( locals() ) expect = test.wrap_stdout("""\ +scons: rebuilding `%(inc_bbb_k)s' because `bbb.k' changed +Install file: "bbb.k" as "%(inc_bbb_k)s" scons: rebuilding `file1' because `file1.in' changed %(_python_)s %(cat_py)s file1 file1.in scons: rebuilding `file2' because `yyy' changed @@ -244,11 +246,6 @@ scons: rebuilding `file3' because: `yyy' changed `zzz' changed %(_python_)s %(cat_py)s file3 xxx yyy zzz -scons: rebuilding `%(inc_bbb_k)s' because: - `%(inc_ddd)s' is no longer a dependency - `%(inc_eee)s' is no longer a dependency - `bbb.k' changed -Install file: "bbb.k" as "%(inc_bbb_k)s" scons: rebuilding `file5' because `%(inc_bbb_k)s' changed %(_python_)s %(cat_py)s file5 file5.k scons: rebuilding `file6' because AlwaysBuild() is specified diff --git a/test/explain/save-info.py b/test/explain/save-info.py index d2ffc7d..af4c3f5 100644 --- a/test/explain/save-info.py +++ b/test/explain/save-info.py @@ -141,7 +141,7 @@ file5.k 1 line 4 test.write(['src', 'subdir', 'file6.in'], "subdir/file6.in 1\n") # -test.run(chdir='src', arguments='.') +test.run(chdir='src', arguments='..') test.must_match(['src', 'file1'], "file1.in 1\n") test.must_match(['src', 'file2'], """\ @@ -176,10 +176,7 @@ scons: rebuilding `file3' because: `yyy' changed `zzz' changed %(_python_)s %(cat_py)s file3 xxx yyy zzz -scons: rebuilding `%(inc_bbb_k)s' because: - `%(inc_ddd)s' is no longer a dependency - `%(inc_eee)s' is no longer a dependency - `bbb.k' changed +scons: rebuilding `%(inc_bbb_k)s' because `bbb.k' changed Install file: "bbb.k" as "%(inc_bbb_k)s" scons: rebuilding `file5' because `%(inc_bbb_k)s' changed %(_python_)s %(cat_py)s file5 file5.k -- cgit v0.12 From 04b306103a2c37b90f2d764112c0cb5527313849 Mon Sep 17 00:00:00 2001 From: William Blevins Date: Fri, 7 Aug 2015 18:04:38 -0400 Subject: Issue 2264: Update announcement and change logs. --- src/Announce.txt | 27 +++++++++++++++++++++++++++ src/CHANGES.txt | 6 ++++++ 2 files changed, 33 insertions(+) diff --git a/src/Announce.txt b/src/Announce.txt index f96e703..ab278ec 100644 --- a/src/Announce.txt +++ b/src/Announce.txt @@ -18,6 +18,33 @@ So that everyone using SCons can help each other learn how to use it more effectively, please go to http://scons.org/lists.php#users to sign up for the scons-users mailing list. +==============IMPORTANT NOTICE FOR NEXT VERSION V2.X.X========== + +PLEASE READ. CHANGES COMING IN NEXT MAJOR RELEASE V2.X.X + +We're enhancing implicit language scanning functionality to improve +correctness. SCons now honors scanner keys for implicit +dependencies and correctly changes scanner type (if necessary) when +traversing implicit dependency trees. This enhancement resolves +missing dependencies with built-in scanners including SWIG (#2264) +and QT: +* http://scons.tigris.org/issues/show_bug.cgi?id=2264 + +This enhancement broadens the horizon for handling heterogeneous +data flow environments (E.G. software builds): +* http://article.gmane.org/gmane.comp.programming.tools.scons.user/26596 + +Notes: +* SCons may find new (and correct) dependencies in cross-langauge contexts. +** Update may cause rebuilds, especially in heterogeneous data environments. +** Update may find previously missed dependencies errors (E.G. cycles). +*** Discovered in some QT test cases. +* SCons handles the SCANNERS variable differently. +** Previously, the Install builder would scan implicit dependencies for + a scanner found in SCANNERS (but not for built-in scanners), but now + the Install builder will not scan recursively regardless in order + to optimize Install behaviour and bring orthogonality to previous behaviour. + ==============IMPORTANT NOTICE FOR NEXT VERSION V2.4.0=========== PLEASE READ. CHANGES COMING IN NEXT MAJOR RELEASE V2.4.0 diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 977d00f..89bf7b5 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -6,6 +6,12 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER + From William Blevins: + - Added support for cross-language dependency scanning; + SCons now respects scanner keys for implicit dependencies. + - Resolved missing cross-language dependencies for + SWIG bindings (fixes #2264). + From Dirk Baechle: - Switched several core classes to using "slots", for reducing the overall memory consumption in large -- cgit v0.12 From a6a65ee80272d61fa2e09e33eeedfa0e08aed333 Mon Sep 17 00:00:00 2001 From: Dirk Baechle Date: Tue, 1 Sep 2015 23:09:11 +0200 Subject: - added "suffix" attribute to backward compat layer (getattr) for Node.FS entries --- src/engine/SCons/Node/FS.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py index a16fde0..a3db8fe 100644 --- a/src/engine/SCons/Node/FS.py +++ b/src/engine/SCons/Node/FS.py @@ -664,8 +664,8 @@ class Base(SCons.Node.Node): """ Together with the node_bwcomp dict defined below, this method provides a simple backward compatibility layer for the Node attributes 'abspath', 'labspath', - 'path', 'tpath' and 'path_elements'. These Node attributes - used to be directly available in v2.3 and earlier, but + 'path', 'tpath', 'suffix' and 'path_elements'. These Node + attributes used to be directly available in v2.3 and earlier, but have been replaced by getter methods that initialize the single variables lazily when required, in order to save memory. The redirection to the getters lets older Tools and @@ -948,7 +948,8 @@ node_bwcomp = {'abspath' : Base.get_abspath, 'labspath' : Base.get_labspath, 'path' : Base.get_internal_path, 'tpath' : Base.get_tpath, - 'path_elements' : Base.get_path_elements} + 'path_elements' : Base.get_path_elements, + 'suffix' : Base.get_suffix} class Entry(Base): """This is the class for generic Node.FS entries--that is, things -- cgit v0.12 From 596b7aca20e286ecb45dade015ab9e89ac6aa791 Mon Sep 17 00:00:00 2001 From: Pawel Tomulik Date: Thu, 3 Sep 2015 01:02:08 +0200 Subject: new versioned libraries - gnulink and cyglink for now --- src/engine/SCons/Defaults.py | 7 + src/engine/SCons/Platform/cygwin.py | 4 +- src/engine/SCons/Tool/__init__.py | 428 ++++++++++++++++++++++++------------ src/engine/SCons/Tool/__init__.xml | 37 +++- src/engine/SCons/Tool/cyglink.py | 148 ++++++++++++- src/engine/SCons/Tool/cyglink.xml | 49 +++++ src/engine/SCons/Tool/gnulink.py | 117 ++++++++++ src/engine/SCons/Tool/gnulink.xml | 4 + src/engine/SCons/Tool/install.py | 130 +++-------- src/engine/SCons/Tool/install.xml | 11 +- src/engine/SCons/Tool/link.py | 148 +++++-------- src/engine/SCons/Tool/link.xml | 154 +++++++++++++ src/engine/SCons/Tool/linkloc.py | 1 + src/engine/SCons/Tool/mingw.py | 1 + src/engine/SCons/Tool/mslink.py | 1 + src/engine/SCons/Tool/mwld.py | 1 + src/engine/SCons/Tool/qt.py | 1 + test/LINK/VersionedLib-j2.py | 135 ++++++++++++ test/LINK/VersionedLib-subdir.py | 149 +++++++++++++ test/LINK/VersionedLib.py | 22 +- 20 files changed, 1187 insertions(+), 361 deletions(-) create mode 100644 src/engine/SCons/Tool/cyglink.xml create mode 100644 test/LINK/VersionedLib-j2.py create mode 100644 test/LINK/VersionedLib-subdir.py diff --git a/src/engine/SCons/Defaults.py b/src/engine/SCons/Defaults.py index 6500443..db48969 100644 --- a/src/engine/SCons/Defaults.py +++ b/src/engine/SCons/Defaults.py @@ -482,6 +482,10 @@ class Variable_Method_Caller(object): frame = frame.f_back return None +def __libversionflags_string(versionvar): + return '${("%s" in locals() and %s and "_%sFLAGS" in locals()) ' \ + 'and _%sFLAGS or None}' % (versionvar, versionvar, versionvar, versionvar) + ConstructionEnvironment = { 'BUILDERS' : {}, 'SCANNERS' : [], @@ -499,6 +503,9 @@ ConstructionEnvironment = { '_LIBDIRFLAGS' : '$( ${_concat(LIBDIRPREFIX, LIBPATH, LIBDIRSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)', '_CPPINCFLAGS' : '$( ${_concat(INCPREFIX, CPPPATH, INCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)', '_CPPDEFFLAGS' : '${_defines(CPPDEFPREFIX, CPPDEFINES, CPPDEFSUFFIX, __env__)}', + + '__SHLIBVERSIONFLAGS' : __libversionflags_string('SHLIBVERSION'), + '__LDMODULEVERSIONFLAGS' : __libversionflags_string('LDMODULEVERSION'), 'TEMPFILE' : NullCmdGenerator, 'Dir' : Variable_Method_Caller('TARGET', 'Dir'), 'Dirs' : Variable_Method_Caller('TARGET', 'Dirs'), diff --git a/src/engine/SCons/Platform/cygwin.py b/src/engine/SCons/Platform/cygwin.py index a012682..34c79ff 100644 --- a/src/engine/SCons/Platform/cygwin.py +++ b/src/engine/SCons/Platform/cygwin.py @@ -42,8 +42,8 @@ def generate(env): env['PROGSUFFIX'] = '.exe' env['SHLIBPREFIX'] = '' env['SHLIBSUFFIX'] = '.dll' - env['LIBPREFIXES'] = [ '$LIBPREFIX', '$SHLIBPREFIX' ] - env['LIBSUFFIXES'] = [ '$LIBSUFFIX', '$SHLIBSUFFIX' ] + env['LIBPREFIXES'] = [ '$LIBPREFIX', '$SHLIBPREFIX', '$IMPLIBPREFIX' ] + env['LIBSUFFIXES'] = [ '$LIBSUFFIX', '$SHLIBSUFFIX', '$IMPLIBSUFFIX' ] env['TEMPFILE'] = TempFileMunge env['TEMPFILEPREFIX'] = '@' env['MAXLINELENGTH'] = 2048 diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py index efd2e33..4a27c0d 100644 --- a/src/engine/SCons/Tool/__init__.py +++ b/src/engine/SCons/Tool/__init__.py @@ -236,150 +236,304 @@ def createStaticLibBuilder(env): 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' or platform == 'sunos': - 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""" +def _call_env_cb(env, callback, args, result = None): + """Returns the result of env[callback](*args) call if env[callback] is + callable. If env[callback] does not exist or is not callable, return the + value provided as the *result* argument. This function is mainly used for + generating library info such as versioned suffixes, symlink maps, sonames + etc. by delegating the core job to callbacks configured by current linker + tool""" + Verbose = False + + if Verbose: + print '_call_env_cb: args=%r' % args + print '_call_env_cb: callback=%r' % callback + try: - version = env.subst('$SHLIBVERSION') + cbfun = env[callback] except KeyError: + pass + else: + if Verbose: + print '_call_env_cb: env[%r] found' % callback + print '_call_env_cb: env[%r]=%r' % (callback, cbfun) + if(callable(cbfun)): + if Verbose: + print '_call_env_cb: env[%r] is callable' % callback + result = cbfun(env, *args) + return result + +class _LibInfoGeneratorBase(object): + """Generator base class for library-related info such as suffixes for + versioned libraries, symlink maps, sonames etc. It handles commonities + of SharedLibrary and LoadableModule + """ + def __init__(self, libtype, infoname): + self.set_libtype(libtype) + self.set_infoname(infoname) + + def set_libtype(self, libtype): + if libtype not in ['ShLib', 'LdMod', 'ImpLib']: + raise ValueError('unsupported libtype %r' % libtype) + self.libtype = libtype + + def get_libtype(self): + return self.libtype + + def set_infoname(self, infoname): + self.infoname = infoname + + def get_infoname(self): + return self.infoname + + def get_lib_prefix(self, env): + prefix = None + libtype = self.get_libtype() + if libtype == 'ShLib': + prefix = env.subst('$SHLIBPREFIX') + elif libtype == 'LdMod': + prefix = env.subst('$LDMODULEPREFIX') + elif libtype == 'ImpLib': + prefix = env.subst('$IMPLIBPREFIX') + return prefix + + def get_lib_suffix(self, env): + suffix = None + libtype = self.get_libtype() + if libtype == 'ShLib': + suffix = env.subst('$SHLIBSUFFIX') + elif libtype == 'LdMod': + suffix = env.subst('$LDMODULESUFFIX') + elif libtype == 'ImpLib': + suffix = env.subst('$IMPLIBSUFFIX') + return suffix + + def get_lib_version(self, env, **kw): version = None + libtype = self.get_libtype() + if libtype == 'ShLib': + version = env.subst('$SHLIBVERSION') + elif libtype == 'LdMod': + version = env.subst('$LDMODULEVERSION') + elif libtype == 'ImpLib': + version = env.subst('$IMPLIBVERSION') + if not version: + try: lt = kw['implib_libtype'] + except KeyError: pass + else: + if lt == 'ShLib': + version = env.subst('$SHLIBVERSION') + elif lt == 'LdMod': + version = env.subst('$LDMODULEVERSION') + return version + + def get_versioned_lib_info_generator(self, **kw): + try: libtype = kw['generator_libtype'] + except KeyError: libtype = self.get_libtype() + infoname = self.get_infoname() + return 'GenerateVersioned%s%s' % (libtype, infoname) + + def generate_versioned_lib_info(self, env, args, result = None, **kw): + callback = self.get_versioned_lib_info_generator(**kw) + return _call_env_cb(env, callback, args, result) + +class _LibSuffixGenerator(_LibInfoGeneratorBase): + """Library suffix generator, used as target_suffix in SharedLibrary and + LoadableModule builders""" + def __init__(self, libtype): + super(_LibSuffixGenerator, self).__init__(libtype, 'Suffix') + + def __call__(self, env, sources = None, **kw): + Verbose = False + + suffix = self.get_lib_suffix(env) + if Verbose: + print "_LibSuffixGenerator: input suffix=%r" % suffix - # libname includes the version number if one was given - libname = getattr(target[0].attributes, 'shlibname', 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 == 'sunos': - suffix_re = re.escape(shlib_suffix + '.' + version) - (major, age, revision) = version.split(".") - soname = re.sub(suffix_re, shlib_suffix, libname) + '.' + major - shlink_flags += [ '-h', soname ] - 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' ] + version = self.get_lib_version(env, **kw) if Verbose: - print "VersionShLib: shlink_flags = ",shlink_flags - envlink = env.Clone() - envlink['SHLINKFLAGS'] = shlink_flags - else: - envlink = env + print "_LibSuffixGenerator: version=%r" % version - result = SCons.Defaults.ShLinkAction(target, source, envlink) + if version: + suffix = self.generate_versioned_lib_info(env, [suffix, version], suffix, **kw) - if version: - # here we need the full pathname so the links end up in the right directory - libname = getattr(target[0].attributes, 'shlibpath', target[0].get_internal_path()) if Verbose: - print "VerShLib: target lib is = ", libname - print "VerShLib: name is = ", target[0].name - print "VerShLib: dir is = ", target[0].dir.path - linknames = VersionShLibLinkNames(version, libname, env) + print "_LibSuffixGenerator: return suffix=%r" % suffix + return suffix + +ShLibSuffixGenerator = _LibSuffixGenerator('ShLib') +LdModSuffixGenerator = _LibSuffixGenerator('LdMod') +ImpLibSuffixGenerator = _LibSuffixGenerator('ImpLib') + +class _LibSymlinkGenerator(_LibInfoGeneratorBase): + """Library symlink map generator. It generates a dict of symlinks that + should be created by SharedLibrary or LoadableModule builders""" + def __init__(self, libtype): + super(_LibSymlinkGenerator, self).__init__(libtype, 'Symlinks') + + def get_noversionsymlinks(self, env, **kw): + disable = None + libtype = self.get_libtype() + if libtype == 'ShLib': + disable = env.subst('$SHLIBNOVERSIONSYMLINKS') + elif libtype == 'LdMod': + disable = env.subst('$LDMODULENOVERSIONSYMLINKS') + elif libtype == 'ImpLib': + try: env['IMPLIBNOVERSIONSYMLINKS'] + except KeyError: + try: lt = kw['implib_libtype'] + except KeyError: pass + else: + if lt == 'ShLib': + disable = env.subst('$SHLIBNOVERSIONSYMLINKS') + elif lt == 'LdMod': + disable = env.subst('$LDMODULENOVERSIONSYMLINKS') + else: + disable = env.subst('$IMPLIBNOVERSIONSYMLINKS') + return disable + + def __call__(self, env, libnode, **kw): + Verbose = False + if Verbose: - print "VerShLib: linknames ",linknames - # Here we just need the file name w/o path as the target of the link - lib_ver = getattr(target[0].attributes, 'shlibname', 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) + print "_LibSymLinkGenerator: str(libnode)=%r" % str(libnode) + + symlinks = None + + version = self.get_lib_version(env, **kw) + disable = self.get_noversionsymlinks(env, **kw) + if Verbose: + print '_LibSymlinkGenerator: version=%r' % version + print '_LibSymlinkGenerator: disable=%r' % disable + + if version and not disable: + suffix = self.get_lib_suffix(env) + symlinks = self.generate_versioned_lib_info(env, [libnode, version, suffix], **kw) + + if Verbose: + print '_LibSymlinkGenerator: return symlinks=%r' % symlinks + return symlinks + +ShLibSymlinkGenerator = _LibSymlinkGenerator('ShLib') +LdModSymlinkGenerator = _LibSymlinkGenerator('LdMod') +ImpLibSymlinkGenerator = _LibSymlinkGenerator('ImpLib') + +class _LibNameGenerator(_LibInfoGeneratorBase): + """Library name generator. Returns library name (e.g. libfoo.so) for + a given node (e.g. /foo/bar/libfoo.so.0.1.2)""" + def __init__(self, libtype): + super(_LibNameGenerator, self).__init__(libtype, 'Name') + + def __call__(self, env, libnode, **kw): + """Returns library name with version suffixes stripped""" + Verbose = False + + if Verbose: + print "_LibNameGenerator: str(libnode)=%r" % str(libnode) + + version = self.get_lib_version(env, **kw) + if Verbose: + print '_LibNameGenerator: version=%r' % version + + name = None + if version: + suffix = self.get_lib_suffix(env) + name = self.generate_versioned_lib_info(env, [libnode, version, suffix], **kw) + + if not name: + name = os.path.basename(str(libnode)) + + if Verbose: + print '_LibNameGenerator: return name=%r' % name + + return name + +ShLibNameGenerator = _LibNameGenerator('ShLib') +LdModNameGenerator = _LibNameGenerator('LdMod') +ImpLibNameGenerator = _LibNameGenerator('ImpLib') + +class _LibSonameGenerator(_LibInfoGeneratorBase): + """Library soname generator. Returns library soname (e.g. libfoo.so.0) for + a given node (e.g. /foo/bar/libfoo.so.0.1.2)""" + def __init__(self, libtype): + super(_LibSonameGenerator, self).__init__(libtype, 'Soname') + + def __call__(self, env, libnode, **kw): + """Returns a SONAME based on a shared library's node path""" + Verbose = False + + if Verbose: + print "_LibSonameGenerator: str(libnode)=%r" % str(libnode) + + soname = env.subst('$SONAME') + if not soname: + version = self.get_lib_version(env,**kw) if Verbose: - print "VerShLib: made sym link of %s -> %s" % (linkname, lib_ver) - return result + print "_LibSonameGenerator: version=%r" % version + if version: + suffix = self.get_lib_suffix(env) + soname = self.generate_versioned_lib_info(env, [libnode, version, suffix], **kw) + + if not soname: + # fallback to library name (as returned by appropriate _LibNameGenerator) + soname = _LibNameGenerator(self.get_libtype())(env, libnode) + if Verbose: + print "_LibSonameGenerator: FALLBACK: soname=%r" % soname + + if Verbose: + print "_LibSonameGenerator: return soname=%r" % soname -# 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']) + return soname + +ShLibSonameGenerator = _LibSonameGenerator('ShLib') +LdModSonameGenerator = _LibSonameGenerator('LdMod') + +def EmitLibSymlinks(env, symlinks, libnode): + """Used by emitters to handle (shared/versioned) library symlinks""" + Verbose = False + for linkname, linktgt in symlinks.iteritems(): + env.SideEffect(linkname, linktgt) + if(Verbose): + print "EmitLibSymlinks: SideEffect(", linkname, ", ", linktgt, ")" + clean = list(set(filter(lambda x : x != linktgt, symlinks.keys() + [str(libnode)]))) + env.Clean(linktgt, clean) + if(Verbose): + print "EmitLibSymlinks: Clean(%r,%r)" % (linktgt, clean) + +def CreateLibSymlinks(env, symlinks): + """Physically creates symlinks. The symlinks argument must be a dict in + form { linkname : linktarget } + """ + + Verbose = False + for linkname, linktgt in symlinks.iteritems(): + linkname = str(env.arg2nodes(linkname)[0]) + linkdir = os.path.dirname(linkname) + if linkdir: + # NOTE: os.path.relpath appears in python 2.6 + linktgt = os.path.relpath(linktgt, linkdir) + else: + linktgt = os.path.basename(linktgt) + if(Verbose): + print "CreateLibSymlinks: preparing to add symlink ", linkname, " -> ", linktgt + try: + os.remove(linkname) + except: + pass + os.symlink(linktgt, linkname) + if(Verbose): + print "CreateLibSymlinks: add symlink ", linkname, " -> ", linktgt + return 0 + +def LibSymlinksActionFunction(target, source, env): + for tgt in target: + symlinks = getattr(getattr(tgt,'attributes', None), 'shliblinks', None) + if symlinks: + CreateLibSymlinks(env, symlinks) + return 0 + +LibSymlinksAction = SCons.Action.Action(LibSymlinksActionFunction, None) def createSharedLibBuilder(env): """This is a utility function that creates the SharedLibrary @@ -393,11 +547,12 @@ def createSharedLibBuilder(env): except KeyError: import SCons.Defaults action_list = [ SCons.Defaults.SharedCheck, - ShLibAction ] + SCons.Defaults.ShLinkAction, + LibSymlinksAction ] shared_lib = SCons.Builder.Builder(action = action_list, emitter = "$SHLIBEMITTER", prefix = '$SHLIBPREFIX', - suffix = '$SHLIBSUFFIX', + suffix = ShLibSuffixGenerator, target_scanner = ProgramScanner, src_suffix = '$SHOBJSUFFIX', src_builder = 'SharedObject') @@ -417,11 +572,12 @@ def createLoadableModuleBuilder(env): except KeyError: import SCons.Defaults action_list = [ SCons.Defaults.SharedCheck, - SCons.Defaults.LdModuleLinkAction ] + SCons.Defaults.LdModuleLinkAction, + LibSymlinksAction ] ld_module = SCons.Builder.Builder(action = action_list, emitter = "$LDMODULEEMITTER", prefix = '$LDMODULEPREFIX', - suffix = '$LDMODULESUFFIX', + suffix = LdModSuffixGenerator, target_scanner = ProgramScanner, src_suffix = '$SHOBJSUFFIX', src_builder = 'SharedObject') diff --git a/src/engine/SCons/Tool/__init__.xml b/src/engine/SCons/Tool/__init__.xml index ee56fc3..7102fa4 100644 --- a/src/engine/SCons/Tool/__init__.xml +++ b/src/engine/SCons/Tool/__init__.xml @@ -464,6 +464,17 @@ as C++ files. + + + +Used to override &cv-link-SHLIBVERSION;/&cv-link-LDMODULEVERSION; when +generating versioned import library for a shared library/loadable module. If +undefined, the &cv-link-SHLIBVERSION;/&cv-link-LDMODULEVERSION; is used do +determine the version of versioned import library. + + + + @@ -472,6 +483,21 @@ TODO + + + +When this construction variable is defined, a versioned loadable module +is created by &b-link-LoadableModule; builder. This activates the +&cv-link-_LDMODULEVERSIONFLAGS; and thus modifies the &cv-link-LDMODULECOM; as +required, adds the version number to the library name, and creates the symlinks +that are needed. &cv-link-LDMODULEVERSION; needs to be of the form X.Y.Z, where +X and Y are numbers, and Z is a number but can also contain letters to +designate alpha, beta, or release candidate patch levels. By default +&cv-link-LDMODULEVERSION; is set to $SHLIBVERSION. + + + + @@ -492,11 +518,12 @@ TODO When this construction variable is defined, a versioned shared library -is created. This modifies the &cv-link-SHLINKFLAGS; as required, adds -the version number to the library name, and creates the symlinks that -are needed. &cv-link-SHLIBVERSION; needs to be of the form X.Y.Z, -where X and Y are numbers, and Z is a number but can also contain -letters to designate alpha, beta, or release candidate patch levels. +is created by &b-link-SharedLibrary; builder. This activates the +&cv-link-_SHLIBVERSIONFLAGS; and thus modifies the &cv-link-SHLINKCOM; as +required, adds the version number to the library name, and creates the symlinks +that are needed. &cv-link-SHLIBVERSION; needs to be of the form X.Y.Z, where X +and Y are numbers, and Z is a number but can also contain letters to designate +alpha, beta, or release candidate patch levels. diff --git a/src/engine/SCons/Tool/cyglink.py b/src/engine/SCons/Tool/cyglink.py index 87716cf..4033978 100644 --- a/src/engine/SCons/Tool/cyglink.py +++ b/src/engine/SCons/Tool/cyglink.py @@ -7,19 +7,26 @@ It will usually be imported through the generic SCons.Tool.Tool() selection method. """ +import re +import os import SCons.Action import SCons.Util +import SCons.Tool import gnulink -def shlib_generator(target, source, env, for_signature): - cmd = SCons.Util.CLVar(['$SHLINK']) +def _lib_generator(target, source, env, for_signature, **kw): + try: cmd = kw['cmd'] + except KeyError: cmd = SCons.Util.CLVar(['$SHLINK']) + + try: vp = kw['varprefix'] + except KeyError: vp = 'SHLIB' - dll = env.FindIxes(target, 'SHLIBPREFIX', 'SHLIBSUFFIX') + dll = env.FindIxes(target, '%sPREFIX' % vp, '%sSUFFIX' % vp) if dll: cmd.extend(['-o', dll]) - cmd.extend(['$SHLINKFLAGS', '$__RPATH']) + cmd.extend(['$SHLINKFLAGS', '$__%sVERSIONFLAGS' % vp, '$__RPATH']) implib = env.FindIxes(target, 'IMPLIBPREFIX', 'IMPLIBSUFFIX') if implib: @@ -35,15 +42,34 @@ def shlib_generator(target, source, env, for_signature): return [cmd] -def shlib_emitter(target, source, env): - dll = env.FindIxes(target, 'SHLIBPREFIX', 'SHLIBSUFFIX') + +def shlib_generator(target, source, env, for_signature): + return _lib_generator(target, source, env, for_signature, + varprefix='SHLIB', + cmd = SCons.Util.CLVar(['$SHLINK'])) + +def ldmod_generator(target, source, env, for_signature): + return _lib_generator(target, source, env, for_signature, + varprefix='LDMODULE', + cmd = SCons.Util.CLVar(['$LDMODULE'])) + +def _lib_emitter(target, source, env, **kw): + Verbose = False + + try: vp = kw['varprefix'] + except KeyError: vp = 'SHLIB' + + try: libtype = kw['libtype'] + except KeyError: libtype = 'ShLib' + + dll = env.FindIxes(target, '%sPREFIX' % vp, '%sSUFFIX' % vp) 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")) + raise SCons.Errors.UserError("A shared library should have exactly one target with the suffix: %s" % env.subst("$%sSUFFIX" % vp)) # Remove any "lib" after the prefix - pre = env.subst('$SHLIBPREFIX') + pre = env.subst('$%sPREFIX' % vp) if dll.name[len(pre):len(pre)+3] == 'lib': dll.name = pre + dll.name[len(pre)+3:] @@ -55,17 +81,90 @@ def shlib_emitter(target, source, env): if not no_import_lib: # Create list of target libraries as strings target_strings = env.ReplaceIxes(orig_target[0], - 'SHLIBPREFIX', 'SHLIBSUFFIX', + '%sPREFIX' % vp, '%sSUFFIX' % vp, 'IMPLIBPREFIX', 'IMPLIBSUFFIX') implib_target = env.fs.File(target_strings) + if Verbose: + print "_lib_emitter: implib_target=%r" % str(implib_target) implib_target.attributes.shared = 1 target.append(implib_target) + symlinks = SCons.Tool.ImpLibSymlinkGenerator(env, implib_target, + implib_libtype=libtype, + generator_libtype=libtype+'ImpLib') + if Verbose: + print "_lib_emitter: implib symlinks=%r" % symlinks + if symlinks: + SCons.Tool.EmitLibSymlinks(env, symlinks, implib_target) + implib_target.attributes.shliblinks = symlinks + return (target, source) + +def shlib_emitter(target, source, env): + return _lib_emitter(target, source, env, varprefix='SHLIB', libtype='ShLib') + +def ldmod_emitter(target, source, env): + return _lib_emitter(target, source, env, varprefix='LDMODULE', libtype='LdMod') +def _versioned_lib_suffix(env, suffix, version): + """Generate versioned shared library suffix from a unversioned one. + If suffix='.dll', and version='0.1.2', then it returns '-0-1-2.dll'""" + Verbose = False + if Verbose: + print "_versioned_lib_suffix: suffix= ", suffix + print "_versioned_lib_suffix: version= ", version + cygversion = re.sub('\.', '-', version) + if not suffix.startswith('-' + cygversion): + suffix = '-' + cygversion + suffix + if Verbose: + print "_versioned_lib_suffix: return suffix= ", suffix + return suffix + +def _versioned_implib_name(env, libnode, version, suffix, **kw): + import link + generator = SCons.Tool.ImpLibSuffixGenerator + libtype = kw['libtype'] + return link._versioned_lib_name(env, libnode, version, suffix, generator, implib_libtype=libtype) + +def _versioned_implib_symlinks(env, libnode, version, suffix, **kw): + """Generate link names that should be created for a versioned shared lirbrary. + Returns a dictionary in the form { linkname : linktarget } + """ + Verbose = False + + if Verbose: + print "_versioned_implib_symlinks: str(libnode)=%r" % str(libnode) + print "_versioned_implib_symlinks: version=%r" % version + + try: libtype = kw['libtype'] + except KeyError: libtype = 'ShLib' + + symlinks = {} + + linkdir = os.path.dirname(str(libnode)) + if Verbose: + print "_versioned_implib_symlinks: linkdir=%r" % linkdir + + name = SCons.Tool.ImpLibNameGenerator(env, libnode, + implib_libtype=libtype, + generator_libtype=libtype+'ImpLib') + if Verbose: + print "_versioned_implib_symlinks: name=%r" % name + + major = version.split('.')[0] + + link0 = os.path.join(str(linkdir), name) + + symlinks[link0] = str(libnode) + + if Verbose: + print "_versioned_implib_symlinks: return symlinks=%r" % symlinks + + return symlinks shlib_action = SCons.Action.Action(shlib_generator, generator=1) +ldmod_action = SCons.Action.Action(ldmod_generator, generator=1) def generate(env): """Add Builders and construction variables for cyglink to an Environment.""" @@ -74,8 +173,9 @@ def generate(env): env['LINKFLAGS'] = SCons.Util.CLVar('-Wl,-no-undefined') env['SHLINKCOM'] = shlib_action - env['LDMODULECOM'] = shlib_action + env['LDMODULECOM'] = ldmod_action env.Append(SHLIBEMITTER = [shlib_emitter]) + env.Append(LDMODULEEMITTER = [ldmod_emitter]) env['SHLIBPREFIX'] = 'cyg' env['SHLIBSUFFIX'] = '.dll' @@ -83,6 +183,34 @@ def generate(env): env['IMPLIBPREFIX'] = 'lib' env['IMPLIBSUFFIX'] = '.dll.a' + # Variables used by versioned shared libraries + env['_SHLIBVERSIONFLAGS'] = '$SHLIBVERSIONFLAGS' + env['_LDMODULEVERSIONFLAGS'] = '$LDMODULEVERSIONFLAGS' + + # SHLIBVERSIONFLAGS and LDMODULEVERSIONFLAGS are same as in gnulink... + + env['GenerateVersionedShLibSuffix'] = _versioned_lib_suffix + env['GenerateVersionedLdModSuffix'] = _versioned_lib_suffix + env['GenerateVersionedImpLibSuffix'] = _versioned_lib_suffix + env['GenerateVersionedShLibImpLibName'] = lambda *args: _versioned_implib_name(*args, libtype='ShLib') + env['GenerateVersionedLdModImpLibName'] = lambda *args: _versioned_implib_name(*args, libtype='LdMod') + env['GenerateVersionedShLibImpLibSymlinks'] = lambda *args: _versioned_implib_symlinks(*args, libtype='ShLib') + env['GenerateVersionedLdModImpLibSymlinks'] = lambda *args: _versioned_implib_symlinks(*args, libtype='LdMod') + + def trydel(env, key): + try: del env[key] + except KeyError: pass + + # these variables were set by gnulink but are not used in cyglink + trydel(env,'_SHLINKSONAME') + trydel(env,'_LDMODULESONAME') + trydel(env,'ShLibSonameGenerator') + trydel(env,'LdModSonameGenerator') + trydel(env,'GenerateVersionedShLibSymlinks') + trydel(env,'GenerateVersionedLdModSymlinks') + trydel(env,'GenerateVersionedShLibSoname') + trydel(env,'GenerateVersionedLdModSoname') + def exists(env): return gnulink.exists(env) diff --git a/src/engine/SCons/Tool/cyglink.xml b/src/engine/SCons/Tool/cyglink.xml new file mode 100644 index 0000000..42208f1 --- /dev/null +++ b/src/engine/SCons/Tool/cyglink.xml @@ -0,0 +1,49 @@ + + + + +%scons; + +%builders-mod; + +%functions-mod; + +%tools-mod; + +%variables-mod; +]> + + + + + + +Set construction variables for cygwin linker/loader. + + + +IMPLIBPREFIX +IMPLIBSUFFIX +LDMODULEVERSIONFLAGS +LINKFLAGS +RPATHPREFIX +RPATHSUFFIX +SHLIBPREFIX +SHLIBSUFFIX +SHLIBVERSIONFLAGS +SHLINKCOM +SHLINKFLAGS +_LDMODULEVERSIONFLAGS +_SHLIBVERSIONFLAGS + + + + diff --git a/src/engine/SCons/Tool/gnulink.py b/src/engine/SCons/Tool/gnulink.py index 3dc8f51..ea0ca5a 100644 --- a/src/engine/SCons/Tool/gnulink.py +++ b/src/engine/SCons/Tool/gnulink.py @@ -34,9 +34,97 @@ selection method. __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import SCons.Util +import SCons.Tool +import os +import sys +import re import link +def _versioned_lib_suffix(env, suffix, version): + """For suffix='.so' and version='0.1.2' it returns '.so.0.1.2'""" + Verbose = False + if Verbose: + print "_versioned_lib_suffix: suffix=%r" % suffix + print "_versioned_lib_suffix: version=%r" % version + if not suffix.endswith(version): + suffix = suffix + '.' + version + if Verbose: + print "_versioned_lib_suffix: return suffix=%r" % suffix + return suffix + +def _versioned_lib_soname(env, libnode, version, suffix, name_generator): + """For libnode='/optional/dir/libfoo.so.X.Y.Z' it returns 'libfoo.so.X'""" + Verbose = False + if Verbose: + print "_versioned_lib_soname: version=%r" % version + name = name_generator(env, libnode) + if Verbose: + print "_versioned_lib_soname: name=%r" % name + major = version.split('.')[0] + soname = name + '.' + major + if Verbose: + print "_versioned_lib_soname: soname=%r" % soname + return soname + +def _versioned_shlib_soname(env, libnode, version, suffix): + generator = SCons.Tool.ShLibNameGenerator + return _versioned_lib_soname(env, libnode, version, suffix, generator) + +def _versioned_ldmod_soname(env, libnode, version, suffix): + generator = SCons.Tool.LdModNameGenerator + return _versioned_lib_soname(env, libnode, version, suffix, generator) + +def _versioned_lib_symlinks(env, libnode, version, suffix, name_generator, soname_generator): + """Generate link names that should be created for a versioned shared lirbrary. + Returns a dictionary in the form { linkname : linktarget } + """ + Verbose = False + + if Verbose: + print "_versioned_lib_symlinks: str(libnode)=%r" % str(libnode) + print "_versioned_lib_symlinks: version=%r" % version + + symlinks = {} + + if sys.platform.startswith('openbsd'): + # OpenBSD uses x.y shared library versioning numbering convention + # and doesn't use symlinks to backwards-compatible libraries + if Verbose: + print "_versioned_lib_symlinks: return symlinks=%r" % symlinks + return symlinks + + linkdir = os.path.dirname(str(libnode)) + if Verbose: + print "_versioned_lib_symlinks: linkdir=%r" % linkdir + + name = name_generator(env, libnode) + if Verbose: + print "_versioned_lib_symlinks: name=%r" % name + + soname = soname_generator(env, libnode) + + link0 = os.path.join(str(linkdir), soname) + link1 = os.path.join(str(linkdir), name) + + symlinks[link0] = str(libnode) + symlinks[link1] = link0 + + if Verbose: + print "_versioned_lib_symlinks: return symlinks=%r" % symlinks + + return symlinks + +def _versioned_shlib_symlinks(env, libnode, version, suffix): + name_generator = SCons.Tool.ShLibNameGenerator + soname_generator = SCons.Tool.ShLibSonameGenerator + return _versioned_lib_symlinks(env, libnode, version, suffix, name_generator, soname_generator) + +def _versioned_ldmod_symlinks(env, libnode, version, suffix): + name_generator = SCons.Tool.LdModNameGenerator + soname_generator = SCons.Tool.LdModSonameGenerator + return _versioned_lib_symlinks(env, libnode, version, suffix, name_generator, soname_generator) + def generate(env): """Add Builders and construction variables for gnulink to an Environment.""" link.generate(env) @@ -49,6 +137,35 @@ def generate(env): env['RPATHPREFIX'] = '-Wl,-rpath=' env['RPATHSUFFIX'] = '' env['_RPATH'] = '${_concat(RPATHPREFIX, RPATH, RPATHSUFFIX, __env__)}' + + # The $_SHLIBVERSIONFLAGS define extra commandline flags used when + # building VERSIONED shared libraries. It's always set, but used only + # when VERSIONED library is built (see __SHLIBVERSIONFLAGS). + if sys.platform.startswith('openbsd'): + # OpenBSD doesn't usually use SONAME for libraries + env['_SHLIBVERSIONFLAGS'] = '$SHLIBVERSIONFLAGS' + env['_LDMODULEVERSIONFLAGS'] = '$LDMODULEVERSIONFLAGS' + else: + env['_SHLIBVERSIONFLAGS'] = '$SHLIBVERSIONFLAGS -Wl,-soname=$_SHLINKSONAME' + env['_LDMODULEVERSIONFLAGS'] = '$LDMODULEVERSIONFLAGS -Wl,-soname=$_LDMODULESONAME' + env['SHLIBVERSIONFLAGS'] = SCons.Util.CLVar('-Wl,-Bsymbolic') + env['LDMODULEVERSIONFLAGS'] = '$SHLIBVERSIONFLAGS' + + # libfoo.so.X.Y.Z -> libfoo.so.X + env['_SHLINKSONAME'] = '${ShLibSonameGenerator(__env__,TARGET)}' + env['_LDMODULESONAME'] = '${LdModSonameGenerator(__env__,TARGET)}' + + env['ShLibSonameGenerator'] = SCons.Tool.ShLibSonameGenerator + env['LdModSonameGenerator'] = SCons.Tool.LdModSonameGenerator + + env['GenerateVersionedShLibSuffix'] = _versioned_lib_suffix + env['GenerateVersionedLdModSuffix'] = _versioned_lib_suffix + env['GenerateVersionedShLibSymlinks'] = _versioned_shlib_symlinks + env['GenerateVersionedLdModSymlinks'] = _versioned_ldmod_symlinks + env['GenerateVersionedShLibName'] = link._versioned_shlib_name + env['GenerateVersionedLdModName'] = link._versioned_ldmod_name + env['GenerateVersionedShLibSoname'] = _versioned_shlib_soname + env['GenerateVersionedLdModSoname'] = _versioned_shlib_soname def exists(env): # TODO: sync with link.smart_link() to choose a linker diff --git a/src/engine/SCons/Tool/gnulink.xml b/src/engine/SCons/Tool/gnulink.xml index 2a36de2..63ce0f4 100644 --- a/src/engine/SCons/Tool/gnulink.xml +++ b/src/engine/SCons/Tool/gnulink.xml @@ -33,6 +33,10 @@ Set construction variables for GNU linker/loader. SHLINKFLAGS RPATHPREFIX RPATHSUFFIX +_LDMODULESONAME +_SHLINKSONAME +LDMODULEVERSIONFLAGS +SHLIBVERSIONFLAGS diff --git a/src/engine/SCons/Tool/install.py b/src/engine/SCons/Tool/install.py index 9f2e937..c5c2adb 100644 --- a/src/engine/SCons/Tool/install.py +++ b/src/engine/SCons/Tool/install.py @@ -38,6 +38,7 @@ import shutil import stat import SCons.Action +import SCons.Tool from SCons.Util import make_path_relative # @@ -141,98 +142,34 @@ def copyFuncVersionedLib(dest, source, env): 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) + installShlibLinks(dest, source, env) return 0 -def versionedLibVersion(dest, source, 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' or platform == 'sunos'): - return (None, None, None) - - if (hasattr(source[0], 'attributes') and - hasattr(source[0].attributes, 'shlibname')): - libname = source[0].attributes.shlibname - else: - libname = os.path.basename(str(dest)) +def listShlibLinksToInstall(dest, source, env): + install_links = {} install_dir = os.path.dirname(str(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' or platform == 'sunos': - # 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): + source = env.arg2nodes(source) + for src in source: + links = getattr(getattr(src,'attributes',None), 'shliblinks', None) + if SCons.Util.is_Dict(links): + for linkname, linktgt in links.iteritems(): + linkname_base = os.path.basename(str(linkname)) + linktgt_base = os.path.basename(str(linktgt)) + install_linkname = os.path.join(install_dir, linkname_base) + install_linktgt = os.path.join(install_dir, linktgt_base) + install_links[install_linkname] = install_linktgt + return install_links + +def installShlibLinks(dest, source, env): """If we are installing a versioned shared library create the required links.""" Verbose = False - linknames = [] - version, libname, install_dir = versionedLibVersion(dest, source, 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) + + symlinks = listShlibLinksToInstall(dest, source, env) + if Verbose: + print 'installShlibLinks: symlinks=%r' % symlinks + if symlinks: + SCons.Tool.CreateLibSymlinks(env, symlinks) return def installFunc(target, source, env): @@ -306,22 +243,11 @@ def add_versioned_targets_to_INSTALLED_FILES(target, source, env): 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], source, 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 + print "add_versioned_targets_to_INSTALLED_FILES: target=%r" % map(str, target) + + symlinks = listShlibLinksToInstall(target[0], source, env) + if symlinks: + SCons.Tool.EmitLibSymlinks(env, symlinks, target[0]) _UNIQUE_INSTALLED_FILES = None return (target, source) diff --git a/src/engine/SCons/Tool/install.xml b/src/engine/SCons/Tool/install.xml index 0aa9384..6ae3e30 100644 --- a/src/engine/SCons/Tool/install.xml +++ b/src/engine/SCons/Tool/install.xml @@ -82,20 +82,13 @@ env.InstallAs(target = ['../lib/libfoo.a', '../lib/libbar.a'], -Installs a versioned shared library. The &cv-link-SHLIBVERSION; -construction variable should be defined in the environment -to confirm the version number in the library name. -If &cv-link-SHLIBVERSION; is not defined a warning will be issued -and the name of the library will be parsed to derive the version. -The symlinks appropriate to the architecture will be generated. +Installs a versioned shared library. The symlinks appropriate to the +architecture will be generated based on symlinks of the source library. env.InstallVersionedLib(target = '/usr/local/bin/foo', source = 'libxyz.1.5.2.so') -env.InstallVersionedLib(target = '/usr/local/bin/foo', - source = 'libxyz.1.5.2.so', - SHLIBVERSION='1.5.2') diff --git a/src/engine/SCons/Tool/link.py b/src/engine/SCons/Tool/link.py index a084bc4..33e50d9 100644 --- a/src/engine/SCons/Tool/link.py +++ b/src/engine/SCons/Tool/link.py @@ -33,9 +33,10 @@ selection method. __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" +import sys import re +import os -import SCons.Defaults import SCons.Tool import SCons.Util import SCons.Warnings @@ -72,97 +73,66 @@ def smart_link(source, target, env, for_signature): return '$CXX' return '$CC' -def shlib_emitter(target, source, env): +def _lib_emitter(target, source, env, **kw): Verbose = False - platform = env.subst('$PLATFORM') + if Verbose: + print "_lib_emitter: str(target[0])=%r" % str(target[0]) 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) - # mark the target with the shared libraries name, including - # the version number - target[0].attributes.shlibname = version_names[0] - shlib = env.File(version_names[0], directory=target[0].get_dir()) - target[0].attributes.shlibpath = shlib.get_internal_path() - for name in version_names[1:]: - env.SideEffect(name, shlib) - env.Clean(shlib, name) - if Verbose: - print "shlib_emitter: add side effect - ",name - env.Clean(shlib, target[0]) - return ([shlib], source) + symlink_generator = kw['symlink_generator'] except KeyError: - version = None + pass + else: + if Verbose: + print "_lib_emitter: symlink_generator=%r" % symlink_generator + symlinks = symlink_generator(env, target[0]) + if Verbose: + print "_lib_emitter: symlinks=%r" % symlinks + + if symlinks: + SCons.Tool.EmitLibSymlinks(env, symlinks, target[0]) + target[0].attributes.shliblinks = symlinks 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""" +def shlib_emitter(target, source, env): + return _lib_emitter(target, source, env, symlink_generator = SCons.Tool.ShLibSymlinkGenerator) + +def ldmod_emitter(target, source, env): + return _lib_emitter(target, source, env, symlink_generator = SCons.Tool.LdModSymlinkGenerator) + +# This is generic enough to be included here... +def _versioned_lib_name(env, libnode, version, suffix, suffix_generator, **kw): + """For libnode='/optional/dir/libfoo.so.X.Y.Z' it returns 'libfoo.so'""" 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' or platform == 'sunos': - versionparts = version.split('.') - if hasattr(target[0].attributes, 'shlibname'): - name = target[0].attributes.shlibname - else: - name = target[0].name - # generate library name with the version number - version_name = 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') - if hasattr(target[0].attributes, 'shlibname'): - name = target[0].attributes.shlibname - else: - 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') - if hasattr(target[0].attributes, 'shlibname'): - name = target[0].attributes.shlibname - else: - 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 + if Verbose: + print "_versioned_lib_name: version=%r" % version + + versioned_name = os.path.basename(str(libnode)) + if Verbose: + print "_versioned_lib_name: versioned_name=%r" % versioned_name + + if Verbose: + print "_versioned_lib_name: suffix=%r" % suffix + + versioned_suffix = suffix_generator(env, **kw) + + versioned_suffix_re = re.escape(versioned_suffix) + '$' + name = re.sub(versioned_suffix_re, suffix, versioned_name) + if Verbose: + print "_versioned_lib_name: name=%r" % name + return name + +def _versioned_shlib_name(env, libnode, version, suffix, **kw): + generator = SCons.Tool.ShLibSuffixGenerator + return _versioned_lib_name(env, libnode, version, suffix, generator, **kw) + +def _versioned_ldmod_name(env, libnode, version, suffix, **kw): + generator = SCons.Tool.LdModSuffixGenerator + return _versioned_lib_name(env, libnode, version, suffix, generator, **kw) + def generate(env): """Add Builders and construction variables for gnulink to an Environment.""" @@ -171,7 +141,7 @@ def generate(env): env['SHLINK'] = '$LINK' env['SHLINKFLAGS'] = SCons.Util.CLVar('$LINKFLAGS -shared') - env['SHLINKCOM'] = '$SHLINK -o $TARGET $SHLINKFLAGS $__RPATH $SOURCES $_LIBDIRFLAGS $_LIBFLAGS' + env['SHLINKCOM'] = '$SHLINK -o $TARGET $SHLINKFLAGS $__SHLIBVERSIONFLAGS $__RPATH $SOURCES $_LIBDIRFLAGS $_LIBFLAGS' # don't set up the emitter, cause AppendUnique will generate a list # starting with None :-( env.Append(SHLIBEMITTER = [shlib_emitter]) @@ -196,15 +166,13 @@ def generate(env): # 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.Append(LDMODULEEMITTER = [ldmod_emitter]) env['LDMODULEPREFIX'] = '$SHLIBPREFIX' env['LDMODULESUFFIX'] = '$SHLIBSUFFIX' env['LDMODULEFLAGS'] = '$SHLINKFLAGS' - env['LDMODULECOM'] = '$LDMODULE -o $TARGET $LDMODULEFLAGS $__RPATH $SOURCES $_LIBDIRFLAGS $_LIBFLAGS' - - + env['LDMODULECOM'] = '$LDMODULE -o $TARGET $LDMODULEFLAGS $__LDMODULEVERSIONFLAGS $__RPATH $SOURCES $_LIBDIRFLAGS $_LIBFLAGS' + env['LDMODULEVERSION'] = '$SHLIBVERSION' + env['LDMODULENOVERSIONSYMLINKS'] = '$SHLIBNOVERSIONSYMLINKS' def exists(env): # This module isn't really a Tool on its own, it's common logic for diff --git a/src/engine/SCons/Tool/link.xml b/src/engine/SCons/Tool/link.xml index d58b9e2..52349da 100644 --- a/src/engine/SCons/Tool/link.xml +++ b/src/engine/SCons/Tool/link.xml @@ -41,11 +41,16 @@ Sets construction variables for generic POSIX linkers. LIBLINKPREFIX LIBLINKSUFFIX SHLIBSUFFIX +__SHLIBVERSIONFLAGS LDMODULE LDMODULEPREFIX LDMODULESUFFIX LDMODULEFLAGS LDMODULECOM +LDMODULEVERSION +LDMODULENOVERSIONSYMLINKS +LDMODULEVERSIONFLAGS +__LDMODULEVERSIONFLAGS SHLINKCOMSTR @@ -54,6 +59,105 @@ Sets construction variables for generic POSIX linkers. + + + +This construction variable automatically introduces &cv-link-_LDMODULEVERSIONFLAGS; +if &cv-link-LDMODULEVERSION; is set. Othervise it evaluates to an empty string. + + + + + + + +This construction variable automatically introduces &cv-link-_SHLIBVERSIONFLAGS; +if &cv-link-SHLIBVERSION; is set. Othervise it evaluates to an empty string. + + + + + + + +A macro that automatically generates loadable module's SONAME based on $TARGET, +$LDMODULEVERSION and $LDMODULESUFFIX. Used by &b-link-LoadableModule; builder +when the linker tool supports SONAME (e.g. &t-link-gnulink;). + + + + + + + +This macro automatically introduces extra flags to &cv-link-LDMODULECOM; when +building versioned &b-link-LoadableModule; (that is when +&cv-link-LDMODULEVERSION; is set). _LDMODULEVERSIONFLAGS +usually adds &cv-link-SHLIBVERSIONFLAGS; and some extra dynamically generated +options (such as -Wl,-soname=$_LDMODULESONAME). It is unused +by plain (unversioned) loadable modules. + + + + + + + +This macro automatically introduces extra flags to &cv-link-SHLINKCOM; when +building versioned &b-link-SharedLibrary; (that is when &cv-link-SHLIBVERSION; +is set). _SHLIBVERSIONFLAGS usually adds &cv-link-SHLIBVERSIONFLAGS; +and some extra dynamically generated options (such as +-Wl,-soname=$_SHLINKSONAME. It is unused by "plain" +(unversioned) shared libraries. + + + + + + + +A macro that automatically generates shared library's SONAME based on $TARGET, +$SHLIBVERSION and $SHLIBSUFFIX. Used by &b-link-SharedLibrary; builder when +the linker tool supports SONAME (e.g. &t-link-gnulink;). + + + + + + + +The prefix used for import library names. For example, cygwin uses import +libraries (libfoo.dll.a) in pair with dynamic libraries +(cygfoo.dll). The &t-link-cyglink; linker sets +&cv-link-IMPLIBPREFIX; to 'lib' and &cv-link-SHLIBPREFIX; +to 'cyg'. + + + + + + + +The suffix used for import library names. For example, cygwin uses import +libraries (libfoo.dll.a) in pair with dynamic libraries +(cygfoo.dll). The &t-link-cyglink; linker sets +&cv-link-IMPLIBSUFFIX; to '.dll.a' and &cv-link-SHLIBSUFFIX; +to '.dll'. + + + + + + + +Used to override &cv-link-SHLIBNOVERSIONSYMLINKS;/&cv-link-LDMODULENOVERSIONSYMLINKS; when +creating versioned import library for a shared library/loadable module. If not defined, +then &cv-link-SHLIBNOVERSIONSYMLINKS;/&cv-link-LDMODULENOVERSIONSYMLINKS; is used to determine +whether to disable symlink generation or not. + + + + @@ -92,6 +196,15 @@ General user options passed to the linker for building loadable modules. + + + +Instructs the &b-link-LoadableModule; builder to not automatically create symlinks +for versioned modules. Defaults to $SHLIBNOVERSIONSYMLINKS + + + + @@ -114,6 +227,16 @@ the same as $SHLIBSUFFIX. + + + +Extra flags added to &cv-link-LDMODULECOM; when building versioned +&b-link-LoadableModule;. These flags are only used when &cv-link-LDMODULEVERSION; is +set. + + + + @@ -169,6 +292,25 @@ for the variable that expands to library search path options. + + + +Instructs the &b-link-SharedLibrary; builder to not create symlinks for versioned +shared libraries. + + + + + + + +Extra flags added to &cv-link-SHLINKCOM; when building versioned +&b-link-SharedLibrary;. These flags are only used when &cv-link-SHLIBVERSION; is +set. + + + + @@ -223,6 +365,18 @@ for the variable that expands to library search path options. + + + +Variable used to hard-code SONAME for versioned shared library/loadable module. + +env.SharedLibrary('test', 'test.c', SHLIBVERSION='0.1.2', SONAME='libtest.so.2') + +The variable is used, for example, by &t-link-gnulink; linker tool. + + + + diff --git a/src/engine/SCons/Tool/linkloc.py b/src/engine/SCons/Tool/linkloc.py index 9c58561..bd643f7 100644 --- a/src/engine/SCons/Tool/linkloc.py +++ b/src/engine/SCons/Tool/linkloc.py @@ -86,6 +86,7 @@ def generate(env): env['SHLINKFLAGS'] = SCons.Util.CLVar('$LINKFLAGS') env['SHLINKCOM'] = '${SUBST_CMD_FILE("$SHLINK $SHLINKFLAGS $_LIBDIRFLAGS $_LIBFLAGS -dll $TARGET $SOURCES")}' env['SHLIBEMITTER']= None + env['LDMODULEEMITTER']= None env['LINK'] = "linkloc" env['LINKFLAGS'] = SCons.Util.CLVar('') env['LINKCOM'] = '${SUBST_CMD_FILE("$LINK $LINKFLAGS $_LIBDIRFLAGS $_LIBFLAGS -exe $TARGET $SOURCES")}' diff --git a/src/engine/SCons/Tool/mingw.py b/src/engine/SCons/Tool/mingw.py index 601ec3b..948ebe5 100644 --- a/src/engine/SCons/Tool/mingw.py +++ b/src/engine/SCons/Tool/mingw.py @@ -146,6 +146,7 @@ def generate(env): env['SHLINKCOM'] = shlib_action env['LDMODULECOM'] = shlib_action env.Append(SHLIBEMITTER = [shlib_emitter]) + env.Append(LDMODULEEMITTER = [shlib_emitter]) env['AS'] = 'as' env['WIN32DEFPREFIX'] = '' diff --git a/src/engine/SCons/Tool/mslink.py b/src/engine/SCons/Tool/mslink.py index 6606e10..1390c20 100644 --- a/src/engine/SCons/Tool/mslink.py +++ b/src/engine/SCons/Tool/mslink.py @@ -263,6 +263,7 @@ def generate(env): env['_SHLINK_SOURCES'] = windowsShlinkSources env['SHLINKCOM'] = compositeShLinkAction env.Append(SHLIBEMITTER = [windowsLibEmitter]) + env.Append(LDMODULEEMITTER = [windowsLibEmitter]) env['LINK'] = 'link' env['LINKFLAGS'] = SCons.Util.CLVar('/nologo') env['_PDB'] = pdbGenerator diff --git a/src/engine/SCons/Tool/mwld.py b/src/engine/SCons/Tool/mwld.py index e762d55..2067660 100644 --- a/src/engine/SCons/Tool/mwld.py +++ b/src/engine/SCons/Tool/mwld.py @@ -56,6 +56,7 @@ def generate(env): env['SHLINKFLAGS'] = '$LINKFLAGS' env['SHLINKCOM'] = shlib_action env['SHLIBEMITTER']= shlib_emitter + env['LDMODULEEMITTER']= shlib_emitter def exists(env): diff --git a/src/engine/SCons/Tool/qt.py b/src/engine/SCons/Tool/qt.py index 716c7d5..7bc0ef6 100644 --- a/src/engine/SCons/Tool/qt.py +++ b/src/engine/SCons/Tool/qt.py @@ -320,6 +320,7 @@ def generate(env): # correctly later by our emitter. env.AppendUnique(PROGEMITTER =[AutomocStatic], SHLIBEMITTER=[AutomocShared], + LDMODULEEMITTER=[AutomocShared], LIBEMITTER =[AutomocStatic], # Of course, we need to link against the qt libraries CPPPATH=["$QT_CPPPATH"], diff --git a/test/LINK/VersionedLib-j2.py b/test/LINK/VersionedLib-j2.py new file mode 100644 index 0000000..076a4dd --- /dev/null +++ b/test/LINK/VersionedLib-j2.py @@ -0,0 +1,135 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Ensure that SharedLibrary builder works with SHLIBVERSION and -j2. +This is regression test for: +http://article.gmane.org/gmane.comp.programming.tools.scons.user/27049 +""" + +import TestSCons +import os +import sys + +import SCons.Platform + +test = TestSCons.TestSCons() + +test.write('foo.c', """ +#if _WIN32 +__declspec(dllexport) +#endif +int foo() { return 0; } +""") + + +test.write('main.c', """ +#if _WIN32 +__declspec(dllimport) +#endif +int foo(); +int main() { return foo(); } +""") + +test.write('SConstruct', """ +env = Environment() +env.AppendUnique(LIBPATH = ['.']) +env.Program('main.c', LIBS = ['foo']) +env.SharedLibrary('foo', 'foo.c', SHLIBVERSION = '0.1.2') +""") + +test.run(arguments = ['-j 2', '--tree=all']) + +platform = SCons.Platform.platform_default() + +if platform == 'cygwin': + # PATH is used to search for *.dll librarier (cygfoo-0-2-1.dll in our case) + path = os.environ.get('PATH','') + if path: path = path + os.pathsep + path = path + test.workpath('.') + os.environ['PATH'] = path + +if os.name == 'posix': + os.environ['LD_LIBRARY_PATH'] = test.workpath('.') +if sys.platform.find('irix') != -1: + os.environ['LD_LIBRARYN32_PATH'] = test.workpath('.') + +test.run(program = test.workpath('main')) + +test.run(arguments = ['-c']) + +platform = SCons.Platform.platform_default() + +if platform == 'posix': + # All (?) the files we expect will get created in the current directory + files = [ + 'libfoo.so', + 'libfoo.so.0', + 'libfoo.so.0.1.2', + 'foo.os', + ] +elif platform == 'darwin': + # All (?) the files we expect will get created in the current directory + files = [ + 'libfoo.dylib', + 'libfoo.0.1.2.dylib', + 'foo.os', + ] +elif platform == 'cygwin': + # All (?) the files we expect will get created in the current directory + files = [ + 'cygfoo-0-1-2.dll', + 'libfoo-0-1-2.dll.a', + 'libfoo.dll.a', + 'foo.os', + ] +elif platform == 'win32': + # All (?) the files we expect will get created in the current directory + files = [ + 'foo.dll', + 'foo.lib', + 'foo.obj', + ] +else: + # All (?) the files we expect will get created in the current directory + files= [ + 'libfoo.so', + 'foo.os'] + +for f in files: + test.must_not_exist([ f]) + +test.must_exist(['main.c']) +test.must_exist(['foo.c']) +test.must_exist(['SConstruct']) + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/LINK/VersionedLib-subdir.py b/test/LINK/VersionedLib-subdir.py new file mode 100644 index 0000000..5fae101 --- /dev/null +++ b/test/LINK/VersionedLib-subdir.py @@ -0,0 +1,149 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Ensure that SharedLibrary builder with SHLIBVERSION='0.1.2' can build its target +in a subdirectory containing .so.0.1.2 in name. + +This is regression test for issue mentioned in: +http://thread.gmane.org/gmane.comp.programming.tools.scons.user/27081 +""" + +import TestSCons +import os +import sys + +import SCons.Platform + +test = TestSCons.TestSCons() + +test.write('foo.c', """ +#if _WIN32 +__declspec(dllexport) +#endif +int foo() { return 0; } +""") + +test.write('main.c', """ +#if _WIN32 +__declspec(dllimport) +#endif +int foo(); +int main() +{ + return foo(); +} +""") + +platform = SCons.Platform.platform_default() + +if platform == 'darwin': + subdir = 'blah.0.1.2.dylib.blah' +elif platform == 'cygwin': + subdir = 'blah-0-1-2.dll.a.blah' +else: + subdir = 'blah.so.0.1.2.blah' + +test.write('SConstruct', """ +env = Environment() +env.AppendUnique(LIBPATH = [ '%s' ]) +env.SharedLibrary('%s/foo', 'foo.c', SHLIBVERSION = '0.1.2') +env.Program('main.c', LIBS=['foo']) +""" % (subdir,subdir)) + +test.run(arguments = ['--tree=all']) + +if platform == 'cygwin': + # PATH is used to search for *.dll librarier (cygfoo-0-2-1.dll in our case) + path = os.environ.get('PATH','') + if path: path = path + os.pathsep + path = path + test.workpath(subdir) + os.environ['PATH'] = path + +if os.name == 'posix': + os.environ['LD_LIBRARY_PATH'] = subdir +if sys.platform.find('irix') != -1: + os.environ['LD_LIBRARYN32_PATH'] = subdir + +test.run(program = test.workpath('main')) + +if platform == 'posix': + # All (?) the files we expect will get created in the current directory + files = [ + 'libfoo.so', + 'libfoo.so.0', + 'libfoo.so.0.1.2', + ] + obj = 'foo.os' +elif platform == 'darwin': + # All (?) the files we expect will get created in the current directory + files = [ + 'libfoo.dylib', + 'libfoo.0.1.2.dylib', + ] + obj = 'foo.os' +elif platform == 'cygwin': + # All (?) the files we expect will get created in the current directory + files = [ + 'cygfoo-0-1-2.dll', + 'libfoo-0-1-2.dll.a', + 'libfoo.dll.a', + ] + obj = 'foo.os' +elif platform == 'win32': + # All (?) the files we expect will get created in the current directory + files = [ + 'foo.dll', + 'foo.lib', + ] + obj = 'foo.obj' +else: + # All (?) the files we expect will get created in the current directory + files= [ + 'libfoo.so', + ] + obj = 'foo.os' + +test.must_exist([ obj ]) +for f in files: + test.must_exist([ subdir, f ]) + +test.run(arguments = ['-c']) + +test.must_not_exist([ obj ]) +for f in files: + test.must_not_exist([ subdir, f ]) + +test.must_exist(['foo.c']) +test.must_exist(['SConstruct']) + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/LINK/VersionedLib.py b/test/LINK/VersionedLib.py index a2345d6..c68dd55 100644 --- a/test/LINK/VersionedLib.py +++ b/test/LINK/VersionedLib.py @@ -39,8 +39,8 @@ import os env = Environment() objs = env.SharedObject('test.c') mylib = env.SharedLibrary('test', objs, SHLIBVERSION = '2.5.4') -env.Program(source=['testapp.c',mylib]) -env.Program(target=['testapp2'],source=['testapp.c','libtest.dylib']) +env.Program('testapp1.c', LIBS = mylib, LIBPATH='.') +env.Program('testapp2.c', LIBS = ['test'], LIBPATH='.') instnode = env.InstallVersionedLib("#/installtest",mylib) env.Default(instnode) """) @@ -55,22 +55,28 @@ return n+1 ; } """) -test.write('testapp.c', """\ +testapp_src = """\ +#if _WIN32 +__declspec(dllimport) +#endif +int testlib(int n); #include int main(int argc, char **argv) { int itest ; itest = testlib(2) ; -printf("results: testlib(2) = %d\n",itest) ; +printf("results: testlib(2) = %d\\n",itest) ; return 0 ; } -""") +""" +test.write('testapp1.c', testapp_src) +test.write('testapp2.c', testapp_src) platform = SCons.Platform.platform_default() -test.run() +test.run(arguments = ['--tree=all']) if platform == 'posix': # All (?) the files we expect will get created in the current directory @@ -103,12 +109,14 @@ elif platform == 'cygwin': files = [ 'cygtest-2-5-4.dll', 'libtest-2-5-4.dll.a', + 'libtest.dll.a', 'test.os', ] # All (?) the files we expect will get created in the 'installtest' directory instfiles = [ 'cygtest-2-5-4.dll', 'libtest-2-5-4.dll.a', + 'libtest.dll.a', ] elif platform == 'win32': # All (?) the files we expect will get created in the current directory @@ -148,7 +156,7 @@ return n+11 ; test.run() -test.run(arguments = '-c') +test.run(arguments = ['-c']) for f in files: test.must_not_exist([ f]) -- cgit v0.12 From 97a7990e29435b7fe752ce220aac9a6048393395 Mon Sep 17 00:00:00 2001 From: Pawel Tomulik Date: Fri, 4 Sep 2015 03:34:59 +0200 Subject: reivised code, fixed cygwin/variant-dir issue, cleaned-up some areas --- src/engine/SCons/Tool/__init__.py | 67 +++++++++------ src/engine/SCons/Tool/cyglink.py | 32 ++++--- src/engine/SCons/Tool/gnulink.py | 19 ++--- src/engine/SCons/Tool/install.py | 23 ++--- test/LINK/VersionedLib-VariantDir.py | 157 +++++++++++++++++++++++++++++++++++ test/LINK/VersionedLib-subdir.py | 4 +- 6 files changed, 242 insertions(+), 60 deletions(-) create mode 100644 test/LINK/VersionedLib-VariantDir.py diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py index 4a27c0d..0e6e7d8 100644 --- a/src/engine/SCons/Tool/__init__.py +++ b/src/engine/SCons/Tool/__init__.py @@ -367,7 +367,7 @@ LdModSuffixGenerator = _LibSuffixGenerator('LdMod') ImpLibSuffixGenerator = _LibSuffixGenerator('ImpLib') class _LibSymlinkGenerator(_LibInfoGeneratorBase): - """Library symlink map generator. It generates a dict of symlinks that + """Library symlink map generator. It generates a list of symlinks that should be created by SharedLibrary or LoadableModule builders""" def __init__(self, libtype): super(_LibSymlinkGenerator, self).__init__(libtype, 'Symlinks') @@ -397,7 +397,7 @@ class _LibSymlinkGenerator(_LibInfoGeneratorBase): Verbose = False if Verbose: - print "_LibSymLinkGenerator: str(libnode)=%r" % str(libnode) + print "_LibSymLinkGenerator: libnode=%r" % libnode.get_path() symlinks = None @@ -412,7 +412,7 @@ class _LibSymlinkGenerator(_LibInfoGeneratorBase): symlinks = self.generate_versioned_lib_info(env, [libnode, version, suffix], **kw) if Verbose: - print '_LibSymlinkGenerator: return symlinks=%r' % symlinks + print '_LibSymlinkGenerator: return symlinks=%r' % StringizeLibSymlinks(symlinks) return symlinks ShLibSymlinkGenerator = _LibSymlinkGenerator('ShLib') @@ -430,7 +430,7 @@ class _LibNameGenerator(_LibInfoGeneratorBase): Verbose = False if Verbose: - print "_LibNameGenerator: str(libnode)=%r" % str(libnode) + print "_LibNameGenerator: libnode=%r" % libnode.get_path() version = self.get_lib_version(env, **kw) if Verbose: @@ -442,7 +442,7 @@ class _LibNameGenerator(_LibInfoGeneratorBase): name = self.generate_versioned_lib_info(env, [libnode, version, suffix], **kw) if not name: - name = os.path.basename(str(libnode)) + name = os.path.basename(libnode.get_path()) if Verbose: print '_LibNameGenerator: return name=%r' % name @@ -464,7 +464,7 @@ class _LibSonameGenerator(_LibInfoGeneratorBase): Verbose = False if Verbose: - print "_LibSonameGenerator: str(libnode)=%r" % str(libnode) + print "_LibSonameGenerator: libnode=%r" % libnode.get_path() soname = env.subst('$SONAME') if not soname: @@ -489,41 +489,56 @@ class _LibSonameGenerator(_LibInfoGeneratorBase): ShLibSonameGenerator = _LibSonameGenerator('ShLib') LdModSonameGenerator = _LibSonameGenerator('LdMod') +def StringizeLibSymlinks(symlinks): + """Converts list with pairs of nodes to list with pairs of node paths + (strings). Used mainly for debugging.""" + if SCons.Util.is_List(symlinks): + try: + return [ (k.get_path(), v.get_path()) for k,v in symlinks ] + except TypeError: + return symlinks + except ValueError: + return symlinks + else: + return symlinks + def EmitLibSymlinks(env, symlinks, libnode): """Used by emitters to handle (shared/versioned) library symlinks""" Verbose = False - for linkname, linktgt in symlinks.iteritems(): - env.SideEffect(linkname, linktgt) + + # nodes involved in process... all symlinks + library + nodes = list(set([ x for x,y in symlinks ] + [libnode])) + + for link, linktgt in symlinks: + env.SideEffect(link, linktgt) if(Verbose): - print "EmitLibSymlinks: SideEffect(", linkname, ", ", linktgt, ")" - clean = list(set(filter(lambda x : x != linktgt, symlinks.keys() + [str(libnode)]))) - env.Clean(linktgt, clean) + print "EmitLibSymlinks: SideEffect(%r,%r)" % (link.get_path(), linktgt.get_path()) + clean_list = filter(lambda x : x != linktgt, nodes) + env.Clean(linktgt, clean_list) if(Verbose): - print "EmitLibSymlinks: Clean(%r,%r)" % (linktgt, clean) + print "EmitLibSymlinks: Clean(%r,%r)" % (linktgt.get_path(), map(lambda x : x.get_path(), clean_list)) def CreateLibSymlinks(env, symlinks): - """Physically creates symlinks. The symlinks argument must be a dict in - form { linkname : linktarget } + """Physically creates symlinks. The symlinks argument must be a list in + form [ (link, linktarget), ... ], where link and linktarget are SCons + nodes. """ Verbose = False - for linkname, linktgt in symlinks.iteritems(): - linkname = str(env.arg2nodes(linkname)[0]) - linkdir = os.path.dirname(linkname) - if linkdir: - # NOTE: os.path.relpath appears in python 2.6 - linktgt = os.path.relpath(linktgt, linkdir) - else: - linktgt = os.path.basename(linktgt) + for link, linktgt in symlinks: + linktgt = link.get_dir().rel_path(linktgt) + link = link.get_path() if(Verbose): - print "CreateLibSymlinks: preparing to add symlink ", linkname, " -> ", linktgt + print "CreateLibSymlinks: preparing to add symlink %r -> %r" % (link, linktgt) try: - os.remove(linkname) + os.remove(link) + if(Verbose): + print "CreateLibSymlinks: removed old file %r" % link except: pass - os.symlink(linktgt, linkname) + os.symlink(linktgt, link) if(Verbose): - print "CreateLibSymlinks: add symlink ", linkname, " -> ", linktgt + print "CreateLibSymlinks: add symlink %r -> %r" % (link, linktgt) return 0 def LibSymlinksActionFunction(target, source, env): diff --git a/src/engine/SCons/Tool/cyglink.py b/src/engine/SCons/Tool/cyglink.py index 4033978..59258b2 100644 --- a/src/engine/SCons/Tool/cyglink.py +++ b/src/engine/SCons/Tool/cyglink.py @@ -56,6 +56,9 @@ def ldmod_generator(target, source, env, for_signature): def _lib_emitter(target, source, env, **kw): Verbose = False + if Verbose: + print "_lib_emitter: target[0]=%r" % target[0].get_path() + try: vp = kw['varprefix'] except KeyError: vp = 'SHLIB' @@ -65,6 +68,9 @@ def _lib_emitter(target, source, env, **kw): dll = env.FindIxes(target, '%sPREFIX' % vp, '%sSUFFIX' % vp) no_import_lib = env.get('no_import_lib', 0) + if Verbose: + print "_lib_emitter: dll=%r" % dll.get_path() + 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("$%sSUFFIX" % vp)) @@ -73,20 +79,28 @@ def _lib_emitter(target, source, env, **kw): if dll.name[len(pre):len(pre)+3] == 'lib': dll.name = pre + dll.name[len(pre)+3:] + if Verbose: + print "_lib_emitter: dll.name=%r" % dll.name + orig_target = target target = [env.fs.File(dll)] target[0].attributes.shared = 1 + if Verbose: + print "_lib_emitter: after target=[env.fs.File(dll)]: target[0]=%r" % target[0].get_path() + # Append an import lib target if not no_import_lib: # Create list of target libraries as strings target_strings = env.ReplaceIxes(orig_target[0], '%sPREFIX' % vp, '%sSUFFIX' % vp, 'IMPLIBPREFIX', 'IMPLIBSUFFIX') + if Verbose: + print "_lib_emitter: target_strings=%r" % target_strings implib_target = env.fs.File(target_strings) if Verbose: - print "_lib_emitter: implib_target=%r" % str(implib_target) + print "_lib_emitter: implib_target=%r" % implib_target.get_path() implib_target.attributes.shared = 1 target.append(implib_target) @@ -94,7 +108,7 @@ def _lib_emitter(target, source, env, **kw): implib_libtype=libtype, generator_libtype=libtype+'ImpLib') if Verbose: - print "_lib_emitter: implib symlinks=%r" % symlinks + print "_lib_emitter: implib symlinks=%r" % SCons.Tool.StringizeLibSymlinks(symlinks) if symlinks: SCons.Tool.EmitLibSymlinks(env, symlinks, implib_target) implib_target.attributes.shliblinks = symlinks @@ -129,20 +143,19 @@ def _versioned_implib_name(env, libnode, version, suffix, **kw): def _versioned_implib_symlinks(env, libnode, version, suffix, **kw): """Generate link names that should be created for a versioned shared lirbrary. - Returns a dictionary in the form { linkname : linktarget } + Returns a list in the form [ (link, linktarget), ... ] """ Verbose = False if Verbose: - print "_versioned_implib_symlinks: str(libnode)=%r" % str(libnode) + print "_versioned_implib_symlinks: libnode=%r" % libnode.get_path() print "_versioned_implib_symlinks: version=%r" % version try: libtype = kw['libtype'] except KeyError: libtype = 'ShLib' - symlinks = {} - linkdir = os.path.dirname(str(libnode)) + linkdir = os.path.dirname(libnode.get_path()) if Verbose: print "_versioned_implib_symlinks: linkdir=%r" % linkdir @@ -154,12 +167,11 @@ def _versioned_implib_symlinks(env, libnode, version, suffix, **kw): major = version.split('.')[0] - link0 = os.path.join(str(linkdir), name) - - symlinks[link0] = str(libnode) + link0 = env.fs.File(os.path.join(linkdir, name)) + symlinks = [(link0, libnode)] if Verbose: - print "_versioned_implib_symlinks: return symlinks=%r" % symlinks + print "_versioned_implib_symlinks: return symlinks=%r" % SCons.Tool.StringizeLibSymlinks(symlinks) return symlinks diff --git a/src/engine/SCons/Tool/gnulink.py b/src/engine/SCons/Tool/gnulink.py index ea0ca5a..14007af 100644 --- a/src/engine/SCons/Tool/gnulink.py +++ b/src/engine/SCons/Tool/gnulink.py @@ -85,18 +85,16 @@ def _versioned_lib_symlinks(env, libnode, version, suffix, name_generator, sonam print "_versioned_lib_symlinks: str(libnode)=%r" % str(libnode) print "_versioned_lib_symlinks: version=%r" % version - symlinks = {} - if sys.platform.startswith('openbsd'): # OpenBSD uses x.y shared library versioning numbering convention # and doesn't use symlinks to backwards-compatible libraries if Verbose: - print "_versioned_lib_symlinks: return symlinks=%r" % symlinks - return symlinks + print "_versioned_lib_symlinks: return symlinks=%r" % None + return None - linkdir = os.path.dirname(str(libnode)) + linkdir = libnode.get_dir() if Verbose: - print "_versioned_lib_symlinks: linkdir=%r" % linkdir + print "_versioned_lib_symlinks: linkdir=%r" % linkdir.get_path() name = name_generator(env, libnode) if Verbose: @@ -104,14 +102,13 @@ def _versioned_lib_symlinks(env, libnode, version, suffix, name_generator, sonam soname = soname_generator(env, libnode) - link0 = os.path.join(str(linkdir), soname) - link1 = os.path.join(str(linkdir), name) + link0 = env.fs.File(soname, linkdir) + link1 = env.fs.File(name, linkdir) - symlinks[link0] = str(libnode) - symlinks[link1] = link0 + symlinks = [ (link0, libnode), (link1, link0) ] if Verbose: - print "_versioned_lib_symlinks: return symlinks=%r" % symlinks + print "_versioned_lib_symlinks: return symlinks=%r" % SCons.Tool.StringizeLibSymlinks(symlinks) return symlinks diff --git a/src/engine/SCons/Tool/install.py b/src/engine/SCons/Tool/install.py index c5c2adb..9d5db9f 100644 --- a/src/engine/SCons/Tool/install.py +++ b/src/engine/SCons/Tool/install.py @@ -147,18 +147,19 @@ def copyFuncVersionedLib(dest, source, env): return 0 def listShlibLinksToInstall(dest, source, env): - install_links = {} - install_dir = os.path.dirname(str(dest)) + install_links = [] source = env.arg2nodes(source) + dest = env.fs.File(dest) + install_dir = dest.get_dir() for src in source: - links = getattr(getattr(src,'attributes',None), 'shliblinks', None) - if SCons.Util.is_Dict(links): - for linkname, linktgt in links.iteritems(): - linkname_base = os.path.basename(str(linkname)) - linktgt_base = os.path.basename(str(linktgt)) - install_linkname = os.path.join(install_dir, linkname_base) - install_linktgt = os.path.join(install_dir, linktgt_base) - install_links[install_linkname] = install_linktgt + symlinks = getattr(getattr(src,'attributes',None), 'shliblinks', None) + if symlinks: + for link, linktgt in symlinks: + link_base = os.path.basename(link.get_path()) + linktgt_base = os.path.basename(linktgt.get_path()) + install_link = env.fs.File(link_base, install_dir) + install_linktgt = env.fs.File(linktgt_base, install_dir) + install_links.append((install_link, install_linktgt)) return install_links def installShlibLinks(dest, source, env): @@ -167,7 +168,7 @@ def installShlibLinks(dest, source, env): symlinks = listShlibLinksToInstall(dest, source, env) if Verbose: - print 'installShlibLinks: symlinks=%r' % symlinks + print 'installShlibLinks: symlinks=%r' % SCons.Tool.StringizeLibSymlinks(symlinks) if symlinks: SCons.Tool.CreateLibSymlinks(env, symlinks) return diff --git a/test/LINK/VersionedLib-VariantDir.py b/test/LINK/VersionedLib-VariantDir.py new file mode 100644 index 0000000..a3ea660 --- /dev/null +++ b/test/LINK/VersionedLib-VariantDir.py @@ -0,0 +1,157 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Ensure that SharedLibrary builder with SHLIBVERSION set works with VariantDir. +""" + +import TestSCons +import os +import sys + +import SCons.Platform + +platform = SCons.Platform.platform_default() + +test = TestSCons.TestSCons() + +test.subdir(['src']) +test.subdir(['src','lib']) +test.subdir(['src','bin']) + +test.write(['src','lib','foo.c'], """ +#if _WIN32 +__declspec(dllexport) +#endif +int foo() { return 0; } +""") + +test.write(['src','bin','main.c'], """ +#if _WIN32 +__declspec(dllimport) +#endif +int foo(); +int main() +{ + return foo(); +} +""") + +test.write('SConstruct', """ +env = Environment() +variant = { 'variant_dir' : 'build', + 'src_dir' : 'src', + 'duplicate' : 0, + 'exports' : { 'env' : env } } +SConscript('src/lib/SConscript', **variant) +SConscript('src/bin/SConscript', **variant) +""") + +test.write(['src','lib','SConscript'], """ +Import('env') +env.SharedLibrary('foo', 'foo.c', SHLIBVERSION = '0.1.2') +""" ) + +test.write(['src','bin','SConscript'], """ +Import('env') +env.Program('main.c', LIBS=['foo'], LIBPATH=['../lib']) +""") + +test.run(arguments = ['--tree=all']) + +if platform == 'cygwin' or platform == 'win32': + # PATH is used to search for *.dll libraries on windows + path = os.environ.get('PATH','') + if path: path = path + os.pathsep + path = path + test.workpath('build/lib') + os.environ['PATH'] = path + +if os.name == 'posix': + os.environ['LD_LIBRARY_PATH'] = test.workpath('build/lib') +if sys.platform.find('irix') != -1: + os.environ['LD_LIBRARYN32_PATH'] = test.workpath('build/lib') + +test.run(program = test.workpath('build/bin/main')) + +if platform == 'posix': + # All (?) the files we expect will get created in the current directory + files = [ + 'libfoo.so', + 'libfoo.so.0', + 'libfoo.so.0.1.2', + ] + obj = 'foo.os' +elif platform == 'darwin': + # All (?) the files we expect will get created in the current directory + files = [ + 'libfoo.dylib', + 'libfoo.0.1.2.dylib', + ] + obj = 'foo.os' +elif platform == 'cygwin': + # All (?) the files we expect will get created in the current directory + files = [ + 'cygfoo-0-1-2.dll', + 'libfoo-0-1-2.dll.a', + 'libfoo.dll.a', + ] + obj = 'foo.os' +elif platform == 'win32': + # All (?) the files we expect will get created in the current directory + files = [ + 'foo.dll', + 'foo.lib', + ] + obj = 'foo.obj' +else: + # All (?) the files we expect will get created in the current directory + files= [ + 'libfoo.so', + ] + obj = 'foo.os' + +test.must_exist([ 'build', 'lib', obj ]) +for f in files: + test.must_exist([ 'build', 'lib', f ]) + +test.run(arguments = ['-c']) + +test.must_not_exist([ 'build', 'lib', obj ]) +for f in files: + test.must_not_exist([ 'build', 'lib', f ]) + +test.must_exist(['src', 'lib', 'foo.c']) +test.must_exist(['SConstruct']) +test.must_exist(['src', 'lib', 'SConscript']) +test.must_exist(['src', 'bin', 'SConscript']) + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/LINK/VersionedLib-subdir.py b/test/LINK/VersionedLib-subdir.py index 5fae101..6facd41 100644 --- a/test/LINK/VersionedLib-subdir.py +++ b/test/LINK/VersionedLib-subdir.py @@ -76,8 +76,8 @@ env.Program('main.c', LIBS=['foo']) test.run(arguments = ['--tree=all']) -if platform == 'cygwin': - # PATH is used to search for *.dll librarier (cygfoo-0-2-1.dll in our case) +if platform == 'cygwin' or platform == 'win32': + # PATH is used to search for *.dll libraries on windows path = os.environ.get('PATH','') if path: path = path + os.pathsep path = path + test.workpath(subdir) -- cgit v0.12 From d124e8dd69f7c73e7ce82d55abf5f69e12379098 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Tomulik?= Date: Fri, 4 Sep 2015 23:37:17 +0200 Subject: refactored the versioned lib code a little --- src/engine/SCons/Tool/__init__.py | 98 ++++++++++++++++++++++++++++++--------- src/engine/SCons/Tool/cyglink.py | 48 +++++++++---------- src/engine/SCons/Tool/gnulink.py | 56 +++++++++++----------- src/engine/SCons/Tool/link.py | 35 ++++++++------ 4 files changed, 148 insertions(+), 89 deletions(-) diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py index 0e6e7d8..0b09a13 100644 --- a/src/engine/SCons/Tool/__init__.py +++ b/src/engine/SCons/Tool/__init__.py @@ -236,31 +236,31 @@ def createStaticLibBuilder(env): return static_lib -def _call_env_cb(env, callback, args, result = None): - """Returns the result of env[callback](*args) call if env[callback] is - callable. If env[callback] does not exist or is not callable, return the - value provided as the *result* argument. This function is mainly used for - generating library info such as versioned suffixes, symlink maps, sonames - etc. by delegating the core job to callbacks configured by current linker - tool""" +def _call_linker_cb(env, callback, args, result = None): + """Returns the result of env['LINKCALLBACKS'][callback](*args) + if env['LINKCALLBACKS'] is a dictionary and env['LINKCALLBACKS'][callback] + is callable. If these conditions are not meet, return the value provided as + the *result* argument. This function is mainly used for generating library + info such as versioned suffixes, symlink maps, sonames etc. by delegating + the core job to callbacks configured by current linker tool""" Verbose = False if Verbose: - print '_call_env_cb: args=%r' % args - print '_call_env_cb: callback=%r' % callback - + print '_call_linker_cb: args=%r' % args + print '_call_linker_cb: callback=%r' % callback + try: - cbfun = env[callback] - except KeyError: + cbfun = env['LINKCALLBACKS'][callback] + except (KeyError, TypeError): pass else: if Verbose: - print '_call_env_cb: env[%r] found' % callback - print '_call_env_cb: env[%r]=%r' % (callback, cbfun) + print '_call_linker_cb: env[%r] found' % callback + print '_call_linker_cb: env[%r]=%r' % (callback, cbfun) if(callable(cbfun)): if Verbose: - print '_call_env_cb: env[%r] is callable' % callback + print '_call_linker_cb: env[%r] is callable' % callback result = cbfun(env, *args) return result @@ -298,6 +298,17 @@ class _LibInfoGeneratorBase(object): prefix = env.subst('$IMPLIBPREFIX') return prefix + def get_lib_prefix(self, env): + prefix = None + libtype = self.get_libtype() + if libtype == 'ShLib': + prefix = env.subst('$SHLIBPREFIX') + elif libtype == 'LdMod': + prefix = env.subst('$LDMODULEPREFIX') + elif libtype == 'ImpLib': + prefix = env.subst('$IMPLIBPREFIX') + return prefix + def get_lib_suffix(self, env): suffix = None libtype = self.get_libtype() @@ -332,11 +343,39 @@ class _LibInfoGeneratorBase(object): try: libtype = kw['generator_libtype'] except KeyError: libtype = self.get_libtype() infoname = self.get_infoname() - return 'GenerateVersioned%s%s' % (libtype, infoname) + return 'Versioned%s%s' % (libtype, infoname) def generate_versioned_lib_info(self, env, args, result = None, **kw): callback = self.get_versioned_lib_info_generator(**kw) - return _call_env_cb(env, callback, args, result) + return _call_linker_cb(env, callback, args, result) + +class _LibPrefixGenerator(_LibInfoGeneratorBase): + """Library prefix generator, used as target_prefix in SharedLibrary and + LoadableModule builders""" + def __init__(self, libtype): + super(_LibPrefixGenerator, self).__init__(libtype, 'Prefix') + + def __call__(self, env, sources = None, **kw): + Verbose = False + + prefix = self.get_lib_prefix(env) + if Verbose: + print "_LibPrefixGenerator: input prefix=%r" % prefix + + version = self.get_lib_version(env, **kw) + if Verbose: + print "_LibPrefixGenerator: version=%r" % version + + if version: + prefix = self.generate_versioned_lib_info(env, [prefix, version], prefix, **kw) + + if Verbose: + print "_LibPrefixGenerator: return prefix=%r" % prefix + return prefix + +ShLibPrefixGenerator = _LibPrefixGenerator('ShLib') +LdModPrefixGenerator = _LibPrefixGenerator('LdMod') +ImpLibPrefixGenerator = _LibPrefixGenerator('ImpLib') class _LibSuffixGenerator(_LibInfoGeneratorBase): """Library suffix generator, used as target_suffix in SharedLibrary and @@ -408,8 +447,9 @@ class _LibSymlinkGenerator(_LibInfoGeneratorBase): print '_LibSymlinkGenerator: disable=%r' % disable if version and not disable: + prefix = self.get_lib_prefix(env) suffix = self.get_lib_suffix(env) - symlinks = self.generate_versioned_lib_info(env, [libnode, version, suffix], **kw) + symlinks = self.generate_versioned_lib_info(env, [libnode, version, prefix, suffix], **kw) if Verbose: print '_LibSymlinkGenerator: return symlinks=%r' % StringizeLibSymlinks(symlinks) @@ -420,8 +460,19 @@ LdModSymlinkGenerator = _LibSymlinkGenerator('LdMod') ImpLibSymlinkGenerator = _LibSymlinkGenerator('ImpLib') class _LibNameGenerator(_LibInfoGeneratorBase): - """Library name generator. Returns library name (e.g. libfoo.so) for - a given node (e.g. /foo/bar/libfoo.so.0.1.2)""" + """Generates "unmangled" library name from a library file node. + + Generally, it's thought to revert modifications done by prefix/suffix + generators (_LibPrefixGenerator/_LibSuffixGenerator) used by a library + builder. For example, on gnulink the suffix generator used by SharedLibrary + builder appends $SHLIBVERSION to $SHLIBSUFFIX producing node name which + ends with "$SHLIBSUFFIX.$SHLIBVERSION". Correspondingly, the implementation + of _LibNameGenerator replaces "$SHLIBSUFFIX.$SHLIBVERSION" with + "$SHLIBSUFFIX" in the node's basename. So that, if $SHLIBSUFFIX is ".so", + $SHLIBVERSION is "0.1.2" and the node path is "/foo/bar/libfoo.so.0.1.2", + the _LibNameGenerator shall return "libfoo.so". Other link tools may + implement it's own way of library name unmangling. + """ def __init__(self, libtype): super(_LibNameGenerator, self).__init__(libtype, 'Name') @@ -438,8 +489,9 @@ class _LibNameGenerator(_LibInfoGeneratorBase): name = None if version: + prefix = self.get_lib_prefix(env) suffix = self.get_lib_suffix(env) - name = self.generate_versioned_lib_info(env, [libnode, version, suffix], **kw) + name = self.generate_versioned_lib_info(env, [libnode, version, prefix, suffix], **kw) if not name: name = os.path.basename(libnode.get_path()) @@ -566,7 +618,7 @@ def createSharedLibBuilder(env): LibSymlinksAction ] shared_lib = SCons.Builder.Builder(action = action_list, emitter = "$SHLIBEMITTER", - prefix = '$SHLIBPREFIX', + prefix = ShLibPrefixGenerator, suffix = ShLibSuffixGenerator, target_scanner = ProgramScanner, src_suffix = '$SHOBJSUFFIX', @@ -591,7 +643,7 @@ def createLoadableModuleBuilder(env): LibSymlinksAction ] ld_module = SCons.Builder.Builder(action = action_list, emitter = "$LDMODULEEMITTER", - prefix = '$LDMODULEPREFIX', + prefix = ShLibPrefixGenerator, suffix = LdModSuffixGenerator, target_scanner = ProgramScanner, src_suffix = '$SHOBJSUFFIX', diff --git a/src/engine/SCons/Tool/cyglink.py b/src/engine/SCons/Tool/cyglink.py index 59258b2..e05e85f 100644 --- a/src/engine/SCons/Tool/cyglink.py +++ b/src/engine/SCons/Tool/cyglink.py @@ -15,6 +15,7 @@ import SCons.Util import SCons.Tool import gnulink +import link def _lib_generator(target, source, env, for_signature, **kw): try: cmd = kw['cmd'] @@ -135,13 +136,13 @@ def _versioned_lib_suffix(env, suffix, version): print "_versioned_lib_suffix: return suffix= ", suffix return suffix -def _versioned_implib_name(env, libnode, version, suffix, **kw): - import link - generator = SCons.Tool.ImpLibSuffixGenerator - libtype = kw['libtype'] - return link._versioned_lib_name(env, libnode, version, suffix, generator, implib_libtype=libtype) +def _versioned_implib_name(env, libnode, version, prefix, suffix, **kw): + return link._versioned_lib_name(env, libnode, version, prefix, suffix, + SCons.Tool.ImpLibPrefixGenerator, + SCons.Tool.ImpLibSuffixGenerator, + implib_libtype=kw['libtype']) -def _versioned_implib_symlinks(env, libnode, version, suffix, **kw): +def _versioned_implib_symlinks(env, libnode, version, prefix, suffix, **kw): """Generate link names that should be created for a versioned shared lirbrary. Returns a list in the form [ (link, linktarget), ... ] """ @@ -201,27 +202,24 @@ def generate(env): # SHLIBVERSIONFLAGS and LDMODULEVERSIONFLAGS are same as in gnulink... - env['GenerateVersionedShLibSuffix'] = _versioned_lib_suffix - env['GenerateVersionedLdModSuffix'] = _versioned_lib_suffix - env['GenerateVersionedImpLibSuffix'] = _versioned_lib_suffix - env['GenerateVersionedShLibImpLibName'] = lambda *args: _versioned_implib_name(*args, libtype='ShLib') - env['GenerateVersionedLdModImpLibName'] = lambda *args: _versioned_implib_name(*args, libtype='LdMod') - env['GenerateVersionedShLibImpLibSymlinks'] = lambda *args: _versioned_implib_symlinks(*args, libtype='ShLib') - env['GenerateVersionedLdModImpLibSymlinks'] = lambda *args: _versioned_implib_symlinks(*args, libtype='LdMod') - - def trydel(env, key): - try: del env[key] - except KeyError: pass + # LINKCALLBACKS are NOT inherited from gnulink + env['LINKCALLBACKS'] = { + 'VersionedShLibSuffix' : _versioned_lib_suffix, + 'VersionedLdModSuffix' : _versioned_lib_suffix, + 'VersionedImpLibSuffix' : _versioned_lib_suffix, + 'VersionedShLibName' : link._versioned_shlib_name, + 'VersionedLdModName' : link._versioned_ldmod_name, + 'VersionedShLibImpLibName' : lambda *args: _versioned_implib_name(*args, libtype='ShLib'), + 'VersionedLdModImpLibName' : lambda *args: _versioned_implib_name(*args, libtype='LdMod'), + 'VersionedShLibImpLibSymlinks' : lambda *args: _versioned_implib_symlinks(*args, libtype='ShLib'), + 'VersionedLdModImpLibSymlinks' : lambda *args: _versioned_implib_symlinks(*args, libtype='LdMod'), + } # these variables were set by gnulink but are not used in cyglink - trydel(env,'_SHLINKSONAME') - trydel(env,'_LDMODULESONAME') - trydel(env,'ShLibSonameGenerator') - trydel(env,'LdModSonameGenerator') - trydel(env,'GenerateVersionedShLibSymlinks') - trydel(env,'GenerateVersionedLdModSymlinks') - trydel(env,'GenerateVersionedShLibSoname') - trydel(env,'GenerateVersionedLdModSoname') + try: del env['_SHLINKSONAME'] + except KeyError: pass + try: del env['_LDMODULESONAME'] + except KeyError: pass def exists(env): return gnulink.exists(env) diff --git a/src/engine/SCons/Tool/gnulink.py b/src/engine/SCons/Tool/gnulink.py index 14007af..e5e8818 100644 --- a/src/engine/SCons/Tool/gnulink.py +++ b/src/engine/SCons/Tool/gnulink.py @@ -53,12 +53,12 @@ def _versioned_lib_suffix(env, suffix, version): print "_versioned_lib_suffix: return suffix=%r" % suffix return suffix -def _versioned_lib_soname(env, libnode, version, suffix, name_generator): +def _versioned_lib_soname(env, libnode, version, prefix, suffix, name_func): """For libnode='/optional/dir/libfoo.so.X.Y.Z' it returns 'libfoo.so.X'""" Verbose = False if Verbose: print "_versioned_lib_soname: version=%r" % version - name = name_generator(env, libnode) + name = name_func(env, libnode, version, prefix, suffix) if Verbose: print "_versioned_lib_soname: name=%r" % name major = version.split('.')[0] @@ -67,22 +67,20 @@ def _versioned_lib_soname(env, libnode, version, suffix, name_generator): print "_versioned_lib_soname: soname=%r" % soname return soname -def _versioned_shlib_soname(env, libnode, version, suffix): - generator = SCons.Tool.ShLibNameGenerator - return _versioned_lib_soname(env, libnode, version, suffix, generator) +def _versioned_shlib_soname(env, libnode, version, prefix, suffix): + return _versioned_lib_soname(env, libnode, version, prefix, suffix, link._versioned_shlib_name) -def _versioned_ldmod_soname(env, libnode, version, suffix): - generator = SCons.Tool.LdModNameGenerator - return _versioned_lib_soname(env, libnode, version, suffix, generator) +def _versioned_ldmod_soname(env, libnode, version, prefix, suffix): + return _versioned_lib_soname(env, libnode, version, prefix, suffix, link._versioned_ldmod_name) -def _versioned_lib_symlinks(env, libnode, version, suffix, name_generator, soname_generator): +def _versioned_lib_symlinks(env, libnode, version, prefix, suffix, name_func, soname_func): """Generate link names that should be created for a versioned shared lirbrary. Returns a dictionary in the form { linkname : linktarget } """ Verbose = False if Verbose: - print "_versioned_lib_symlinks: str(libnode)=%r" % str(libnode) + print "_versioned_lib_symlinks: libnode=%r" % libnode.get_path() print "_versioned_lib_symlinks: version=%r" % version if sys.platform.startswith('openbsd'): @@ -96,11 +94,11 @@ def _versioned_lib_symlinks(env, libnode, version, suffix, name_generator, sonam if Verbose: print "_versioned_lib_symlinks: linkdir=%r" % linkdir.get_path() - name = name_generator(env, libnode) + name = name_func(env, libnode, version, prefix, suffix) if Verbose: print "_versioned_lib_symlinks: name=%r" % name - soname = soname_generator(env, libnode) + soname = soname_func(env, libnode, version, prefix, suffix) link0 = env.fs.File(soname, linkdir) link1 = env.fs.File(name, linkdir) @@ -112,15 +110,15 @@ def _versioned_lib_symlinks(env, libnode, version, suffix, name_generator, sonam return symlinks -def _versioned_shlib_symlinks(env, libnode, version, suffix): - name_generator = SCons.Tool.ShLibNameGenerator - soname_generator = SCons.Tool.ShLibSonameGenerator - return _versioned_lib_symlinks(env, libnode, version, suffix, name_generator, soname_generator) +def _versioned_shlib_symlinks(env, libnode, version, prefix, suffix): + nf = link._versioned_shlib_name + sf = _versioned_shlib_soname + return _versioned_lib_symlinks(env, libnode, version, prefix, suffix, nf, sf) -def _versioned_ldmod_symlinks(env, libnode, version, suffix): - name_generator = SCons.Tool.LdModNameGenerator - soname_generator = SCons.Tool.LdModSonameGenerator - return _versioned_lib_symlinks(env, libnode, version, suffix, name_generator, soname_generator) +def _versioned_ldmod_symlinks(env, libnode, version, prefix, suffix): + nf = link._versioned_ldmod_name + sf = _versioned_ldmod_soname + return _versioned_lib_symlinks(env, libnode, version, prefix, suffix, nf, sf) def generate(env): """Add Builders and construction variables for gnulink to an Environment.""" @@ -155,14 +153,16 @@ def generate(env): env['ShLibSonameGenerator'] = SCons.Tool.ShLibSonameGenerator env['LdModSonameGenerator'] = SCons.Tool.LdModSonameGenerator - env['GenerateVersionedShLibSuffix'] = _versioned_lib_suffix - env['GenerateVersionedLdModSuffix'] = _versioned_lib_suffix - env['GenerateVersionedShLibSymlinks'] = _versioned_shlib_symlinks - env['GenerateVersionedLdModSymlinks'] = _versioned_ldmod_symlinks - env['GenerateVersionedShLibName'] = link._versioned_shlib_name - env['GenerateVersionedLdModName'] = link._versioned_ldmod_name - env['GenerateVersionedShLibSoname'] = _versioned_shlib_soname - env['GenerateVersionedLdModSoname'] = _versioned_shlib_soname + env['LINKCALLBACKS'] = { + 'VersionedShLibSuffix' : _versioned_lib_suffix, + 'VersionedLdModSuffix' : _versioned_lib_suffix, + 'VersionedShLibSymlinks' : _versioned_shlib_symlinks, + 'VersionedLdModSymlinks' : _versioned_ldmod_symlinks, + 'VersionedShLibName' : link._versioned_shlib_name, + 'VersionedLdModName' : link._versioned_ldmod_name, + 'VersionedShLibSoname' : _versioned_shlib_soname, + 'VersionedLdModSoname' : _versioned_shlib_soname, + } def exists(env): # TODO: sync with link.smart_link() to choose a linker diff --git a/src/engine/SCons/Tool/link.py b/src/engine/SCons/Tool/link.py index 33e50d9..d52a9e5 100644 --- a/src/engine/SCons/Tool/link.py +++ b/src/engine/SCons/Tool/link.py @@ -76,7 +76,7 @@ def smart_link(source, target, env, for_signature): def _lib_emitter(target, source, env, **kw): Verbose = False if Verbose: - print "_lib_emitter: str(target[0])=%r" % str(target[0]) + print "_lib_emitter: target[0]=%r" % target[0].get_path() for tgt in target: tgt.attributes.shared = 1 @@ -103,35 +103,44 @@ def ldmod_emitter(target, source, env): return _lib_emitter(target, source, env, symlink_generator = SCons.Tool.LdModSymlinkGenerator) # This is generic enough to be included here... -def _versioned_lib_name(env, libnode, version, suffix, suffix_generator, **kw): +def _versioned_lib_name(env, libnode, version, prefix, suffix, prefix_generator, suffix_generator, **kw): """For libnode='/optional/dir/libfoo.so.X.Y.Z' it returns 'libfoo.so'""" Verbose = False if Verbose: + print "_versioned_lib_name: libnode=%r" % libnode.get_path() print "_versioned_lib_name: version=%r" % version + print "_versioned_lib_name: prefix=%r" % prefix + print "_versioned_lib_name: suffix=%r" % suffix + print "_versioned_lib_name: suffix_generator=%r" % suffix_generator - versioned_name = os.path.basename(str(libnode)) + versioned_name = os.path.basename(libnode.get_path()) if Verbose: print "_versioned_lib_name: versioned_name=%r" % versioned_name - if Verbose: - print "_versioned_lib_name: suffix=%r" % suffix - + versioned_prefix = prefix_generator(env, **kw) versioned_suffix = suffix_generator(env, **kw) + if Verbose: + print "_versioned_lib_name: versioned_prefix=%r" % versioned_prefix + print "_versioned_lib_name: versioned_suffix=%r" % versioned_suffix + versioned_prefix_re = '^' + re.escape(versioned_prefix) versioned_suffix_re = re.escape(versioned_suffix) + '$' - name = re.sub(versioned_suffix_re, suffix, versioned_name) + name = re.sub(versioned_prefix_re, prefix, versioned_name) + name = re.sub(versioned_suffix_re, suffix, name) if Verbose: print "_versioned_lib_name: name=%r" % name return name -def _versioned_shlib_name(env, libnode, version, suffix, **kw): - generator = SCons.Tool.ShLibSuffixGenerator - return _versioned_lib_name(env, libnode, version, suffix, generator, **kw) +def _versioned_shlib_name(env, libnode, version, prefix, suffix, **kw): + pg = SCons.Tool.ShLibPrefixGenerator + sg = SCons.Tool.ShLibSuffixGenerator + return _versioned_lib_name(env, libnode, version, prefix, suffix, pg, sg, **kw) -def _versioned_ldmod_name(env, libnode, version, suffix, **kw): - generator = SCons.Tool.LdModSuffixGenerator - return _versioned_lib_name(env, libnode, version, suffix, generator, **kw) +def _versioned_ldmod_name(env, libnode, version, prefix, suffix, **kw): + pg = SCons.Tool.LdModPrefixGenerator + sg = SCons.Tool.LdModSuffixGenerator + return _versioned_lib_name(env, libnode, version, prefix, suffix, pg, sg, **kw) def generate(env): -- cgit v0.12 From 76b1f15cd9d50e70672908bed0a5c065232e4301 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Tomulik?= Date: Fri, 4 Sep 2015 23:44:31 +0200 Subject: remove redundant get_lib_prefix() method --- src/engine/SCons/Tool/__init__.py | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py index 0b09a13..23b08c6 100644 --- a/src/engine/SCons/Tool/__init__.py +++ b/src/engine/SCons/Tool/__init__.py @@ -298,17 +298,6 @@ class _LibInfoGeneratorBase(object): prefix = env.subst('$IMPLIBPREFIX') return prefix - def get_lib_prefix(self, env): - prefix = None - libtype = self.get_libtype() - if libtype == 'ShLib': - prefix = env.subst('$SHLIBPREFIX') - elif libtype == 'LdMod': - prefix = env.subst('$LDMODULEPREFIX') - elif libtype == 'ImpLib': - prefix = env.subst('$IMPLIBPREFIX') - return prefix - def get_lib_suffix(self, env): suffix = None libtype = self.get_libtype() -- cgit v0.12 From 13c193a7dabeecc0381a6ef770e72de216eb3f5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Tomulik?= Date: Fri, 4 Sep 2015 23:55:20 +0200 Subject: minor fix in Tool/__init__.py --- src/engine/SCons/Tool/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py index 23b08c6..df917ed 100644 --- a/src/engine/SCons/Tool/__init__.py +++ b/src/engine/SCons/Tool/__init__.py @@ -632,7 +632,7 @@ def createLoadableModuleBuilder(env): LibSymlinksAction ] ld_module = SCons.Builder.Builder(action = action_list, emitter = "$LDMODULEEMITTER", - prefix = ShLibPrefixGenerator, + prefix = LdModPrefixGenerator, suffix = LdModSuffixGenerator, target_scanner = ProgramScanner, src_suffix = '$SHOBJSUFFIX', -- cgit v0.12 From cf4df802f7c81e2eb07628850165ad1e2269334a Mon Sep 17 00:00:00 2001 From: Pawel Tomulik Date: Sat, 5 Sep 2015 00:50:43 +0200 Subject: add action string function for LibSymlinksAction --- src/engine/SCons/Tool/__init__.py | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py index df917ed..d1f41ec 100644 --- a/src/engine/SCons/Tool/__init__.py +++ b/src/engine/SCons/Tool/__init__.py @@ -466,7 +466,7 @@ class _LibNameGenerator(_LibInfoGeneratorBase): super(_LibNameGenerator, self).__init__(libtype, 'Name') def __call__(self, env, libnode, **kw): - """Returns library name with version suffixes stripped""" + """Returns "demangled" library name""" Verbose = False if Verbose: @@ -536,9 +536,7 @@ def StringizeLibSymlinks(symlinks): if SCons.Util.is_List(symlinks): try: return [ (k.get_path(), v.get_path()) for k,v in symlinks ] - except TypeError: - return symlinks - except ValueError: + except (TypeError, ValueError): return symlinks else: return symlinks @@ -589,7 +587,24 @@ def LibSymlinksActionFunction(target, source, env): CreateLibSymlinks(env, symlinks) return 0 -LibSymlinksAction = SCons.Action.Action(LibSymlinksActionFunction, None) +def LibSymlinksStrFun(target, source, env,*args): + cmd = None + for tgt in target: + symlinks = getattr(getattr(tgt,'attributes', None), 'shliblinks', None) + if symlinks: + if cmd is None: cmd = "" + if cmd: cmd += "\n" + cmd += "Create symlinks for: %r" % tgt.get_path() + try: + linkstr = ', '.join([ "%r->%r" %(k,v) for k,v in StringizeLibSymlinks(symlinks)]) + except (KeyError, ValueError): + pass + else: + cmd += ": %s" % linkstr + return cmd + + +LibSymlinksAction = SCons.Action.Action(LibSymlinksActionFunction, LibSymlinksStrFun) def createSharedLibBuilder(env): """This is a utility function that creates the SharedLibrary -- cgit v0.12 From 2a1a18d6c6a311f28eca6b97372475a09732bad0 Mon Sep 17 00:00:00 2001 From: Pawel Tomulik Date: Mon, 7 Sep 2015 09:34:25 +0200 Subject: minor correction to debug code in Tool/__init__.py --- src/engine/SCons/Tool/__init__.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py index d1f41ec..87a4cf4 100644 --- a/src/engine/SCons/Tool/__init__.py +++ b/src/engine/SCons/Tool/__init__.py @@ -253,14 +253,16 @@ def _call_linker_cb(env, callback, args, result = None): try: cbfun = env['LINKCALLBACKS'][callback] except (KeyError, TypeError): + if Verbose: + print '_call_linker_cb: env["LINKCALLBACKS"][%r] not found or can not be used' pass else: if Verbose: - print '_call_linker_cb: env[%r] found' % callback - print '_call_linker_cb: env[%r]=%r' % (callback, cbfun) + print '_call_linker_cb: env["LINKCALLBACKS"][%r] found' % callback + print '_call_linker_cb: env["LINKCALLBACKS"][%r]=%r' % (callback, cbfun) if(callable(cbfun)): if Verbose: - print '_call_linker_cb: env[%r] is callable' % callback + print '_call_linker_cb: env["LINKCALLBACKS"][%r] is callable' % callback result = cbfun(env, *args) return result -- cgit v0.12 From 67e838665e0520c7d7e53b2aeb85ca0c89e86b69 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 14 Sep 2015 13:24:04 -0700 Subject: Updated generated docs prior to 2.4.0 release --- doc/generated/examples/caching_ex-random_1.xml | 4 ++-- doc/generated/examples/troubleshoot_explain1_3.xml | 2 +- doc/generated/tools.gen | 12 ++++++------ doc/generated/tools.mod | 4 ++-- doc/generated/variables.gen | 6 ++---- 5 files changed, 13 insertions(+), 15 deletions(-) diff --git a/doc/generated/examples/caching_ex-random_1.xml b/doc/generated/examples/caching_ex-random_1.xml index 6f64f8f..18b04eb 100644 --- a/doc/generated/examples/caching_ex-random_1.xml +++ b/doc/generated/examples/caching_ex-random_1.xml @@ -1,9 +1,9 @@ % scons -Q -cc -o f2.o -c f2.c -cc -o f4.o -c f4.c cc -o f3.o -c f3.c cc -o f5.o -c f5.c +cc -o f4.o -c f4.c +cc -o f2.o -c f2.c cc -o f1.o -c f1.c cc -o prog f1.o f2.o f3.o f4.o f5.o diff --git a/doc/generated/examples/troubleshoot_explain1_3.xml b/doc/generated/examples/troubleshoot_explain1_3.xml index 246ee56..3d8592d 100644 --- a/doc/generated/examples/troubleshoot_explain1_3.xml +++ b/doc/generated/examples/troubleshoot_explain1_3.xml @@ -3,5 +3,5 @@ cp file.in file.oout scons: warning: Cannot find target file.out after building -File "/home/bdbaddog/scons/as_scons/bootstrap/src/script/scons.py", line 199, in <module> +File "/scons/as_scons/bootstrap/src/script/scons.py", line 199, in <module> diff --git a/doc/generated/tools.gen b/doc/generated/tools.gen index db89475..4613333 100644 --- a/doc/generated/tools.gen +++ b/doc/generated/tools.gen @@ -772,19 +772,19 @@ Sets construction variables for the Sets: &cv-link-AS;, &cv-link-ASCOM;, &cv-link-ASFLAGS;, &cv-link-ASPPCOM;, &cv-link-ASPPFLAGS;.Uses: &cv-link-ASCOMSTR;, &cv-link-ASPPCOMSTR;. - - packaging + + Packaging -A framework for building binary and source packages. +Sets construction variables for the Package Builder. - - Packaging + + packaging -Sets construction variables for the Package Builder. +A framework for building binary and source packages. diff --git a/doc/generated/tools.mod b/doc/generated/tools.mod index 5a5795a..4ebffb9 100644 --- a/doc/generated/tools.mod +++ b/doc/generated/tools.mod @@ -77,8 +77,8 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. mwcc"> mwld"> nasm"> -packaging"> Packaging"> +packaging"> pdf"> pdflatex"> pdftex"> @@ -187,8 +187,8 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. mwcc"> mwld"> nasm"> -packaging"> Packaging"> +packaging"> pdf"> pdflatex"> pdftex"> diff --git a/doc/generated/variables.gen b/doc/generated/variables.gen index bf18796..04c3efe 100644 --- a/doc/generated/variables.gen +++ b/doc/generated/variables.gen @@ -6753,9 +6753,7 @@ and translated into the The list of directories that the scripting language wrapper and interface generate will search for included files. The SWIG implicit dependency scanner will search these -directories for include files. -The default is to use the same path -specified as $CPPPATH. +directories for include files. The default value is an empty list. @@ -6802,7 +6800,7 @@ include $_SWIGINCFLAGS: -env = Environment(SWIGCOM="my_swig -o $TARGET $_SWIGINCFLAGS $SORUCES") +env = Environment(SWIGCOM="my_swig -o $TARGET $_SWIGINCFLAGS $SOURCES") -- cgit v0.12 From 1dc8c086aae30f3ff3e31506875550ee6916922f Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 14 Sep 2015 13:36:50 -0700 Subject: updates to release, announce, changes, debian/changelog for 2.4.0 release --- debian/changelog | 7 +++++++ src/Announce.txt | 13 +++++-------- src/RELEASE.txt | 56 +++++++++++++++----------------------------------------- 3 files changed, 27 insertions(+), 49 deletions(-) diff --git a/debian/changelog b/debian/changelog index b161db1..0b5f17e 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ + +scons (2.3.6) unstable; urgency=low + + * Maintenance release. + + -- William Deegan Mon, 14 Sep 2015 21:07:32 -0700 + scons (2.3.6) unstable; urgency=low * Maintenance release. diff --git a/src/Announce.txt b/src/Announce.txt index f96e703..5f121af 100644 --- a/src/Announce.txt +++ b/src/Announce.txt @@ -18,14 +18,7 @@ So that everyone using SCons can help each other learn how to use it more effectively, please go to http://scons.org/lists.php#users to sign up for the scons-users mailing list. -==============IMPORTANT NOTICE FOR NEXT VERSION V2.4.0=========== - -PLEASE READ. CHANGES COMING IN NEXT MAJOR RELEASE V2.4.0 -As has been pre-announced in SCons's mailing lists: - -* https://pairlist4.pair.net/pipermail/scons-users/2014-July/002734.html , -* https://pairlist2.pair.net/pipermail/scons-dev/2014-December/002107.html -* https://pairlist4.pair.net/pipermail/scons-users/2015-February/003454.html +==============IMPORTANT NOTICE FOR VERSION V2.4.0=========== We're planning to switch the Node class to using "slots" in the core sources, mainly to reduce memory consumption by up to 35% in large build projects. @@ -45,6 +38,10 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER changes. + Please note the following important changes since release 2.3.6: + - Switch Node class to using "slots" should reduce memory usage + and speed up builds. + Please note the following important changes since release 2.3.5: - Support for Visual Studio 2015 diff --git a/src/RELEASE.txt b/src/RELEASE.txt index 83212a7..74d955e 100644 --- a/src/RELEASE.txt +++ b/src/RELEASE.txt @@ -1,72 +1,46 @@ - A new SCons checkpoint release, 2.3.8.alpha.yyyymmdd, is now available - on the SCons download page: + A new SCons release, 2.4.0 , is now available on the SCons download page: http://www.scons.org/download.php - XXX The primary purpose of this release ... XXX - - A SCons "checkpoint release" is intended to provide early access to - new features so they can be tested in the field before being released - for adoption by other software distributions. - - Note that a checkpoint release is developed using the same test-driven - development methodology as all SCons releases. Existing SCons - functionality should all work as it does in previous releases (except - for any changes identified in the release notes) and early adopters - should be able to use a checkpoint release safely for production work - with existing SConscript files. If not, it represents not only a bug - in SCons but also a hole in the regression test suite, and we want to - hear about it. - - New features may be more lightly tested than in past releases, - especially as concerns their interaction with all of the other - functionality in SCons. We are especially interested in hearing bug - reports about new functionality. - - We do not recommend that downstream distributions (Debian, Fedora, - etc.) package a checkpoint release, mainly to avoid confusing the - "public" release numbering with the long checkpoint release names. - - Here is a summary of the changes since 1.3.0: + Here is a summary of the changes since 2.3.6: NEW FUNCTIONALITY - - List new features (presumably why a checkpoint is being released) + - None DEPRECATED FUNCTIONALITY - - List anything that's been deprecated since the last release + - None CHANGED/ENHANCED EXISTING FUNCTIONALITY - - List modifications to existing features, where the previous behavior - wouldn't actually be considered a bug + - Switched several core classes to using "slots", for + reducing the overall memory consumption in large + projects (fixes #2180, #2178, #2198) + - Memoizer counting uses decorators now, instead of + the old metaclasses approach. FIXES - - List fixes of outright bugs + - 2180, 2178, 2198 (See above) IMPROVEMENTS - - List improvements that wouldn't be visible to the user in the - documentation: performance improvements (describe the circumstances - under which they would be observed), or major code cleanups + - See CHANGED/ENHANCED EXISTING FUNCTIONALITY above PACKAGING - - List changes in the way SCons is packaged and/or released + - None DOCUMENTATION - - List any significant changes to the documentation (not individual - typo fixes, even if they're mentioned in src/CHANGES.txt to give - the contributor credit) + - Bug 2504 - Fixed incorrect default SWIGPATH in documentation DEVELOPMENT - - List visible changes in the way SCons is developed + - None - Thanks to CURLY, LARRY, and MOE for their contributions to this release. + Thanks to Dirk Baechle, and Andrew Featherstone for their contributions to this release. Contributors are listed alphabetically by their last name. __COPYRIGHT__ -- cgit v0.12 From 4f3e3c23da4fe1b1cc22ac1c1030c94f26217ec5 Mon Sep 17 00:00:00 2001 From: ptomulik Date: Tue, 15 Sep 2015 16:06:48 +0200 Subject: revision: address remarks made by Gary Oberbrunner --- src/engine/SCons/Tool/__init__.py | 234 +++++++++++++++++++++++-------------- src/engine/SCons/Tool/__init__.xml | 2 +- 2 files changed, 145 insertions(+), 91 deletions(-) diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py index 87a4cf4..357b765 100644 --- a/src/engine/SCons/Tool/__init__.py +++ b/src/engine/SCons/Tool/__init__.py @@ -239,7 +239,7 @@ def createStaticLibBuilder(env): def _call_linker_cb(env, callback, args, result = None): """Returns the result of env['LINKCALLBACKS'][callback](*args) if env['LINKCALLBACKS'] is a dictionary and env['LINKCALLBACKS'][callback] - is callable. If these conditions are not meet, return the value provided as + is callable. If these conditions are not met, return the value provided as the *result* argument. This function is mainly used for generating library info such as versioned suffixes, symlink maps, sonames etc. by delegating the core job to callbacks configured by current linker tool""" @@ -254,7 +254,7 @@ def _call_linker_cb(env, callback, args, result = None): cbfun = env['LINKCALLBACKS'][callback] except (KeyError, TypeError): if Verbose: - print '_call_linker_cb: env["LINKCALLBACKS"][%r] not found or can not be used' + print '_call_linker_cb: env["LINKCALLBACKS"][%r] not found or can not be used' % callback pass else: if Verbose: @@ -266,22 +266,91 @@ def _call_linker_cb(env, callback, args, result = None): result = cbfun(env, *args) return result +def _call_env_subst(env, string, *args, **kw): + kw2 = {} + for k in ('raw', 'target', 'source', 'conv', 'executor'): + try: kw2[k] = kw[k] + except KeyError: pass + return env.subst(string, *args, **kw2) + +class _ShLibInfoSupport(object): + def get_libtype(self): + return 'ShLib' + def get_lib_prefix(self, env, *args, **kw): + return _call_env_subst(env,'$SHLIBPREFIX', *args, **kw) + def get_lib_suffix(self, env, *args, **kw): + return _call_env_subst(env,'$SHLIBSUFFIX', *args, **kw) + def get_lib_version(self, env, *args, **kw): + return _call_env_subst(env,'$SHLIBVERSION', *args, **kw) + def get_lib_noversionsymlinks(self, env, *args, **kw): + return _call_env_subst(env,'$SHLIBNOVERSIONSYMLINKS', *args, **kw) + +class _LdModInfoSupport(object): + def get_libtype(self): + return 'LdMod' + def get_lib_prefix(self, env, *args, **kw): + return _call_env_subst(env,'$LDMODULEPREFIX', *args, **kw) + def get_lib_suffix(self, env, *args, **kw): + return _call_env_subst(env,'$LDMODULESUFFIX', *args, **kw) + def get_lib_version(self, env, *args, **kw): + return _call_env_subst(env,'$LDMODULEVERSION', *args, **kw) + def get_lib_noversionsymlinks(self, env, *args, **kw): + return _call_env_subst(env,'$LDMODULENOVERSIONSYMLINKS', *args, **kw) + +class _ImpLibInfoSupport(object): + def get_libtype(self): + return 'ImpLib' + def get_lib_prefix(self, env, *args, **kw): + return _call_env_subst(env,'$IMPLIBPREFIX', *args, **kw) + def get_lib_suffix(self, env, *args, **kw): + return _call_env_subst(env,'$IMPLIBSUFFIX', *args, **kw) + def get_lib_version(self, env, *args, **kw): + version = _call_env_subst(env,'$IMPLIBVERSION', *args, **kw) + if not version: + try: lt = kw['implib_libtype'] + except KeyError: pass + else: + if lt == 'ShLib': + version = _call_env_subst(env,'$SHLIBVERSION', *args, **kw) + elif lt == 'LdMod': + version = _call_env_subst(env,'$LDMODULEVERSION', *args, **kw) + return version + def get_lib_noversionsymlinks(self, env, *args, **kw): + disable = None + try: env['IMPLIBNOVERSIONSYMLINKS'] + except KeyError: + try: lt = kw['implib_libtype'] + except KeyError: pass + else: + if lt == 'ShLib': + disable = _call_env_subst(env,'$SHLIBNOVERSIONSYMLINKS', *args, **kw) + elif lt == 'LdMod': + disable = _call_env_subst(env,'$LDMODULENOVERSIONSYMLINKS', *args, **kw) + else: + disable = _call_env_subst(env,'$IMPLIBNOVERSIONSYMLINKS', *args, **kw) + return disable + class _LibInfoGeneratorBase(object): """Generator base class for library-related info such as suffixes for versioned libraries, symlink maps, sonames etc. It handles commonities of SharedLibrary and LoadableModule """ + _support_classes = { 'ShLib' : _ShLibInfoSupport, + 'LdMod' : _LdModInfoSupport, + 'ImpLib' : _ImpLibInfoSupport } def __init__(self, libtype, infoname): self.set_libtype(libtype) self.set_infoname(infoname) def set_libtype(self, libtype): - if libtype not in ['ShLib', 'LdMod', 'ImpLib']: + try: + support_class = self._support_classes[libtype] + except KeyError: raise ValueError('unsupported libtype %r' % libtype) - self.libtype = libtype + self._support = support_class() def get_libtype(self): - return self.libtype + return self._support.get_libtype() def set_infoname(self, infoname): self.infoname = infoname @@ -289,47 +358,21 @@ class _LibInfoGeneratorBase(object): def get_infoname(self): return self.infoname - def get_lib_prefix(self, env): - prefix = None - libtype = self.get_libtype() - if libtype == 'ShLib': - prefix = env.subst('$SHLIBPREFIX') - elif libtype == 'LdMod': - prefix = env.subst('$LDMODULEPREFIX') - elif libtype == 'ImpLib': - prefix = env.subst('$IMPLIBPREFIX') - return prefix + def get_lib_prefix(self, env, *args, **kw): + return self._support.get_lib_prefix(env,*args,**kw) - def get_lib_suffix(self, env): - suffix = None - libtype = self.get_libtype() - if libtype == 'ShLib': - suffix = env.subst('$SHLIBSUFFIX') - elif libtype == 'LdMod': - suffix = env.subst('$LDMODULESUFFIX') - elif libtype == 'ImpLib': - suffix = env.subst('$IMPLIBSUFFIX') - return suffix + def get_lib_suffix(self, env, *args, **kw): + return self._support.get_lib_suffix(env,*args,**kw) - def get_lib_version(self, env, **kw): - version = None - libtype = self.get_libtype() - if libtype == 'ShLib': - version = env.subst('$SHLIBVERSION') - elif libtype == 'LdMod': - version = env.subst('$LDMODULEVERSION') - elif libtype == 'ImpLib': - version = env.subst('$IMPLIBVERSION') - if not version: - try: lt = kw['implib_libtype'] - except KeyError: pass - else: - if lt == 'ShLib': - version = env.subst('$SHLIBVERSION') - elif lt == 'LdMod': - version = env.subst('$LDMODULEVERSION') - return version + def get_lib_version(self, env, *args, **kw): + return self._support.get_lib_version(env,*args,**kw) + def get_lib_noversionsymlinks(self, env, *args, **kw): + return self._support.get_lib_noversionsymlinks(env,*args,**kw) + + # Returns name of generator linker callback that shall be used to generate + # our info for a versioned library. For example, if our libtype is 'ShLib' + # and infoname is 'Prefix', it would return 'VersionedShLibPrefix'. def get_versioned_lib_info_generator(self, **kw): try: libtype = kw['generator_libtype'] except KeyError: libtype = self.get_libtype() @@ -349,16 +392,22 @@ class _LibPrefixGenerator(_LibInfoGeneratorBase): def __call__(self, env, sources = None, **kw): Verbose = False - prefix = self.get_lib_prefix(env) + if sources and 'source' not in kw: + kw2 = kw.copy() + kw2['source'] = sources + else: + kw2 = kw + + prefix = self.get_lib_prefix(env,**kw2) if Verbose: print "_LibPrefixGenerator: input prefix=%r" % prefix - version = self.get_lib_version(env, **kw) + version = self.get_lib_version(env, **kw2) if Verbose: print "_LibPrefixGenerator: version=%r" % version if version: - prefix = self.generate_versioned_lib_info(env, [prefix, version], prefix, **kw) + prefix = self.generate_versioned_lib_info(env, [prefix, version], prefix, **kw2) if Verbose: print "_LibPrefixGenerator: return prefix=%r" % prefix @@ -377,16 +426,22 @@ class _LibSuffixGenerator(_LibInfoGeneratorBase): def __call__(self, env, sources = None, **kw): Verbose = False - suffix = self.get_lib_suffix(env) + if sources and 'source' not in kw: + kw2 = kw.copy() + kw2['source'] = sources + else: + kw2 = kw + + suffix = self.get_lib_suffix(env, **kw2) if Verbose: print "_LibSuffixGenerator: input suffix=%r" % suffix - version = self.get_lib_version(env, **kw) + version = self.get_lib_version(env, **kw2) if Verbose: print "_LibSuffixGenerator: version=%r" % version if version: - suffix = self.generate_versioned_lib_info(env, [suffix, version], suffix, **kw) + suffix = self.generate_versioned_lib_info(env, [suffix, version], suffix, **kw2) if Verbose: print "_LibSuffixGenerator: return suffix=%r" % suffix @@ -402,45 +457,30 @@ class _LibSymlinkGenerator(_LibInfoGeneratorBase): def __init__(self, libtype): super(_LibSymlinkGenerator, self).__init__(libtype, 'Symlinks') - def get_noversionsymlinks(self, env, **kw): - disable = None - libtype = self.get_libtype() - if libtype == 'ShLib': - disable = env.subst('$SHLIBNOVERSIONSYMLINKS') - elif libtype == 'LdMod': - disable = env.subst('$LDMODULENOVERSIONSYMLINKS') - elif libtype == 'ImpLib': - try: env['IMPLIBNOVERSIONSYMLINKS'] - except KeyError: - try: lt = kw['implib_libtype'] - except KeyError: pass - else: - if lt == 'ShLib': - disable = env.subst('$SHLIBNOVERSIONSYMLINKS') - elif lt == 'LdMod': - disable = env.subst('$LDMODULENOVERSIONSYMLINKS') - else: - disable = env.subst('$IMPLIBNOVERSIONSYMLINKS') - return disable - def __call__(self, env, libnode, **kw): Verbose = False + if libnode and 'target' not in kw: + kw2 = kw.copy() + kw2['target'] = libnode + else: + kw2 = kw + if Verbose: print "_LibSymLinkGenerator: libnode=%r" % libnode.get_path() symlinks = None - version = self.get_lib_version(env, **kw) - disable = self.get_noversionsymlinks(env, **kw) + version = self.get_lib_version(env, **kw2) + disable = self.get_lib_noversionsymlinks(env, **kw2) if Verbose: print '_LibSymlinkGenerator: version=%r' % version print '_LibSymlinkGenerator: disable=%r' % disable if version and not disable: - prefix = self.get_lib_prefix(env) - suffix = self.get_lib_suffix(env) - symlinks = self.generate_versioned_lib_info(env, [libnode, version, prefix, suffix], **kw) + prefix = self.get_lib_prefix(env,**kw2) + suffix = self.get_lib_suffix(env,**kw2) + symlinks = self.generate_versioned_lib_info(env, [libnode, version, prefix, suffix], **kw2) if Verbose: print '_LibSymlinkGenerator: return symlinks=%r' % StringizeLibSymlinks(symlinks) @@ -471,18 +511,24 @@ class _LibNameGenerator(_LibInfoGeneratorBase): """Returns "demangled" library name""" Verbose = False + if libnode and 'target' not in kw: + kw2 = kw.copy() + kw2['target'] = libnode + else: + kw2 = kw + if Verbose: print "_LibNameGenerator: libnode=%r" % libnode.get_path() - version = self.get_lib_version(env, **kw) + version = self.get_lib_version(env, **kw2) if Verbose: print '_LibNameGenerator: version=%r' % version name = None if version: - prefix = self.get_lib_prefix(env) - suffix = self.get_lib_suffix(env) - name = self.generate_versioned_lib_info(env, [libnode, version, prefix, suffix], **kw) + prefix = self.get_lib_prefix(env,**kw2) + suffix = self.get_lib_suffix(env,**kw2) + name = self.generate_versioned_lib_info(env, [libnode, version, prefix, suffix], **kw2) if not name: name = os.path.basename(libnode.get_path()) @@ -506,17 +552,23 @@ class _LibSonameGenerator(_LibInfoGeneratorBase): """Returns a SONAME based on a shared library's node path""" Verbose = False + if libnode and 'target' not in kw: + kw2 = kw.copy() + kw2['target'] = libnode + else: + kw2 = kw + if Verbose: print "_LibSonameGenerator: libnode=%r" % libnode.get_path() - soname = env.subst('$SONAME') + soname = _call_env_subst(env, '$SONAME', **kw2) if not soname: - version = self.get_lib_version(env,**kw) + version = self.get_lib_version(env,**kw2) if Verbose: print "_LibSonameGenerator: version=%r" % version if version: - suffix = self.get_lib_suffix(env) - soname = self.generate_versioned_lib_info(env, [libnode, version, suffix], **kw) + suffix = self.get_lib_suffix(env,**kw2) + soname = self.generate_versioned_lib_info(env, [libnode, version, suffix], **kw2) if not soname: # fallback to library name (as returned by appropriate _LibNameGenerator) @@ -571,13 +623,15 @@ def CreateLibSymlinks(env, symlinks): link = link.get_path() if(Verbose): print "CreateLibSymlinks: preparing to add symlink %r -> %r" % (link, linktgt) - try: - os.remove(link) + # Delete the (previously created) symlink if exists. Let only symlinks + # to be deleted to prevent accidental deletion of source files... + if env.fs.islink(link): + env.fs.unlink(link) if(Verbose): - print "CreateLibSymlinks: removed old file %r" % link - except: - pass - os.symlink(linktgt, link) + print "CreateLibSymlinks: removed old symlink %r" % link + # If a file or directory exists with the same name as link, an OSError + # will be thrown, which should be enough, I think. + env.fs.symlink(linktgt, link) if(Verbose): print "CreateLibSymlinks: add symlink %r -> %r" % (link, linktgt) return 0 @@ -589,7 +643,7 @@ def LibSymlinksActionFunction(target, source, env): CreateLibSymlinks(env, symlinks) return 0 -def LibSymlinksStrFun(target, source, env,*args): +def LibSymlinksStrFun(target, source, env, *args): cmd = None for tgt in target: symlinks = getattr(getattr(tgt,'attributes', None), 'shliblinks', None) diff --git a/src/engine/SCons/Tool/__init__.xml b/src/engine/SCons/Tool/__init__.xml index 7102fa4..7f19bfc 100644 --- a/src/engine/SCons/Tool/__init__.xml +++ b/src/engine/SCons/Tool/__init__.xml @@ -469,7 +469,7 @@ as C++ files. Used to override &cv-link-SHLIBVERSION;/&cv-link-LDMODULEVERSION; when generating versioned import library for a shared library/loadable module. If -undefined, the &cv-link-SHLIBVERSION;/&cv-link-LDMODULEVERSION; is used do +undefined, the &cv-link-SHLIBVERSION;/&cv-link-LDMODULEVERSION; is used to determine the version of versioned import library. -- cgit v0.12 From 95266ff25dd0be222e1838a439190317c60601d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carn=C3=AB=20Draug?= Date: Fri, 18 Sep 2015 01:39:38 +0100 Subject: Add configure check CheckProg, to check for existence of a program. --- src/engine/SCons/Conftest.py | 16 ++++++++++++++++ src/engine/SCons/SConf.py | 9 +++++++++ src/engine/SCons/SConfTests.py | 18 ++++++++++++++++++ 3 files changed, 43 insertions(+) diff --git a/src/engine/SCons/Conftest.py b/src/engine/SCons/Conftest.py index e9702ff..87a3022 100644 --- a/src/engine/SCons/Conftest.py +++ b/src/engine/SCons/Conftest.py @@ -684,6 +684,22 @@ return 0; return ret +def CheckProg(context, prog_name): + """ + Configure check for a specific program. + + Check whether program prog_name exists in path. If it is found, + returns the path for it, otherwise returns None. + """ + context.Display("Checking whether %s program exists..." % prog_name) + path = context.env.WhereIs(prog_name) + if path: + context.Display(path + "\n") + else: + context.Display("no\n") + return path + + # # END OF PUBLIC FUNCTIONS # diff --git a/src/engine/SCons/SConf.py b/src/engine/SCons/SConf.py index 8bce8ce..987b8ea 100644 --- a/src/engine/SCons/SConf.py +++ b/src/engine/SCons/SConf.py @@ -444,6 +444,7 @@ class SConfBase(object): 'CheckCXXHeader' : CheckCXXHeader, 'CheckLib' : CheckLib, 'CheckLibWithHeader' : CheckLibWithHeader, + 'CheckProg' : CheckProg, } self.AddTests(default_tests) self.AddTests(custom_tests) @@ -1047,6 +1048,14 @@ def CheckLibWithHeader(context, libs, header, language, context.did_show_result = 1 return not res +def CheckProg(context, prog_name): + """Simple check if a program exists in the path. Returns the path + for the application, or None if not found. + """ + res = SCons.Conftest.CheckProg(context, prog_name) + context.did_show_result = 1 + return res + # Local Variables: # tab-width:4 # indent-tabs-mode:nil diff --git a/src/engine/SCons/SConfTests.py b/src/engine/SCons/SConfTests.py index 233ee78..57a9d04 100644 --- a/src/engine/SCons/SConfTests.py +++ b/src/engine/SCons/SConfTests.py @@ -611,6 +611,24 @@ int main() { finally: sconf.Finish() + def test_CheckProg(self): + """Test SConf.CheckProg() + """ + self._resetSConfState() + sconf = self.SConf.SConf(self.scons_env, + conf_dir=self.test.workpath('config.tests'), + log_file=self.test.workpath('config.log')) + + try: + r = sconf.CheckProg('sh') + assert r, "/bin/sh" + r = sconf.CheckProg('hopefully-not-a-program') + assert r is None + + finally: + sconf.Finish() + + def test_Define(self): """Test SConf.Define() """ -- cgit v0.12 From 3173faf4aa18308832c7c8a983e3ff556d2cb5ba Mon Sep 17 00:00:00 2001 From: Pawel Tomulik Date: Sat, 19 Sep 2015 02:09:53 +0200 Subject: support free-form SHLIBVERSION/LDMODULEVERSION --- src/engine/SCons/Tool/gnulink.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/engine/SCons/Tool/gnulink.py b/src/engine/SCons/Tool/gnulink.py index e5e8818..0c5087b 100644 --- a/src/engine/SCons/Tool/gnulink.py +++ b/src/engine/SCons/Tool/gnulink.py @@ -103,7 +103,11 @@ def _versioned_lib_symlinks(env, libnode, version, prefix, suffix, name_func, so link0 = env.fs.File(soname, linkdir) link1 = env.fs.File(name, linkdir) - symlinks = [ (link0, libnode), (link1, link0) ] + # This allows anything in SHLIBVERSION (especially SHLIBVERSION=1). + if link0 == libnode: + symlinks = [ (link1, libnode) ] + else: + symlinks = [ (link0, libnode), (link1, link0) ] if Verbose: print "_versioned_lib_symlinks: return symlinks=%r" % SCons.Tool.StringizeLibSymlinks(symlinks) -- cgit v0.12 From f6f919842bf5dc265422309b98546e182e3ee9ae Mon Sep 17 00:00:00 2001 From: Pawel Tomulik Date: Sat, 19 Sep 2015 21:24:29 +0200 Subject: gnulink: create direct symlinks instead of daisy-chained ones --- src/engine/SCons/Tool/gnulink.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/engine/SCons/Tool/gnulink.py b/src/engine/SCons/Tool/gnulink.py index 0c5087b..aabc2f1 100644 --- a/src/engine/SCons/Tool/gnulink.py +++ b/src/engine/SCons/Tool/gnulink.py @@ -103,11 +103,13 @@ def _versioned_lib_symlinks(env, libnode, version, prefix, suffix, name_func, so link0 = env.fs.File(soname, linkdir) link1 = env.fs.File(name, linkdir) - # This allows anything in SHLIBVERSION (especially SHLIBVERSION=1). + # We create direct symlinks, not daisy-chained. if link0 == libnode: + # This enables SHLIBVERSION without periods (e.g. SHLIBVERSION=1) symlinks = [ (link1, libnode) ] else: - symlinks = [ (link0, libnode), (link1, link0) ] + # This handles usual SHLIBVERSION, i.e. '1.2', '1.2.3', etc. + symlinks = [ (link0, libnode), (link1, libnode) ] if Verbose: print "_versioned_lib_symlinks: return symlinks=%r" % SCons.Tool.StringizeLibSymlinks(symlinks) -- cgit v0.12 From 9a43408e4419ba54733222df65a38a9d1a925b6d Mon Sep 17 00:00:00 2001 From: Pawel Tomulik Date: Sun, 20 Sep 2015 02:24:11 +0200 Subject: support for versioned libraries for sunlink --- src/engine/SCons/Tool/gnulink.py | 96 +++--------------------------------- src/engine/SCons/Tool/link.py | 85 +++++++++++++++++++++++++++++++ src/engine/SCons/Tool/sunlink.py | 21 ++++++++ test/LINK/VersionedLib-VariantDir.py | 8 +++ test/LINK/VersionedLib-j2.py | 8 +++ test/LINK/VersionedLib-subdir.py | 8 +++ test/LINK/VersionedLib.py | 14 ++++++ 7 files changed, 150 insertions(+), 90 deletions(-) diff --git a/src/engine/SCons/Tool/gnulink.py b/src/engine/SCons/Tool/gnulink.py index aabc2f1..92c38c4 100644 --- a/src/engine/SCons/Tool/gnulink.py +++ b/src/engine/SCons/Tool/gnulink.py @@ -41,90 +41,6 @@ import re import link -def _versioned_lib_suffix(env, suffix, version): - """For suffix='.so' and version='0.1.2' it returns '.so.0.1.2'""" - Verbose = False - if Verbose: - print "_versioned_lib_suffix: suffix=%r" % suffix - print "_versioned_lib_suffix: version=%r" % version - if not suffix.endswith(version): - suffix = suffix + '.' + version - if Verbose: - print "_versioned_lib_suffix: return suffix=%r" % suffix - return suffix - -def _versioned_lib_soname(env, libnode, version, prefix, suffix, name_func): - """For libnode='/optional/dir/libfoo.so.X.Y.Z' it returns 'libfoo.so.X'""" - Verbose = False - if Verbose: - print "_versioned_lib_soname: version=%r" % version - name = name_func(env, libnode, version, prefix, suffix) - if Verbose: - print "_versioned_lib_soname: name=%r" % name - major = version.split('.')[0] - soname = name + '.' + major - if Verbose: - print "_versioned_lib_soname: soname=%r" % soname - return soname - -def _versioned_shlib_soname(env, libnode, version, prefix, suffix): - return _versioned_lib_soname(env, libnode, version, prefix, suffix, link._versioned_shlib_name) - -def _versioned_ldmod_soname(env, libnode, version, prefix, suffix): - return _versioned_lib_soname(env, libnode, version, prefix, suffix, link._versioned_ldmod_name) - -def _versioned_lib_symlinks(env, libnode, version, prefix, suffix, name_func, soname_func): - """Generate link names that should be created for a versioned shared lirbrary. - Returns a dictionary in the form { linkname : linktarget } - """ - Verbose = False - - if Verbose: - print "_versioned_lib_symlinks: libnode=%r" % libnode.get_path() - print "_versioned_lib_symlinks: version=%r" % version - - if sys.platform.startswith('openbsd'): - # OpenBSD uses x.y shared library versioning numbering convention - # and doesn't use symlinks to backwards-compatible libraries - if Verbose: - print "_versioned_lib_symlinks: return symlinks=%r" % None - return None - - linkdir = libnode.get_dir() - if Verbose: - print "_versioned_lib_symlinks: linkdir=%r" % linkdir.get_path() - - name = name_func(env, libnode, version, prefix, suffix) - if Verbose: - print "_versioned_lib_symlinks: name=%r" % name - - soname = soname_func(env, libnode, version, prefix, suffix) - - link0 = env.fs.File(soname, linkdir) - link1 = env.fs.File(name, linkdir) - - # We create direct symlinks, not daisy-chained. - if link0 == libnode: - # This enables SHLIBVERSION without periods (e.g. SHLIBVERSION=1) - symlinks = [ (link1, libnode) ] - else: - # This handles usual SHLIBVERSION, i.e. '1.2', '1.2.3', etc. - symlinks = [ (link0, libnode), (link1, libnode) ] - - if Verbose: - print "_versioned_lib_symlinks: return symlinks=%r" % SCons.Tool.StringizeLibSymlinks(symlinks) - - return symlinks - -def _versioned_shlib_symlinks(env, libnode, version, prefix, suffix): - nf = link._versioned_shlib_name - sf = _versioned_shlib_soname - return _versioned_lib_symlinks(env, libnode, version, prefix, suffix, nf, sf) - -def _versioned_ldmod_symlinks(env, libnode, version, prefix, suffix): - nf = link._versioned_ldmod_name - sf = _versioned_ldmod_soname - return _versioned_lib_symlinks(env, libnode, version, prefix, suffix, nf, sf) def generate(env): """Add Builders and construction variables for gnulink to an Environment.""" @@ -160,14 +76,14 @@ def generate(env): env['LdModSonameGenerator'] = SCons.Tool.LdModSonameGenerator env['LINKCALLBACKS'] = { - 'VersionedShLibSuffix' : _versioned_lib_suffix, - 'VersionedLdModSuffix' : _versioned_lib_suffix, - 'VersionedShLibSymlinks' : _versioned_shlib_symlinks, - 'VersionedLdModSymlinks' : _versioned_ldmod_symlinks, + 'VersionedShLibSuffix' : link._versioned_lib_suffix, + 'VersionedLdModSuffix' : link._versioned_lib_suffix, + 'VersionedShLibSymlinks' : link._versioned_shlib_symlinks, + 'VersionedLdModSymlinks' : link._versioned_ldmod_symlinks, 'VersionedShLibName' : link._versioned_shlib_name, 'VersionedLdModName' : link._versioned_ldmod_name, - 'VersionedShLibSoname' : _versioned_shlib_soname, - 'VersionedLdModSoname' : _versioned_shlib_soname, + 'VersionedShLibSoname' : link._versioned_shlib_soname, + 'VersionedLdModSoname' : link._versioned_shlib_soname, } def exists(env): diff --git a/src/engine/SCons/Tool/link.py b/src/engine/SCons/Tool/link.py index d52a9e5..0af7776 100644 --- a/src/engine/SCons/Tool/link.py +++ b/src/engine/SCons/Tool/link.py @@ -142,6 +142,91 @@ def _versioned_ldmod_name(env, libnode, version, prefix, suffix, **kw): sg = SCons.Tool.LdModSuffixGenerator return _versioned_lib_name(env, libnode, version, prefix, suffix, pg, sg, **kw) +def _versioned_lib_suffix(env, suffix, version): + """For suffix='.so' and version='0.1.2' it returns '.so.0.1.2'""" + Verbose = False + if Verbose: + print "_versioned_lib_suffix: suffix=%r" % suffix + print "_versioned_lib_suffix: version=%r" % version + if not suffix.endswith(version): + suffix = suffix + '.' + version + if Verbose: + print "_versioned_lib_suffix: return suffix=%r" % suffix + return suffix + +def _versioned_lib_soname(env, libnode, version, prefix, suffix, name_func): + """For libnode='/optional/dir/libfoo.so.X.Y.Z' it returns 'libfoo.so.X'""" + Verbose = False + if Verbose: + print "_versioned_lib_soname: version=%r" % version + name = name_func(env, libnode, version, prefix, suffix) + if Verbose: + print "_versioned_lib_soname: name=%r" % name + major = version.split('.')[0] + soname = name + '.' + major + if Verbose: + print "_versioned_lib_soname: soname=%r" % soname + return soname + +def _versioned_shlib_soname(env, libnode, version, prefix, suffix): + return _versioned_lib_soname(env, libnode, version, prefix, suffix, _versioned_shlib_name) + +def _versioned_ldmod_soname(env, libnode, version, prefix, suffix): + return _versioned_lib_soname(env, libnode, version, prefix, suffix, _versioned_ldmod_name) + +def _versioned_lib_symlinks(env, libnode, version, prefix, suffix, name_func, soname_func): + """Generate link names that should be created for a versioned shared lirbrary. + Returns a dictionary in the form { linkname : linktarget } + """ + Verbose = False + + if Verbose: + print "_versioned_lib_symlinks: libnode=%r" % libnode.get_path() + print "_versioned_lib_symlinks: version=%r" % version + + if sys.platform.startswith('openbsd'): + # OpenBSD uses x.y shared library versioning numbering convention + # and doesn't use symlinks to backwards-compatible libraries + if Verbose: + print "_versioned_lib_symlinks: return symlinks=%r" % None + return None + + linkdir = libnode.get_dir() + if Verbose: + print "_versioned_lib_symlinks: linkdir=%r" % linkdir.get_path() + + name = name_func(env, libnode, version, prefix, suffix) + if Verbose: + print "_versioned_lib_symlinks: name=%r" % name + + soname = soname_func(env, libnode, version, prefix, suffix) + + link0 = env.fs.File(soname, linkdir) + link1 = env.fs.File(name, linkdir) + + # We create direct symlinks, not daisy-chained. + if link0 == libnode: + # This enables SHLIBVERSION without periods (e.g. SHLIBVERSION=1) + symlinks = [ (link1, libnode) ] + else: + # This handles usual SHLIBVERSION, i.e. '1.2', '1.2.3', etc. + symlinks = [ (link0, libnode), (link1, libnode) ] + + if Verbose: + print "_versioned_lib_symlinks: return symlinks=%r" % SCons.Tool.StringizeLibSymlinks(symlinks) + + return symlinks + +def _versioned_shlib_symlinks(env, libnode, version, prefix, suffix): + nf = _versioned_shlib_name + sf = _versioned_shlib_soname + return _versioned_lib_symlinks(env, libnode, version, prefix, suffix, nf, sf) + +def _versioned_ldmod_symlinks(env, libnode, version, prefix, suffix): + nf = _versioned_ldmod_name + sf = _versioned_ldmod_soname + return _versioned_lib_symlinks(env, libnode, version, prefix, suffix, nf, sf) + def generate(env): """Add Builders and construction variables for gnulink to an Environment.""" diff --git a/src/engine/SCons/Tool/sunlink.py b/src/engine/SCons/Tool/sunlink.py index 5996a30..c9bb17d 100644 --- a/src/engine/SCons/Tool/sunlink.py +++ b/src/engine/SCons/Tool/sunlink.py @@ -66,6 +66,27 @@ def generate(env): env['RPATHSUFFIX'] = '' env['_RPATH'] = '${_concat(RPATHPREFIX, RPATH, RPATHSUFFIX, __env__)}' + # Support for versioned libraries + env['_SHLIBVERSIONFLAGS'] = '$SHLIBVERSIONFLAGS -h $_SHLINKSONAME' + env['_LDMODULEVERSIONFLAGS'] = '$LDMODULEVERSIONFLAGS -h $_LDMODULESONAME' + + env['_SHLINKSONAME'] = '${ShLibSonameGenerator(__env__,TARGET)}' + env['_LDMODULESONAME'] = '${LdModSonameGenerator(__env__,TARGET)}' + + env['ShLibSonameGenerator'] = SCons.Tool.ShLibSonameGenerator + env['LdModSonameGenerator'] = SCons.Tool.LdModSonameGenerator + + env['LINKCALLBACKS'] = { + 'VersionedShLibSuffix' : link._versioned_lib_suffix, + 'VersionedLdModSuffix' : link._versioned_lib_suffix, + 'VersionedShLibSymlinks' : link._versioned_shlib_symlinks, + 'VersionedLdModSymlinks' : link._versioned_ldmod_symlinks, + 'VersionedShLibName' : link._versioned_shlib_name, + 'VersionedLdModName' : link._versioned_ldmod_name, + 'VersionedShLibSoname' : link._versioned_shlib_soname, + 'VersionedLdModSoname' : link._versioned_shlib_soname, + } + def exists(env): return ccLinker diff --git a/test/LINK/VersionedLib-VariantDir.py b/test/LINK/VersionedLib-VariantDir.py index a3ea660..7406a33 100644 --- a/test/LINK/VersionedLib-VariantDir.py +++ b/test/LINK/VersionedLib-VariantDir.py @@ -126,6 +126,14 @@ elif platform == 'win32': 'foo.lib', ] obj = 'foo.obj' +elif platform == 'sunos': + # All (?) the files we expect will get created in the current directory + files = [ + 'libfoo.so', + 'libfoo.so.0', + 'libfoo.so.0.1.2', + ] + obj = 'so_foo.os' else: # All (?) the files we expect will get created in the current directory files= [ diff --git a/test/LINK/VersionedLib-j2.py b/test/LINK/VersionedLib-j2.py index 076a4dd..6f37e54 100644 --- a/test/LINK/VersionedLib-j2.py +++ b/test/LINK/VersionedLib-j2.py @@ -113,6 +113,14 @@ elif platform == 'win32': 'foo.lib', 'foo.obj', ] +elif platform == 'sunos': + # All (?) the files we expect will get created in the current directory + files = [ + 'libfoo.so', + 'libfoo.so.0', + 'libfoo.so.0.1.2', + 'so_foo.os', + ] else: # All (?) the files we expect will get created in the current directory files= [ diff --git a/test/LINK/VersionedLib-subdir.py b/test/LINK/VersionedLib-subdir.py index 6facd41..15369ef 100644 --- a/test/LINK/VersionedLib-subdir.py +++ b/test/LINK/VersionedLib-subdir.py @@ -120,6 +120,14 @@ elif platform == 'win32': 'foo.lib', ] obj = 'foo.obj' +elif platform == 'sunos': + # All (?) the files we expect will get created in the current directory + files = [ + 'libfoo.so', + 'libfoo.so.0', + 'libfoo.so.0.1.2', + ] + obj = 'so_foo.os' else: # All (?) the files we expect will get created in the current directory files= [ diff --git a/test/LINK/VersionedLib.py b/test/LINK/VersionedLib.py index c68dd55..a75e4a5 100644 --- a/test/LINK/VersionedLib.py +++ b/test/LINK/VersionedLib.py @@ -130,6 +130,20 @@ elif platform == 'win32': 'test.dll', 'test.lib', ] +elif platform == 'sunos': + # All (?) the files we expect will get created in the current directory + files = [ + 'libtest.so', + 'libtest.so.2', + 'libtest.so.2.5.4', + 'so_test.os', + ] + # All (?) the files we expect will get created in the 'installtest' directory + instfiles = [ + 'libtest.so', + 'libtest.so.2', + 'libtest.so.2.5.4', + ] else: # All (?) the files we expect will get created in the current directory files= [ -- cgit v0.12 From cb508c9a37c2a3cd5fcf55cc1efd4c47a0abdd41 Mon Sep 17 00:00:00 2001 From: Pawel Tomulik Date: Sun, 20 Sep 2015 04:21:27 +0200 Subject: fix broken soname generator --- src/engine/SCons/Defaults.py | 17 ++++++++++++----- src/engine/SCons/Tool/__init__.py | 3 ++- src/engine/SCons/Tool/gnulink.py | 2 +- src/engine/SCons/Tool/sunlink.py | 2 +- 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/engine/SCons/Defaults.py b/src/engine/SCons/Defaults.py index db48969..c8170c3 100644 --- a/src/engine/SCons/Defaults.py +++ b/src/engine/SCons/Defaults.py @@ -482,9 +482,14 @@ class Variable_Method_Caller(object): frame = frame.f_back return None -def __libversionflags_string(versionvar): - return '${("%s" in locals() and %s and "_%sFLAGS" in locals()) ' \ - 'and _%sFLAGS or None}' % (versionvar, versionvar, versionvar, versionvar) +# if env[version_var] id defined, returns env[flags_var], otherwise returns None +def __libversionflags(env, version_var, flags_var): + try: + if env[version_var]: + return env[flags_var] + except KeyError: + pass + return None ConstructionEnvironment = { 'BUILDERS' : {}, @@ -504,8 +509,10 @@ ConstructionEnvironment = { '_CPPINCFLAGS' : '$( ${_concat(INCPREFIX, CPPPATH, INCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)', '_CPPDEFFLAGS' : '${_defines(CPPDEFPREFIX, CPPDEFINES, CPPDEFSUFFIX, __env__)}', - '__SHLIBVERSIONFLAGS' : __libversionflags_string('SHLIBVERSION'), - '__LDMODULEVERSIONFLAGS' : __libversionflags_string('LDMODULEVERSION'), + '__libversionflags' : __libversionflags, + '__SHLIBVERSIONFLAGS' : '${__libversionflags(__env__,"SHLIBVERSION","_SHLIBVERSIONFLAGS")}', + '__LDMODULEVERSIONFLAGS' : '${__libversionflags(__env__,"LDMODULEVERSION","_LDMODULEVERSIONFLAGS")}', + 'TEMPFILE' : NullCmdGenerator, 'Dir' : Variable_Method_Caller('TARGET', 'Dir'), 'Dirs' : Variable_Method_Caller('TARGET', 'Dirs'), diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py index 357b765..96b9d98 100644 --- a/src/engine/SCons/Tool/__init__.py +++ b/src/engine/SCons/Tool/__init__.py @@ -567,8 +567,9 @@ class _LibSonameGenerator(_LibInfoGeneratorBase): if Verbose: print "_LibSonameGenerator: version=%r" % version if version: + prefix = self.get_lib_prefix(env,**kw2) suffix = self.get_lib_suffix(env,**kw2) - soname = self.generate_versioned_lib_info(env, [libnode, version, suffix], **kw2) + soname = self.generate_versioned_lib_info(env, [libnode, version, prefix, suffix], **kw2) if not soname: # fallback to library name (as returned by appropriate _LibNameGenerator) diff --git a/src/engine/SCons/Tool/gnulink.py b/src/engine/SCons/Tool/gnulink.py index 92c38c4..2e0ed03 100644 --- a/src/engine/SCons/Tool/gnulink.py +++ b/src/engine/SCons/Tool/gnulink.py @@ -83,7 +83,7 @@ def generate(env): 'VersionedShLibName' : link._versioned_shlib_name, 'VersionedLdModName' : link._versioned_ldmod_name, 'VersionedShLibSoname' : link._versioned_shlib_soname, - 'VersionedLdModSoname' : link._versioned_shlib_soname, + 'VersionedLdModSoname' : link._versioned_ldmod_soname, } def exists(env): diff --git a/src/engine/SCons/Tool/sunlink.py b/src/engine/SCons/Tool/sunlink.py index c9bb17d..751bf92 100644 --- a/src/engine/SCons/Tool/sunlink.py +++ b/src/engine/SCons/Tool/sunlink.py @@ -84,7 +84,7 @@ def generate(env): 'VersionedShLibName' : link._versioned_shlib_name, 'VersionedLdModName' : link._versioned_ldmod_name, 'VersionedShLibSoname' : link._versioned_shlib_soname, - 'VersionedLdModSoname' : link._versioned_shlib_soname, + 'VersionedLdModSoname' : link._versioned_ldmod_soname, } def exists(env): -- cgit v0.12 From 31a9cc12812eeb3a83dd26010ec6947a79368f96 Mon Sep 17 00:00:00 2001 From: Pawel Tomulik Date: Sun, 20 Sep 2015 05:36:54 +0200 Subject: refactor code -> avoid code duplication --- src/engine/SCons/Tool/gnulink.py | 35 ++++++------------------------- src/engine/SCons/Tool/link.py | 45 ++++++++++++++++++++++++++++++++++++++++ src/engine/SCons/Tool/sunar.py | 2 +- src/engine/SCons/Tool/sunlink.py | 21 ++----------------- 4 files changed, 54 insertions(+), 49 deletions(-) diff --git a/src/engine/SCons/Tool/gnulink.py b/src/engine/SCons/Tool/gnulink.py index 2e0ed03..6b0d5b3 100644 --- a/src/engine/SCons/Tool/gnulink.py +++ b/src/engine/SCons/Tool/gnulink.py @@ -55,36 +55,13 @@ def generate(env): env['RPATHSUFFIX'] = '' env['_RPATH'] = '${_concat(RPATHPREFIX, RPATH, RPATHSUFFIX, __env__)}' - # The $_SHLIBVERSIONFLAGS define extra commandline flags used when - # building VERSIONED shared libraries. It's always set, but used only - # when VERSIONED library is built (see __SHLIBVERSIONFLAGS). - if sys.platform.startswith('openbsd'): - # OpenBSD doesn't usually use SONAME for libraries - env['_SHLIBVERSIONFLAGS'] = '$SHLIBVERSIONFLAGS' - env['_LDMODULEVERSIONFLAGS'] = '$LDMODULEVERSIONFLAGS' - else: - env['_SHLIBVERSIONFLAGS'] = '$SHLIBVERSIONFLAGS -Wl,-soname=$_SHLINKSONAME' - env['_LDMODULEVERSIONFLAGS'] = '$LDMODULEVERSIONFLAGS -Wl,-soname=$_LDMODULESONAME' - env['SHLIBVERSIONFLAGS'] = SCons.Util.CLVar('-Wl,-Bsymbolic') - env['LDMODULEVERSIONFLAGS'] = '$SHLIBVERSIONFLAGS' - - # libfoo.so.X.Y.Z -> libfoo.so.X - env['_SHLINKSONAME'] = '${ShLibSonameGenerator(__env__,TARGET)}' - env['_LDMODULESONAME'] = '${LdModSonameGenerator(__env__,TARGET)}' + # OpenBSD doesn't usually use SONAME for libraries + use_soname = not sys.platform.startswith('openbsd') + link._setup_versioned_lib_variables(env, tool = 'gnulink', use_soname = use_soname) + env['LINKCALLBACKS'] = link._versioned_lib_callbacks() - env['ShLibSonameGenerator'] = SCons.Tool.ShLibSonameGenerator - env['LdModSonameGenerator'] = SCons.Tool.LdModSonameGenerator - - env['LINKCALLBACKS'] = { - 'VersionedShLibSuffix' : link._versioned_lib_suffix, - 'VersionedLdModSuffix' : link._versioned_lib_suffix, - 'VersionedShLibSymlinks' : link._versioned_shlib_symlinks, - 'VersionedLdModSymlinks' : link._versioned_ldmod_symlinks, - 'VersionedShLibName' : link._versioned_shlib_name, - 'VersionedLdModName' : link._versioned_ldmod_name, - 'VersionedShLibSoname' : link._versioned_shlib_soname, - 'VersionedLdModSoname' : link._versioned_ldmod_soname, - } + # For backward-compatiblity with older SCons versions + env['SHLIBVERSIONFLAGS'] = SCons.Util.CLVar('-Wl,-Bsymbolic') def exists(env): # TODO: sync with link.smart_link() to choose a linker diff --git a/src/engine/SCons/Tool/link.py b/src/engine/SCons/Tool/link.py index 0af7776..6bd36e4 100644 --- a/src/engine/SCons/Tool/link.py +++ b/src/engine/SCons/Tool/link.py @@ -227,6 +227,51 @@ def _versioned_ldmod_symlinks(env, libnode, version, prefix, suffix): sf = _versioned_ldmod_soname return _versioned_lib_symlinks(env, libnode, version, prefix, suffix, nf, sf) +def _versioned_lib_callbacks(): + return { + 'VersionedShLibSuffix' : _versioned_lib_suffix, + 'VersionedLdModSuffix' : _versioned_lib_suffix, + 'VersionedShLibSymlinks' : _versioned_shlib_symlinks, + 'VersionedLdModSymlinks' : _versioned_ldmod_symlinks, + 'VersionedShLibName' : _versioned_shlib_name, + 'VersionedLdModName' : _versioned_ldmod_name, + 'VersionedShLibSoname' : _versioned_shlib_soname, + 'VersionedLdModSoname' : _versioned_ldmod_soname, + }.copy() + +# Setup all variables required by the versioning machinery +def _setup_versioned_lib_variables(env, **kw): + + tool = None + try: tool = kw['tool'] + except KeyError: pass + + use_soname = False + try: use_soname = kw['use_soname'] + except KeyError: pass + + # The $_SHLIBVERSIONFLAGS define extra commandline flags used when + # building VERSIONED shared libraries. It's always set, but used only + # when VERSIONED library is built (see __SHLIBVERSIONFLAGS in SCons/Defaults.py). + if use_soname: + # If the linker uses SONAME, then we need this little automata + if tool == 'sunlink': + env['_SHLIBVERSIONFLAGS'] = '$SHLIBVERSIONFLAGS -h $_SHLINKSONAME' + env['_LDMODULEVERSIONFLAGS'] = '$LDMODULEVERSIONFLAGS -h $_LDMODULESONAME' + else: + env['_SHLIBVERSIONFLAGS'] = '$SHLIBVERSIONFLAGS -Wl,-soname=$_SHLINKSONAME' + env['_LDMODULEVERSIONFLAGS'] = '$LDMODULEVERSIONFLAGS -Wl,-soname=$_LDMODULESONAME' + env['_SHLINKSONAME'] = '${ShLibSonameGenerator(__env__,TARGET)}' + env['_LDMODULESONAME'] = '${LdModSonameGenerator(__env__,TARGET)}' + env['ShLibSonameGenerator'] = SCons.Tool.ShLibSonameGenerator + env['LdModSonameGenerator'] = SCons.Tool.LdModSonameGenerator + else: + env['_SHLIBVERSIONFLAGS'] = '$SHLIBVERSIONFLAGS' + env['_LDMODULEVERSIONFLAGS'] = '$LDMODULEVERSIONFLAGS' + + # LDOMDULVERSIONFLAGS should always default to $SHLIBVERSIONFLAGS + env['LDMODULEVERSIONFLAGS'] = '$SHLIBVERSIONFLAGS' + def generate(env): """Add Builders and construction variables for gnulink to an Environment.""" diff --git a/src/engine/SCons/Tool/sunar.py b/src/engine/SCons/Tool/sunar.py index 779414f..3ee4344 100644 --- a/src/engine/SCons/Tool/sunar.py +++ b/src/engine/SCons/Tool/sunar.py @@ -53,7 +53,7 @@ def generate(env): env['SHLINK'] = '$LINK' env['SHLINKFLAGS'] = SCons.Util.CLVar('$LINKFLAGS -G') - env['SHLINKCOM'] = '$SHLINK $SHLINKFLAGS -o $TARGET $SOURCES $_LIBDIRFLAGS $_LIBFLAGS' + env['SHLINKCOM'] = '$SHLINK -o $TARGET $SHLINKFLAGS $__SHLIBVERSIONFLAGS $__RPATH $SOURCES $_LIBDIRFLAGS $_LIBFLAGS' env['LIBPREFIX'] = 'lib' env['LIBSUFFIX'] = '.a' diff --git a/src/engine/SCons/Tool/sunlink.py b/src/engine/SCons/Tool/sunlink.py index 751bf92..680af03 100644 --- a/src/engine/SCons/Tool/sunlink.py +++ b/src/engine/SCons/Tool/sunlink.py @@ -67,25 +67,8 @@ def generate(env): env['_RPATH'] = '${_concat(RPATHPREFIX, RPATH, RPATHSUFFIX, __env__)}' # Support for versioned libraries - env['_SHLIBVERSIONFLAGS'] = '$SHLIBVERSIONFLAGS -h $_SHLINKSONAME' - env['_LDMODULEVERSIONFLAGS'] = '$LDMODULEVERSIONFLAGS -h $_LDMODULESONAME' - - env['_SHLINKSONAME'] = '${ShLibSonameGenerator(__env__,TARGET)}' - env['_LDMODULESONAME'] = '${LdModSonameGenerator(__env__,TARGET)}' - - env['ShLibSonameGenerator'] = SCons.Tool.ShLibSonameGenerator - env['LdModSonameGenerator'] = SCons.Tool.LdModSonameGenerator - - env['LINKCALLBACKS'] = { - 'VersionedShLibSuffix' : link._versioned_lib_suffix, - 'VersionedLdModSuffix' : link._versioned_lib_suffix, - 'VersionedShLibSymlinks' : link._versioned_shlib_symlinks, - 'VersionedLdModSymlinks' : link._versioned_ldmod_symlinks, - 'VersionedShLibName' : link._versioned_shlib_name, - 'VersionedLdModName' : link._versioned_ldmod_name, - 'VersionedShLibSoname' : link._versioned_shlib_soname, - 'VersionedLdModSoname' : link._versioned_ldmod_soname, - } + link._setup_versioned_lib_variables(env, tool = 'sunlink', use_soname = True) + env['LINKCALLBACKS'] = link._versioned_lib_callbacks() def exists(env): return ccLinker -- cgit v0.12 From 9e5928980c0855f91de016467ef752d3aa338f1a Mon Sep 17 00:00:00 2001 From: Pawel Tomulik Date: Sun, 20 Sep 2015 13:42:22 +0200 Subject: do not set SHxxxx variables in sunar.py --- src/engine/SCons/Tool/sunar.py | 3 --- src/engine/SCons/Tool/sunar.xml | 4 ---- 2 files changed, 7 deletions(-) diff --git a/src/engine/SCons/Tool/sunar.py b/src/engine/SCons/Tool/sunar.py index 3ee4344..eb58457 100644 --- a/src/engine/SCons/Tool/sunar.py +++ b/src/engine/SCons/Tool/sunar.py @@ -51,9 +51,6 @@ def generate(env): 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 -o $TARGET $SHLINKFLAGS $__SHLIBVERSIONFLAGS $__RPATH $SOURCES $_LIBDIRFLAGS $_LIBFLAGS' env['LIBPREFIX'] = 'lib' env['LIBSUFFIX'] = '.a' diff --git a/src/engine/SCons/Tool/sunar.xml b/src/engine/SCons/Tool/sunar.xml index 65f0c9e..f875217 100644 --- a/src/engine/SCons/Tool/sunar.xml +++ b/src/engine/SCons/Tool/sunar.xml @@ -33,15 +33,11 @@ Sets construction variables for the Sun library archiver. AR ARFLAGS ARCOM -SHLINK -SHLINKFLAGS -SHLINKCOM LIBPREFIX LIBSUFFIX ARCOMSTR -SHLINKCOMSTR -- cgit v0.12 From 123fea257474ede95fa6bef8fb403cc83eff5cdc Mon Sep 17 00:00:00 2001 From: Pawel Tomulik Date: Sun, 20 Sep 2015 17:01:35 +0200 Subject: add tests to test/LINK/VersionedLib.py --- test/LINK/VersionedLib.py | 332 ++++++++++++++++++++++++++++++---------------- 1 file changed, 215 insertions(+), 117 deletions(-) diff --git a/test/LINK/VersionedLib.py b/test/LINK/VersionedLib.py index a75e4a5..2e38dee 100644 --- a/test/LINK/VersionedLib.py +++ b/test/LINK/VersionedLib.py @@ -32,30 +32,167 @@ import SCons.Platform _exe = TestSCons._exe -test = TestSCons.TestSCons() +platform = SCons.Platform.platform_default() -test.write('SConstruct', """\ -import os -env = Environment() -objs = env.SharedObject('test.c') -mylib = env.SharedLibrary('test', objs, SHLIBVERSION = '2.5.4') -env.Program('testapp1.c', LIBS = mylib, LIBPATH='.') -env.Program('testapp2.c', LIBS = ['test'], LIBPATH='.') -instnode = env.InstallVersionedLib("#/installtest",mylib) -env.Default(instnode) -""") +if platform == 'posix': + test_plan = [ + { + 'libversion' : '2', + 'files' : [ 'libtest.so', 'libtest.so.2', 'test.os' ], + 'instfiles' : [ 'libtest.so', 'libtest.so.2' ], + 'symlinks' : [ ('libtest.so', 'libtest.so.2') ], + }, + { + 'libversion' : '2.5', + 'files' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.5', 'test.os' ], + 'instfiles' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.5' ], + 'symlinks' : [ ('libtest.so', 'libtest.so.2.5'), ('libtest.so.2', 'libtest.so.2.5') ], + }, + { + 'libversion' : '2.5.4', + 'files' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.5.4', 'test.os' ], + 'instfiles' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.5.4' ], + 'symlinks' : [ ('libtest.so', 'libtest.so.2.5.4'), ('libtest.so.2', 'libtest.so.2.5.4') ], + }, + { + 'libversion' : '2.5.4.7.8', + 'files' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.5.4.7.8', 'test.os' ], + 'instfiles' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.5.4.7.8' ], + 'symlinks' : [ ('libtest.so', 'libtest.so.2.5.4.7.8'), ('libtest.so.2', 'libtest.so.2.5.4.7.8') ], + }, + { + 'libversion' : 'aabf114f', + 'files' : [ 'libtest.so', 'libtest.so.aabf114f', 'test.os' ], + 'instfiles' : [ 'libtest.so', 'libtest.so.aabf114f' ], + 'symlinks' : [ ('libtest.so', 'libtest.so.aabf114f') ], + }, + { + 'libversion' : '2.dfffa11', + 'files' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.dfffa11', 'test.os' ], + 'instfiles' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.dfffa11' ], + 'symlinks' : [ ('libtest.so', 'libtest.so.2.dfffa11'), ('libtest.so.2', 'libtest.so.2.dfffa11') ], + }, + ] +elif platform == 'darwin': + # All (?) the files we expect will get created in the current directory + test_plan = [ + { + 'libversion' : '2.5.4', + 'files' : [ 'libtest.dylib', 'libtest.2.5.4.dylib', 'test.os' ], + 'instfiles' : [ 'libtest.dylib', 'libtest.2.5.4.dylib' ], + 'symlinks' : [], + }, + ] +elif platform == 'cygwin': + test_plan = [ + { + 'libversion' : '2.5.4', + 'files' : [ 'cygtest-2-5-4.dll', 'libtest-2-5-4.dll.a', 'libtest.dll.a', 'test.os' ], + 'instfiles' : [ 'cygtest-2-5-4.dll', 'libtest-2-5-4.dll.a', 'libtest.dll.a' ], + 'symlinks' : [], + }, + { + 'libversion' : '2', + 'files' : [ 'cygtest-2.dll', 'libtest-2.dll.a', 'libtest.dll.a', 'test.os' ], + 'instfiles' : [ 'cygtest-2.dll', 'libtest-2.dll.a', 'libtest.dll.a' ], + 'symlinks' : [ ('libtest.dll.a', 'libtest-2.dll.a') ], + }, + { + 'libversion' : '2.5', + 'files' : [ 'cygtest-2-5.dll', 'libtest-2-5.dll.a', 'libtest.dll.a', 'test.os' ], + 'instfiles' : [ 'cygtest-2-5.dll', 'libtest-2-5.dll.a', 'libtest.dll.a' ], + 'symlinks' : [ ('libtest.dll.a', 'libtest-2-5.dll.a') ], + }, + { + 'libversion' : '2.5.4', + 'files' : [ 'cygtest-2-5-4.dll', 'libtest-2-5-4.dll.a', 'libtest.dll.a', 'test.os' ], + 'instfiles' : [ 'cygtest-2-5-4.dll', 'libtest-2-5-4.dll.a', 'libtest.dll.a' ], + 'symlinks' : [ ('libtest.dll.a', 'libtest-2-5-4.dll.a') ], + }, + { + 'libversion' : '2.5.4.7.8', + 'files' : [ 'cygtest-2-5-4-7-8.dll', 'libtest-2-5-4-7-8.dll.a', 'libtest.dll.a', 'test.os' ], + 'instfiles' : [ 'cygtest-2-5-4-7-8.dll', 'libtest-2-5-4-7-8.dll.a', 'libtest.dll.a' ], + 'symlinks' : [ ('libtest.dll.a', 'libtest-2-5-4-7-8.dll.a') ], + }, + { + 'libversion' : 'aabf114f', + 'files' : [ 'cygtest-aabf114f.dll', 'libtest-aabf114f.dll.a', 'libtest.dll.a', 'test.os' ], + 'instfiles' : [ 'cygtest-aabf114f.dll', 'libtest-aabf114f.dll.a', 'libtest.dll.a' ], + 'symlinks' : [ ('libtest.dll.a', 'libtest-aabf114f.dll.a') ], + }, + { + 'libversion' : '2.dfffa11', + 'files' : [ 'cygtest-2-dfffa11.dll', 'libtest-2-dfffa11.dll.a', 'libtest.dll.a', 'test.os' ], + 'instfiles' : [ 'cygtest-2-dfffa11.dll', 'libtest-2-dfffa11.dll.a', 'libtest.dll.a' ], + 'symlinks' : [ ('libtest.dll.a', 'libtest-2-dfffa11.dll.a') ], + }, + ] +elif platform == 'win32': + test_plan = [ + { + 'libversion' : '2.5.4', + 'files' : [ 'test.dll', 'test.lib', 'test.obj' ], + 'instfiles' : [ 'test.dll', 'test.lib' ], + 'symlinks' : [], + }, + ] +elif platform == 'sunos': + test_plan = [ + { + 'libversion' : '2', + 'files' : [ 'libtest.so', 'libtest.so.2', 'so_test.os' ], + 'instfiles' : [ 'libtest.so', 'libtest.so.2' ], + 'symlinks' : [ ('libtest.so', 'libtest.so.2') ], + }, + { + 'libversion' : '2.5', + 'files' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.5', 'so_test.os' ], + 'instfiles' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.5' ], + 'symlinks' : [ ('libtest.so', 'libtest.so.2.5'), ('libtest.so.2', 'libtest.so.2.5') ], + }, + { + 'libversion' : '2.5.4', + 'files' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.5.4', 'so_test.os' ], + 'instfiles' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.5.4' ], + 'symlinks' : [ ('libtest.so', 'libtest.so.2.5.4'), ('libtest.so.2', 'libtest.so.2.5.4') ], + }, + { + 'libversion' : '2.5.4.7.8', + 'files' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.5.4.7.8', 'so_test.os' ], + 'instfiles' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.5.4.7.8' ], + 'symlinks' : [ ('libtest.so', 'libtest.so.2.5.4.7.8'), ('libtest.so.2', 'libtest.so.2.5.4.7.8') ], + }, + { + 'libversion' : 'aabf114f', + 'files' : [ 'libtest.so', 'libtest.so.aabf114f', 'so_test.os' ], + 'instfiles' : [ 'libtest.so', 'libtest.so.aabf114f' ], + 'symlinks' : [ ('libtest.so', 'libtest.so.aabf114f') ], + }, + { + 'libversion' : '2.dfffa11', + 'files' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.dfffa11', 'so_test.os' ], + 'instfiles' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.dfffa11' ], + 'symlinks' : [ ('libtest.so', 'libtest.so.2.dfffa11'), ('libtest.so.2', 'libtest.so.2.dfffa11') ], + }, + ] +else: + test_plan = [ + { + 'libversion' : '2.5.4', + 'files' : [ 'libtest.so', 'test.os' ], + 'instfiles' : [ ], + }, + ] -test.write('test.c', """\ +test_c_src = """\ #if _WIN32 __declspec(dllexport) #endif -int testlib(int n) -{ -return n+1 ; -} -""") +int testlib(int n) { return n+1 ; } +""" -testapp_src = """\ +testapp_c_src = """\ #if _WIN32 __declspec(dllimport) #endif @@ -70,112 +207,73 @@ printf("results: testlib(2) = %d\\n",itest) ; return 0 ; } """ -test.write('testapp1.c', testapp_src) -test.write('testapp2.c', testapp_src) -platform = SCons.Platform.platform_default() +for t in test_plan: + test = TestSCons.TestSCons() -test.run(arguments = ['--tree=all']) + libversion = t['libversion'] + files = t['files'] + symlinks = t['symlinks'] + instfiles = t['instfiles'] -if platform == 'posix': - # All (?) the files we expect will get created in the current directory - files = [ - 'libtest.so', - 'libtest.so.2', - 'libtest.so.2.5.4', - 'test.os', - ] - # All (?) the files we expect will get created in the 'installtest' directory - instfiles = [ - 'libtest.so', - 'libtest.so.2', - 'libtest.so.2.5.4', - ] -elif platform == 'darwin': - # All (?) the files we expect will get created in the current directory - files = [ - 'libtest.dylib', - 'libtest.2.5.4.dylib', - 'test.os', - ] - # All (?) the files we expect will get created in the 'installtest' directory - instfiles = [ - 'libtest.dylib', - 'libtest.2.5.4.dylib', - ] -elif platform == 'cygwin': - # All (?) the files we expect will get created in the current directory - files = [ - 'cygtest-2-5-4.dll', - 'libtest-2-5-4.dll.a', - 'libtest.dll.a', - 'test.os', - ] - # All (?) the files we expect will get created in the 'installtest' directory - instfiles = [ - 'cygtest-2-5-4.dll', - 'libtest-2-5-4.dll.a', - 'libtest.dll.a', - ] -elif platform == 'win32': - # All (?) the files we expect will get created in the current directory - files = [ - 'test.dll', - 'test.lib', - 'test.obj', - ] - # All (?) the files we expect will get created in the 'installtest' directory - instfiles = [ - 'test.dll', - 'test.lib', - ] -elif platform == 'sunos': - # All (?) the files we expect will get created in the current directory - files = [ - 'libtest.so', - 'libtest.so.2', - 'libtest.so.2.5.4', - 'so_test.os', - ] - # All (?) the files we expect will get created in the 'installtest' directory - instfiles = [ - 'libtest.so', - 'libtest.so.2', - 'libtest.so.2.5.4', - ] -else: - # All (?) the files we expect will get created in the current directory - files= [ - 'libtest.so', - 'test.os'] - # All (?) the files we expect will get created in the 'installtest' directory - instfiles = [] - -for f in files: - test.must_exist([ f]) -for f in instfiles: - test.must_exist(['installtest', f]) - -# modify test.c and make sure it can recompile when links already exist -test.write('test.c', """\ -#if _WIN32 -__declspec(dllexport) -#endif -int testlib(int n) -{ -return n+11 ; -} -""") + test.write('SConstruct', """\ +import os +env = Environment() +objs = env.SharedObject('test.c') +mylib = env.SharedLibrary('test', objs, SHLIBVERSION = '%s') +env.Program('testapp1.c', LIBS = mylib, LIBPATH='.') +env.Program('testapp2.c', LIBS = ['test'], LIBPATH='.') +instnode = env.InstallVersionedLib("#/installtest",mylib) +env.Default(instnode) +""" % libversion) + + test.write('test.c', test_c_src) + test.write('testapp1.c', testapp_c_src) + test.write('testapp2.c', testapp_c_src) + + test.run(arguments = ['--tree=all']) + + for f in files: + test.must_exist([ f]) + for f in instfiles: + test.must_exist(['installtest', f]) + + wrong_symlinks = [] + for (linkname,expected) in symlinks: + try: + endpoint = os.readlink(linkname) + except OSError, err: + print "%s (expected symlink %r -> %r)" % (err, linkname, expected) + wrong_symlinks.append(linkname) + else: + if endpoint != expected: + print "Wrong symlink: %r -> %r (expected symlink: %r -> %r)" % (linkname, endpoint, linkname, expected) + wrong_symlinks.append(linkname) + + if wrong_symlinks: + test.fail_test(wrong_symlinks) + + # modify test.c and make sure it can recompile when links already exist + test.write('test.c', """\ + #if _WIN32 + __declspec(dllexport) + #endif + int testlib(int n) + { + return n+11 ; + } + """) + + test.run() -test.run() + test.run(arguments = ['-c']) -test.run(arguments = ['-c']) + for f in files: + test.must_not_exist([ f]) -for f in files: - test.must_not_exist([ f]) -for f in instfiles: - test.must_not_exist(['installtest', f]) + for f in instfiles: + test.must_not_exist(['installtest', f]) test.pass_test() -- cgit v0.12 From 26f6e3f56d9741cc91cbe034a0e43d91e0fac6a3 Mon Sep 17 00:00:00 2001 From: Pawel Tomulik Date: Sun, 20 Sep 2015 17:09:34 +0200 Subject: fix test/LINK/VersionedLib.py to convince sun studio compiler --- test/LINK/VersionedLib.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/test/LINK/VersionedLib.py b/test/LINK/VersionedLib.py index 2e38dee..0d74a35 100644 --- a/test/LINK/VersionedLib.py +++ b/test/LINK/VersionedLib.py @@ -192,6 +192,13 @@ __declspec(dllexport) int testlib(int n) { return n+1 ; } """ +test_c_src2 = """\ +#if _WIN32 +__declspec(dllexport) +#endif +int testlib(int n) { return n+11 ; } +""" + testapp_c_src = """\ #if _WIN32 __declspec(dllimport) @@ -255,15 +262,7 @@ env.Default(instnode) test.fail_test(wrong_symlinks) # modify test.c and make sure it can recompile when links already exist - test.write('test.c', """\ - #if _WIN32 - __declspec(dllexport) - #endif - int testlib(int n) - { - return n+11 ; - } - """) + test.write('test.c', test_c_src2) test.run() -- cgit v0.12 From ffcb8963212db0e83b79c9cbb584ed6ff3da837a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Tomulik?= Date: Sun, 20 Sep 2015 19:55:34 +0200 Subject: cyglink: fix for shlib symlink not being cleaned correctly --- src/engine/SCons/Tool/__init__.py | 8 ++++++-- src/engine/SCons/Tool/cyglink.py | 2 +- test/LINK/VersionedLib.py | 6 ------ 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py index 96b9d98..7374687 100644 --- a/src/engine/SCons/Tool/__init__.py +++ b/src/engine/SCons/Tool/__init__.py @@ -596,19 +596,23 @@ def StringizeLibSymlinks(symlinks): else: return symlinks -def EmitLibSymlinks(env, symlinks, libnode): +def EmitLibSymlinks(env, symlinks, libnode, **kw): """Used by emitters to handle (shared/versioned) library symlinks""" Verbose = False # nodes involved in process... all symlinks + library nodes = list(set([ x for x,y in symlinks ] + [libnode])) + + clean_targets = kw.get('clean_targets', []) + if not SCons.Util.is_List(clean_targets): + clean_targets = [ clean_targets ] for link, linktgt in symlinks: env.SideEffect(link, linktgt) if(Verbose): print "EmitLibSymlinks: SideEffect(%r,%r)" % (link.get_path(), linktgt.get_path()) clean_list = filter(lambda x : x != linktgt, nodes) - env.Clean(linktgt, clean_list) + env.Clean(list(set([linktgt] + clean_targets)), clean_list) if(Verbose): print "EmitLibSymlinks: Clean(%r,%r)" % (linktgt.get_path(), map(lambda x : x.get_path(), clean_list)) diff --git a/src/engine/SCons/Tool/cyglink.py b/src/engine/SCons/Tool/cyglink.py index e05e85f..deeb410 100644 --- a/src/engine/SCons/Tool/cyglink.py +++ b/src/engine/SCons/Tool/cyglink.py @@ -111,7 +111,7 @@ def _lib_emitter(target, source, env, **kw): if Verbose: print "_lib_emitter: implib symlinks=%r" % SCons.Tool.StringizeLibSymlinks(symlinks) if symlinks: - SCons.Tool.EmitLibSymlinks(env, symlinks, implib_target) + SCons.Tool.EmitLibSymlinks(env, symlinks, implib_target, clean_targets = target[0]) implib_target.attributes.shliblinks = symlinks return (target, source) diff --git a/test/LINK/VersionedLib.py b/test/LINK/VersionedLib.py index 0d74a35..360fa24 100644 --- a/test/LINK/VersionedLib.py +++ b/test/LINK/VersionedLib.py @@ -86,12 +86,6 @@ elif platform == 'darwin': elif platform == 'cygwin': test_plan = [ { - 'libversion' : '2.5.4', - 'files' : [ 'cygtest-2-5-4.dll', 'libtest-2-5-4.dll.a', 'libtest.dll.a', 'test.os' ], - 'instfiles' : [ 'cygtest-2-5-4.dll', 'libtest-2-5-4.dll.a', 'libtest.dll.a' ], - 'symlinks' : [], - }, - { 'libversion' : '2', 'files' : [ 'cygtest-2.dll', 'libtest-2.dll.a', 'libtest.dll.a', 'test.os' ], 'instfiles' : [ 'cygtest-2.dll', 'libtest-2.dll.a', 'libtest.dll.a' ], -- cgit v0.12 From 11711340ea36b162fcef4462f4f01d1d223700cf Mon Sep 17 00:00:00 2001 From: Pawel Tomulik Date: Sun, 20 Sep 2015 21:37:39 +0200 Subject: s/SHLINKSONAME/SHLIBSONAME/ --- src/engine/SCons/Defaults.py | 1 + src/engine/SCons/Tool/cyglink.py | 2 +- src/engine/SCons/Tool/gdc.py | 2 +- src/engine/SCons/Tool/gnulink.xml | 2 +- src/engine/SCons/Tool/link.py | 6 +++--- src/engine/SCons/Tool/link.xml | 4 ++-- 6 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/engine/SCons/Defaults.py b/src/engine/SCons/Defaults.py index c8170c3..744da5f 100644 --- a/src/engine/SCons/Defaults.py +++ b/src/engine/SCons/Defaults.py @@ -512,6 +512,7 @@ ConstructionEnvironment = { '__libversionflags' : __libversionflags, '__SHLIBVERSIONFLAGS' : '${__libversionflags(__env__,"SHLIBVERSION","_SHLIBVERSIONFLAGS")}', '__LDMODULEVERSIONFLAGS' : '${__libversionflags(__env__,"LDMODULEVERSION","_LDMODULEVERSIONFLAGS")}', + '__DSHLIBVERSIONFLAGS' : '${__libversionflags(__env__,"DSHLIBVERSION","_DSHLIBVERSIONFLAGS")}', 'TEMPFILE' : NullCmdGenerator, 'Dir' : Variable_Method_Caller('TARGET', 'Dir'), diff --git a/src/engine/SCons/Tool/cyglink.py b/src/engine/SCons/Tool/cyglink.py index deeb410..5230910 100644 --- a/src/engine/SCons/Tool/cyglink.py +++ b/src/engine/SCons/Tool/cyglink.py @@ -216,7 +216,7 @@ def generate(env): } # these variables were set by gnulink but are not used in cyglink - try: del env['_SHLINKSONAME'] + try: del env['_SHLIBSONAME'] except KeyError: pass try: del env['_LDMODULESONAME'] except KeyError: pass diff --git a/src/engine/SCons/Tool/gdc.py b/src/engine/SCons/Tool/gdc.py index 799c3ab..347efef 100644 --- a/src/engine/SCons/Tool/gdc.py +++ b/src/engine/SCons/Tool/gdc.py @@ -97,7 +97,7 @@ def generate(env): env['DSHLINK'] = '$DC' env['DSHLINKFLAGS'] = SCons.Util.CLVar('$DLINKFLAGS -shared') - env['SHDLINKCOM'] = '$DLINK -o $TARGET $DSHLINKFLAGS $__RPATH $SOURCES $_LIBDIRFLAGS $_LIBFLAGS' + env['SHDLINKCOM'] = '$DLINK -o $TARGET $DSHLINKFLAGS $__DSHLIBVERSIONFLAGS $__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 '') diff --git a/src/engine/SCons/Tool/gnulink.xml b/src/engine/SCons/Tool/gnulink.xml index 63ce0f4..0e055c7 100644 --- a/src/engine/SCons/Tool/gnulink.xml +++ b/src/engine/SCons/Tool/gnulink.xml @@ -34,7 +34,7 @@ Set construction variables for GNU linker/loader. RPATHPREFIX RPATHSUFFIX _LDMODULESONAME -_SHLINKSONAME +_SHLIBSONAME LDMODULEVERSIONFLAGS SHLIBVERSIONFLAGS diff --git a/src/engine/SCons/Tool/link.py b/src/engine/SCons/Tool/link.py index 6bd36e4..a4a2a4c 100644 --- a/src/engine/SCons/Tool/link.py +++ b/src/engine/SCons/Tool/link.py @@ -256,12 +256,12 @@ def _setup_versioned_lib_variables(env, **kw): if use_soname: # If the linker uses SONAME, then we need this little automata if tool == 'sunlink': - env['_SHLIBVERSIONFLAGS'] = '$SHLIBVERSIONFLAGS -h $_SHLINKSONAME' + env['_SHLIBVERSIONFLAGS'] = '$SHLIBVERSIONFLAGS -h $_SHLIBSONAME' env['_LDMODULEVERSIONFLAGS'] = '$LDMODULEVERSIONFLAGS -h $_LDMODULESONAME' else: - env['_SHLIBVERSIONFLAGS'] = '$SHLIBVERSIONFLAGS -Wl,-soname=$_SHLINKSONAME' + env['_SHLIBVERSIONFLAGS'] = '$SHLIBVERSIONFLAGS -Wl,-soname=$_SHLIBSONAME' env['_LDMODULEVERSIONFLAGS'] = '$LDMODULEVERSIONFLAGS -Wl,-soname=$_LDMODULESONAME' - env['_SHLINKSONAME'] = '${ShLibSonameGenerator(__env__,TARGET)}' + env['_SHLIBSONAME'] = '${ShLibSonameGenerator(__env__,TARGET)}' env['_LDMODULESONAME'] = '${LdModSonameGenerator(__env__,TARGET)}' env['ShLibSonameGenerator'] = SCons.Tool.ShLibSonameGenerator env['LdModSonameGenerator'] = SCons.Tool.LdModSonameGenerator diff --git a/src/engine/SCons/Tool/link.xml b/src/engine/SCons/Tool/link.xml index 52349da..2f913fe 100644 --- a/src/engine/SCons/Tool/link.xml +++ b/src/engine/SCons/Tool/link.xml @@ -107,13 +107,13 @@ This macro automatically introduces extra flags to &cv-link-SHLINKCOM; when building versioned &b-link-SharedLibrary; (that is when &cv-link-SHLIBVERSION; is set). _SHLIBVERSIONFLAGS usually adds &cv-link-SHLIBVERSIONFLAGS; and some extra dynamically generated options (such as --Wl,-soname=$_SHLINKSONAME. It is unused by "plain" +-Wl,-soname=$_SHLIBSONAME. It is unused by "plain" (unversioned) shared libraries. - + A macro that automatically generates shared library's SONAME based on $TARGET, -- cgit v0.12 From 0662dc87640b0b2b42e51b87aa611e666c8a99eb Mon Sep 17 00:00:00 2001 From: Pawel Tomulik Date: Sun, 20 Sep 2015 22:22:10 +0200 Subject: gdc: support soname in D versioned libraries --- src/engine/SCons/Defaults.py | 1 - src/engine/SCons/Tool/gdc.py | 10 +++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/engine/SCons/Defaults.py b/src/engine/SCons/Defaults.py index 744da5f..c8170c3 100644 --- a/src/engine/SCons/Defaults.py +++ b/src/engine/SCons/Defaults.py @@ -512,7 +512,6 @@ ConstructionEnvironment = { '__libversionflags' : __libversionflags, '__SHLIBVERSIONFLAGS' : '${__libversionflags(__env__,"SHLIBVERSION","_SHLIBVERSIONFLAGS")}', '__LDMODULEVERSIONFLAGS' : '${__libversionflags(__env__,"LDMODULEVERSION","_LDMODULEVERSIONFLAGS")}', - '__DSHLIBVERSIONFLAGS' : '${__libversionflags(__env__,"DSHLIBVERSION","_DSHLIBVERSIONFLAGS")}', 'TEMPFILE' : NullCmdGenerator, 'Dir' : Variable_Method_Caller('TARGET', 'Dir'), diff --git a/src/engine/SCons/Tool/gdc.py b/src/engine/SCons/Tool/gdc.py index 347efef..255e6f1 100644 --- a/src/engine/SCons/Tool/gdc.py +++ b/src/engine/SCons/Tool/gdc.py @@ -97,7 +97,15 @@ def generate(env): env['DSHLINK'] = '$DC' env['DSHLINKFLAGS'] = SCons.Util.CLVar('$DLINKFLAGS -shared') - env['SHDLINKCOM'] = '$DLINK -o $TARGET $DSHLINKFLAGS $__DSHLIBVERSIONFLAGS $__RPATH $SOURCES $_LIBDIRFLAGS $_LIBFLAGS' + # NOTE: using $__SHLIBVERSIONFLAGS here is just a quick hack. The macro + # $__SHLIBVERSIONFLAGS involves _SHLIBVERSIONFLAGS, which are set by + # current linker tool. If the current linker tool is not same as that used + # by gdc, and SHLIBVERSION is defined, an invalid flags may be generated + # for the gdc linker. It looks like the D tools should define its own + # set of variables (__DSHLIBVERSIONFLAGS, _DSHLIBVERSIONFLAGS, + # DSHLIBVERSIONFLAGS, DSHLIBVERSION, etc...) and duplicate the versioning + # machinery. + env['SHDLINKCOM'] = '$DLINK -o $TARGET $DSHLINKFLAGS $__SHLIBVERSIONFLAGS $__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 '') -- cgit v0.12 From 48fcd009ca14235134b8bcc45e9fef7dde472a70 Mon Sep 17 00:00:00 2001 From: Pawel Tomulik Date: Mon, 21 Sep 2015 00:59:51 +0200 Subject: add simple test for $__SHLIBVERSIONFLAGS --- test/LINK/SHLIBVERSIONFLAGS.py | 59 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 test/LINK/SHLIBVERSIONFLAGS.py diff --git a/test/LINK/SHLIBVERSIONFLAGS.py b/test/LINK/SHLIBVERSIONFLAGS.py new file mode 100644 index 0000000..d8fd2e6 --- /dev/null +++ b/test/LINK/SHLIBVERSIONFLAGS.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import os +import re + +import TestSCons +import SCons.Platform +import SCons.Defaults + +linkers = [ 'gnulink', 'cyglink', 'sunlink' ] + +foo_c_src = "void foo() {}\n" + +env = SCons.Defaults.DefaultEnvironment() +platform = SCons.Platform.platform_default() +tool_list = SCons.Platform.DefaultToolList(platform, env) + +test = TestSCons.TestSCons() +test.write('foo.c', foo_c_src) +test.write('SConstruct', "SharedLibrary('foo','foo.c',SHLIBVERSION='1.2.3')\n") + +if 'gnulink' in tool_list: + test.run(stdout = r".+ -Wl,-Bsymbolic -Wl,-soname=libfoo.so.1( .+)+", match = TestSCons.match_re_dotall) + test.run(arguments = ['-c']) +elif 'sunlink' in tool_list: + test.run(stdout = r".+ -h libfoo.so.1( .+)+", match = TestSCons.match_re_dotall) + test.run(arguments = ['-c']) + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: -- cgit v0.12 From c9aab89dd20ec11842c0183cf3c68fa5b8870155 Mon Sep 17 00:00:00 2001 From: Pawel Tomulik Date: Mon, 21 Sep 2015 01:55:43 +0200 Subject: add SONAME support to D tools --- src/engine/SCons/Defaults.py | 1 + src/engine/SCons/Tool/dmd.py | 13 ++++++++++++- src/engine/SCons/Tool/gdc.py | 21 ++++++++++++--------- src/engine/SCons/Tool/ldc.py | 14 +++++++++++++- 4 files changed, 38 insertions(+), 11 deletions(-) diff --git a/src/engine/SCons/Defaults.py b/src/engine/SCons/Defaults.py index c8170c3..744da5f 100644 --- a/src/engine/SCons/Defaults.py +++ b/src/engine/SCons/Defaults.py @@ -512,6 +512,7 @@ ConstructionEnvironment = { '__libversionflags' : __libversionflags, '__SHLIBVERSIONFLAGS' : '${__libversionflags(__env__,"SHLIBVERSION","_SHLIBVERSIONFLAGS")}', '__LDMODULEVERSIONFLAGS' : '${__libversionflags(__env__,"LDMODULEVERSION","_LDMODULEVERSIONFLAGS")}', + '__DSHLIBVERSIONFLAGS' : '${__libversionflags(__env__,"DSHLIBVERSION","_DSHLIBVERSIONFLAGS")}', 'TEMPFILE' : NullCmdGenerator, 'Dir' : Variable_Method_Caller('TARGET', 'Dir'), diff --git a/src/engine/SCons/Tool/dmd.py b/src/engine/SCons/Tool/dmd.py index a7d46c6..3722936 100644 --- a/src/engine/SCons/Tool/dmd.py +++ b/src/engine/SCons/Tool/dmd.py @@ -114,7 +114,7 @@ def generate(env): env['DSHLINK'] = '$DC' env['DSHLINKFLAGS'] = SCons.Util.CLVar('$DLINKFLAGS -shared -defaultlib=libphobos2.so') - env['SHDLINKCOM'] = '$DLINK -of$TARGET $DSHLINKFLAGS $__DRPATH $SOURCES $_DLIBDIRFLAGS $_DLIBFLAGS' + env['SHDLINKCOM'] = '$DLINK -of$TARGET $DSHLINKFLAGS $__DSHLIBVERSIONFLAGS $__DRPATH $SOURCES $_DLIBDIRFLAGS $_DLIBFLAGS' env['DLIBLINKPREFIX'] = '' if env['PLATFORM'] == 'win32' else '-L-l' env['DLIBLINKSUFFIX'] = '.lib' if env['PLATFORM'] == 'win32' else '' @@ -139,6 +139,17 @@ def generate(env): env['DRPATHSUFFIX'] = '' env['_DRPATH'] = '${_concat(DRPATHPREFIX, RPATH, DRPATHSUFFIX, __env__)}' + # Support for versioned libraries + env['_DSHLIBVERSIONFLAGS'] = '$DSHLIBVERSIONFLAGS -L-soname=$_DSHLIBSONAME' + env['_DSHLIBSONAME'] = '${DShLibSonameGenerator(__env__,TARGET)}' + # NOTE: this is a quick hack, the soname will only work if there is + # c/c++ linker loaded which provides callback for the ShLibSonameGenerator + env['DShLibSonameGenerator'] = SCons.Tool.ShLibSonameGenerator + # NOTE: this is only for further reference, currently $DSHLIBVERSION does + # not work, the user must use $SHLIBVERSION + env['DSHLIBVERSION'] = '$SHLIBVERSION' + env['DSHLIBVERSIONFLAGS'] = [] + SCons.Tool.createStaticLibBuilder(env) diff --git a/src/engine/SCons/Tool/gdc.py b/src/engine/SCons/Tool/gdc.py index 255e6f1..32199b3 100644 --- a/src/engine/SCons/Tool/gdc.py +++ b/src/engine/SCons/Tool/gdc.py @@ -97,15 +97,7 @@ def generate(env): env['DSHLINK'] = '$DC' env['DSHLINKFLAGS'] = SCons.Util.CLVar('$DLINKFLAGS -shared') - # NOTE: using $__SHLIBVERSIONFLAGS here is just a quick hack. The macro - # $__SHLIBVERSIONFLAGS involves _SHLIBVERSIONFLAGS, which are set by - # current linker tool. If the current linker tool is not same as that used - # by gdc, and SHLIBVERSION is defined, an invalid flags may be generated - # for the gdc linker. It looks like the D tools should define its own - # set of variables (__DSHLIBVERSIONFLAGS, _DSHLIBVERSIONFLAGS, - # DSHLIBVERSIONFLAGS, DSHLIBVERSION, etc...) and duplicate the versioning - # machinery. - env['SHDLINKCOM'] = '$DLINK -o $TARGET $DSHLINKFLAGS $__SHLIBVERSIONFLAGS $__RPATH $SOURCES $_LIBDIRFLAGS $_LIBFLAGS' + env['SHDLINKCOM'] = '$DLINK -o $TARGET $DSHLINKFLAGS $__DSHLIBVERSIONFLAGS $__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 '') @@ -123,6 +115,17 @@ def generate(env): env['RPATHSUFFIX'] = '' env['_RPATH'] = '${_concat(RPATHPREFIX, RPATH, RPATHSUFFIX, __env__)}' + # Support for versioned libraries + env['_DSHLIBVERSIONFLAGS'] = '$DSHLIBVERSIONFLAGS -Wl,-soname=$_DSHLIBSONAME' + env['_DSHLIBSONAME'] = '${DShLibSonameGenerator(__env__,TARGET)}' + # NOTE: this is a quick hack, the soname will only work if there is + # c/c++ linker loaded which provides callback for the ShLibSonameGenerator + env['DShLibSonameGenerator'] = SCons.Tool.ShLibSonameGenerator + # NOTE: this is only for further reference, currently $DSHLIBVERSION does + # not work, the user must use $SHLIBVERSION + env['DSHLIBVERSION'] = '$SHLIBVERSION' + env['DSHLIBVERSIONFLAGS'] = '$SHLIBVERSIONFLAGS' + SCons.Tool.createStaticLibBuilder(env) diff --git a/src/engine/SCons/Tool/ldc.py b/src/engine/SCons/Tool/ldc.py index 8f9b117..a3c1275 100644 --- a/src/engine/SCons/Tool/ldc.py +++ b/src/engine/SCons/Tool/ldc.py @@ -105,7 +105,7 @@ def generate(env): # Hack for Fedora the packages of which use the wrong name :-( if os.path.exists('/usr/lib64/libphobos-ldc.so') or os.path.exists('/usr/lib32/libphobos-ldc.so') or os.path.exists('/usr/lib/libphobos-ldc.so') : env['DSHLINKFLAGS'] = SCons.Util.CLVar('$DLINKFLAGS -shared -defaultlib=phobos-ldc') - env['SHDLINKCOM'] = '$DLINK -of=$TARGET $DSHLINKFLAGS $__DRPATH $SOURCES $_DLIBDIRFLAGS $_DLIBFLAGS' + env['SHDLINKCOM'] = '$DLINK -of=$TARGET $DSHLINKFLAGS $__DSHLIBVERSIONFLAGS $__DRPATH $SOURCES $_DLIBDIRFLAGS $_DLIBFLAGS' env['DLIBLINKPREFIX'] = '' if env['PLATFORM'] == 'win32' else '-L-l' env['DLIBLINKSUFFIX'] = '.lib' if env['PLATFORM'] == 'win32' else '' @@ -131,6 +131,18 @@ def generate(env): env['DRPATHSUFFIX'] = '' env['_DRPATH'] = '${_concat(DRPATHPREFIX, RPATH, DRPATHSUFFIX, __env__)}' + # Support for versioned libraries + env['_DSHLIBVERSIONFLAGS'] = '$DSHLIBVERSIONFLAGS -L-soname=$_DSHLIBSONAME' + env['_DSHLIBSONAME'] = '${DShLibSonameGenerator(__env__,TARGET)}' + # NOTE: this is a quick hack, the soname will only work if there is + # c/c++ linker loaded which provides callback for the ShLibSonameGenerator + env['DShLibSonameGenerator'] = SCons.Tool.ShLibSonameGenerator + # NOTE: this is only for further reference, currently $DSHLIBVERSION does + # not work, the user must use $SHLIBVERSION + env['DSHLIBVERSION'] = '$SHLIBVERSION' + env['DSHLIBVERSIONFLAGS'] = [] + print "AKUKU: %r" % env.subst('$_DSHLIBVERSIONFLAGS') + SCons.Tool.createStaticLibBuilder(env) -- cgit v0.12 From 810d9787e113ec41451bb4722a764f551cb35178 Mon Sep 17 00:00:00 2001 From: Pawel Tomulik Date: Mon, 21 Sep 2015 02:03:24 +0200 Subject: remove debug message from ldc.py --- src/engine/SCons/Tool/ldc.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/engine/SCons/Tool/ldc.py b/src/engine/SCons/Tool/ldc.py index a3c1275..ade95db 100644 --- a/src/engine/SCons/Tool/ldc.py +++ b/src/engine/SCons/Tool/ldc.py @@ -141,7 +141,6 @@ def generate(env): # not work, the user must use $SHLIBVERSION env['DSHLIBVERSION'] = '$SHLIBVERSION' env['DSHLIBVERSIONFLAGS'] = [] - print "AKUKU: %r" % env.subst('$_DSHLIBVERSIONFLAGS') SCons.Tool.createStaticLibBuilder(env) -- cgit v0.12 From 30664716b8dd63de48ab40865c48db8580f4956b Mon Sep 17 00:00:00 2001 From: Pawel Tomulik Date: Mon, 21 Sep 2015 02:28:58 +0200 Subject: correct logic in VersionedLib*.py tests --- test/LINK/VersionedLib-VariantDir.py | 13 ++++++++----- test/LINK/VersionedLib-j2.py | 13 ++++++++----- test/LINK/VersionedLib-subdir.py | 17 ++++++++++------- test/LINK/VersionedLib.py | 15 ++++++++------- 4 files changed, 34 insertions(+), 24 deletions(-) diff --git a/test/LINK/VersionedLib-VariantDir.py b/test/LINK/VersionedLib-VariantDir.py index 7406a33..0a631b0 100644 --- a/test/LINK/VersionedLib-VariantDir.py +++ b/test/LINK/VersionedLib-VariantDir.py @@ -33,8 +33,11 @@ import os import sys import SCons.Platform +import SCons.Defaults +env = SCons.Defaults.DefaultEnvironment() platform = SCons.Platform.platform_default() +tool_list = SCons.Platform.DefaultToolList(platform, env) test = TestSCons.TestSCons() @@ -96,7 +99,7 @@ if sys.platform.find('irix') != -1: test.run(program = test.workpath('build/bin/main')) -if platform == 'posix': +if 'gnulink' in tool_list: # All (?) the files we expect will get created in the current directory files = [ 'libfoo.so', @@ -104,14 +107,14 @@ if platform == 'posix': 'libfoo.so.0.1.2', ] obj = 'foo.os' -elif platform == 'darwin': +elif 'applelink' in tool_list: # All (?) the files we expect will get created in the current directory files = [ 'libfoo.dylib', 'libfoo.0.1.2.dylib', ] obj = 'foo.os' -elif platform == 'cygwin': +elif 'cyglink' in tool_list: # All (?) the files we expect will get created in the current directory files = [ 'cygfoo-0-1-2.dll', @@ -119,14 +122,14 @@ elif platform == 'cygwin': 'libfoo.dll.a', ] obj = 'foo.os' -elif platform == 'win32': +elif 'mslink' in tool_list: # All (?) the files we expect will get created in the current directory files = [ 'foo.dll', 'foo.lib', ] obj = 'foo.obj' -elif platform == 'sunos': +elif 'sunlink' in tool_list: # All (?) the files we expect will get created in the current directory files = [ 'libfoo.so', diff --git a/test/LINK/VersionedLib-j2.py b/test/LINK/VersionedLib-j2.py index 6f37e54..249b54f 100644 --- a/test/LINK/VersionedLib-j2.py +++ b/test/LINK/VersionedLib-j2.py @@ -35,6 +35,7 @@ import os import sys import SCons.Platform +import SCons.Defaults test = TestSCons.TestSCons() @@ -63,7 +64,9 @@ env.SharedLibrary('foo', 'foo.c', SHLIBVERSION = '0.1.2') test.run(arguments = ['-j 2', '--tree=all']) +env = SCons.Defaults.DefaultEnvironment() platform = SCons.Platform.platform_default() +tool_list = SCons.Platform.DefaultToolList(platform, env) if platform == 'cygwin': # PATH is used to search for *.dll librarier (cygfoo-0-2-1.dll in our case) @@ -83,7 +86,7 @@ test.run(arguments = ['-c']) platform = SCons.Platform.platform_default() -if platform == 'posix': +if 'gnulink' in tool_list: # All (?) the files we expect will get created in the current directory files = [ 'libfoo.so', @@ -91,14 +94,14 @@ if platform == 'posix': 'libfoo.so.0.1.2', 'foo.os', ] -elif platform == 'darwin': +elif 'applelink' in tool_list: # All (?) the files we expect will get created in the current directory files = [ 'libfoo.dylib', 'libfoo.0.1.2.dylib', 'foo.os', ] -elif platform == 'cygwin': +elif 'cyglink' in tool_list: # All (?) the files we expect will get created in the current directory files = [ 'cygfoo-0-1-2.dll', @@ -106,14 +109,14 @@ elif platform == 'cygwin': 'libfoo.dll.a', 'foo.os', ] -elif platform == 'win32': +elif 'mslink' in tool_list: # All (?) the files we expect will get created in the current directory files = [ 'foo.dll', 'foo.lib', 'foo.obj', ] -elif platform == 'sunos': +elif 'sunlink' in tool_list: # All (?) the files we expect will get created in the current directory files = [ 'libfoo.so', diff --git a/test/LINK/VersionedLib-subdir.py b/test/LINK/VersionedLib-subdir.py index 15369ef..a2e141b 100644 --- a/test/LINK/VersionedLib-subdir.py +++ b/test/LINK/VersionedLib-subdir.py @@ -37,6 +37,7 @@ import os import sys import SCons.Platform +import SCons.Defaults test = TestSCons.TestSCons() @@ -58,11 +59,13 @@ int main() } """) +env = SCons.Defaults.DefaultEnvironment() platform = SCons.Platform.platform_default() +tool_list = SCons.Platform.DefaultToolList(platform, env) -if platform == 'darwin': +if 'applelink' in tool_list: subdir = 'blah.0.1.2.dylib.blah' -elif platform == 'cygwin': +elif 'cyglink' in tool_list: subdir = 'blah-0-1-2.dll.a.blah' else: subdir = 'blah.so.0.1.2.blah' @@ -90,7 +93,7 @@ if sys.platform.find('irix') != -1: test.run(program = test.workpath('main')) -if platform == 'posix': +if 'gnulink' in tool_list: # All (?) the files we expect will get created in the current directory files = [ 'libfoo.so', @@ -98,14 +101,14 @@ if platform == 'posix': 'libfoo.so.0.1.2', ] obj = 'foo.os' -elif platform == 'darwin': +elif 'applelink' in tool_list: # All (?) the files we expect will get created in the current directory files = [ 'libfoo.dylib', 'libfoo.0.1.2.dylib', ] obj = 'foo.os' -elif platform == 'cygwin': +elif 'cyglink' in tool_list: # All (?) the files we expect will get created in the current directory files = [ 'cygfoo-0-1-2.dll', @@ -113,14 +116,14 @@ elif platform == 'cygwin': 'libfoo.dll.a', ] obj = 'foo.os' -elif platform == 'win32': +elif 'mslink' in tool_list: # All (?) the files we expect will get created in the current directory files = [ 'foo.dll', 'foo.lib', ] obj = 'foo.obj' -elif platform == 'sunos': +elif 'sunlink' in tool_list: # All (?) the files we expect will get created in the current directory files = [ 'libfoo.so', diff --git a/test/LINK/VersionedLib.py b/test/LINK/VersionedLib.py index 360fa24..599c8aa 100644 --- a/test/LINK/VersionedLib.py +++ b/test/LINK/VersionedLib.py @@ -29,12 +29,13 @@ import sys import TestSCons import SCons.Platform +import SCons.Defaults -_exe = TestSCons._exe - +env = SCons.Defaults.DefaultEnvironment() platform = SCons.Platform.platform_default() +tool_list = SCons.Platform.DefaultToolList(platform, env) -if platform == 'posix': +if 'gnulink' in tool_list: test_plan = [ { 'libversion' : '2', @@ -73,7 +74,7 @@ if platform == 'posix': 'symlinks' : [ ('libtest.so', 'libtest.so.2.dfffa11'), ('libtest.so.2', 'libtest.so.2.dfffa11') ], }, ] -elif platform == 'darwin': +elif 'applelink' in tool_list: # All (?) the files we expect will get created in the current directory test_plan = [ { @@ -83,7 +84,7 @@ elif platform == 'darwin': 'symlinks' : [], }, ] -elif platform == 'cygwin': +elif 'cyglink' in tool_list: test_plan = [ { 'libversion' : '2', @@ -122,7 +123,7 @@ elif platform == 'cygwin': 'symlinks' : [ ('libtest.dll.a', 'libtest-2-dfffa11.dll.a') ], }, ] -elif platform == 'win32': +elif 'mslink' in tool_list: test_plan = [ { 'libversion' : '2.5.4', @@ -131,7 +132,7 @@ elif platform == 'win32': 'symlinks' : [], }, ] -elif platform == 'sunos': +elif 'sunlink' in tool_list: test_plan = [ { 'libversion' : '2', -- cgit v0.12 From 5a0037f5d5b0cdf34e3d61aa4ce702d805ccab2a Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 21 Sep 2015 08:51:12 -0700 Subject: adding amd64 win installer to list of files --- bin/upload-release-files.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/bin/upload-release-files.sh b/bin/upload-release-files.sh index bf09751..735f143 100755 --- a/bin/upload-release-files.sh +++ b/bin/upload-release-files.sh @@ -1,4 +1,6 @@ #!/bin/sh +set -e +set -x if [ $# -lt 2 ]; then echo Usage: $0 VERSION SF_USERNAME @@ -17,6 +19,8 @@ SF_TOPDIR='/home/frs/project/scons' cd build/dist cp -f ../../src/CHANGES.txt ../../src/RELEASE.txt ../../src/Announce.txt . +cp scons-$VERSION.win32.exe scons-$VERSION-setup.exe + set -x # Upload main scons release files: @@ -24,6 +28,7 @@ $RSYNC $RSYNCOPTS \ scons-$VERSION-1.noarch.rpm \ scons-$VERSION-1.src.rpm \ scons-$VERSION-setup.exe \ + scons-$VERSION.win-amd64.exe \ scons-$VERSION.tar.gz \ scons-$VERSION.zip \ Announce.txt CHANGES.txt RELEASE.txt \ -- cgit v0.12 From 1b99bf81ad3ce90268f2b8097946bb2e24ef05b6 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 21 Sep 2015 08:56:47 -0700 Subject: Regenerated docs for 2.4.0 Release --- doc/generated/examples/caching_ex-random_1.xml | 4 ++-- doc/generated/examples/troubleshoot_stacktrace_2.xml | 2 +- doc/generated/variables.gen | 6 ++---- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/doc/generated/examples/caching_ex-random_1.xml b/doc/generated/examples/caching_ex-random_1.xml index 6f64f8f..e7aa631 100644 --- a/doc/generated/examples/caching_ex-random_1.xml +++ b/doc/generated/examples/caching_ex-random_1.xml @@ -1,9 +1,9 @@ % scons -Q -cc -o f2.o -c f2.c cc -o f4.o -c f4.c -cc -o f3.o -c f3.c cc -o f5.o -c f5.c +cc -o f2.o -c f2.c +cc -o f3.o -c f3.c cc -o f1.o -c f1.c cc -o prog f1.o f2.o f3.o f4.o f5.o diff --git a/doc/generated/examples/troubleshoot_stacktrace_2.xml b/doc/generated/examples/troubleshoot_stacktrace_2.xml index 1ab65ee..add59ff 100644 --- a/doc/generated/examples/troubleshoot_stacktrace_2.xml +++ b/doc/generated/examples/troubleshoot_stacktrace_2.xml @@ -8,6 +8,6 @@ scons: internal stack trace: return SCons.Taskmaster.OutOfDateTask.prepare(self) File "bootstrap/src/engine/SCons/Taskmaster.py", line 191, in prepare executor.prepare() - File "bootstrap/src/engine/SCons/Executor.py", line 396, in prepare + File "bootstrap/src/engine/SCons/Executor.py", line 430, in prepare raise SCons.Errors.StopError(msg % (s, self.batches[0].targets[0])) diff --git a/doc/generated/variables.gen b/doc/generated/variables.gen index bf18796..04c3efe 100644 --- a/doc/generated/variables.gen +++ b/doc/generated/variables.gen @@ -6753,9 +6753,7 @@ and translated into the The list of directories that the scripting language wrapper and interface generate will search for included files. The SWIG implicit dependency scanner will search these -directories for include files. -The default is to use the same path -specified as $CPPPATH. +directories for include files. The default value is an empty list. @@ -6802,7 +6800,7 @@ include $_SWIGINCFLAGS: -env = Environment(SWIGCOM="my_swig -o $TARGET $_SWIGINCFLAGS $SORUCES") +env = Environment(SWIGCOM="my_swig -o $TARGET $_SWIGINCFLAGS $SOURCES") -- cgit v0.12 From 093d03ccf05f2a317a6e68efb57f35f79af6d450 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 21 Sep 2015 09:07:09 -0700 Subject: updates for 2.4.0 release --- debian/changelog | 6 ++++++ src/Announce.txt | 8 +++++--- src/CHANGES.txt | 9 ++++++--- src/RELEASE.txt | 55 +++++++++++++++---------------------------------------- 4 files changed, 32 insertions(+), 46 deletions(-) diff --git a/debian/changelog b/debian/changelog index b161db1..7311f78 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +scons (2.4.0) unstable; urgency=low + + * Maintenance release. + + -- William Deegan Mon, 21 Sep 2015 08:56:00 -0700 + scons (2.3.6) unstable; urgency=low * Maintenance release. diff --git a/src/Announce.txt b/src/Announce.txt index f96e703..1d59702 100644 --- a/src/Announce.txt +++ b/src/Announce.txt @@ -18,9 +18,8 @@ So that everyone using SCons can help each other learn how to use it more effectively, please go to http://scons.org/lists.php#users to sign up for the scons-users mailing list. -==============IMPORTANT NOTICE FOR NEXT VERSION V2.4.0=========== +==============IMPORTANT NOTICE=========== -PLEASE READ. CHANGES COMING IN NEXT MAJOR RELEASE V2.4.0 As has been pre-announced in SCons's mailing lists: * https://pairlist4.pair.net/pipermail/scons-users/2014-July/002734.html , @@ -37,13 +36,16 @@ released. Especially if you are directly using the Node class. ================================================================= -RELEASE VERSION/DATE TO BE FILLED IN LATER +RELEASE 2.4.0 - Mon, 21 Sep 2015 08:56:00 -0700 Please consult the RELEASE.txt file for a summary of changes since the last release and consult the CHANGES.txt file for complete a list of changes since last release. This announcement highlights only the important changes. + Please note the following important changes since release 2.3.6: + - Switch several core classes to use "slots" to reduce memory + usage. (PR #2180, #2178, #2198) Please note the following important changes since release 2.3.5: - Support for Visual Studio 2015 diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 977d00f..0299718 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -4,15 +4,18 @@ Change Log -RELEASE VERSION/DATE TO BE FILLED IN LATER +RELEASE 2.4.0 - Mon, 21 Sep 2015 08:56:00 -0700 From Dirk Baechle: - - Switched several core classes to using "slots", for - reducing the overall memory consumption in large + - Switched several core classes to use "slots", to + reduce the overall memory consumption in large projects (fixes #2180, #2178, #2198) - Memoizer counting uses decorators now, instead of the old metaclasses approach. + From Andrew Featherstone + - Fixed typo in SWIGPATH description + RELEASE 2.3.6 - Mon, 31 Jul 2015 14:35:03 -0700 From Rob Smith: diff --git a/src/RELEASE.txt b/src/RELEASE.txt index 83212a7..0bb481d 100644 --- a/src/RELEASE.txt +++ b/src/RELEASE.txt @@ -1,72 +1,47 @@ - A new SCons checkpoint release, 2.3.8.alpha.yyyymmdd, is now available + A new SCons release, 2.4.0, is now available on the SCons download page: http://www.scons.org/download.php - XXX The primary purpose of this release ... XXX - - A SCons "checkpoint release" is intended to provide early access to - new features so they can be tested in the field before being released - for adoption by other software distributions. - - Note that a checkpoint release is developed using the same test-driven - development methodology as all SCons releases. Existing SCons - functionality should all work as it does in previous releases (except - for any changes identified in the release notes) and early adopters - should be able to use a checkpoint release safely for production work - with existing SConscript files. If not, it represents not only a bug - in SCons but also a hole in the regression test suite, and we want to - hear about it. - - New features may be more lightly tested than in past releases, - especially as concerns their interaction with all of the other - functionality in SCons. We are especially interested in hearing bug - reports about new functionality. - - We do not recommend that downstream distributions (Debian, Fedora, - etc.) package a checkpoint release, mainly to avoid confusing the - "public" release numbering with the long checkpoint release names. - - Here is a summary of the changes since 1.3.0: + Here is a summary of the changes since 2.3.6: NEW FUNCTIONALITY - - List new features (presumably why a checkpoint is being released) + - None DEPRECATED FUNCTIONALITY - - List anything that's been deprecated since the last release + - None CHANGED/ENHANCED EXISTING FUNCTIONALITY - - List modifications to existing features, where the previous behavior - wouldn't actually be considered a bug + - None FIXES - - List fixes of outright bugs + - None IMPROVEMENTS - - List improvements that wouldn't be visible to the user in the - documentation: performance improvements (describe the circumstances - under which they would be observed), or major code cleanups + - Switched several core classes to use "slots", to + reduce the overall memory consumption in large + projects (fixes #2180, #2178, #2198) + - Memoizer counting uses decorators now, instead of + the old metaclasses approach. PACKAGING - - List changes in the way SCons is packaged and/or released + - Added new amd64 windows 64 bit installer DOCUMENTATION - - List any significant changes to the documentation (not individual - typo fixes, even if they're mentioned in src/CHANGES.txt to give - the contributor credit) + - None DEVELOPMENT - - List visible changes in the way SCons is developed + - None - Thanks to CURLY, LARRY, and MOE for their contributions to this release. + Thanks to Dirk Baechle, Andrew Featherstone for their contributions to this release. Contributors are listed alphabetically by their last name. __COPYRIGHT__ -- cgit v0.12 From 61aa2966263cdff2cada2f2a9853e982206f989a Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 21 Sep 2015 10:03:12 -0700 Subject: release 2.4.0 --- QMTest/TestSCons.py | 2 +- README.rst | 38 +++++++++++++++++++------------------- ReleaseConfig | 2 +- SConstruct | 4 ++-- src/Announce.txt | 2 +- src/CHANGES.txt | 2 +- 6 files changed, 25 insertions(+), 25 deletions(-) diff --git a/QMTest/TestSCons.py b/QMTest/TestSCons.py index a9b4e3e..06fa575 100644 --- a/QMTest/TestSCons.py +++ b/QMTest/TestSCons.py @@ -34,7 +34,7 @@ from TestCmd import PIPE # here provides some independent verification that what we packaged # conforms to what we expect. -default_version = '2.3.6' +default_version = '2.4.0' python_version_unsupported = (2, 3, 0) python_version_deprecated = (2, 7, 0) diff --git a/README.rst b/README.rst index 9ed0ccc..4f51523 100644 --- a/README.rst +++ b/README.rst @@ -156,7 +156,7 @@ Or on Windows:: By default, the above commands will do the following: -- Install the version-numbered "scons-2.3.3" and "sconsign-2.3.3" scripts in +- Install the version-numbered "scons-2.4.0" and "sconsign-2.4.0" scripts in the default system script directory (/usr/bin or C:\\Python\*\\Scripts, for example). This can be disabled by specifying the "--no-version-script" option on the command line. @@ -168,23 +168,23 @@ By default, the above commands will do the following: before making it the default on your system. On UNIX or Linux systems, you can have the "scons" and "sconsign" scripts be - hard links or symbolic links to the "scons-2.3.3" and "sconsign-2.3.3" + hard links or symbolic links to the "scons-2.4.0" and "sconsign-2.4.0" scripts by specifying the "--hardlink-scons" or "--symlink-scons" options on the command line. -- Install "scons-2.3.3.bat" and "scons.bat" wrapper scripts in the Python +- Install "scons-2.4.0.bat" and "scons.bat" wrapper scripts in the Python prefix directory on Windows (C:\\Python\*, for example). This can be disabled by specifying the "--no-install-bat" option on the command line. On UNIX or Linux systems, the "--install-bat" option may be specified to - have "scons-2.3.3.bat" and "scons.bat" files installed in the default system + have "scons-2.4.0.bat" and "scons.bat" files installed in the default system script directory, which is useful if you want to install SCons in a shared file system directory that can be used to execute SCons from both UNIX/Linux and Windows systems. - Install the SCons build engine (a Python module) in an appropriate - version-numbered SCons library directory (/usr/lib/scons-2.3.3 or - C:\\Python\*\\scons-2.3.3, for example). See below for more options related to + version-numbered SCons library directory (/usr/lib/scons-2.4.0 or + C:\\Python\*\\scons-2.4.0, for example). See below for more options related to installing the build engine library. - Install the troff-format man pages in an appropriate directory on UNIX or @@ -462,7 +462,7 @@ running all of "runtest.py -a". Building Packages ================= -We use SCons (version 2.3.3 or later) to build its own packages. If you +We use SCons (version 2.4.0 or later) to build its own packages. If you already have an appropriate version of SCons installed on your system, you can build everything by simply running it:: @@ -477,18 +477,18 @@ about `Executing SCons Without Installing`_):: Depending on the utilities installed on your system, any or all of the following packages will be built:: - build/dist/scons-2.3.3-1.noarch.rpm - build/dist/scons-2.3.3-1.src.rpm - build/dist/scons-2.3.3.linux-i686.tar.gz - build/dist/scons-2.3.6.tar.gz - build/dist/scons-2.3.6.win32.exe - build/dist/scons-2.3.6.zip - build/dist/scons-doc-2.3.6.tar.gz - build/dist/scons-local-2.3.6.tar.gz - build/dist/scons-local-2.3.6.zip - build/dist/scons-src-2.3.6.tar.gz - build/dist/scons-src-2.3.6.zip - build/dist/scons_2.3.3-1_all.deb + build/dist/scons-2.4.0-1.noarch.rpm + build/dist/scons-2.4.0-1.src.rpm + build/dist/scons-2.4.0.linux-i686.tar.gz + build/dist/scons-2.4.0.tar.gz + build/dist/scons-2.4.0.win32.exe + build/dist/scons-2.4.0.zip + build/dist/scons-doc-2.4.0.tar.gz + build/dist/scons-local-2.4.0.tar.gz + build/dist/scons-local-2.4.0.zip + build/dist/scons-src-2.4.0.tar.gz + build/dist/scons-src-2.4.0.zip + build/dist/scons_2.4.0-1_all.deb The SConstruct file is supposed to be smart enough to avoid trying to build packages for which you don't have the proper utilities installed. For diff --git a/ReleaseConfig b/ReleaseConfig index 5a191ba..1026c58 100644 --- a/ReleaseConfig +++ b/ReleaseConfig @@ -32,7 +32,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" # 'final', the patchlevel is set to the release date. This value is # mandatory and must be present in this file. #version_tuple = (2, 2, 0, 'final', 0) -version_tuple = (2, 3, 8, 'alpha', 0) +version_tuple = (2, 4, 0) # Python versions prior to unsupported_python_version cause a fatal error # when that version is used. Python versions prior to deprecate_python_version diff --git a/SConstruct b/SConstruct index e8b6c9a..4bff134 100644 --- a/SConstruct +++ b/SConstruct @@ -6,7 +6,7 @@ copyright_years = '2001 - 2015' # This gets inserted into the man pages to reflect the month of release. -month_year = 'July 2015' +month_year = 'September 2015' # # __COPYRIGHT__ @@ -43,7 +43,7 @@ import tempfile import bootstrap project = 'scons' -default_version = '2.3.6' +default_version = '2.4.0' copyright = "Copyright (c) %s The SCons Foundation" % copyright_years platform = distutils.util.get_platform() diff --git a/src/Announce.txt b/src/Announce.txt index 1d59702..25f6b15 100644 --- a/src/Announce.txt +++ b/src/Announce.txt @@ -36,7 +36,7 @@ released. Especially if you are directly using the Node class. ================================================================= -RELEASE 2.4.0 - Mon, 21 Sep 2015 08:56:00 -0700 +RELEASE 2.4.0 - Mon, 21 Sep 2015 09:07:51 -0700 Please consult the RELEASE.txt file for a summary of changes since the last release and consult the CHANGES.txt file for complete a list of changes diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 0299718..8e25e37 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -4,7 +4,7 @@ Change Log -RELEASE 2.4.0 - Mon, 21 Sep 2015 08:56:00 -0700 +RELEASE 2.4.0 - Mon, 21 Sep 2015 09:07:51 -0700 From Dirk Baechle: - Switched several core classes to use "slots", to -- cgit v0.12 -- cgit v0.12 From 8d3afad7ff75457151e6321f05a858f0f2be5dff Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 21 Sep 2015 10:48:21 -0700 Subject: update readme's --- README.rst | 4 ++-- src/README.txt | 55 +++++++++++++++++++++++++++++++------------------------ 2 files changed, 33 insertions(+), 26 deletions(-) diff --git a/README.rst b/README.rst index 4f51523..05be712 100644 --- a/README.rst +++ b/README.rst @@ -47,7 +47,7 @@ version at the SCons download page: Execution Requirements ====================== -Running SCons requires Python version 2.6 or later (Python 3 is not +Running SCons requires Python version 2.7 or later (Python 3 is not yet supported). There should be no other dependencies or requirements to run SCons. @@ -748,5 +748,5 @@ many contributors, including but not at all limited to: \... and many others. -__COPYRIGHT__ +Copyright (c) 2001 - 2015 The SCons Foundation diff --git a/src/README.txt b/src/README.txt index 5d880c2..d16433e 100644 --- a/src/README.txt +++ b/src/README.txt @@ -2,7 +2,7 @@ SCons - a software construction tool - Version __VERSION__ + Version 2.4.0 This is SCons, a tool for building software (and other files). SCons is @@ -28,7 +28,8 @@ the latest version by checking the SCons download page at: EXECUTION REQUIREMENTS ====================== -Running SCons requires Python version 2.4 or later. There should be +Running SCons requires Python version 2.7.*. Currently it does not +run on the Python 3.x release. There should be no other dependencies or requirements to run SCons. (There is, however, an additional requirement to *install* SCons from this particular package; see the next section.) @@ -70,17 +71,17 @@ By default, the above command will do the following: making it the default on your system. On UNIX or Linux systems, you can have the "scons" and "sconsign" - scripts be hard links or symbolic links to the "scons-__VERSION__" and - "sconsign-__VERSION__" scripts by specifying the "--hardlink-scons" + scripts be hard links or symbolic links to the "scons-2.4.0" and + "sconsign-2.4.0" scripts by specifying the "--hardlink-scons" or "--symlink-scons" options on the command line. - -- Install "scons-__VERSION__.bat" and "scons.bat" wrapper scripts in the + -- Install "scons-2.4.0.bat" and "scons.bat" wrapper scripts in the Python prefix directory on Windows (C:\Python*, for example). This can be disabled by specifying the "--no-install-bat" option on the command line. On UNIX or Linux systems, the "--install-bat" option may be - specified to have "scons-__VERSION__.bat" and "scons.bat" files + specified to have "scons-2.4.0.bat" and "scons.bat" files installed in the default system script directory, which is useful if you want to install SCons in a shared file system directory that can be used to execute SCons from both UNIX/Linux and @@ -88,7 +89,7 @@ By default, the above command will do the following: -- Install the SCons build engine (a Python module) in an appropriate version-numbered SCons library directory - (/usr/lib/scons-__VERSION__ or C:\Python*\scons-__VERSION__, for example). + (/usr/lib/scons-2.4.0 or C:\Python*\scons-2.4.0, for example). See below for more options related to installing the build engine library. @@ -224,20 +225,26 @@ Check the SCons web site at: AUTHOR INFO =========== - -Steven Knight -knight at baldmt dot com -http://www.baldmt.com/~knight/ - -With plenty of help from the SCons Development team: - Chad Austin - Charles Crain - Steve Leblanc - Greg Noel - Gary Oberbrunner - Anthony Roach - Greg Spencer - Christoph Wiedemann - -__COPYRIGHT__ -__FILE__ __REVISION__ __DATE__ __DEVELOPER__ +SCons was originally written by Steven Knight, knight at baldmt dot com. +Since around 2010 it has been maintained by the SCons +development team, co-managed by Bill Deegan and Gary Oberbrunner, with +many contributors, including but not at all limited to: + +- Chad Austin +- Dirk Baechle +- Charles Crain +- William Deegan +- Steve Leblanc +- Rob Managan +- Greg Noel +- Gary Oberbrunner +- Anthony Roach +- Greg Spencer +- Tom Tanner +- Anatoly Techtonik +- Christoph Wiedemann +- Russel Winder + +\... and many others. + +Copyright (c) 2001 - 2015 The SCons Foundation -- cgit v0.12 From 016463aaaafff9fb747d6a7c4cbed53220b601b5 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 21 Sep 2015 10:55:47 -0700 Subject: add uploading src/README.txt to sourceforge --- bin/upload-release-files.sh | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/bin/upload-release-files.sh b/bin/upload-release-files.sh index 735f143..c853bda 100755 --- a/bin/upload-release-files.sh +++ b/bin/upload-release-files.sh @@ -17,9 +17,10 @@ SF_TOPDIR='/home/frs/project/scons' # the build products are here: cd build/dist -cp -f ../../src/CHANGES.txt ../../src/RELEASE.txt ../../src/Announce.txt . +cp -f ../../src/CHANGES.txt ../../src/RELEASE.txt ../../src/Announce.txt ../../src/README.txt . cp scons-$VERSION.win32.exe scons-$VERSION-setup.exe +cp scons-$VERSION.win-amd64.exe scons-$VERSION-amd64-setup.exe set -x @@ -28,7 +29,7 @@ $RSYNC $RSYNCOPTS \ scons-$VERSION-1.noarch.rpm \ scons-$VERSION-1.src.rpm \ scons-$VERSION-setup.exe \ - scons-$VERSION.win-amd64.exe \ + scons-$VERSION-amd64-setup.exe \ scons-$VERSION.tar.gz \ scons-$VERSION.zip \ Announce.txt CHANGES.txt RELEASE.txt \ @@ -48,6 +49,12 @@ $RSYNC $RSYNCOPTS \ Announce.txt CHANGES.txt RELEASE.txt \ $SF_USER@$SF_MACHINE:$SF_TOPDIR/scons-src/$VERSION/ +# Readme +$RSYNC $RSYNCOPTS \ + README.txt \ + $SF_USER@$SF_MACHINE:$SF_TOPDIR/ + + # # scons.org stuff: -- cgit v0.12 From 859dd4545a76e4f2d7bc90e8193a9175fbc0060b Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 21 Sep 2015 10:58:16 -0700 Subject: switch back to develop content --- ReleaseConfig | 2 +- src/Announce.txt | 2 +- src/CHANGES.txt | 7 +++++++ src/RELEASE.txt | 55 ++++++++++++++++++++++++++++++++++++++++--------------- 4 files changed, 49 insertions(+), 17 deletions(-) diff --git a/ReleaseConfig b/ReleaseConfig index 5a191ba..07cbe44 100644 --- a/ReleaseConfig +++ b/ReleaseConfig @@ -32,7 +32,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" # 'final', the patchlevel is set to the release date. This value is # mandatory and must be present in this file. #version_tuple = (2, 2, 0, 'final', 0) -version_tuple = (2, 3, 8, 'alpha', 0) +version_tuple = (2, 3, 9, 'alpha', 0) # Python versions prior to unsupported_python_version cause a fatal error # when that version is used. Python versions prior to deprecate_python_version diff --git a/src/Announce.txt b/src/Announce.txt index 1d59702..7a13b81 100644 --- a/src/Announce.txt +++ b/src/Announce.txt @@ -36,7 +36,7 @@ released. Especially if you are directly using the Node class. ================================================================= -RELEASE 2.4.0 - Mon, 21 Sep 2015 08:56:00 -0700 +RELEASE VERSION/DATE TO BE FILLED IN LATER Please consult the RELEASE.txt file for a summary of changes since the last release and consult the CHANGES.txt file for complete a list of changes diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 0299718..fd617cb 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -4,6 +4,13 @@ Change Log +RELEASE VERSION/DATE TO BE FILLED IN LATER + + From John Doe: + + - Whatever John Doe did. + + RELEASE 2.4.0 - Mon, 21 Sep 2015 08:56:00 -0700 From Dirk Baechle: diff --git a/src/RELEASE.txt b/src/RELEASE.txt index 0bb481d..d13de57 100644 --- a/src/RELEASE.txt +++ b/src/RELEASE.txt @@ -1,47 +1,72 @@ - A new SCons release, 2.4.0, is now available + A new SCons checkpoint release, 2.3.9.alpha.yyyymmdd, is now available on the SCons download page: http://www.scons.org/download.php - Here is a summary of the changes since 2.3.6: + XXX The primary purpose of this release ... XXX + + A SCons "checkpoint release" is intended to provide early access to + new features so they can be tested in the field before being released + for adoption by other software distributions. + + Note that a checkpoint release is developed using the same test-driven + development methodology as all SCons releases. Existing SCons + functionality should all work as it does in previous releases (except + for any changes identified in the release notes) and early adopters + should be able to use a checkpoint release safely for production work + with existing SConscript files. If not, it represents not only a bug + in SCons but also a hole in the regression test suite, and we want to + hear about it. + + New features may be more lightly tested than in past releases, + especially as concerns their interaction with all of the other + functionality in SCons. We are especially interested in hearing bug + reports about new functionality. + + We do not recommend that downstream distributions (Debian, Fedora, + etc.) package a checkpoint release, mainly to avoid confusing the + "public" release numbering with the long checkpoint release names. + + Here is a summary of the changes since 1.3.0: NEW FUNCTIONALITY - - None + - List new features (presumably why a checkpoint is being released) DEPRECATED FUNCTIONALITY - - None + - List anything that's been deprecated since the last release CHANGED/ENHANCED EXISTING FUNCTIONALITY - - None + - List modifications to existing features, where the previous behavior + wouldn't actually be considered a bug FIXES - - None + - List fixes of outright bugs IMPROVEMENTS - - Switched several core classes to use "slots", to - reduce the overall memory consumption in large - projects (fixes #2180, #2178, #2198) - - Memoizer counting uses decorators now, instead of - the old metaclasses approach. + - List improvements that wouldn't be visible to the user in the + documentation: performance improvements (describe the circumstances + under which they would be observed), or major code cleanups PACKAGING - - Added new amd64 windows 64 bit installer + - List changes in the way SCons is packaged and/or released DOCUMENTATION - - None + - List any significant changes to the documentation (not individual + typo fixes, even if they're mentioned in src/CHANGES.txt to give + the contributor credit) DEVELOPMENT - - None + - List visible changes in the way SCons is developed - Thanks to Dirk Baechle, Andrew Featherstone for their contributions to this release. + Thanks to CURLY, LARRY, and MOE for their contributions to this release. Contributors are listed alphabetically by their last name. __COPYRIGHT__ -- cgit v0.12 From 9fee88e50ebc808dff8aae58fea35b354af83d0a Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 21 Sep 2015 17:46:28 -0700 Subject: remove extraneous release boilerplate text --- src/CHANGES.txt | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 31cc073..fd617cb 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -11,34 +11,6 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER - Whatever John Doe did. -RELEASE VERSION/DATE TO BE FILLED IN LATER - - From John Doe: - - - Whatever John Doe did. - - -RELEASE VERSION/DATE TO BE FILLED IN LATER - - From John Doe: - - - Whatever John Doe did. - - -RELEASE VERSION/DATE TO BE FILLED IN LATER - - From John Doe: - - - Whatever John Doe did. - - -RELEASE VERSION/DATE TO BE FILLED IN LATER - - From John Doe: - - - Whatever John Doe did. - - RELEASE 2.4.0 - Mon, 21 Sep 2015 08:56:00 -0700 From Dirk Baechle: -- cgit v0.12 From 600def5cde72f16a2684005ced499dff9d0e5653 Mon Sep 17 00:00:00 2001 From: Florian Miedniak Date: Tue, 22 Sep 2015 10:47:29 +0200 Subject: Fixed #3011: Glob() called with exclude didn't work when called from a SConscript that is executed with variant_dir set and duplicate=0 --- src/engine/SCons/Node/FS.py | 7 ++++++- test/Glob/VariantDir.py | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py index a3db8fe..7461710 100644 --- a/src/engine/SCons/Node/FS.py +++ b/src/engine/SCons/Node/FS.py @@ -2182,7 +2182,12 @@ class Dir(Base): r = [os.path.join(str(dir), x) for x in r] result.extend(r) if exclude: - result = filter(lambda x: not any(fnmatch.fnmatch(str(x), e) for e in SCons.Util.flatten(exclude)), result) + excludes = [] + excludeList = SCons.Util.flatten(exclude) + for x in excludeList: + r = self.glob(x, ondisk, source, strings) + excludes.extend(r) + result = filter(lambda x: not any(fnmatch.fnmatch(str(x), str(e)) for e in SCons.Util.flatten(excludes)), result) return sorted(result, key=lambda a: str(a)) def _glob1(self, pattern, ondisk=True, source=False, strings=False): diff --git a/test/Glob/VariantDir.py b/test/Glob/VariantDir.py index 175e5b9..c9c1d07 100644 --- a/test/Glob/VariantDir.py +++ b/test/Glob/VariantDir.py @@ -34,6 +34,7 @@ import TestSCons test = TestSCons.TestSCons() test.subdir('src') +test.subdir('src/sub1') test.write('SConstruct', """\ VariantDir('var1', 'src') @@ -41,6 +42,9 @@ VariantDir('var2', 'src') SConscript('var1/SConscript') SConscript('var2/SConscript') +SConscript('var1/sub1/SConscript') +SConscript('var2/sub1/SConscript') +SConscript('src/sub1/SConscript', src_dir = 'src', variant_dir = 'var3', duplicate=0) """) test.write(['src', 'SConscript'], """\ @@ -55,16 +59,46 @@ def concatenate(target, source, env): env['BUILDERS']['Concatenate'] = Builder(action=concatenate) env.Concatenate('f.out', sorted(Glob('f*.in'), key=lambda t: t.name)) +env.Concatenate('fex.out', sorted(Glob('f*.in', exclude = 'f1.in'), key=lambda t: t.name)) +""") + +test.write(['src', 'sub1', 'SConscript'], """\ +env = Environment() + +def concatenate(target, source, env): + fp = open(str(target[0]), 'wb') + for s in source: + fp.write(open(str(s), 'rb').read()) + fp.close() + +env['BUILDERS']['Concatenate'] = Builder(action=concatenate) + +env.Concatenate('f.out', sorted(Glob('f*.in'), key=lambda t: t.name)) +env.Concatenate('fex.out', sorted(Glob('f*.in', exclude = 'f1.in'), key=lambda t: t.name)) """) test.write(['src', 'f1.in'], "src/f1.in\n") test.write(['src', 'f2.in'], "src/f2.in\n") test.write(['src', 'f3.in'], "src/f3.in\n") +test.write(['src', 'sub1', 'f1.in'], "src/sub1/f1.in\n") +test.write(['src', 'sub1', 'f2.in'], "src/sub1/f2.in\n") +test.write(['src', 'sub1', 'f3.in'], "src/sub1/f3.in\n") + test.run(arguments = '.') test.must_match(['var1', 'f.out'], "src/f1.in\nsrc/f2.in\nsrc/f3.in\n") test.must_match(['var2', 'f.out'], "src/f1.in\nsrc/f2.in\nsrc/f3.in\n") +test.must_match(['var1', 'fex.out'], "src/f2.in\nsrc/f3.in\n") +test.must_match(['var2', 'fex.out'], "src/f2.in\nsrc/f3.in\n") + +test.must_match(['var1', 'sub1', 'f.out'], "src/sub1/f1.in\nsrc/sub1/f2.in\nsrc/sub1/f3.in\n") +test.must_match(['var2', 'sub1', 'f.out'], "src/sub1/f1.in\nsrc/sub1/f2.in\nsrc/sub1/f3.in\n") +test.must_match(['var1', 'sub1', 'fex.out'], "src/sub1/f2.in\nsrc/sub1/f3.in\n") +test.must_match(['var2', 'sub1', 'fex.out'], "src/sub1/f2.in\nsrc/sub1/f3.in\n") + +test.must_match(['var3', 'sub1', 'f.out'], "src/sub1/f1.in\nsrc/sub1/f2.in\nsrc/sub1/f3.in\n") +test.must_match(['var3', 'sub1', 'fex.out'], "src/sub1/f2.in\nsrc/sub1/f3.in\n") test.pass_test() -- cgit v0.12 From e902d86ed981c406ce5a8d120c46f580d8ef0717 Mon Sep 17 00:00:00 2001 From: ptomulik Date: Tue, 22 Sep 2015 12:57:48 +0200 Subject: add blurb to src/CHANGES.txt --- src/CHANGES.txt | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 977d00f..860df99 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -6,6 +6,33 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER + From Paweł Tomulik: + - Reimplemented versioning for shared libraries, with the following effects + - Fixed tigris issues #3001, #3006. + - Fixed several other issues not reported to tigris, including: + issues with versioned libraries in subdirectories with tricky names, + issues with versioned libraries and variant directories, + issue with soname not being injected to library when using D linkers, + - Switched to direct symlinks instead of daisy-chained ones -- soname and + development symlinks point directly to the versioned shared library now), + for rationale see: + https://www.debian.org/doc/debian-policy/ch-sharedlibs.html + https://fedoraproject.org/wiki/Packaging:Guidelines#Devel_Packages + https://bitbucket.org/scons/scons/pull-requests/247/new-versioned-libraries-gnulink-cyglink/diff#comment-10063929 + - New construction variables to allow override default behavior: SONAME, + SHLIBVERSIONFLAGS, _SHLIBVERSIONFLAGS, SHLIBNOVERSIONSYMLINKS, + LDMODULEVERSION, LDMODULEVERSIONFLAGS, _LDMODULEVERSIONFLAGS, + LDMODULENOVERSIONSYMLINKS. + - Changed logic used to configure the versioning machinery from + platform-centric to linker-oriented. + - The SHLIBVERSION/LDMODULEVERSION variables are no longer validated by + SCons (more freedom to users). + - InstallVersionedLib() doesn't use SHLIBVERSION anymore. + - Enchanced docs for the library versioning stuff. + - New tests for versioned libraries. + - Library versioning is currently implemented for the following linker + tools: 'cyglink', 'gnulink', 'sunlink'. + From Dirk Baechle: - Switched several core classes to using "slots", for reducing the overall memory consumption in large -- cgit v0.12 From 0179419a4beb70434d930d418dbbcfa7cd628afb Mon Sep 17 00:00:00 2001 From: William Blevins Date: Wed, 23 Sep 2015 14:37:51 +0100 Subject: Added test to verify InstallVersionLib available from DefaultEnvironment. --- test/LINK/VersionedLib.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/LINK/VersionedLib.py b/test/LINK/VersionedLib.py index 599c8aa..3f4a912 100644 --- a/test/LINK/VersionedLib.py +++ b/test/LINK/VersionedLib.py @@ -228,6 +228,12 @@ env.Program('testapp1.c', LIBS = mylib, LIBPATH='.') env.Program('testapp2.c', LIBS = ['test'], LIBPATH='.') instnode = env.InstallVersionedLib("#/installtest",mylib) env.Default(instnode) + +# Extra test to ensure that InstallVersionedLib can be called from the DefaultEnvironment +# Ensures orthogonality where InstallVersionedLib wasn't previously available: SCons gave NameError. +instnode = InstallVersionedLib("defaultenv-installtest",mylib) +Default(instnode) + """ % libversion) test.write('test.c', test_c_src) @@ -240,6 +246,7 @@ env.Default(instnode) test.must_exist([ f]) for f in instfiles: test.must_exist(['installtest', f]) + test.must_exist(['defaultenv-installtest', f]) wrong_symlinks = [] for (linkname,expected) in symlinks: @@ -268,6 +275,7 @@ env.Default(instnode) for f in instfiles: test.must_not_exist(['installtest', f]) + test.must_not_exist(['defaultenv-installtest', f]) test.pass_test() -- cgit v0.12 From 336f967488b7f51a7b073a8808075dd2080a0580 Mon Sep 17 00:00:00 2001 From: William Blevins Date: Tue, 22 Sep 2015 21:15:53 +0100 Subject: Added InstallVersionedLib to default environment init for orthogonality with other Install[As] methods. --- src/engine/SCons/Script/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/engine/SCons/Script/__init__.py b/src/engine/SCons/Script/__init__.py index bb7b632..90b1fc3 100644 --- a/src/engine/SCons/Script/__init__.py +++ b/src/engine/SCons/Script/__init__.py @@ -318,6 +318,7 @@ GlobalDefaultEnvironmentFunctions = [ 'Ignore', 'Install', 'InstallAs', + 'InstallVersionedLib', 'Literal', 'Local', 'ParseDepends', -- cgit v0.12 From 366627b426a8b90e0c1fc0ffaf51f31dbdf76de1 Mon Sep 17 00:00:00 2001 From: William Blevins Date: Wed, 23 Sep 2015 00:01:24 +0100 Subject: Updated CHANGES.txt for adding InstallVersionedLib to DefaultEnvironment context. --- src/CHANGES.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 802ca5e..5f54668 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -6,6 +6,10 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER + From William Blevins: + - InstallVersionedLib now available in the DefaultEnvironment context. + - Improves orthogonality of use cases between different Install functions. + From Paweł Tomulik: - Reimplemented versioning for shared libraries, with the following effects - Fixed tigris issues #3001, #3006. -- cgit v0.12 From 1d5c456aa0d3d34b4cf46350ae3eb5b7a0150234 Mon Sep 17 00:00:00 2001 From: Florian Miedniak Date: Wed, 23 Sep 2015 22:52:03 +0200 Subject: Corrected indentation --- src/engine/SCons/Node/FS.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py index 7461710..4e78852 100644 --- a/src/engine/SCons/Node/FS.py +++ b/src/engine/SCons/Node/FS.py @@ -2185,8 +2185,8 @@ class Dir(Base): excludes = [] excludeList = SCons.Util.flatten(exclude) for x in excludeList: - r = self.glob(x, ondisk, source, strings) - excludes.extend(r) + r = self.glob(x, ondisk, source, strings) + excludes.extend(r) result = filter(lambda x: not any(fnmatch.fnmatch(str(x), str(e)) for e in SCons.Util.flatten(excludes)), result) return sorted(result, key=lambda a: str(a)) -- cgit v0.12 From 337a0ab2a7ee2f12cec0975b44e66a78c8be7bae Mon Sep 17 00:00:00 2001 From: Florian Miedniak Date: Wed, 23 Sep 2015 22:52:23 +0200 Subject: added some blurb --- src/CHANGES.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 5f54668..f23d847 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -6,6 +6,9 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER + From Florian Miedniak: + - Fixed tigris issue #3011: Glob() excludes didn't work when used with VariantDir(duplicate=0) + From William Blevins: - InstallVersionedLib now available in the DefaultEnvironment context. - Improves orthogonality of use cases between different Install functions. -- cgit v0.12 From 9efc846a1dbd96a07f1141497015129543a0274b Mon Sep 17 00:00:00 2001 From: William Blevins Date: Wed, 23 Sep 2015 22:59:56 +0100 Subject: Updated SHLIBVERSION documentation to reflect PR-247. --- src/engine/SCons/Tool/__init__.xml | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/src/engine/SCons/Tool/__init__.xml b/src/engine/SCons/Tool/__init__.xml index 7f19bfc..358ff1e 100644 --- a/src/engine/SCons/Tool/__init__.xml +++ b/src/engine/SCons/Tool/__init__.xml @@ -200,22 +200,20 @@ For maximum portability, use the &b-LoadableModule; builder for the latter. When the &cv-link-SHLIBVERSION; construction variable is defined a versioned shared library is created. This modifies the &cv-link-SHLINKFLAGS; as required, adds the version number to the library name, and creates the symlinks that -are needed. &cv-link-SHLIBVERSION; needs to be of the form X.Y.Z, where X -and Y are numbers, and Z is a number but can also contain letters to designate -alpha, beta, or release candidate patch levels. +are needed. env.SharedLibrary(target = 'bar', source = ['bar.c', 'foo.o'], SHLIBVERSION='1.5.2') - -This builder may create multiple links to the library. On a POSIX system, -for the shared library libbar.so.2.3.1, the links created would be -libbar.so and libbar.so.2; on a Darwin (OSX) system -the library would be libbar.2.3.1.dylib and the link would be -libbar.dylib. +On a POSIX system, versions with a single token create exactly one symlink: +libbar.so.6 would have symlinks libbar.so only. +On a POSIX system, versions with two or more +tokens create exactly two symlinks: libbar.so.2.3.1 would have symlinks +libbar.so and libbar.so.2; on a Darwin (OSX) system the library would be +libbar.2.3.1.dylib and the link would be libbar.dylib. @@ -490,10 +488,8 @@ When this construction variable is defined, a versioned loadable module is created by &b-link-LoadableModule; builder. This activates the &cv-link-_LDMODULEVERSIONFLAGS; and thus modifies the &cv-link-LDMODULECOM; as required, adds the version number to the library name, and creates the symlinks -that are needed. &cv-link-LDMODULEVERSION; needs to be of the form X.Y.Z, where -X and Y are numbers, and Z is a number but can also contain letters to -designate alpha, beta, or release candidate patch levels. By default -&cv-link-LDMODULEVERSION; is set to $SHLIBVERSION. +that are needed. &cv-link-LDMODULEVERSION; versions should exist in the same +format as &cv-link-SHLIBVERSION. @@ -521,9 +517,9 @@ When this construction variable is defined, a versioned shared library is created by &b-link-SharedLibrary; builder. This activates the &cv-link-_SHLIBVERSIONFLAGS; and thus modifies the &cv-link-SHLINKCOM; as required, adds the version number to the library name, and creates the symlinks -that are needed. &cv-link-SHLIBVERSION; needs to be of the form X.Y.Z, where X -and Y are numbers, and Z is a number but can also contain letters to designate -alpha, beta, or release candidate patch levels. +that are needed. &cv-link-SHLIBVERSION; versions should exist as alpha-numeric, +decimal-delimited values as defined by the regular expression "\w+[\.\w+]*". +Example &cv-link-SHLIBVERSION; values include '1', '1.2.3', and '1.2.gitaa412c8b'. -- cgit v0.12 From 72d8407c28fc02cb986fa561c793e1b202e53867 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carn=C3=AB=20Draug?= Date: Sat, 26 Sep 2015 19:01:04 +0100 Subject: Add new CheckProg configure method to documentation and list of changes. --- doc/scons.mod | 1 + doc/user/sconf.xml | 20 ++++++++++++++++++++ src/CHANGES.txt | 4 ++++ 3 files changed, 25 insertions(+) diff --git a/doc/scons.mod b/doc/scons.mod index 72dc7ff..8d64054 100644 --- a/doc/scons.mod +++ b/doc/scons.mod @@ -276,6 +276,7 @@ CheckHeader"> CheckLib"> CheckLibWithHeader"> +CheckProg"> CheckType"> CheckTypeSize"> TryAction"> diff --git a/doc/user/sconf.xml b/doc/user/sconf.xml index 569ab1a..fe933f1 100644 --- a/doc/user/sconf.xml +++ b/doc/user/sconf.xml @@ -304,6 +304,26 @@ scons: `.' is up to date.
+ Checking for the Presence of a program + + + + Check for the presence of a program + by using the &CheckProg; method: + + + + +env = Environment() +conf = Configure(env) +if not conf.CheckProg('foobar'): + print 'Unable to find the program foobar on the system' + Exit(1) +env = conf.Finish() + + +
+
Adding Your Own Custom Checks diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 977d00f..3869621 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -13,6 +13,10 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER - Memoizer counting uses decorators now, instead of the old metaclasses approach. + From Carnë Draug: + - Added new configure check, CheckProg, to check for + existence of a program. + RELEASE 2.3.6 - Mon, 31 Jul 2015 14:35:03 -0700 From Rob Smith: -- cgit v0.12 From 699440f601523b736d98cfef8f1bddcc2f184a39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carn=C3=AB=20Draug?= Date: Sat, 26 Sep 2015 20:42:53 +0100 Subject: doc: do not recommend os.popen which is deprecated in python --- doc/user/tasks.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/user/tasks.xml b/doc/user/tasks.xml index 0bdf678..8026a53 100644 --- a/doc/user/tasks.xml +++ b/doc/user/tasks.xml @@ -96,8 +96,8 @@ filenames = [x for x in filenames if os.path.splitext(x)[1] in extensions] The "backtick function": run a shell command and capture the output -import os -output = os.popen(command).read() +import subprocess +output = subprocess.check_output(command) -- cgit v0.12 From 60ec8bc52b7c15a3f017a898b20644810609d185 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 28 Sep 2015 10:05:31 -0700 Subject: fix spelling mistakes found by debian lintian tool list here: https://lintian.debian.org/full/debian@jff-webhosting.net.html#scons_2.3.6-1 --- doc/man/scons.xml | 2 +- doc/user/build-install.xml | 2 +- src/engine/SCons/Environment.py | 2 +- src/engine/SCons/Script/SConsOptions.py | 2 +- src/engine/SCons/Tool/gettext.xml | 2 +- src/engine/SCons/Tool/midl.xml | 2 +- src/engine/SCons/Tool/msgmerge.xml | 2 +- src/engine/SCons/Tool/msvc.xml | 2 +- src/engine/SCons/Tool/packaging/rpm.py | 2 +- src/engine/SCons/Tool/xgettext.xml | 2 +- test/TEX/variant_dir_newglossary.py | 2 +- test/packaging/guess-package-name.py | 2 +- test/packaging/msi/explicit-target.py | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/doc/man/scons.xml b/doc/man/scons.xml index c3abb64..5c832c2 100644 --- a/doc/man/scons.xml +++ b/doc/man/scons.xml @@ -7040,7 +7040,7 @@ env.Program('MyApp', ['Foo.cpp', 'Bar.cpp']) For more information see the document for the PCH builder, and the PCH and PCHSTOP construction variables. To learn about the details of precompiled -headers consult the MSDN documention for /Yc, /Yu, and /Yp. +headers consult the MSDN documentation for /Yc, /Yu, and /Yp. diff --git a/doc/user/build-install.xml b/doc/user/build-install.xml index d107b4a..3e66172 100644 --- a/doc/user/build-install.xml +++ b/doc/user/build-install.xml @@ -231,7 +231,7 @@ Python 2.5.1 Or, you can use a graphical RPM package manager. - See your package manager application's documention + See your package manager application's documentation for specific instructions about how to use it to install a downloaded RPM. diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py index 8db743b..7e2f896 100644 --- a/src/engine/SCons/Environment.py +++ b/src/engine/SCons/Environment.py @@ -612,7 +612,7 @@ class SubstitutionEnvironment(object): def Override(self, overrides): """ - Produce a modified environment whose variables are overriden by + Produce a modified environment whose variables are overridden by the overrides dictionaries. "overrides" is a dictionary that will override the variables of this environment. diff --git a/src/engine/SCons/Script/SConsOptions.py b/src/engine/SCons/Script/SConsOptions.py index 8ecc093..68c60cc 100644 --- a/src/engine/SCons/Script/SConsOptions.py +++ b/src/engine/SCons/Script/SConsOptions.py @@ -268,7 +268,7 @@ class SConsOptionParser(optparse.OptionParser): preserve_unknown_options = False def error(self, msg): - # overriden OptionValueError exception handler + # overridden OptionValueError exception handler self.print_usage(sys.stderr) sys.stderr.write("SCons Error: %s\n" % msg) sys.exit(2) diff --git a/src/engine/SCons/Tool/gettext.xml b/src/engine/SCons/Tool/gettext.xml index 96e467a..f9f8b81 100644 --- a/src/engine/SCons/Tool/gettext.xml +++ b/src/engine/SCons/Tool/gettext.xml @@ -27,7 +27,7 @@ See its __doc__ string for a discussion of the format. This is actually a toolset, which supports internationalization and -localization of sofware being constructed with SCons. The toolset loads +localization of software being constructed with SCons. The toolset loads following tools: diff --git a/src/engine/SCons/Tool/midl.xml b/src/engine/SCons/Tool/midl.xml index 1420978..efd83cc 100644 --- a/src/engine/SCons/Tool/midl.xml +++ b/src/engine/SCons/Tool/midl.xml @@ -44,7 +44,7 @@ Sets construction variables for the Microsoft IDL compiler. Builds a Windows type library (.tlb) file from an input IDL file (.idl). -In addition, it will build the associated inteface stub and +In addition, it will build the associated interface stub and proxy source files, naming them according to the base name of the .idl file. For example, diff --git a/src/engine/SCons/Tool/msgmerge.xml b/src/engine/SCons/Tool/msgmerge.xml index 2bfc6df..139b21c 100644 --- a/src/engine/SCons/Tool/msgmerge.xml +++ b/src/engine/SCons/Tool/msgmerge.xml @@ -64,7 +64,7 @@ Target nodes defined through &b-POUpdate; are not built by default (they're Ignored from '.' node). Instead, they are added automatically to special Alias ('po-update' by default). The alias name may be changed -through the &cv-link-POUPDATE_ALIAS; construction variable. You can easilly +through the &cv-link-POUPDATE_ALIAS; construction variable. You can easily update PO files in your project by scons po-update. diff --git a/src/engine/SCons/Tool/msvc.xml b/src/engine/SCons/Tool/msvc.xml index 793784f..2b4619e 100644 --- a/src/engine/SCons/Tool/msvc.xml +++ b/src/engine/SCons/Tool/msvc.xml @@ -86,7 +86,7 @@ file as the second element. Normally the object file is ignored. This builder method is only provided when Microsoft Visual C++ is being used as the compiler. The PCH builder method is generally used in -conjuction with the PCH construction variable to force object files to use +conjunction with the PCH construction variable to force object files to use the precompiled header: diff --git a/src/engine/SCons/Tool/packaging/rpm.py b/src/engine/SCons/Tool/packaging/rpm.py index 656d8fb..92977d0 100644 --- a/src/engine/SCons/Tool/packaging/rpm.py +++ b/src/engine/SCons/Tool/packaging/rpm.py @@ -168,7 +168,7 @@ def build_specfile_sections(spec): '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 + # These are for internal use but could possibly be overridden 'X_RPM_PREP' : '%%prep\n%s\n\n', 'X_RPM_BUILD' : '%%build\n%s\n\n', 'X_RPM_INSTALL' : '%%install\n%s\n\n', diff --git a/src/engine/SCons/Tool/xgettext.xml b/src/engine/SCons/Tool/xgettext.xml index 6e28a9d..380f92a 100644 --- a/src/engine/SCons/Tool/xgettext.xml +++ b/src/engine/SCons/Tool/xgettext.xml @@ -108,7 +108,7 @@ the results shall be as the comments above say. Example 2. The &b-POTUpdate; builder may be used with no target specified, in which case default target messages.pot will be used. The -default target may also be overriden by setting &cv-link-POTDOMAIN; construction +default target may also be overridden by setting &cv-link-POTDOMAIN; construction variable or providing it as an override to &b-POTUpdate; builder: diff --git a/test/TEX/variant_dir_newglossary.py b/test/TEX/variant_dir_newglossary.py index 8604270..5a28ed4 100644 --- a/test/TEX/variant_dir_newglossary.py +++ b/test/TEX/variant_dir_newglossary.py @@ -25,7 +25,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ -Validate the use of \newglossary in TeX source files in conjuction +Validate the use of \newglossary in TeX source files in conjunction with variant_dir. Test configuration contributed by Kendrick Boyd. diff --git a/test/packaging/guess-package-name.py b/test/packaging/guess-package-name.py index 9c85b9a..33c3329 100644 --- a/test/packaging/guess-package-name.py +++ b/test/packaging/guess-package-name.py @@ -86,7 +86,7 @@ test.run(stderr = None) test.must_exist( 'src.tar.gz' ) # -# TEST: default package name creation with overriden packager. +# TEST: default package name creation with overridden packager. # test.write('SConstruct', """ diff --git a/test/packaging/msi/explicit-target.py b/test/packaging/msi/explicit-target.py index bc786ee..85bfa85 100644 --- a/test/packaging/msi/explicit-target.py +++ b/test/packaging/msi/explicit-target.py @@ -26,7 +26,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ Test the ability to use a explicit target package name and the use -of FindInstalledFiles() in conjuction with .msi packages. +of FindInstalledFiles() in conjunction with .msi packages. """ import TestSCons -- cgit v0.12 From b2b1d5d272bdcfe1f9dc7c4bc57b8c8927fe7784 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 28 Sep 2015 11:08:40 -0700 Subject: added .DS_Store to hgignore --- .hgignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgignore b/.hgignore index 27c728a..dcc9505 100644 --- a/.hgignore +++ b/.hgignore @@ -9,6 +9,7 @@ syntax:glob *~ *.xcodeproj *.orig +*.DS_Store doc/user/scons-user doc/user/scons_db.xml -- cgit v0.12 From 8474df368aeed8807eb4b9ca20041676f42e69c6 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 28 Sep 2015 11:39:22 -0700 Subject: fixed syntax error from previous pull request #256 --- src/engine/SCons/Tool/__init__.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/SCons/Tool/__init__.xml b/src/engine/SCons/Tool/__init__.xml index 358ff1e..69cc597 100644 --- a/src/engine/SCons/Tool/__init__.xml +++ b/src/engine/SCons/Tool/__init__.xml @@ -489,7 +489,7 @@ is created by &b-link-LoadableModule; builder. This activates the &cv-link-_LDMODULEVERSIONFLAGS; and thus modifies the &cv-link-LDMODULECOM; as required, adds the version number to the library name, and creates the symlinks that are needed. &cv-link-LDMODULEVERSION; versions should exist in the same -format as &cv-link-SHLIBVERSION. +format as &cv-link-SHLIBVERSION;. -- cgit v0.12 From 3359572ab98baf9f408c7e86ad0d2df9a50594a4 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 28 Sep 2015 13:01:37 -0700 Subject: exit with non-zero exit code if validation fails --- bin/docs-validate.py | 1 + 1 file changed, 1 insertion(+) diff --git a/bin/docs-validate.py b/bin/docs-validate.py index c445c3f..f888c21 100644 --- a/bin/docs-validate.py +++ b/bin/docs-validate.py @@ -25,3 +25,4 @@ if __name__ == "__main__": print "OK" else: print "Validation failed! Please correct the errors above and try again." + sys.exit(1) -- cgit v0.12 From 898fa44b70ce4998801db843dbe5b263f4d34a18 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 28 Sep 2015 13:57:59 -0700 Subject: Added help for pull request #226 --- doc/generated/builders.gen | 35 ++-- doc/generated/examples/caching_ex-random_1.xml | 4 +- .../examples/commandline_Variables_Help_1.xml | 2 + doc/generated/examples/output_ex1_1.xml | 2 + doc/generated/examples/output_ex2_1.xml | 2 + doc/generated/examples/output_ex2_2.xml | 2 + doc/generated/examples/troubleshoot_Dump_1.xml | 4 + doc/generated/examples/troubleshoot_Dump_2.xml | 4 + doc/generated/examples/troubleshoot_explain1_3.xml | 2 +- doc/generated/functions.gen | 18 +- doc/generated/tools.gen | 16 +- doc/generated/tools.mod | 2 + doc/generated/variables.gen | 184 ++++++++++++++++++++- doc/generated/variables.mod | 32 ++++ doc/user/output.xml | 22 +++ src/engine/SCons/Script/SConscript.xml | 16 +- 16 files changed, 302 insertions(+), 45 deletions(-) diff --git a/doc/generated/builders.gen b/doc/generated/builders.gen index 02dc04b..d49156f 100644 --- a/doc/generated/builders.gen +++ b/doc/generated/builders.gen @@ -505,20 +505,13 @@ env.InstallAs(target = ['../lib/libfoo.a', '../lib/libbar.a'], -Installs a versioned shared library. The $SHLIBVERSION -construction variable should be defined in the environment -to confirm the version number in the library name. -If $SHLIBVERSION is not defined a warning will be issued -and the name of the library will be parsed to derive the version. -The symlinks appropriate to the architecture will be generated. +Installs a versioned shared library. The symlinks appropriate to the +architecture will be generated based on symlinks of the source library. env.InstallVersionedLib(target = '/usr/local/bin/foo', source = 'libxyz.1.5.2.so') -env.InstallVersionedLib(target = '/usr/local/bin/foo', - source = 'libxyz.1.5.2.so', - SHLIBVERSION='1.5.2') @@ -1257,7 +1250,7 @@ file as the second element. Normally the object file is ignored. This builder method is only provided when Microsoft Visual C++ is being used as the compiler. The PCH builder method is generally used in -conjuction with the PCH construction variable to force object files to use +conjunction with the PCH construction variable to force object files to use the precompiled header: @@ -1490,7 +1483,7 @@ the results shall be as the comments above say. Example 2. The POTUpdate builder may be used with no target specified, in which case default target messages.pot will be used. The -default target may also be overriden by setting $POTDOMAIN construction +default target may also be overridden by setting $POTDOMAIN construction variable or providing it as an override to POTUpdate builder: @@ -1623,7 +1616,7 @@ Target nodes defined through P (they're Ignored from '.' node). Instead, they are added automatically to special Alias ('po-update' by default). The alias name may be changed -through the $POUPDATE_ALIAS construction variable. You can easilly +through the $POUPDATE_ALIAS construction variable. You can easily update PO files in your project by scons po-update. @@ -1995,22 +1988,20 @@ For maximum portability, use the $SHLIBVERSION construction variable is defined a versioned shared library is created. This modifies the $SHLINKFLAGS as required, adds the version number to the library name, and creates the symlinks that -are needed. $SHLIBVERSION needs to be of the form X.Y.Z, where X -and Y are numbers, and Z is a number but can also contain letters to designate -alpha, beta, or release candidate patch levels. +are needed. env.SharedLibrary(target = 'bar', source = ['bar.c', 'foo.o'], SHLIBVERSION='1.5.2') - -This builder may create multiple links to the library. On a POSIX system, -for the shared library libbar.so.2.3.1, the links created would be -libbar.so and libbar.so.2; on a Darwin (OSX) system -the library would be libbar.2.3.1.dylib and the link would be -libbar.dylib. +On a POSIX system, versions with a single token create exactly one symlink: +libbar.so.6 would have symlinks libbar.so only. +On a POSIX system, versions with two or more +tokens create exactly two symlinks: libbar.so.2.3.1 would have symlinks +libbar.so and libbar.so.2; on a Darwin (OSX) system the library would be +libbar.2.3.1.dylib and the link would be libbar.dylib. @@ -2564,7 +2555,7 @@ running scons '.'. Builds a Windows type library (.tlb) file from an input IDL file (.idl). -In addition, it will build the associated inteface stub and +In addition, it will build the associated interface stub and proxy source files, naming them according to the base name of the .idl file. For example, diff --git a/doc/generated/examples/caching_ex-random_1.xml b/doc/generated/examples/caching_ex-random_1.xml index e7aa631..904e1dd 100644 --- a/doc/generated/examples/caching_ex-random_1.xml +++ b/doc/generated/examples/caching_ex-random_1.xml @@ -1,9 +1,9 @@ % scons -Q -cc -o f4.o -c f4.c -cc -o f5.o -c f5.c cc -o f2.o -c f2.c +cc -o f5.o -c f5.c cc -o f3.o -c f3.c +cc -o f4.o -c f4.c cc -o f1.o -c f1.c cc -o prog f1.o f2.o f3.o f4.o f5.o diff --git a/doc/generated/examples/commandline_Variables_Help_1.xml b/doc/generated/examples/commandline_Variables_Help_1.xml index db171eb..76f13c5 100644 --- a/doc/generated/examples/commandline_Variables_Help_1.xml +++ b/doc/generated/examples/commandline_Variables_Help_1.xml @@ -1,6 +1,8 @@ % scons -Q -h +Local Build Variables: + RELEASE: Set to 1 to build for release default: 0 actual: 0 diff --git a/doc/generated/examples/output_ex1_1.xml b/doc/generated/examples/output_ex1_1.xml index 535960b..2607243 100644 --- a/doc/generated/examples/output_ex1_1.xml +++ b/doc/generated/examples/output_ex1_1.xml @@ -3,6 +3,8 @@ scons: Reading SConscript files ... scons: done reading SConscript files. +Local Build Variables: + Type: 'scons program' to build the production program, 'scons debug' to build the debug version. diff --git a/doc/generated/examples/output_ex2_1.xml b/doc/generated/examples/output_ex2_1.xml index e951c3a..74d7192 100644 --- a/doc/generated/examples/output_ex2_1.xml +++ b/doc/generated/examples/output_ex2_1.xml @@ -3,6 +3,8 @@ scons: Reading SConscript files ... scons: done reading SConscript files. +Local Build Variables: + Type: 'scons program' to build the production program. Type: 'scons windebug' to build the Windows debug version. diff --git a/doc/generated/examples/output_ex2_2.xml b/doc/generated/examples/output_ex2_2.xml index 8dca6c3..9130d5a 100644 --- a/doc/generated/examples/output_ex2_2.xml +++ b/doc/generated/examples/output_ex2_2.xml @@ -3,6 +3,8 @@ scons: Reading SConscript files ... scons: done reading SConscript files. +Local Build Variables: + Type: 'scons program' to build the production program. Use scons -H for help about command-line options. diff --git a/doc/generated/examples/troubleshoot_Dump_1.xml b/doc/generated/examples/troubleshoot_Dump_1.xml index 248e85c..bf141a0 100644 --- a/doc/generated/examples/troubleshoot_Dump_1.xml +++ b/doc/generated/examples/troubleshoot_Dump_1.xml @@ -64,7 +64,11 @@ scons: Reading SConscript files ... '_LIBDIRFLAGS': '$( ${_concat(LIBDIRPREFIX, LIBPATH, LIBDIRSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)', '_LIBFLAGS': '${_concat(LIBLINKPREFIX, LIBS, LIBLINKSUFFIX, __env__)}', '__DRPATH': '$_DRPATH', + '__DSHLIBVERSIONFLAGS': '${__libversionflags(__env__,"DSHLIBVERSION","_DSHLIBVERSIONFLAGS")}', + '__LDMODULEVERSIONFLAGS': '${__libversionflags(__env__,"LDMODULEVERSION","_LDMODULEVERSIONFLAGS")}', '__RPATH': '$_RPATH', + '__SHLIBVERSIONFLAGS': '${__libversionflags(__env__,"SHLIBVERSION","_SHLIBVERSIONFLAGS")}', + '__libversionflags': <function __libversionflags at 0x700000&gt;, '_concat': <function _concat at 0x700000&gt;, '_defines': <function _defines at 0x700000&gt;, '_stripixes': <function _stripixes at 0x700000&gt;} diff --git a/doc/generated/examples/troubleshoot_Dump_2.xml b/doc/generated/examples/troubleshoot_Dump_2.xml index d6fa404..0ae8fe1 100644 --- a/doc/generated/examples/troubleshoot_Dump_2.xml +++ b/doc/generated/examples/troubleshoot_Dump_2.xml @@ -97,6 +97,10 @@ scons: Reading SConscript files ... '_LIBDIRFLAGS': '$( ${_concat(LIBDIRPREFIX, LIBPATH, LIBDIRSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)', '_LIBFLAGS': '${_concat(LIBLINKPREFIX, LIBS, LIBLINKSUFFIX, __env__)}', '_MSVC_OUTPUT_FLAG': <function msvc_output_flag at 0x700000&gt;, + '__DSHLIBVERSIONFLAGS': '${__libversionflags(__env__,"DSHLIBVERSION","_DSHLIBVERSIONFLAGS")}', + '__LDMODULEVERSIONFLAGS': '${__libversionflags(__env__,"LDMODULEVERSION","_LDMODULEVERSIONFLAGS")}', + '__SHLIBVERSIONFLAGS': '${__libversionflags(__env__,"SHLIBVERSION","_SHLIBVERSIONFLAGS")}', + '__libversionflags': <function __libversionflags at 0x700000&gt;, '_concat': <function _concat at 0x700000&gt;, '_defines': <function _defines at 0x700000&gt;, '_stripixes': <function _stripixes at 0x700000&gt;} diff --git a/doc/generated/examples/troubleshoot_explain1_3.xml b/doc/generated/examples/troubleshoot_explain1_3.xml index 246ee56..9763efe 100644 --- a/doc/generated/examples/troubleshoot_explain1_3.xml +++ b/doc/generated/examples/troubleshoot_explain1_3.xml @@ -3,5 +3,5 @@ cp file.in file.oout scons: warning: Cannot find target file.out after building -File "/home/bdbaddog/scons/as_scons/bootstrap/src/script/scons.py", line 199, in <module> +File "/home/bdbaddog/scons/scons/bootstrap/src/script/scons.py", line 199, in <module> diff --git a/doc/generated/functions.gen b/doc/generated/functions.gen index 3ad36e5..e80c1c9 100644 --- a/doc/generated/functions.gen +++ b/doc/generated/functions.gen @@ -2565,10 +2565,10 @@ sources = Glob('*.cpp', exclude=['os_*_specific_*.cpp']) + Glob('os_%s_specific_ - Help(text) + Help(text, append=False) - env.Help(text) + env.Help(text, append=False) @@ -2576,12 +2576,18 @@ This specifies help text to be printed if the argument is given to scons. -If +If Help -is called multiple times, the text is appended together in the order -that +is called multiple times, the text is appended together in the order that Help -is called. +is called. With append set to False, any +Help +text generated with +AddOption +is clobbered. If append is True, the AddOption help is prepended to the help +string, thus preserving the + +message. diff --git a/doc/generated/tools.gen b/doc/generated/tools.gen index db89475..fcb7587 100644 --- a/doc/generated/tools.gen +++ b/doc/generated/tools.gen @@ -129,6 +129,14 @@ Sets construction variables for generic POSIX C++ compilers. Sets: &cv-link-CPPDEFPREFIX;, &cv-link-CPPDEFSUFFIX;, &cv-link-CXX;, &cv-link-CXXCOM;, &cv-link-CXXFILESUFFIX;, &cv-link-CXXFLAGS;, &cv-link-INCPREFIX;, &cv-link-INCSUFFIX;, &cv-link-OBJSUFFIX;, &cv-link-SHCXX;, &cv-link-SHCXXCOM;, &cv-link-SHCXXFLAGS;, &cv-link-SHOBJSUFFIX;.Uses: &cv-link-CXXCOMSTR;. + + cyglink + + +Set construction variables for cygwin linker/loader. + +Sets: &cv-link-IMPLIBPREFIX;, &cv-link-IMPLIBSUFFIX;, &cv-link-LDMODULEVERSIONFLAGS;, &cv-link-LINKFLAGS;, &cv-link-RPATHPREFIX;, &cv-link-RPATHSUFFIX;, &cv-link-SHLIBPREFIX;, &cv-link-SHLIBSUFFIX;, &cv-link-SHLIBVERSIONFLAGS;, &cv-link-SHLINKCOM;, &cv-link-SHLINKFLAGS;, &cv-link-_LDMODULEVERSIONFLAGS;, &cv-link-_SHLIBVERSIONFLAGS;. + default @@ -395,7 +403,7 @@ Sets construction variables for the D language compiler GDC. This is actually a toolset, which supports internationalization and -localization of sofware being constructed with SCons. The toolset loads +localization of software being constructed with SCons. The toolset loads following tools: @@ -454,7 +462,7 @@ Sets construction variables for the GNU F95/F2003 GNU compiler. Set construction variables for GNU linker/loader. -Sets: &cv-link-RPATHPREFIX;, &cv-link-RPATHSUFFIX;, &cv-link-SHLINKFLAGS;. +Sets: &cv-link-LDMODULEVERSIONFLAGS;, &cv-link-RPATHPREFIX;, &cv-link-RPATHSUFFIX;, &cv-link-SHLIBVERSIONFLAGS;, &cv-link-SHLINKFLAGS;, &cv-link-_LDMODULESONAME;, &cv-link-_SHLIBSONAME;. gs @@ -623,7 +631,7 @@ Sets construction variables for the Sets construction variables for generic POSIX linkers. -Sets: &cv-link-LDMODULE;, &cv-link-LDMODULECOM;, &cv-link-LDMODULEFLAGS;, &cv-link-LDMODULEPREFIX;, &cv-link-LDMODULESUFFIX;, &cv-link-LIBDIRPREFIX;, &cv-link-LIBDIRSUFFIX;, &cv-link-LIBLINKPREFIX;, &cv-link-LIBLINKSUFFIX;, &cv-link-LINK;, &cv-link-LINKCOM;, &cv-link-LINKFLAGS;, &cv-link-SHLIBSUFFIX;, &cv-link-SHLINK;, &cv-link-SHLINKCOM;, &cv-link-SHLINKFLAGS;.Uses: &cv-link-LDMODULECOMSTR;, &cv-link-LINKCOMSTR;, &cv-link-SHLINKCOMSTR;. +Sets: &cv-link-LDMODULE;, &cv-link-LDMODULECOM;, &cv-link-LDMODULEFLAGS;, &cv-link-LDMODULENOVERSIONSYMLINKS;, &cv-link-LDMODULEPREFIX;, &cv-link-LDMODULESUFFIX;, &cv-link-LDMODULEVERSION;, &cv-link-LDMODULEVERSIONFLAGS;, &cv-link-LIBDIRPREFIX;, &cv-link-LIBDIRSUFFIX;, &cv-link-LIBLINKPREFIX;, &cv-link-LIBLINKSUFFIX;, &cv-link-LINK;, &cv-link-LINKCOM;, &cv-link-LINKFLAGS;, &cv-link-SHLIBSUFFIX;, &cv-link-SHLINK;, &cv-link-SHLINKCOM;, &cv-link-SHLINKFLAGS;, &cv-link-__LDMODULEVERSIONFLAGS;, &cv-link-__SHLIBVERSIONFLAGS;.Uses: &cv-link-LDMODULECOMSTR;, &cv-link-LINKCOMSTR;, &cv-link-SHLINKCOMSTR;. linkloc @@ -901,7 +909,7 @@ Sets construction variables for the SGI linker. Sets construction variables for the Sun library archiver. -Sets: &cv-link-AR;, &cv-link-ARCOM;, &cv-link-ARFLAGS;, &cv-link-LIBPREFIX;, &cv-link-LIBSUFFIX;, &cv-link-SHLINK;, &cv-link-SHLINKCOM;, &cv-link-SHLINKFLAGS;.Uses: &cv-link-ARCOMSTR;, &cv-link-SHLINKCOMSTR;. +Sets: &cv-link-AR;, &cv-link-ARCOM;, &cv-link-ARFLAGS;, &cv-link-LIBPREFIX;, &cv-link-LIBSUFFIX;.Uses: &cv-link-ARCOMSTR;. sunc++ diff --git a/doc/generated/tools.mod b/doc/generated/tools.mod index 5a5795a..1191e6a 100644 --- a/doc/generated/tools.mod +++ b/doc/generated/tools.mod @@ -22,6 +22,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. cvf"> CVS"> cXX"> +cyglink"> default"> dmd"> docbook"> @@ -132,6 +133,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. cvf"> CVS"> cXX"> +cyglink"> default"> dmd"> docbook"> diff --git a/doc/generated/variables.gen b/doc/generated/variables.gen index 04c3efe..3d8a87a 100644 --- a/doc/generated/variables.gen +++ b/doc/generated/variables.gen @@ -13,6 +13,24 @@ ]> + + __LDMODULEVERSIONFLAGS + + +This construction variable automatically introduces $_LDMODULEVERSIONFLAGS +if $LDMODULEVERSION is set. Othervise it evaluates to an empty string. + + + + + __SHLIBVERSIONFLAGS + + +This construction variable automatically introduces $_SHLIBVERSIONFLAGS +if $SHLIBVERSION is set. Othervise it evaluates to an empty string. + + + AR @@ -2874,6 +2892,52 @@ The default list is: + + IMPLIBNOVERSIONSYMLINKS + + +Used to override $SHLIBNOVERSIONSYMLINKS/$LDMODULENOVERSIONSYMLINKS when +creating versioned import library for a shared library/loadable module. If not defined, +then $SHLIBNOVERSIONSYMLINKS/$LDMODULENOVERSIONSYMLINKS is used to determine +whether to disable symlink generation or not. + + + + + IMPLIBPREFIX + + +The prefix used for import library names. For example, cygwin uses import +libraries (libfoo.dll.a) in pair with dynamic libraries +(cygfoo.dll). The cyglink linker sets +$IMPLIBPREFIX to 'lib' and $SHLIBPREFIX +to 'cyg'. + + + + + IMPLIBSUFFIX + + +The suffix used for import library names. For example, cygwin uses import +libraries (libfoo.dll.a) in pair with dynamic libraries +(cygfoo.dll). The cyglink linker sets +$IMPLIBSUFFIX to '.dll.a' and $SHLIBSUFFIX +to '.dll'. + + + + + IMPLIBVERSION + + +Used to override $SHLIBVERSION/$LDMODULEVERSION when +generating versioned import library for a shared library/loadable module. If +undefined, the $SHLIBVERSION/$LDMODULEVERSION is used to +determine the version of versioned import library. + + + IMPLICIT_COMMAND_DEPENDENCIES @@ -3408,6 +3472,15 @@ General user options passed to the linker for building loadable modules. + + LDMODULENOVERSIONSYMLINKS + + +Instructs the LoadableModule builder to not automatically create symlinks +for versioned modules. Defaults to $SHLIBNOVERSIONSYMLINKS + + + LDMODULEPREFIX @@ -3419,6 +3492,16 @@ the same as + _LDMODULESONAME + + +A macro that automatically generates loadable module's SONAME based on $TARGET, +$LDMODULEVERSION and $LDMODULESUFFIX. Used by LoadableModule builder +when the linker tool supports SONAME (e.g. gnulink). + + + LDMODULESUFFIX @@ -3430,6 +3513,42 @@ the same as $SHLIBSUFFIX. + + LDMODULEVERSION + + +When this construction variable is defined, a versioned loadable module +is created by LoadableModule builder. This activates the +$_LDMODULEVERSIONFLAGS and thus modifies the $LDMODULECOM as +required, adds the version number to the library name, and creates the symlinks +that are needed. $LDMODULEVERSION versions should exist in the same +format as $SHLIBVERSION. + + + + + LDMODULEVERSIONFLAGS + + +Extra flags added to $LDMODULECOM when building versioned +LoadableModule. These flags are only used when $LDMODULEVERSION is +set. + + + + + _LDMODULEVERSIONFLAGS + + +This macro automatically introduces extra flags to $LDMODULECOM when +building versioned LoadableModule (that is when +$LDMODULEVERSION is set). _LDMODULEVERSIONFLAGS +usually adds $SHLIBVERSIONFLAGS and some extra dynamically generated +options (such as -Wl,-soname=$_LDMODULESONAME). It is unused +by plain (unversioned) loadable modules. + + + LEX @@ -6385,6 +6504,15 @@ TODO + + SHLIBNOVERSIONSYMLINKS + + +Instructs the SharedLibrary builder to not create symlinks for versioned +shared libraries. + + + SHLIBPREFIX @@ -6393,6 +6521,16 @@ The prefix used for shared library file names. + + _SHLIBSONAME + + +A macro that automatically generates shared library's SONAME based on $TARGET, +$SHLIBVERSION and $SHLIBSUFFIX. Used by SharedLibrary builder when +the linker tool supports SONAME (e.g. gnulink). + + + SHLIBSUFFIX @@ -6406,11 +6544,35 @@ The suffix used for shared library file names. When this construction variable is defined, a versioned shared library -is created. This modifies the $SHLINKFLAGS as required, adds -the version number to the library name, and creates the symlinks that -are needed. $SHLIBVERSION needs to be of the form X.Y.Z, -where X and Y are numbers, and Z is a number but can also contain -letters to designate alpha, beta, or release candidate patch levels. +is created by SharedLibrary builder. This activates the +$_SHLIBVERSIONFLAGS and thus modifies the $SHLINKCOM as +required, adds the version number to the library name, and creates the symlinks +that are needed. $SHLIBVERSION versions should exist as alpha-numeric, +decimal-delimited values as defined by the regular expression "\w+[\.\w+]*". +Example $SHLIBVERSION values include '1', '1.2.3', and '1.2.gitaa412c8b'. + + + + + SHLIBVERSIONFLAGS + + +Extra flags added to $SHLINKCOM when building versioned +SharedLibrary. These flags are only used when $SHLIBVERSION is +set. + + + + + _SHLIBVERSIONFLAGS + + +This macro automatically introduces extra flags to $SHLINKCOM when +building versioned SharedLibrary (that is when $SHLIBVERSION +is set). _SHLIBVERSIONFLAGS usually adds $SHLIBVERSIONFLAGS +and some extra dynamically generated options (such as +-Wl,-soname=$_SHLIBSONAME. It is unused by "plain" +(unversioned) shared libraries. @@ -6484,6 +6646,18 @@ The suffix used for shared object file names. + + SONAME + + +Variable used to hard-code SONAME for versioned shared library/loadable module. + +env.SharedLibrary('test', 'test.c', SHLIBVERSION='0.1.2', SONAME='libtest.so.2') + +The variable is used, for example, by gnulink linker tool. + + + SOURCE diff --git a/doc/generated/variables.mod b/doc/generated/variables.mod index fc12a92..f7303f2 100644 --- a/doc/generated/variables.mod +++ b/doc/generated/variables.mod @@ -8,6 +8,8 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. --> +$__LDMODULEVERSIONFLAGS"> +$__SHLIBVERSIONFLAGS"> $AR"> $ARCHITECTURE"> $ARCOM"> @@ -216,6 +218,10 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. $HOST_ARCH"> $HOST_OS"> $IDLSUFFIXES"> +$IMPLIBNOVERSIONSYMLINKS"> +$IMPLIBPREFIX"> +$IMPLIBSUFFIX"> +$IMPLIBVERSION"> $IMPLICIT_COMMAND_DEPENDENCIES"> $INCPREFIX"> $INCSUFFIX"> @@ -253,8 +259,13 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. $LDMODULECOM"> $LDMODULECOMSTR"> $LDMODULEFLAGS"> +$LDMODULENOVERSIONSYMLINKS"> $LDMODULEPREFIX"> +$_LDMODULESONAME"> $LDMODULESUFFIX"> +$LDMODULEVERSION"> +$LDMODULEVERSIONFLAGS"> +$_LDMODULEVERSIONFLAGS"> $LEX"> $LEXCOM"> $LEXCOMSTR"> @@ -505,15 +516,20 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. $SHFORTRANPPCOM"> $SHFORTRANPPCOMSTR"> $SHLIBEMITTER"> +$SHLIBNOVERSIONSYMLINKS"> $SHLIBPREFIX"> +$_SHLIBSONAME"> $SHLIBSUFFIX"> $SHLIBVERSION"> +$SHLIBVERSIONFLAGS"> +$_SHLIBVERSIONFLAGS"> $SHLINK"> $SHLINKCOM"> $SHLINKCOMSTR"> $SHLINKFLAGS"> $SHOBJPREFIX"> $SHOBJSUFFIX"> +$SONAME"> $SOURCE"> $SOURCE_URL"> $SOURCES"> @@ -646,6 +662,8 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. --> +$__LDMODULEVERSIONFLAGS"> +$__SHLIBVERSIONFLAGS"> $AR"> $ARCHITECTURE"> $ARCOM"> @@ -854,6 +872,10 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. $HOST_ARCH"> $HOST_OS"> $IDLSUFFIXES"> +$IMPLIBNOVERSIONSYMLINKS"> +$IMPLIBPREFIX"> +$IMPLIBSUFFIX"> +$IMPLIBVERSION"> $IMPLICIT_COMMAND_DEPENDENCIES"> $INCPREFIX"> $INCSUFFIX"> @@ -891,8 +913,13 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. $LDMODULECOM"> $LDMODULECOMSTR"> $LDMODULEFLAGS"> +$LDMODULENOVERSIONSYMLINKS"> $LDMODULEPREFIX"> +$_LDMODULESONAME"> $LDMODULESUFFIX"> +$LDMODULEVERSION"> +$LDMODULEVERSIONFLAGS"> +$_LDMODULEVERSIONFLAGS"> $LEX"> $LEXCOM"> $LEXCOMSTR"> @@ -1143,15 +1170,20 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. $SHFORTRANPPCOM"> $SHFORTRANPPCOMSTR"> $SHLIBEMITTER"> +$SHLIBNOVERSIONSYMLINKS"> $SHLIBPREFIX"> +$_SHLIBSONAME"> $SHLIBSUFFIX"> $SHLIBVERSION"> +$SHLIBVERSIONFLAGS"> +$_SHLIBVERSIONFLAGS"> $SHLINK"> $SHLINKCOM"> $SHLINKCOMSTR"> $SHLINKFLAGS"> $SHOBJPREFIX"> $SHOBJSUFFIX"> +$SONAME"> $SOURCE"> $SOURCE_URL"> $SOURCES"> diff --git a/doc/user/output.xml b/doc/user/output.xml index cdb28d7..78dcca4 100644 --- a/doc/user/output.xml +++ b/doc/user/output.xml @@ -83,6 +83,21 @@ Type: 'scons program' to build the production program, + Optionally, one can specify the append flag: + + + + + +Help(""" +Type: 'scons program' to build the production program, + 'scons debug' to build the debug version. +""", append=True) + + + + + (Note the above use of the Python triple-quote syntax, which comes in very handy for specifying multi-line strings like help text.) @@ -120,6 +135,13 @@ Type: 'scons program' to build the production program, + When used with &AddOption; Help("text", append=False) will clobber any help output associated with AddOption(). + To preserve the help output from AddOption(), set append=True. + + + + + Another use would be to make the help text conditional on some variable. For example, suppose you only want to display diff --git a/src/engine/SCons/Script/SConscript.xml b/src/engine/SCons/Script/SConscript.xml index c74ad5e..8553fbe 100644 --- a/src/engine/SCons/Script/SConscript.xml +++ b/src/engine/SCons/Script/SConscript.xml @@ -240,7 +240,7 @@ file is found. -(text) +(text, append=False) @@ -248,12 +248,18 @@ This specifies help text to be printed if the argument is given to &scons;. -If +If &f-Help; -is called multiple times, the text is appended together in the order -that +is called multiple times, the text is appended together in the order that &f-Help; -is called. +is called. With append set to False, any +&f-Help; +text generated with +&f-AddOption; +is clobbered. If append is True, the AddOption help is prepended to the help +string, thus preserving the + +message. -- cgit v0.12 From 0a76f5e2f9a3b55995014fc18881bdb068765817 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Tue, 29 Sep 2015 08:52:43 -0700 Subject: Removed 'Local Build Variables:' from output when append flag for help is True. This change breaks a bunch of tests and isn't core to the bug itself --- src/engine/SCons/Script/__init__.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/engine/SCons/Script/__init__.py b/src/engine/SCons/Script/__init__.py index 4dcd055..6bfc36f 100644 --- a/src/engine/SCons/Script/__init__.py +++ b/src/engine/SCons/Script/__init__.py @@ -269,10 +269,16 @@ def HelpFunction(text, append=False): help_text = s.getvalue() s.close() else: - help_text = "" - help_text = help_text + "\nLocal Build Variables:\n" + text - else: - help_text = help_text + text + help_text = "" +# +# Was in original patch but this text is arbitrary and breaks tests +# so I removed it (Deegan) +# help_text = help_text + "\nLocal Build Variables:\n" + text +# else: +# help_text = help_text + text + + help_text= help_text + text + # # Will be non-zero if we are reading an SConscript file. -- cgit v0.12 From a0a71904847f0ea0434bdce3a93dd730bd2a0bbb Mon Sep 17 00:00:00 2001 From: William Deegan Date: Tue, 29 Sep 2015 08:54:32 -0700 Subject: test for pull request #226 bug #2831 --- test/Help.py | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/test/Help.py b/test/Help.py index 747fe59..693fd28 100644 --- a/test/Help.py +++ b/test/Help.py @@ -82,6 +82,69 @@ Use scons -H for help about command-line options. test.run(arguments = '-h', stdout = expect) +# Bug #2831 - append flag to Help doesn't wipe out addoptions and variables used together +test.write('SConstruct', r""" + +AddOption('--debugging', + dest='debugging', + action='store_true', + default=False, + metavar='BDEBUGGING', + help='Compile with debugging symbols') + +vars = Variables() +vars.Add(ListVariable('buildmod', 'List of modules to build', 'none', + ['python'])) + +env = Environment() + +Help(vars.GenerateHelpText(env),append=True) +""") + +expect = ".*--debugging.*Compile with debugging symbols.*buildmod: List of modules to build.*" + +test.run(arguments = '-h', stdout = expect, match=TestSCons.match_re_dotall) + + +# Bug 2831 +# This test checks to verify that append=False doesn't include anything +# but the expected help for the specified Variable() + +test.write('SConstruct', r""" + +AddOption('--debugging', + dest='debugging', + action='store_true', + default=False, + metavar='BDEBUGGING', + help='Compile with debugging symbols') + +vars = Variables() +vars.Add(ListVariable('buildmod', 'List of modules to build', 'none', + ['python'])) + +env = Environment() + +Help(vars.GenerateHelpText(env),append=False) +""") + +expect = """\ +scons: Reading SConscript files ... +scons: done reading SConscript files. + +buildmod: List of modules to build + (all|none|comma-separated list of names) + allowed names: python + default: none + actual: None + +Use scons -H for help about command-line options. +""" + +test.run(arguments = '-h', stdout = expect) + + + test.pass_test() # Local Variables: -- cgit v0.12 From 47dfbcf847f63eb6b22c8579cf125b54d3166414 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Tue, 29 Sep 2015 08:59:18 -0700 Subject: Moved Dirks changes.txt change for fixin SVG license into the 2.4.1 section of CHANGES.txt --- src/CHANGES.txt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 11fdeba..bafd0d1 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -43,6 +43,11 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER - Library versioning is currently implemented for the following linker tools: 'cyglink', 'gnulink', 'sunlink'. + From Dirk Baechle: + - Fixed license of SVG titlepage files in the context of Debian + packaging, such that they allow for commercial use too (#2985). + + RELEASE 2.4.0 - Mon, 21 Sep 2015 08:56:00 -0700 From Dirk Baechle: @@ -81,8 +86,6 @@ RELEASE 2.3.5 - Mon, 17 Jun 2015 21:07:32 -0700 From Dirk Baechle: - Added new method rentry_exists_on_disk to Node.FS (PR #193). - - Fixed license of SVG titlepage files in the context of Debian - packaging, such that they allow for commercial use too (#2985). From Russel Winder: - Fixed several D tests under the different OS. -- cgit v0.12 From 935b462d736bc8d9622bd9719a83cacf5d406d53 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Tue, 29 Sep 2015 09:36:48 -0700 Subject: fix test which was verifying that PrintHelp wasn't in SCons.script because at some point in the past there was such a function which was removed. Pull request #226 for bug #2831 restored/recreated a same named function and broke this test --- test/Script-import.py | 1 - 1 file changed, 1 deletion(-) diff --git a/test/Script-import.py b/test/Script-import.py index 98ae271..504de0e 100644 --- a/test/Script-import.py +++ b/test/Script-import.py @@ -62,7 +62,6 @@ SCons.Script.CleanTask SCons.Script.QuestionTask old_SCons_Script_variables = [ - 'PrintHelp', 'OptParser', 'keep_going_on_error', 'print_explanations', -- cgit v0.12 From 739878908fb7b8ffae09804369069ee33056dec5 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Tue, 29 Sep 2015 09:53:39 -0700 Subject: added emacs temp files to hgignore --- .hgignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgignore b/.hgignore index dcc9505..a56960d 100644 --- a/.hgignore +++ b/.hgignore @@ -10,6 +10,7 @@ syntax:glob *.xcodeproj *.orig *.DS_Store +*# doc/user/scons-user doc/user/scons_db.xml -- cgit v0.12 From 089b32203cb485b9115f03f35d2b437e848c78da Mon Sep 17 00:00:00 2001 From: William Deegan Date: Tue, 29 Sep 2015 11:22:17 -0700 Subject: Fix failing LEX/live.py because no return type was specified for main and apple compiler/flex complains about it in stderr --- test/LEX/live.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test/LEX/live.py b/test/LEX/live.py index f50b06f..e4b4dfb 100644 --- a/test/LEX/live.py +++ b/test/LEX/live.py @@ -68,6 +68,7 @@ yywrap() return 1; } +int main() { yylex(); -- cgit v0.12 From 2355e88c9637174f10c3dec3efb15ee6626fb3e5 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Tue, 29 Sep 2015 12:05:35 -0700 Subject: fix test to run on macosx by fixing C99 non compliance --- test/RANLIB/RANLIB.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/RANLIB/RANLIB.py b/test/RANLIB/RANLIB.py index c9fc10f..fbfe36c 100644 --- a/test/RANLIB/RANLIB.py +++ b/test/RANLIB/RANLIB.py @@ -81,6 +81,10 @@ library_function(void) test.write('main.c', r""" #include + +void +library_function(void); + int main(int argc, char *argv[]) { -- cgit v0.12 From 6ea319bd567743546bb77c6440ddb80d9a63b3cb Mon Sep 17 00:00:00 2001 From: William Deegan Date: Tue, 29 Sep 2015 12:35:18 -0700 Subject: fix C99 non compliance --- test/RANLIB/RANLIBFLAGS.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/RANLIB/RANLIBFLAGS.py b/test/RANLIB/RANLIBFLAGS.py index 636059b..86e5283 100644 --- a/test/RANLIB/RANLIBFLAGS.py +++ b/test/RANLIB/RANLIBFLAGS.py @@ -82,6 +82,10 @@ library_function(void) test.write('main.c', r""" #include +void +library_function(void); + + int main(int argc, char *argv[]) { -- cgit v0.12 From f067b35d278ddafcc4e48668f0eade10c71a69c0 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Tue, 29 Sep 2015 13:18:21 -0700 Subject: add another possible path for JAVA_HOME on OSX --- QMTest/TestSCons.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/QMTest/TestSCons.py b/QMTest/TestSCons.py index 06fa575..75bf395 100644 --- a/QMTest/TestSCons.py +++ b/QMTest/TestSCons.py @@ -714,6 +714,9 @@ class TestSCons(TestCommon): home = '/System/Library/Frameworks/JavaVM.framework/Home' else: home = '/System/Library/Frameworks/JavaVM.framework/Versions/%s/Home' % version + if not os.path.exists(home): + # This works on OSX 10.10 + home = '/System/Library/Frameworks/JavaVM.framework/Versions/Current/' else: jar = self.java_where_jar(version) home = os.path.normpath('%s/..'%jar) -- cgit v0.12 From c4fc0ad2e86ca03de81332cc984db0e0ccd98959 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Tue, 29 Sep 2015 13:22:24 -0700 Subject: Pull request # 234 (Bug #2840) code checkin. No tests yet --- src/engine/SCons/Builder.py | 6 +++--- test/CPPDEFINES/pkg-config.py | 11 ++++++----- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/engine/SCons/Builder.py b/src/engine/SCons/Builder.py index 769b15d..52a592b 100644 --- a/src/engine/SCons/Builder.py +++ b/src/engine/SCons/Builder.py @@ -292,9 +292,9 @@ def _node_errors(builder, env, tlist, slist): if t.has_explicit_builder(): if not t.env is None and not t.env is env: action = t.builder.action - t_contents = action.get_contents(tlist, slist, t.env) - contents = action.get_contents(tlist, slist, env) - + t_contents = t.builder.action.get_contents(tlist, slist, t.env) + contents = builder.action.get_contents(tlist, slist, env) + if t_contents == contents: msg = "Two different environments were specified for target %s,\n\tbut they appear to have the same action: %s" % (t, action.genstring(tlist, slist, t.env)) SCons.Warnings.warn(SCons.Warnings.DuplicateEnvironmentWarning, msg) diff --git a/test/CPPDEFINES/pkg-config.py b/test/CPPDEFINES/pkg-config.py index 0656900..1b308d3 100644 --- a/test/CPPDEFINES/pkg-config.py +++ b/test/CPPDEFINES/pkg-config.py @@ -32,7 +32,8 @@ import TestSCons test = TestSCons.TestSCons() -if not test.where_is('pkg-config'): +pkg_config_path = test.where_is('pkg-config') +if not pkg_config_path: test.skip_test("Could not find 'pkg-config' in system PATH, skipping test.\n") test.write('bug.pc', """\ @@ -58,7 +59,7 @@ test.write('SConstruct', """\ # http://scons.tigris.org/issues/show_bug.cgi?id=2671 # Passing test cases env_1 = Environment(CPPDEFINES=[('DEBUG','1'), 'TEST']) -env_1.ParseConfig('PKG_CONFIG_PATH=. pkg-config --cflags bug') +env_1.ParseConfig('PKG_CONFIG_PATH=. %(pkg_config_path)s --cflags bug') print env_1.subst('$_CPPDEFFLAGS') env_2 = Environment(CPPDEFINES=[('DEBUG','1'), 'TEST']) @@ -67,7 +68,7 @@ print env_2.subst('$_CPPDEFFLAGS') # Failing test cases env_3 = Environment(CPPDEFINES={'DEBUG':1, 'TEST':None}) -env_3.ParseConfig('PKG_CONFIG_PATH=. pkg-config --cflags bug') +env_3.ParseConfig('PKG_CONFIG_PATH=. %(pkg_config_path)s --cflags bug') print env_3.subst('$_CPPDEFFLAGS') env_4 = Environment(CPPDEFINES={'DEBUG':1, 'TEST':None}) @@ -76,10 +77,10 @@ print env_4.subst('$_CPPDEFFLAGS') # http://scons.tigris.org/issues/show_bug.cgi?id=1738 env_1738_1 = Environment(tools=['default']) -env_1738_1.ParseConfig('PKG_CONFIG_PATH=. pkg-config --cflags --libs bug') +env_1738_1.ParseConfig('PKG_CONFIG_PATH=. %(pkg_config_path)s --cflags --libs bug') env_1738_1.Append(CPPDEFINES={'value' : '1'}) print env_1738_1.subst('$_CPPDEFFLAGS') -""") +"""%locals() ) expect_print_output="""\ -DDEBUG=1 -DTEST -DSOMETHING -DVARIABLE=2 -- cgit v0.12 From 9794cbe901096e0835bd4db0958826ec9ed316f4 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Tue, 29 Sep 2015 15:20:11 -0700 Subject: Revised pull request #234 fixing bug 2840. Andrew Featherstone had code changes, but no test --- src/CHANGES.txt | 5 ++++ src/engine/SCons/Builder.py | 1 + test/Builder/different-actions.py | 56 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+) create mode 100644 test/Builder/different-actions.py diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 47a3f97..e27f978 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -18,6 +18,11 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER - Added new configure check, CheckProg, to check for existence of a program. + From Andrew Featherstone: + - Fix for issue #2840 - Fix for two environments specifying same target with different + actions not throwing hard error. Instead SCons was incorrectly issuing a warning + and continuing. + From Florian Miedniak: - Fixed tigris issue #3011: Glob() excludes didn't work when used with VariantDir(duplicate=0) diff --git a/src/engine/SCons/Builder.py b/src/engine/SCons/Builder.py index 52a592b..c86012b 100644 --- a/src/engine/SCons/Builder.py +++ b/src/engine/SCons/Builder.py @@ -292,6 +292,7 @@ def _node_errors(builder, env, tlist, slist): if t.has_explicit_builder(): if not t.env is None and not t.env is env: action = t.builder.action + t_contents = t.builder.action.get_contents(tlist, slist, t.env) contents = builder.action.get_contents(tlist, slist, env) diff --git a/test/Builder/different-actions.py b/test/Builder/different-actions.py new file mode 100644 index 0000000..33a1363 --- /dev/null +++ b/test/Builder/different-actions.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Verify that two builders in two environments with different +actions generate an error. +""" + +import TestSCons + +test = TestSCons.TestSCons(match=TestSCons.match_re) + +test.write('SConstruct', """\ +e1 = Environment() +e2 = Environment() + +e1.Command('out.txt', [], 'echo 1 > $TARGET') +e2.Command('out.txt', [], 'echo 2 > $TARGET') +""") + +expect = TestSCons.re_escape(""" +scons: *** Two environments with different actions were specified for the same target: out.txt +""") + TestSCons.file_expr + +test.run(arguments='out.txt', status=2, stderr=expect) + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: -- cgit v0.12 From 7a02c48b0d3e29f4f24b0a3fec8fc566a131a66d Mon Sep 17 00:00:00 2001 From: William Deegan Date: Tue, 29 Sep 2015 15:58:10 -0700 Subject: fix CheckProg test to work on win32 --- src/engine/SCons/SConfTests.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/engine/SCons/SConfTests.py b/src/engine/SCons/SConfTests.py index 57a9d04..c9df0be 100644 --- a/src/engine/SCons/SConfTests.py +++ b/src/engine/SCons/SConfTests.py @@ -620,8 +620,14 @@ int main() { log_file=self.test.workpath('config.log')) try: - r = sconf.CheckProg('sh') - assert r, "/bin/sh" + if os.name != 'nt': + r = sconf.CheckProg('sh') + assert r, "/bin/sh" + else: + r = sconf.CheckProg('cmd.exe') + assertIn('cmd.exe',r) + + r = sconf.CheckProg('hopefully-not-a-program') assert r is None -- cgit v0.12 From 94c7bf6f844758f8f9a3b993bae88e91fc1fe452 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Wed, 30 Sep 2015 19:42:56 -0400 Subject: fix broken on windows test in SConfTest.py --- src/engine/SCons/SConfTests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/SCons/SConfTests.py b/src/engine/SCons/SConfTests.py index c9df0be..9bdfceb 100644 --- a/src/engine/SCons/SConfTests.py +++ b/src/engine/SCons/SConfTests.py @@ -625,7 +625,7 @@ int main() { assert r, "/bin/sh" else: r = sconf.CheckProg('cmd.exe') - assertIn('cmd.exe',r) + self.assertIn('cmd.exe',r) r = sconf.CheckProg('hopefully-not-a-program') -- cgit v0.12 From 615a3429f4ad7aef9d3ffb19a56c26ebb8a2b1cf Mon Sep 17 00:00:00 2001 From: William Blevins Date: Thu, 1 Oct 2015 13:31:34 +0100 Subject: Corrected hgignore regex for emacs temporary files. --- .hgignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.hgignore b/.hgignore index a56960d..3e16531 100644 --- a/.hgignore +++ b/.hgignore @@ -10,7 +10,7 @@ syntax:glob *.xcodeproj *.orig *.DS_Store -*# +*\# doc/user/scons-user doc/user/scons_db.xml -- cgit v0.12 From 4bac666bb4f85f0efe0b4002a527c9f4b510c306 Mon Sep 17 00:00:00 2001 From: William Blevins Date: Thu, 1 Oct 2015 13:37:41 +0100 Subject: Code cleanup: removed function for supporting relpath in pre-2.6 python. --- src/engine/SCons/Tool/GettextCommon.py | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/src/engine/SCons/Tool/GettextCommon.py b/src/engine/SCons/Tool/GettextCommon.py index cd2f306..bdd52c0 100644 --- a/src/engine/SCons/Tool/GettextCommon.py +++ b/src/engine/SCons/Tool/GettextCommon.py @@ -306,23 +306,6 @@ class RPaths(object): - 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 = () @@ -330,7 +313,7 @@ class RPaths(object): for node in nodes: rpath = None if isinstance(node, SCons.Node.FS.Base): - rpath = relpath(node.get_abspath(), cwd) + rpath = os.path.relpath(node.get_abspath(), cwd) # FIXME: Other types possible here? if rpath is not None: rpaths += (rpath,) -- cgit v0.12 From 139c0c0bf9e1d5a789a05628dee7efddd5dfbfbe Mon Sep 17 00:00:00 2001 From: William Deegan Date: Thu, 1 Oct 2015 17:44:15 -0400 Subject: Bug # 2791 - minor change to setup.py makes the package installable with jython. Seems better to check if the current system has the capabilities needed by the logic than to look for posix --- src/setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/setup.py b/src/setup.py index fb16bdd..91b7752 100644 --- a/src/setup.py +++ b/src/setup.py @@ -343,7 +343,7 @@ class install_scripts(_install_scripts): self.copy_scons(src, scons_version_bat) # --- distutils copy/paste --- - if os.name == 'posix': + if hasattr(os, 'chmod') and hasattr(os,'stat'): # Set the executable bits (owner, group, and world) on # all the scripts we just installed. for file in self.get_outputs(): -- cgit v0.12 From e906e28a107c1db871d79745de2798a3d0992900 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Thu, 1 Oct 2015 18:16:59 -0400 Subject: update Changes for bug 2791 --- src/CHANGES.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index e27f978..5c2d8d3 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -6,6 +6,9 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER + From Arfrever Frehtes Taifersar Arahesis: + - Fix for Bug # 2791 - Setup.py fails unnecessarily under Jython. + From Dirk Baechle: - Fixed license of SVG titlepage files in the context of Debian packaging, such that they allow for commercial use too (#2985). -- cgit v0.12 From 080663ec198503579048f297f2a4c154d13d169d Mon Sep 17 00:00:00 2001 From: William Deegan Date: Fri, 2 Oct 2015 10:16:00 -0400 Subject: Add changelog for pull request #222 --- src/CHANGES.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 5c2d8d3..e67de21 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -26,6 +26,10 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER actions not throwing hard error. Instead SCons was incorrectly issuing a warning and continuing. + From Hiroaki Itoh : + - Add support `Microsoft Visual C++ Compiler for Python 2.7' + Compiler can be obtained at: https://www.microsoft.com/en-us/download/details.aspx?id=44266 + From Florian Miedniak: - Fixed tigris issue #3011: Glob() excludes didn't work when used with VariantDir(duplicate=0) -- cgit v0.12 From ee7a6695240de8f36b24d2bd024da76617ec7890 Mon Sep 17 00:00:00 2001 From: Pawel Tomulik Date: Sat, 17 Oct 2015 09:25:16 +0200 Subject: small enchancement to swig tool --- src/engine/SCons/Tool/swig.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/engine/SCons/Tool/swig.py b/src/engine/SCons/Tool/swig.py index a315182..8828ef1 100644 --- a/src/engine/SCons/Tool/swig.py +++ b/src/engine/SCons/Tool/swig.py @@ -44,6 +44,8 @@ import SCons.Tool import SCons.Util import SCons.Node +swigs = [ 'swig', 'swig3.0', 'swig2.0' ] + SwigAction = SCons.Action.Action('$SWIGCOM', '$SWIGCOMSTR') def swigSuffixEmitter(env, source): @@ -160,7 +162,8 @@ def generate(env): java_file.add_action('.i', SwigAction) java_file.add_emitter('.i', _swigEmitter) - env['SWIG'] = 'swig' + if 'SWIG' not in env: + env['SWIG'] = env.Detect(swigs) or swigs[0] env['SWIGVERSION'] = _get_swig_version(env) env['SWIGFLAGS'] = SCons.Util.CLVar('') env['SWIGDIRECTORSUFFIX'] = '_wrap.h' -- cgit v0.12 From bf2c481c10c280ecc352c7ea0ca45d8304a5f7d3 Mon Sep 17 00:00:00 2001 From: Pawel Tomulik Date: Sun, 18 Oct 2015 17:57:26 +0200 Subject: add blurb to src/CHANGES.txt for PR #270 --- src/CHANGES.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index e67de21..823eb4b 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -6,6 +6,10 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER + From Paweł Tomulik: + - Fix to swig tool - pick-up 'swig', 'swig3.0' and 'swig2.0' (in order). + - Fix to swig tool - respect env['SWIG'] provided by user. + From Arfrever Frehtes Taifersar Arahesis: - Fix for Bug # 2791 - Setup.py fails unnecessarily under Jython. -- cgit v0.12 From 3cde69b6fb17c84aaf4fca368feb63cefd44ce97 Mon Sep 17 00:00:00 2001 From: Pawel Tomulik Date: Mon, 19 Oct 2015 20:11:36 +0200 Subject: edit test/SWIG/SWIG.py to covert PR #270 --- test/SWIG/SWIG.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/test/SWIG/SWIG.py b/test/SWIG/SWIG.py index 96e00e7..d53fa49 100644 --- a/test/SWIG/SWIG.py +++ b/test/SWIG/SWIG.py @@ -43,10 +43,20 @@ if not python: test.write('myswig.py', r""" import getopt import sys -opts, args = getopt.getopt(sys.argv[1:], 'c:o:') +opts, args = getopt.getopt(sys.argv[1:], 'c:o:v:') for opt, arg in opts: if opt == '-c': pass elif opt == '-o': out = arg + elif opt == '-v' and arg == 'ersion': + print "" + print "SWIG Version 0.1.2" + print "" + print "Compiled with g++ [x86_64-pc-linux-gnu]" + print "" + print "Configured options: +pcre" + print "" + print "Please see http://www.swig.org for reporting bugs and further information" + sys.exit(0) infile = open(args[0], 'rb') outfile = open(out, 'wb') for l in infile.readlines(): @@ -58,6 +68,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'swig'], SWIG = [r'%(python)s', 'myswig.py']) +print env.subst("Using SWIG $SWIGVERSION") env.Program(target = 'test1', source = 'test1.i') env.CFile(target = 'test2', source = 'test2.i') env.Clone(SWIGFLAGS = '-c++').Program(target = 'test3', source = 'test3.i') @@ -91,7 +102,7 @@ main(int argc, char *argv[]) { swig """) -test.run(arguments = '.', stderr = None) +test.run(arguments = '.', stderr = None, stdout = r'.*Using SWIG 0.1.2.*', match = TestSCons.match_re_dotall) test.run(program = test.workpath('test1' + _exe), stdout = "test1.i\n") test.must_exist(test.workpath('test1_wrap.c')) -- cgit v0.12 From f1f51552641c5137d5196b962446dfe2f7236995 Mon Sep 17 00:00:00 2001 From: Pawel Tomulik Date: Mon, 19 Oct 2015 20:13:55 +0200 Subject: fix swig tool to properly retrieve swig version --- src/engine/SCons/Tool/swig.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/engine/SCons/Tool/swig.py b/src/engine/SCons/Tool/swig.py index 8828ef1..44686ef 100644 --- a/src/engine/SCons/Tool/swig.py +++ b/src/engine/SCons/Tool/swig.py @@ -130,9 +130,10 @@ def _swigEmitter(target, source, env): target.extend(java_files) return (target, source) -def _get_swig_version(env): +def _get_swig_version(env, swig): """Run the SWIG command line tool to get and return the version number""" - pipe = SCons.Action._subproc(env, [env['SWIG'], '-version'], + swig = env.subst(swig) + pipe = SCons.Action._subproc(env, SCons.Util.CLVar(swig) + ['-version'], stdin = 'devnull', stderr = 'devnull', stdout = subprocess.PIPE) @@ -164,7 +165,7 @@ def generate(env): if 'SWIG' not in env: env['SWIG'] = env.Detect(swigs) or swigs[0] - env['SWIGVERSION'] = _get_swig_version(env) + env['SWIGVERSION'] = _get_swig_version(env, env['SWIG']) env['SWIGFLAGS'] = SCons.Util.CLVar('') env['SWIGDIRECTORSUFFIX'] = '_wrap.h' env['SWIGCFILESUFFIX'] = '_wrap$CFILESUFFIX' -- cgit v0.12 From c2428e8d97e15df9ca267f2dc574158cd9a0d8ac Mon Sep 17 00:00:00 2001 From: William Deegan Date: Wed, 21 Oct 2015 17:53:28 -0700 Subject: Kick buildbot --- README.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/README.rst b/README.rst index 05be712..35ead76 100644 --- a/README.rst +++ b/README.rst @@ -750,3 +750,4 @@ many contributors, including but not at all limited to: Copyright (c) 2001 - 2015 The SCons Foundation + -- cgit v0.12 From 8fb4d9a12e7924c40357ba748d1ce71981cb975f Mon Sep 17 00:00:00 2001 From: William Deegan Date: Thu, 22 Oct 2015 07:41:51 -0700 Subject: Kick buildbot --- README.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/README.rst b/README.rst index 35ead76..05be712 100644 --- a/README.rst +++ b/README.rst @@ -750,4 +750,3 @@ many contributors, including but not at all limited to: Copyright (c) 2001 - 2015 The SCons Foundation - -- cgit v0.12 From dec3978a72f6d65a0a8c8e4e180ff7b658c9f630 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 9 Nov 2015 09:30:07 -0800 Subject: merge changes from 2.4.1 release to default --- QMTest/TestSCons.py | 2 +- README.rst | 34 ++++----- ReleaseConfig | 2 +- SConstruct | 4 +- debian/changelog | 6 ++ doc/generated/examples/caching_ex-random_1.xml | 2 +- .../examples/commandline_Variables_Help_1.xml | 2 - doc/generated/examples/output_ex1_1.xml | 2 - doc/generated/examples/output_ex2_1.xml | 2 - doc/generated/examples/output_ex2_2.xml | 2 - doc/generated/examples/troubleshoot_explain1_3.xml | 2 +- doc/generated/tools.gen | 12 +-- doc/generated/tools.mod | 4 +- doc/generated/variables.gen | 20 ++--- doc/generated/variables.mod | 4 +- src/Announce.txt | 79 ++++++++++++++++--- src/CHANGES.txt | 8 +- src/RELEASE.txt | 88 +++++++++++----------- 18 files changed, 161 insertions(+), 114 deletions(-) diff --git a/QMTest/TestSCons.py b/QMTest/TestSCons.py index 75bf395..ef70261 100644 --- a/QMTest/TestSCons.py +++ b/QMTest/TestSCons.py @@ -34,7 +34,7 @@ from TestCmd import PIPE # here provides some independent verification that what we packaged # conforms to what we expect. -default_version = '2.4.0' +default_version = '2.4.1' python_version_unsupported = (2, 3, 0) python_version_deprecated = (2, 7, 0) diff --git a/README.rst b/README.rst index 05be712..a2b15a6 100644 --- a/README.rst +++ b/README.rst @@ -156,7 +156,7 @@ Or on Windows:: By default, the above commands will do the following: -- Install the version-numbered "scons-2.4.0" and "sconsign-2.4.0" scripts in +- Install the version-numbered "scons-2.4.1" and "sconsign-2.4.1" scripts in the default system script directory (/usr/bin or C:\\Python\*\\Scripts, for example). This can be disabled by specifying the "--no-version-script" option on the command line. @@ -168,16 +168,16 @@ By default, the above commands will do the following: before making it the default on your system. On UNIX or Linux systems, you can have the "scons" and "sconsign" scripts be - hard links or symbolic links to the "scons-2.4.0" and "sconsign-2.4.0" + hard links or symbolic links to the "scons-2.4.1" and "sconsign-2.4.1" scripts by specifying the "--hardlink-scons" or "--symlink-scons" options on the command line. -- Install "scons-2.4.0.bat" and "scons.bat" wrapper scripts in the Python +- Install "scons-2.4.1.bat" and "scons.bat" wrapper scripts in the Python prefix directory on Windows (C:\\Python\*, for example). This can be disabled by specifying the "--no-install-bat" option on the command line. On UNIX or Linux systems, the "--install-bat" option may be specified to - have "scons-2.4.0.bat" and "scons.bat" files installed in the default system + have "scons-2.4.1.bat" and "scons.bat" files installed in the default system script directory, which is useful if you want to install SCons in a shared file system directory that can be used to execute SCons from both UNIX/Linux and Windows systems. @@ -462,7 +462,7 @@ running all of "runtest.py -a". Building Packages ================= -We use SCons (version 2.4.0 or later) to build its own packages. If you +We use SCons (version 2.4.1 or later) to build its own packages. If you already have an appropriate version of SCons installed on your system, you can build everything by simply running it:: @@ -477,18 +477,18 @@ about `Executing SCons Without Installing`_):: Depending on the utilities installed on your system, any or all of the following packages will be built:: - build/dist/scons-2.4.0-1.noarch.rpm - build/dist/scons-2.4.0-1.src.rpm - build/dist/scons-2.4.0.linux-i686.tar.gz - build/dist/scons-2.4.0.tar.gz - build/dist/scons-2.4.0.win32.exe - build/dist/scons-2.4.0.zip - build/dist/scons-doc-2.4.0.tar.gz - build/dist/scons-local-2.4.0.tar.gz - build/dist/scons-local-2.4.0.zip - build/dist/scons-src-2.4.0.tar.gz - build/dist/scons-src-2.4.0.zip - build/dist/scons_2.4.0-1_all.deb + build/dist/scons-2.4.1-1.noarch.rpm + build/dist/scons-2.4.1-1.src.rpm + build/dist/scons-2.4.1.linux-i686.tar.gz + build/dist/scons-2.4.1.tar.gz + build/dist/scons-2.4.1.win32.exe + build/dist/scons-2.4.1.zip + build/dist/scons-doc-2.4.1.tar.gz + build/dist/scons-local-2.4.1.tar.gz + build/dist/scons-local-2.4.1.zip + build/dist/scons-src-2.4.1.tar.gz + build/dist/scons-src-2.4.1.zip + build/dist/scons_2.4.1-1_all.deb The SConstruct file is supposed to be smart enough to avoid trying to build packages for which you don't have the proper utilities installed. For diff --git a/ReleaseConfig b/ReleaseConfig index 6194438..4396248 100644 --- a/ReleaseConfig +++ b/ReleaseConfig @@ -32,7 +32,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" # 'final', the patchlevel is set to the release date. This value is # mandatory and must be present in this file. #version_tuple = (2, 2, 0, 'final', 0) -version_tuple = (2, 4, 1, 'alpha', 0) +version_tuple = (2, 4, 1) # Python versions prior to unsupported_python_version cause a fatal error # when that version is used. Python versions prior to deprecate_python_version diff --git a/SConstruct b/SConstruct index 4bff134..79249e9 100644 --- a/SConstruct +++ b/SConstruct @@ -6,7 +6,7 @@ copyright_years = '2001 - 2015' # This gets inserted into the man pages to reflect the month of release. -month_year = 'September 2015' +month_year = 'November 2015' # # __COPYRIGHT__ @@ -43,7 +43,7 @@ import tempfile import bootstrap project = 'scons' -default_version = '2.4.0' +default_version = '2.4.1' copyright = "Copyright (c) %s The SCons Foundation" % copyright_years platform = distutils.util.get_platform() diff --git a/debian/changelog b/debian/changelog index 7311f78..9d60e3a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +scons (2.4.1) unstable; urgency=low + + * Maintenance release. + + -- William Deegan Sat, 07 Nov 2015 08:56:00 -0700 + scons (2.4.0) unstable; urgency=low * Maintenance release. diff --git a/doc/generated/examples/caching_ex-random_1.xml b/doc/generated/examples/caching_ex-random_1.xml index 904e1dd..6a0337b 100644 --- a/doc/generated/examples/caching_ex-random_1.xml +++ b/doc/generated/examples/caching_ex-random_1.xml @@ -1,9 +1,9 @@ % scons -Q cc -o f2.o -c f2.c +cc -o f1.o -c f1.c cc -o f5.o -c f5.c cc -o f3.o -c f3.c cc -o f4.o -c f4.c -cc -o f1.o -c f1.c cc -o prog f1.o f2.o f3.o f4.o f5.o diff --git a/doc/generated/examples/commandline_Variables_Help_1.xml b/doc/generated/examples/commandline_Variables_Help_1.xml index 76f13c5..db171eb 100644 --- a/doc/generated/examples/commandline_Variables_Help_1.xml +++ b/doc/generated/examples/commandline_Variables_Help_1.xml @@ -1,8 +1,6 @@ % scons -Q -h -Local Build Variables: - RELEASE: Set to 1 to build for release default: 0 actual: 0 diff --git a/doc/generated/examples/output_ex1_1.xml b/doc/generated/examples/output_ex1_1.xml index 2607243..535960b 100644 --- a/doc/generated/examples/output_ex1_1.xml +++ b/doc/generated/examples/output_ex1_1.xml @@ -3,8 +3,6 @@ scons: Reading SConscript files ... scons: done reading SConscript files. -Local Build Variables: - Type: 'scons program' to build the production program, 'scons debug' to build the debug version. diff --git a/doc/generated/examples/output_ex2_1.xml b/doc/generated/examples/output_ex2_1.xml index 74d7192..e951c3a 100644 --- a/doc/generated/examples/output_ex2_1.xml +++ b/doc/generated/examples/output_ex2_1.xml @@ -3,8 +3,6 @@ scons: Reading SConscript files ... scons: done reading SConscript files. -Local Build Variables: - Type: 'scons program' to build the production program. Type: 'scons windebug' to build the Windows debug version. diff --git a/doc/generated/examples/output_ex2_2.xml b/doc/generated/examples/output_ex2_2.xml index 9130d5a..8dca6c3 100644 --- a/doc/generated/examples/output_ex2_2.xml +++ b/doc/generated/examples/output_ex2_2.xml @@ -3,8 +3,6 @@ scons: Reading SConscript files ... scons: done reading SConscript files. -Local Build Variables: - Type: 'scons program' to build the production program. Use scons -H for help about command-line options. diff --git a/doc/generated/examples/troubleshoot_explain1_3.xml b/doc/generated/examples/troubleshoot_explain1_3.xml index 9763efe..3d8592d 100644 --- a/doc/generated/examples/troubleshoot_explain1_3.xml +++ b/doc/generated/examples/troubleshoot_explain1_3.xml @@ -3,5 +3,5 @@ cp file.in file.oout scons: warning: Cannot find target file.out after building -File "/home/bdbaddog/scons/scons/bootstrap/src/script/scons.py", line 199, in <module> +File "/scons/as_scons/bootstrap/src/script/scons.py", line 199, in <module> diff --git a/doc/generated/tools.gen b/doc/generated/tools.gen index fcb7587..ba12966 100644 --- a/doc/generated/tools.gen +++ b/doc/generated/tools.gen @@ -780,19 +780,19 @@ Sets construction variables for the Sets: &cv-link-AS;, &cv-link-ASCOM;, &cv-link-ASFLAGS;, &cv-link-ASPPCOM;, &cv-link-ASPPFLAGS;.Uses: &cv-link-ASCOMSTR;, &cv-link-ASPPCOMSTR;. - - packaging + + Packaging -A framework for building binary and source packages. +Sets construction variables for the Package Builder. - - Packaging + + packaging -Sets construction variables for the Package Builder. +A framework for building binary and source packages. diff --git a/doc/generated/tools.mod b/doc/generated/tools.mod index 1191e6a..2ee2270 100644 --- a/doc/generated/tools.mod +++ b/doc/generated/tools.mod @@ -78,8 +78,8 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. mwcc"> mwld"> nasm"> -packaging"> Packaging"> +packaging"> pdf"> pdflatex"> pdftex"> @@ -189,8 +189,8 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. mwcc"> mwld"> nasm"> -packaging"> Packaging"> +packaging"> pdf"> pdflatex"> pdftex"> diff --git a/doc/generated/variables.gen b/doc/generated/variables.gen index 3d8a87a..b377102 100644 --- a/doc/generated/variables.gen +++ b/doc/generated/variables.gen @@ -6553,16 +6553,6 @@ Example - - SHLIBVERSIONFLAGS - - -Extra flags added to $SHLINKCOM when building versioned -SharedLibrary. These flags are only used when $SHLIBVERSION is -set. - - - _SHLIBVERSIONFLAGS @@ -6576,6 +6566,16 @@ and some extra dynamically generated options (such as + + SHLIBVERSIONFLAGS + + +Extra flags added to $SHLINKCOM when building versioned +SharedLibrary. These flags are only used when $SHLIBVERSION is +set. + + + SHLINK diff --git a/doc/generated/variables.mod b/doc/generated/variables.mod index f7303f2..955a9eb 100644 --- a/doc/generated/variables.mod +++ b/doc/generated/variables.mod @@ -521,8 +521,8 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. $_SHLIBSONAME"> $SHLIBSUFFIX"> $SHLIBVERSION"> -$SHLIBVERSIONFLAGS"> $_SHLIBVERSIONFLAGS"> +$SHLIBVERSIONFLAGS"> $SHLINK"> $SHLINKCOM"> $SHLINKCOMSTR"> @@ -1175,8 +1175,8 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. $_SHLIBSONAME"> $SHLIBSUFFIX"> $SHLIBVERSION"> -$SHLIBVERSIONFLAGS"> $_SHLIBVERSIONFLAGS"> +$SHLIBVERSIONFLAGS"> $SHLINK"> $SHLINKCOM"> $SHLINKCOMSTR"> diff --git a/src/Announce.txt b/src/Announce.txt index 7a13b81..719b4d7 100644 --- a/src/Announce.txt +++ b/src/Announce.txt @@ -18,31 +18,86 @@ So that everyone using SCons can help each other learn how to use it more effectively, please go to http://scons.org/lists.php#users to sign up for the scons-users mailing list. -==============IMPORTANT NOTICE=========== +==============IMPORTANT NOTICE FOR NEXT VERSION V2.5.0========== +PLEASE READ. CHANGES COMING IN NEXT MAJOR RELEASE V2.5.0 -As has been pre-announced in SCons's mailing lists: +We're enhancing implicit language scanning functionality to improve +correctness. SCons now honors scanner keys for implicit dependencies +and correctly changes scanner type (if necessary) when traversing +implicit dependency trees. -* https://pairlist4.pair.net/pipermail/scons-users/2014-July/002734.html , -* https://pairlist2.pair.net/pipermail/scons-dev/2014-December/002107.html -* https://pairlist4.pair.net/pipermail/scons-users/2015-February/003454.html +This enhancement resolves missing dependencies +with built-in scanners including SWIG (#2264) and QT: +* http://scons.tigris.org/issues/show_bug.cgi?id=2264 -We're planning to switch the Node class to using "slots" in the core sources, -mainly to reduce memory consumption by up to 35% in large build projects. +This enhancement broadens the horizon for handling heterogeneous +data flow environments (E.G. software builds): +* http://article.gmane.org/gmane.comp.programming.tools.scons.user/26596 +Notes: -This feature has been tested extensively and we don't expect any problems for you. -However as with all major changes it would be wise to test V2.4.0 when it is -released. Especially if you are directly using the Node class. +* SCons may find new (and correct) dependencies in cross-langauge contexts. +** Update may cause rebuilds, especially in heterogeneous data environments. +** Update may find previously missed dependencies errors (E.G. cycles). +*** Discovered in some QT test cases. +* SCons handles the SCANNERS variable differently. +** Previously, the Install builder would scan implicit dependencies for + a scanner found in SCANNERS (but not for built-in scanners), but now + the Install builder will not scan recursively regardless in order + to optimize Install behaviour and bring orthogonality to previous behaviour. -================================================================= ++================================================================= -RELEASE VERSION/DATE TO BE FILLED IN LATER +RELEASE 2.4.1 - Mon, 07 Nov 2015 10:37:21 -0700 Please consult the RELEASE.txt file for a summary of changes since the last release and consult the CHANGES.txt file for complete a list of changes since last release. This announcement highlights only the important changes. + Please note the following important changes since release 2.4.0: + - Fix to swig tool - pick-up 'swig', 'swig3.0' and 'swig2.0' (in order). + - Fix to swig tool - respect env['SWIG'] provided by user. + - Fix for Bug # 2791 - Setup.py fails unnecessarily under Jython. + - Fixed license of SVG titlepage files in the context of Debian + packaging, such that they allow for commercial use too (#2985). + - InstallVersionedLib now available in the DefaultEnvironment context. + - Improves orthogonality of use cases between different Install functions. + - Added new configure check, CheckProg, to check for + existence of a program. + - Fix for issue #2840 - Fix for two environments specifying same target with different + actions not throwing hard error. Instead SCons was incorrectly issuing a warning + and continuing. + - Add support `Microsoft Visual C++ Compiler for Python 2.7' + Compiler can be obtained at: https://www.microsoft.com/en-us/download/details.aspx?id=44266 + - Fixed tigris issue #3011: Glob() excludes didn't work when used with VariantDir(duplicate=0) + - Fix bug 2831 and allow Help() text to be appended to AddOption() help. + - Reimplemented versioning for shared libraries, with the following effects + - Fixed tigris issues #3001, #3006. + - Fixed several other issues not reported to tigris, including: + issues with versioned libraries in subdirectories with tricky names, + issues with versioned libraries and variant directories, + issue with soname not being injected to library when using D linkers, + - Switched to direct symlinks instead of daisy-chained ones -- soname and + development symlinks point directly to the versioned shared library now), + for rationale see: + https://www.debian.org/doc/debian-policy/ch-sharedlibs.html + https://fedoraproject.org/wiki/Packaging:Guidelines#Devel_Packages + https://bitbucket.org/scons/scons/pull-requests/247/new-versioned-libraries-gnulink-cyglink/diff#comment-10063929 + - New construction variables to allow override default behavior: SONAME, + SHLIBVERSIONFLAGS, _SHLIBVERSIONFLAGS, SHLIBNOVERSIONSYMLINKS, + LDMODULEVERSION, LDMODULEVERSIONFLAGS, _LDMODULEVERSIONFLAGS, + LDMODULENOVERSIONSYMLINKS. + - Changed logic used to configure the versioning machinery from + platform-centric to linker-oriented. + - The SHLIBVERSION/LDMODULEVERSION variables are no longer validated by + SCons (more freedom to users). + - InstallVersionedLib() doesn't use SHLIBVERSION anymore. + - Enchanced docs for the library versioning stuff. + - New tests for versioned libraries. + - Library versioning is currently implemented for the following linker + tools: 'cyglink', 'gnulink', 'sunlink'. + Please note the following important changes since release 2.3.6: - Switch several core classes to use "slots" to reduce memory usage. (PR #2180, #2178, #2198) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 823eb4b..40245a8 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -4,11 +4,7 @@ Change Log -RELEASE VERSION/DATE TO BE FILLED IN LATER - - From Paweł Tomulik: - - Fix to swig tool - pick-up 'swig', 'swig3.0' and 'swig2.0' (in order). - - Fix to swig tool - respect env['SWIG'] provided by user. +RELEASE 2.4.1 - Mon, 07 Nov 2015 10:37:21 -0700 From Arfrever Frehtes Taifersar Arahesis: - Fix for Bug # 2791 - Setup.py fails unnecessarily under Jython. @@ -66,6 +62,8 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER - New tests for versioned libraries. - Library versioning is currently implemented for the following linker tools: 'cyglink', 'gnulink', 'sunlink'. + - Fix to swig tool - pick-up 'swig', 'swig3.0' and 'swig2.0' (in order). + - Fix to swig tool - respect env['SWIG'] provided by user. diff --git a/src/RELEASE.txt b/src/RELEASE.txt index 1bf2eb1..baf3283 100644 --- a/src/RELEASE.txt +++ b/src/RELEASE.txt @@ -1,72 +1,68 @@ - A new SCons checkpoint release, 2.3.13.alpha.yyyymmdd, is now available + A new SCons release, 2.4.1, is now available on the SCons download page: http://www.scons.org/download.php - XXX The primary purpose of this release ... XXX - - A SCons "checkpoint release" is intended to provide early access to - new features so they can be tested in the field before being released - for adoption by other software distributions. - - Note that a checkpoint release is developed using the same test-driven - development methodology as all SCons releases. Existing SCons - functionality should all work as it does in previous releases (except - for any changes identified in the release notes) and early adopters - should be able to use a checkpoint release safely for production work - with existing SConscript files. If not, it represents not only a bug - in SCons but also a hole in the regression test suite, and we want to - hear about it. - - New features may be more lightly tested than in past releases, - especially as concerns their interaction with all of the other - functionality in SCons. We are especially interested in hearing bug - reports about new functionality. - - We do not recommend that downstream distributions (Debian, Fedora, - etc.) package a checkpoint release, mainly to avoid confusing the - "public" release numbering with the long checkpoint release names. - - Here is a summary of the changes since 1.3.0: + Here is a summary of the changes since 2.4.0: NEW FUNCTIONALITY - - - List new features (presumably why a checkpoint is being released) + - InstallVersionedLib now available in the DefaultEnvironment context. + - Added new configure check, CheckProg, to check for existence of a program. + - Add support `Microsoft Visual C++ Compiler for Python 2.7' + Compiler can be obtained at: https://www.microsoft.com/en-us/download/details.aspx?id=44266 DEPRECATED FUNCTIONALITY - - List anything that's been deprecated since the last release - CHANGED/ENHANCED EXISTING FUNCTIONALITY - - List modifications to existing features, where the previous behavior - wouldn't actually be considered a bug + - Reimplemented versioning for shared libraries, with the following effects + - Fixed tigris issues #3001, #3006. + - Fixed several other issues not reported to tigris, including: + issues with versioned libraries in subdirectories with tricky names, + issues with versioned libraries and variant directories, + issue with soname not being injected to library when using D linkers, + - Switched to direct symlinks instead of daisy-chained ones -- soname and + development symlinks point directly to the versioned shared library now), + for rationale see: + https://www.debian.org/doc/debian-policy/ch-sharedlibs.html + https://fedoraproject.org/wiki/Packaging:Guidelines#Devel_Packages + https://bitbucket.org/scons/scons/pull-requests/247/new-versioned-libraries-gnulink-cyglink/diff#comment-10063929 + - New construction variables to allow override default behavior: SONAME, + SHLIBVERSIONFLAGS, _SHLIBVERSIONFLAGS, SHLIBNOVERSIONSYMLINKS, + LDMODULEVERSION, LDMODULEVERSIONFLAGS, _LDMODULEVERSIONFLAGS, + LDMODULENOVERSIONSYMLINKS. + - Changed logic used to configure the versioning machinery from + platform-centric to linker-oriented. + - The SHLIBVERSION/LDMODULEVERSION variables are no longer validated by + SCons (more freedom to users). + - InstallVersionedLib() doesn't use SHLIBVERSION anymore. + - Enchanced docs for the library versioning stuff. + - New tests for versioned libraries. + - Library versioning is currently implemented for the following linker + tools: 'cyglink', 'gnulink', 'sunlink'. FIXES - - List fixes of outright bugs + - Fix for issue #2840 - Fix for two environments specifying same target with different + actions not throwing hard error. Instead SCons was incorrectly issuing a warning + and continuing. + - Fix to swig tool - pick-up 'swig', 'swig3.0' and 'swig2.0' (in order). + - Fix to swig tool - respect env['SWIG'] provided by user. + - Fix for Bug # 2791 - Setup.py fails unnecessarily under Jython. + - Fixed license of SVG titlepage files in the context of Debian + packaging, such that they allow for commercial use too (#2985). + - Fixed tigris issue #3011: Glob() excludes didn't work when used with VariantDir(duplicate=0) + - Fix bug 2831 and allow Help() text to be appended to AddOption() help. IMPROVEMENTS - - List improvements that wouldn't be visible to the user in the - documentation: performance improvements (describe the circumstances - under which they would be observed), or major code cleanups - PACKAGING - - List changes in the way SCons is packaged and/or released - DOCUMENTATION - - List any significant changes to the documentation (not individual - typo fixes, even if they're mentioned in src/CHANGES.txt to give - the contributor credit) - DEVELOPMENT - - List visible changes in the way SCons is developed - - Thanks to CURLY, LARRY, and MOE for their contributions to this release. + Thanks to Arfrever Frehtes Taifersar Arahesis, Dirk Baechle, William Blevins, Carnë Draug, Andrew Featherstone, Hiroaki Itoh, Florian Miedniak, William Roberts, Paweł Tomulik for their contributions to this release. Contributors are listed alphabetically by their last name. __COPYRIGHT__ -- cgit v0.12 From 2d6ae148c1a3c49fb8400f7de0787e1179aab53c Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 9 Nov 2015 09:31:05 -0800 Subject: post 2.4.1 release changes --- ReleaseConfig | 2 +- src/Announce.txt | 2 +- src/CHANGES.txt | 7 +++++ src/RELEASE.txt | 88 +++++++++++++++++++++++++++++--------------------------- 4 files changed, 55 insertions(+), 44 deletions(-) diff --git a/ReleaseConfig b/ReleaseConfig index 4396248..ced44c6 100644 --- a/ReleaseConfig +++ b/ReleaseConfig @@ -32,7 +32,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" # 'final', the patchlevel is set to the release date. This value is # mandatory and must be present in this file. #version_tuple = (2, 2, 0, 'final', 0) -version_tuple = (2, 4, 1) +version_tuple = (2, 4, 2, 'alpha', 0) # Python versions prior to unsupported_python_version cause a fatal error # when that version is used. Python versions prior to deprecate_python_version diff --git a/src/Announce.txt b/src/Announce.txt index 719b4d7..c20d7df 100644 --- a/src/Announce.txt +++ b/src/Announce.txt @@ -48,7 +48,7 @@ Notes: +================================================================= -RELEASE 2.4.1 - Mon, 07 Nov 2015 10:37:21 -0700 +RELEASE VERSION/DATE TO BE FILLED IN LATER Please consult the RELEASE.txt file for a summary of changes since the last release and consult the CHANGES.txt file for complete a list of changes diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 40245a8..02afa43 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -4,6 +4,13 @@ Change Log +RELEASE VERSION/DATE TO BE FILLED IN LATER + + From John Doe: + + - Whatever John Doe did. + + RELEASE 2.4.1 - Mon, 07 Nov 2015 10:37:21 -0700 From Arfrever Frehtes Taifersar Arahesis: diff --git a/src/RELEASE.txt b/src/RELEASE.txt index baf3283..ed17984 100644 --- a/src/RELEASE.txt +++ b/src/RELEASE.txt @@ -1,68 +1,72 @@ - A new SCons release, 2.4.1, is now available + A new SCons checkpoint release, 2.4.2.alpha.yyyymmdd, is now available on the SCons download page: http://www.scons.org/download.php - Here is a summary of the changes since 2.4.0: + XXX The primary purpose of this release ... XXX + + A SCons "checkpoint release" is intended to provide early access to + new features so they can be tested in the field before being released + for adoption by other software distributions. + + Note that a checkpoint release is developed using the same test-driven + development methodology as all SCons releases. Existing SCons + functionality should all work as it does in previous releases (except + for any changes identified in the release notes) and early adopters + should be able to use a checkpoint release safely for production work + with existing SConscript files. If not, it represents not only a bug + in SCons but also a hole in the regression test suite, and we want to + hear about it. + + New features may be more lightly tested than in past releases, + especially as concerns their interaction with all of the other + functionality in SCons. We are especially interested in hearing bug + reports about new functionality. + + We do not recommend that downstream distributions (Debian, Fedora, + etc.) package a checkpoint release, mainly to avoid confusing the + "public" release numbering with the long checkpoint release names. + + Here is a summary of the changes since 1.3.0: NEW FUNCTIONALITY - - InstallVersionedLib now available in the DefaultEnvironment context. - - Added new configure check, CheckProg, to check for existence of a program. - - Add support `Microsoft Visual C++ Compiler for Python 2.7' - Compiler can be obtained at: https://www.microsoft.com/en-us/download/details.aspx?id=44266 + + - List new features (presumably why a checkpoint is being released) DEPRECATED FUNCTIONALITY + - List anything that's been deprecated since the last release + CHANGED/ENHANCED EXISTING FUNCTIONALITY - - Reimplemented versioning for shared libraries, with the following effects - - Fixed tigris issues #3001, #3006. - - Fixed several other issues not reported to tigris, including: - issues with versioned libraries in subdirectories with tricky names, - issues with versioned libraries and variant directories, - issue with soname not being injected to library when using D linkers, - - Switched to direct symlinks instead of daisy-chained ones -- soname and - development symlinks point directly to the versioned shared library now), - for rationale see: - https://www.debian.org/doc/debian-policy/ch-sharedlibs.html - https://fedoraproject.org/wiki/Packaging:Guidelines#Devel_Packages - https://bitbucket.org/scons/scons/pull-requests/247/new-versioned-libraries-gnulink-cyglink/diff#comment-10063929 - - New construction variables to allow override default behavior: SONAME, - SHLIBVERSIONFLAGS, _SHLIBVERSIONFLAGS, SHLIBNOVERSIONSYMLINKS, - LDMODULEVERSION, LDMODULEVERSIONFLAGS, _LDMODULEVERSIONFLAGS, - LDMODULENOVERSIONSYMLINKS. - - Changed logic used to configure the versioning machinery from - platform-centric to linker-oriented. - - The SHLIBVERSION/LDMODULEVERSION variables are no longer validated by - SCons (more freedom to users). - - InstallVersionedLib() doesn't use SHLIBVERSION anymore. - - Enchanced docs for the library versioning stuff. - - New tests for versioned libraries. - - Library versioning is currently implemented for the following linker - tools: 'cyglink', 'gnulink', 'sunlink'. + - List modifications to existing features, where the previous behavior + wouldn't actually be considered a bug FIXES - - Fix for issue #2840 - Fix for two environments specifying same target with different - actions not throwing hard error. Instead SCons was incorrectly issuing a warning - and continuing. - - Fix to swig tool - pick-up 'swig', 'swig3.0' and 'swig2.0' (in order). - - Fix to swig tool - respect env['SWIG'] provided by user. - - Fix for Bug # 2791 - Setup.py fails unnecessarily under Jython. - - Fixed license of SVG titlepage files in the context of Debian - packaging, such that they allow for commercial use too (#2985). - - Fixed tigris issue #3011: Glob() excludes didn't work when used with VariantDir(duplicate=0) - - Fix bug 2831 and allow Help() text to be appended to AddOption() help. + - List fixes of outright bugs IMPROVEMENTS + - List improvements that wouldn't be visible to the user in the + documentation: performance improvements (describe the circumstances + under which they would be observed), or major code cleanups + PACKAGING + - List changes in the way SCons is packaged and/or released + DOCUMENTATION + - List any significant changes to the documentation (not individual + typo fixes, even if they're mentioned in src/CHANGES.txt to give + the contributor credit) + DEVELOPMENT - Thanks to Arfrever Frehtes Taifersar Arahesis, Dirk Baechle, William Blevins, Carnë Draug, Andrew Featherstone, Hiroaki Itoh, Florian Miedniak, William Roberts, Paweł Tomulik for their contributions to this release. + - List visible changes in the way SCons is developed + + Thanks to CURLY, LARRY, and MOE for their contributions to this release. Contributors are listed alphabetically by their last name. __COPYRIGHT__ -- cgit v0.12 From ebc3286289111b5134032f03c29cb8a0ef7d5d34 Mon Sep 17 00:00:00 2001 From: anatoly techtonik Date: Wed, 11 Nov 2015 21:44:46 +0300 Subject: Document SCons.Debug.caller_trace() behavior --- src/CHANGES.txt | 12 +++++++++--- src/engine/SCons/Debug.py | 11 +++++++++-- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 02afa43..23fd49b 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -4,17 +4,20 @@ Change Log + RELEASE VERSION/DATE TO BE FILLED IN LATER From John Doe: - - Whatever John Doe did. + From Anatoly Techtonik: + - Document SCons.Debug.caller_trace() behavior. + RELEASE 2.4.1 - Mon, 07 Nov 2015 10:37:21 -0700 From Arfrever Frehtes Taifersar Arahesis: - - Fix for Bug # 2791 - Setup.py fails unnecessarily under Jython. + - Fix for Bug # 2791 - setup.py fails unnecessarily under Jython. From Dirk Baechle: - Fixed license of SVG titlepage files in the context of Debian @@ -73,7 +76,6 @@ RELEASE 2.4.1 - Mon, 07 Nov 2015 10:37:21 -0700 - Fix to swig tool - respect env['SWIG'] provided by user. - RELEASE 2.4.0 - Mon, 21 Sep 2015 08:56:00 -0700 From Dirk Baechle: @@ -86,6 +88,8 @@ RELEASE 2.4.0 - Mon, 21 Sep 2015 08:56:00 -0700 From Andrew Featherstone - Fixed typo in SWIGPATH description + + RELEASE 2.3.6 - Mon, 31 Jul 2015 14:35:03 -0700 From Rob Smith: @@ -379,6 +383,8 @@ RELEASE 2.3.0 - Mon, 02 Mar 2013 13:22:29 -0400 Add builder InstallVersionedLib to create the required symlinks installing a versioned shared library. + + RELEASE 2.2.0 - Mon, 05 Aug 2012 15:37:48 +0000 From dubcanada on Bitbucket: diff --git a/src/engine/SCons/Debug.py b/src/engine/SCons/Debug.py index b47c24c..9e520ff 100644 --- a/src/engine/SCons/Debug.py +++ b/src/engine/SCons/Debug.py @@ -1,7 +1,10 @@ """SCons.Debug Code for debugging SCons internal things. Shouldn't be -needed by most users. +needed by most users. Quick shortcuts: + +from SCons.Debug import caller_trace +caller_trace() """ @@ -137,8 +140,12 @@ def caller_stack(): caller_bases = {} caller_dicts = {} -# trace a caller's stack def caller_trace(back=0): + """ + Trace caller stack and save info into global dicts, which + are printed automatically at the end of SCons execution. + """ + global caller_bases, caller_dicts import traceback tb = traceback.extract_stack(limit=3+back) tb.reverse() -- cgit v0.12 From 046f1eba099033932261d60b90e8a7cd140adb17 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Wed, 11 Nov 2015 17:53:13 -0500 Subject: change release config files to post release state --- QMTest/TestSCons.py | 2 +- README.rst | 16 ++++++++-------- SConstruct | 4 ++-- src/CHANGES.txt | 7 +++++++ src/RELEASE.txt | 55 ++++++++++++++++++++++++++++++++++++++--------------- 5 files changed, 58 insertions(+), 26 deletions(-) diff --git a/QMTest/TestSCons.py b/QMTest/TestSCons.py index ef70261..a9fd6a0 100644 --- a/QMTest/TestSCons.py +++ b/QMTest/TestSCons.py @@ -34,7 +34,7 @@ from TestCmd import PIPE # here provides some independent verification that what we packaged # conforms to what we expect. -default_version = '2.4.1' +default_version = '2.4.2.alpha.yyyymmdd' python_version_unsupported = (2, 3, 0) python_version_deprecated = (2, 7, 0) diff --git a/README.rst b/README.rst index a2b15a6..5710586 100644 --- a/README.rst +++ b/README.rst @@ -480,14 +480,14 @@ following packages will be built:: build/dist/scons-2.4.1-1.noarch.rpm build/dist/scons-2.4.1-1.src.rpm build/dist/scons-2.4.1.linux-i686.tar.gz - build/dist/scons-2.4.1.tar.gz - build/dist/scons-2.4.1.win32.exe - build/dist/scons-2.4.1.zip - build/dist/scons-doc-2.4.1.tar.gz - build/dist/scons-local-2.4.1.tar.gz - build/dist/scons-local-2.4.1.zip - build/dist/scons-src-2.4.1.tar.gz - build/dist/scons-src-2.4.1.zip + build/dist/scons-2.4.2.alpha.yyyymmdd.tar.gz + build/dist/scons-2.4.2.alpha.yyyymmdd.win32.exe + build/dist/scons-2.4.2.alpha.yyyymmdd.zip + build/dist/scons-doc-2.4.2.alpha.yyyymmdd.tar.gz + build/dist/scons-local-2.4.2.alpha.yyyymmdd.tar.gz + build/dist/scons-local-2.4.2.alpha.yyyymmdd.zip + build/dist/scons-src-2.4.2.alpha.yyyymmdd.tar.gz + build/dist/scons-src-2.4.2.alpha.yyyymmdd.zip build/dist/scons_2.4.1-1_all.deb The SConstruct file is supposed to be smart enough to avoid trying to build diff --git a/SConstruct b/SConstruct index 79249e9..3bbaca6 100644 --- a/SConstruct +++ b/SConstruct @@ -6,7 +6,7 @@ copyright_years = '2001 - 2015' # This gets inserted into the man pages to reflect the month of release. -month_year = 'November 2015' +month_year = 'MONTH YEAR' # # __COPYRIGHT__ @@ -43,7 +43,7 @@ import tempfile import bootstrap project = 'scons' -default_version = '2.4.1' +default_version = '2.4.2.alpha.yyyymmdd' copyright = "Copyright (c) %s The SCons Foundation" % copyright_years platform = distutils.util.get_platform() diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 02afa43..685a6ae 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -11,6 +11,13 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER - Whatever John Doe did. +RELEASE 2.4.2.alpha.yyyymmdd - NEW DATE WILL BE INSERTED HERE + + From John Doe: + + - Whatever John Doe did. + + RELEASE 2.4.1 - Mon, 07 Nov 2015 10:37:21 -0700 From Arfrever Frehtes Taifersar Arahesis: diff --git a/src/RELEASE.txt b/src/RELEASE.txt index 114b4f5..3bff366 100644 --- a/src/RELEASE.txt +++ b/src/RELEASE.txt @@ -1,47 +1,72 @@ - A new SCons checkpoint release, 2.4.2.alpha.yyyymmdd, is now available + A new SCons checkpoint release, 2.4.3.alpha.yyyymmdd, is now available on the SCons download page: http://www.scons.org/download.php - Here is a summary of the changes since 2.3.6: + XXX The primary purpose of this release ... XXX + + A SCons "checkpoint release" is intended to provide early access to + new features so they can be tested in the field before being released + for adoption by other software distributions. + + Note that a checkpoint release is developed using the same test-driven + development methodology as all SCons releases. Existing SCons + functionality should all work as it does in previous releases (except + for any changes identified in the release notes) and early adopters + should be able to use a checkpoint release safely for production work + with existing SConscript files. If not, it represents not only a bug + in SCons but also a hole in the regression test suite, and we want to + hear about it. + + New features may be more lightly tested than in past releases, + especially as concerns their interaction with all of the other + functionality in SCons. We are especially interested in hearing bug + reports about new functionality. + + We do not recommend that downstream distributions (Debian, Fedora, + etc.) package a checkpoint release, mainly to avoid confusing the + "public" release numbering with the long checkpoint release names. + + Here is a summary of the changes since 1.3.0: NEW FUNCTIONALITY - - None + - List new features (presumably why a checkpoint is being released) DEPRECATED FUNCTIONALITY - - None + - List anything that's been deprecated since the last release CHANGED/ENHANCED EXISTING FUNCTIONALITY - - Switched several core classes to using "slots", for - reducing the overall memory consumption in large - projects (fixes #2180, #2178, #2198) - - Memoizer counting uses decorators now, instead of - the old metaclasses approach. + - List modifications to existing features, where the previous behavior + wouldn't actually be considered a bug FIXES - - 2180, 2178, 2198 (See above) + - List fixes of outright bugs IMPROVEMENTS - - See CHANGED/ENHANCED EXISTING FUNCTIONALITY above + - List improvements that wouldn't be visible to the user in the + documentation: performance improvements (describe the circumstances + under which they would be observed), or major code cleanups PACKAGING - - None + - List changes in the way SCons is packaged and/or released DOCUMENTATION - - Bug 2504 - Fixed incorrect default SWIGPATH in documentation + - List any significant changes to the documentation (not individual + typo fixes, even if they're mentioned in src/CHANGES.txt to give + the contributor credit) DEVELOPMENT - - None + - List visible changes in the way SCons is developed - Thanks to Dirk Baechle, and Andrew Featherstone for their contributions to this release. + Thanks to CURLY, LARRY, and MOE for their contributions to this release. Contributors are listed alphabetically by their last name. __COPYRIGHT__ -- cgit v0.12 From c2d974ea65afe9ab1968a16c797155fd799527ca Mon Sep 17 00:00:00 2001 From: William Deegan Date: Thu, 12 Nov 2015 23:49:22 -0500 Subject: minor changes to fix too many files open when trying to run with pypy --- bootstrap.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/bootstrap.py b/bootstrap.py index f3bc105..90917dc 100755 --- a/bootstrap.py +++ b/bootstrap.py @@ -27,6 +27,8 @@ import os.path import sys import glob import subprocess +import filecmp +import shutil __doc__ = """bootstrap.py @@ -127,7 +129,7 @@ def main(): def must_copy(dst, src): if not os.path.exists(dst): return 1 - return open(dst, 'rb').read() != open(src, 'rb').read() + return filecmp.cmp(dst,src) # Note: We don't use the getopt module to process the command-line # arguments because we'd have to teach it about all of the SCons options. @@ -195,7 +197,8 @@ def main(): os.makedirs(dir) try: os.unlink(dst) except: pass - open(dst, 'wb').write( open(src, 'rb').read() ) + + shutil.copyfile(src,dst) if update_only: sys.exit(0) -- cgit v0.12 From 5ea93b2da34adbb831d8c88d894c0cdb98e9452e Mon Sep 17 00:00:00 2001 From: William Deegan Date: Fri, 13 Nov 2015 20:03:54 -0500 Subject: need to add new SWIG.py scanner to manifest to get it to install --- src/engine/MANIFEST.in | 1 + 1 file changed, 1 insertion(+) diff --git a/src/engine/MANIFEST.in b/src/engine/MANIFEST.in index f62d16e..f7d5aa7 100644 --- a/src/engine/MANIFEST.in +++ b/src/engine/MANIFEST.in @@ -39,6 +39,7 @@ SCons/Scanner/IDL.py SCons/Scanner/LaTeX.py SCons/Scanner/Prog.py SCons/Scanner/RC.py +SCons/Scanner/SWIG.py SCons/SConf.py SCons/SConsign.py SCons/Script/__init__.py -- cgit v0.12 From 781d31e33c51d2e18435706fb2cb7f051e02a384 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Thu, 19 Nov 2015 10:37:07 -0800 Subject: remove compat module for subprocess. No longer needed as we are only going to run on python 2.7.x --- src/engine/SCons/compat/__init__.py | 6 - src/engine/SCons/compat/_scons_subprocess.py | 1281 -------------------------- 2 files changed, 1287 deletions(-) delete mode 100644 src/engine/SCons/compat/_scons_subprocess.py diff --git a/src/engine/SCons/compat/__init__.py b/src/engine/SCons/compat/__init__.py index c870fbc..281392c 100644 --- a/src/engine/SCons/compat/__init__.py +++ b/src/engine/SCons/compat/__init__.py @@ -186,12 +186,6 @@ rename_module('winreg', '_winreg') try: - import subprocess -except ImportError: - # Pre-2.4 Python has no subprocess module. - import_as('_scons_subprocess', 'subprocess') - -try: sys.intern except AttributeError: # Pre-2.6 Python has no sys.intern() function. diff --git a/src/engine/SCons/compat/_scons_subprocess.py b/src/engine/SCons/compat/_scons_subprocess.py deleted file mode 100644 index eebe53d..0000000 --- a/src/engine/SCons/compat/_scons_subprocess.py +++ /dev/null @@ -1,1281 +0,0 @@ -# subprocess - Subprocesses with accessible I/O streams -# -# For more information about this module, see PEP 324. -# -# This module should remain compatible with Python 2.2, see PEP 291. -# -# Copyright (c) 2003-2005 by Peter Astrand -# -# Licensed to PSF under a Contributor Agreement. -# See http://www.python.org/2.4/license for licensing details. - -r"""subprocess - Subprocesses with accessible I/O streams - -This module allows you to spawn processes, connect to their -input/output/error pipes, and obtain their return codes. This module -intends to replace several other, older modules and functions, like: - -os.system -os.spawn* -os.popen* -popen2.* -commands.* - -Information about how the subprocess module can be used to replace these -modules and functions can be found below. - - - -Using the subprocess module -=========================== -This module defines one class called Popen: - -class Popen(args, bufsize=0, executable=None, - stdin=None, stdout=None, stderr=None, - preexec_fn=None, close_fds=False, shell=False, - cwd=None, env=None, universal_newlines=False, - startupinfo=None, creationflags=0): - - -Arguments are: - -args should be a string, or a sequence of program arguments. The -program to execute is normally the first item in the args sequence or -string, but can be explicitly set by using the executable argument. - -On UNIX, with shell=False (default): In this case, the Popen class -uses os.execvp() to execute the child program. args should normally -be a sequence. A string will be treated as a sequence with the string -as the only item (the program to execute). - -On UNIX, with shell=True: If args is a string, it specifies the -command string to execute through the shell. If args is a sequence, -the first item specifies the command string, and any additional items -will be treated as additional shell arguments. - -On Windows: the Popen class uses CreateProcess() to execute the child -program, which operates on strings. If args is a sequence, it will be -converted to a string using the list2cmdline method. Please note that -not all MS Windows applications interpret the command line the same -way: The list2cmdline is designed for applications using the same -rules as the MS C runtime. - -bufsize, if given, has the same meaning as the corresponding argument -to the built-in open() function: 0 means unbuffered, 1 means line -buffered, any other positive value means use a buffer of -(approximately) that size. A negative bufsize means to use the system -default, which usually means fully buffered. The default value for -bufsize is 0 (unbuffered). - -stdin, stdout and stderr specify the executed programs' standard -input, standard output and standard error file handles, respectively. -Valid values are PIPE, an existing file descriptor (a positive -integer), an existing file object, and None. PIPE indicates that a -new pipe to the child should be created. With None, no redirection -will occur; the child's file handles will be inherited from the -parent. Additionally, stderr can be STDOUT, which indicates that the -stderr data from the applications should be captured into the same -file handle as for stdout. - -If preexec_fn is set to a callable object, this object will be called -in the child process just before the child is executed. - -If close_fds is true, all file descriptors except 0, 1 and 2 will be -closed before the child process is executed. - -if shell is true, the specified command will be executed through the -shell. - -If cwd is not None, the current directory will be changed to cwd -before the child is executed. - -If env is not None, it defines the environment variables for the new -process. - -If universal_newlines is true, the file objects stdout and stderr are -opened as a text files, but lines may be terminated by any of '\n', -the Unix end-of-line convention, '\r', the Macintosh convention or -'\r\n', the Windows convention. All of these external representations -are seen as '\n' by the Python program. Note: This feature is only -available if Python is built with universal newline support (the -default). Also, the newlines attribute of the file objects stdout, -stdin and stderr are not updated by the communicate() method. - -The startupinfo and creationflags, if given, will be passed to the -underlying CreateProcess() function. They can specify things such as -appearance of the main window and priority for the new process. -(Windows only) - - -This module also defines two shortcut functions: - -call(*popenargs, **kwargs): - Run command with arguments. Wait for command to complete, then - return the returncode attribute. - - The arguments are the same as for the Popen constructor. Example: - - retcode = call(["ls", "-l"]) - -check_call(*popenargs, **kwargs): - Run command with arguments. Wait for command to complete. If the - exit code was zero then return, otherwise raise - CalledProcessError. The CalledProcessError object will have the - return code in the returncode attribute. - - The arguments are the same as for the Popen constructor. Example: - - check_call(["ls", "-l"]) - -Exceptions ----------- -Exceptions raised in the child process, before the new program has -started to execute, will be re-raised in the parent. Additionally, -the exception object will have one extra attribute called -'child_traceback', which is a string containing traceback information -from the childs point of view. - -The most common exception raised is OSError. This occurs, for -example, when trying to execute a non-existent file. Applications -should prepare for OSErrors. - -A ValueError will be raised if Popen is called with invalid arguments. - -check_call() will raise CalledProcessError, if the called process -returns a non-zero return code. - - -Security --------- -Unlike some other popen functions, this implementation will never call -/bin/sh implicitly. This means that all characters, including shell -metacharacters, can safely be passed to child processes. - - -Popen objects -============= -Instances of the Popen class have the following methods: - -poll() - Check if child process has terminated. Returns returncode - attribute. - -wait() - Wait for child process to terminate. Returns returncode attribute. - -communicate(input=None) - Interact with process: Send data to stdin. Read data from stdout - and stderr, until end-of-file is reached. Wait for process to - terminate. The optional stdin argument should be a string to be - sent to the child process, or None, if no data should be sent to - the child. - - communicate() returns a tuple (stdout, stderr). - - Note: The data read is buffered in memory, so do not use this - method if the data size is large or unlimited. - -The following attributes are also available: - -stdin - If the stdin argument is PIPE, this attribute is a file object - that provides input to the child process. Otherwise, it is None. - -stdout - If the stdout argument is PIPE, this attribute is a file object - that provides output from the child process. Otherwise, it is - None. - -stderr - If the stderr argument is PIPE, this attribute is file object that - provides error output from the child process. Otherwise, it is - None. - -pid - The process ID of the child process. - -returncode - The child return code. A None value indicates that the process - hasn't terminated yet. A negative value -N indicates that the - child was terminated by signal N (UNIX only). - - -Replacing older functions with the subprocess module -==================================================== -In this section, "a ==> b" means that b can be used as a replacement -for a. - -Note: All functions in this section fail (more or less) silently if -the executed program cannot be found; this module raises an OSError -exception. - -In the following examples, we assume that the subprocess module is -imported with "from subprocess import *". - - -Replacing /bin/sh shell backquote ---------------------------------- -output=`mycmd myarg` -==> -output = Popen(["mycmd", "myarg"], stdout=PIPE).communicate()[0] - - -Replacing shell pipe line -------------------------- -output=`dmesg | grep hda` -==> -p1 = Popen(["dmesg"], stdout=PIPE) -p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE) -output = p2.communicate()[0] - - -Replacing os.system() ---------------------- -sts = os.system("mycmd" + " myarg") -==> -p = Popen("mycmd" + " myarg", shell=True) -pid, sts = os.waitpid(p.pid, 0) - -Note: - -* Calling the program through the shell is usually not required. - -* It's easier to look at the returncode attribute than the - exitstatus. - -A more real-world example would look like this: - -try: - retcode = call("mycmd" + " myarg", shell=True) - if retcode < 0: - print >>sys.stderr, "Child was terminated by signal", -retcode - else: - print >>sys.stderr, "Child returned", retcode -except OSError, e: - print >>sys.stderr, "Execution failed:", e - - -Replacing os.spawn* -------------------- -P_NOWAIT example: - -pid = os.spawnlp(os.P_NOWAIT, "/bin/mycmd", "mycmd", "myarg") -==> -pid = Popen(["/bin/mycmd", "myarg"]).pid - - -P_WAIT example: - -retcode = os.spawnlp(os.P_WAIT, "/bin/mycmd", "mycmd", "myarg") -==> -retcode = call(["/bin/mycmd", "myarg"]) - - -Vector example: - -os.spawnvp(os.P_NOWAIT, path, args) -==> -Popen([path] + args[1:]) - - -Environment example: - -os.spawnlpe(os.P_NOWAIT, "/bin/mycmd", "mycmd", "myarg", env) -==> -Popen(["/bin/mycmd", "myarg"], env={"PATH": "/usr/bin"}) - - -Replacing os.popen* -------------------- -pipe = os.popen(cmd, mode='r', bufsize) -==> -pipe = Popen(cmd, shell=True, bufsize=bufsize, stdout=PIPE).stdout - -pipe = os.popen(cmd, mode='w', bufsize) -==> -pipe = Popen(cmd, shell=True, bufsize=bufsize, stdin=PIPE).stdin - - -(child_stdin, child_stdout) = os.popen2(cmd, mode, bufsize) -==> -p = Popen(cmd, shell=True, bufsize=bufsize, - stdin=PIPE, stdout=PIPE, close_fds=True) -(child_stdin, child_stdout) = (p.stdin, p.stdout) - - -(child_stdin, - child_stdout, - child_stderr) = os.popen3(cmd, mode, bufsize) -==> -p = Popen(cmd, shell=True, bufsize=bufsize, - stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True) -(child_stdin, - child_stdout, - child_stderr) = (p.stdin, p.stdout, p.stderr) - - -(child_stdin, child_stdout_and_stderr) = os.popen4(cmd, mode, bufsize) -==> -p = Popen(cmd, shell=True, bufsize=bufsize, - stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True) -(child_stdin, child_stdout_and_stderr) = (p.stdin, p.stdout) - - -Replacing popen2.* ------------------- -Note: If the cmd argument to popen2 functions is a string, the command -is executed through /bin/sh. If it is a list, the command is directly -executed. - -(child_stdout, child_stdin) = popen2.popen2("somestring", bufsize, mode) -==> -p = Popen(["somestring"], shell=True, bufsize=bufsize - stdin=PIPE, stdout=PIPE, close_fds=True) -(child_stdout, child_stdin) = (p.stdout, p.stdin) - - -(child_stdout, child_stdin) = popen2.popen2(["mycmd", "myarg"], bufsize, mode) -==> -p = Popen(["mycmd", "myarg"], bufsize=bufsize, - stdin=PIPE, stdout=PIPE, close_fds=True) -(child_stdout, child_stdin) = (p.stdout, p.stdin) - -The popen2.Popen3 and popen3.Popen4 basically works as subprocess.Popen, -except that: - -* subprocess.Popen raises an exception if the execution fails -* the capturestderr argument is replaced with the stderr argument. -* stdin=PIPE and stdout=PIPE must be specified. -* popen2 closes all filedescriptors by default, but you have to specify - close_fds=True with subprocess.Popen. - - -""" - -import sys -mswindows = (sys.platform == "win32") - -import os -import types -import traceback - -# Exception classes used by this module. -class CalledProcessError(Exception): - """This exception is raised when a process run by check_call() returns - a non-zero exit status. The exit status will be stored in the - returncode attribute.""" - def __init__(self, returncode, cmd): - self.returncode = returncode - self.cmd = cmd - def __str__(self): - return "Command '%s' returned non-zero exit status %d" % (self.cmd, self.returncode) - - -if mswindows: - try: - import threading - except ImportError: - # SCons: the threading module is only used by the communicate() - # method, which we don't actually use, so don't worry if we - # can't import it. - pass - import msvcrt - try: - # Try to get _subprocess - from _subprocess import * - class STARTUPINFO(object): - dwFlags = 0 - hStdInput = None - hStdOutput = None - hStdError = None - wShowWindow = 0 - class pywintypes(object): - error = IOError - except ImportError: - # If not there, then drop back to requiring pywin32 - # TODO: Should this be wrapped in try as well? To notify user to install - # pywin32 ? With URL to it? - import pywintypes - from win32api import GetStdHandle, STD_INPUT_HANDLE, \ - STD_OUTPUT_HANDLE, STD_ERROR_HANDLE - from win32api import GetCurrentProcess, DuplicateHandle, \ - GetModuleFileName, GetVersion - from win32con import DUPLICATE_SAME_ACCESS, SW_HIDE - from win32pipe import CreatePipe - from win32process import CreateProcess, STARTUPINFO, \ - GetExitCodeProcess, STARTF_USESTDHANDLES, \ - STARTF_USESHOWWINDOW, CREATE_NEW_CONSOLE - from win32event import WaitForSingleObject, INFINITE, WAIT_OBJECT_0 - - -else: - import select - import errno - import fcntl - import pickle - - try: - fcntl.F_GETFD - except AttributeError: - fcntl.F_GETFD = 1 - - try: - fcntl.F_SETFD - except AttributeError: - fcntl.F_SETFD = 2 - -__all__ = ["Popen", "PIPE", "STDOUT", "call", "check_call", "CalledProcessError"] - -try: - MAXFD = os.sysconf("SC_OPEN_MAX") -except KeyboardInterrupt: - raise # SCons: don't swallow keyboard interrupts -except: - MAXFD = 256 - -try: - isinstance(1, int) -except TypeError: - def is_int(obj): - return isinstance(obj, type(1)) - def is_int_or_long(obj): - return type(obj) in (type(1), type(1L)) -else: - def is_int(obj): - return isinstance(obj, int) - def is_int_or_long(obj): - return isinstance(obj, (int, long)) - -try: - types.StringTypes -except AttributeError: - try: - types.StringTypes = (str, unicode) - except NameError: - types.StringTypes = (str,) -def is_string(obj): - return isinstance(obj, types.StringTypes) - -_active = [] - -def _cleanup(): - for inst in _active[:]: - if inst.poll(_deadstate=sys.maxsize) >= 0: - try: - _active.remove(inst) - except ValueError: - # This can happen if two threads create a new Popen instance. - # It's harmless that it was already removed, so ignore. - pass - -PIPE = -1 -STDOUT = -2 - - -def call(*popenargs, **kwargs): - """Run command with arguments. Wait for command to complete, then - return the returncode attribute. - - The arguments are the same as for the Popen constructor. Example: - - retcode = call(["ls", "-l"]) - """ - return apply(Popen, popenargs, kwargs).wait() - - -def check_call(*popenargs, **kwargs): - """Run command with arguments. Wait for command to complete. If - the exit code was zero then return, otherwise raise - CalledProcessError. The CalledProcessError object will have the - return code in the returncode attribute. - - The arguments are the same as for the Popen constructor. Example: - - check_call(["ls", "-l"]) - """ - retcode = call(*popenargs, **kwargs) - cmd = kwargs.get("args") - if cmd is None: - cmd = popenargs[0] - if retcode: - raise CalledProcessError(retcode, cmd) - return retcode - - -def list2cmdline(seq): - """ - Translate a sequence of arguments into a command line - string, using the same rules as the MS C runtime: - - 1) Arguments are delimited by white space, which is either a - space or a tab. - - 2) A string surrounded by double quotation marks is - interpreted as a single argument, regardless of white space - contained within. A quoted string can be embedded in an - argument. - - 3) A double quotation mark preceded by a backslash is - interpreted as a literal double quotation mark. - - 4) Backslashes are interpreted literally, unless they - immediately precede a double quotation mark. - - 5) If backslashes immediately precede a double quotation mark, - every pair of backslashes is interpreted as a literal - backslash. If the number of backslashes is odd, the last - backslash escapes the next double quotation mark as - described in rule 3. - """ - - # See - # http://msdn.microsoft.com/library/en-us/vccelng/htm/progs_12.asp - result = [] - needquote = False - for arg in seq: - bs_buf = [] - - # Add a space to separate this argument from the others - if result: - result.append(' ') - - needquote = (" " in arg) or ("\t" in arg) - if needquote: - result.append('"') - - for c in arg: - if c == '\\': - # Don't know if we need to double yet. - bs_buf.append(c) - elif c == '"': - # Double backspaces. - result.append('\\' * len(bs_buf)*2) - bs_buf = [] - result.append('\\"') - else: - # Normal char - if bs_buf: - result.extend(bs_buf) - bs_buf = [] - result.append(c) - - # Add remaining backspaces, if any. - if bs_buf: - result.extend(bs_buf) - - if needquote: - result.extend(bs_buf) - result.append('"') - - return ''.join(result) - -class Popen(object): - def __init__(self, args, bufsize=0, executable=None, - stdin=None, stdout=None, stderr=None, - preexec_fn=None, close_fds=False, shell=False, - cwd=None, env=None, universal_newlines=False, - startupinfo=None, creationflags=0): - """Create new Popen instance.""" - _cleanup() - - self._child_created = False - if not is_int_or_long(bufsize): - raise TypeError("bufsize must be an integer") - - if mswindows: - if preexec_fn is not None: - raise ValueError("preexec_fn is not supported on Windows " - "platforms") - if close_fds: - raise ValueError("close_fds is not supported on Windows " - "platforms") - else: - # POSIX - if startupinfo is not None: - raise ValueError("startupinfo is only supported on Windows " - "platforms") - if creationflags != 0: - raise ValueError("creationflags is only supported on Windows " - "platforms") - - self.stdin = None - self.stdout = None - self.stderr = None - self.pid = None - self.returncode = None - self.universal_newlines = universal_newlines - - # Input and output objects. The general principle is like - # this: - # - # Parent Child - # ------ ----- - # p2cwrite ---stdin---> p2cread - # c2pread <--stdout--- c2pwrite - # errread <--stderr--- errwrite - # - # On POSIX, the child objects are file descriptors. On - # Windows, these are Windows file handles. The parent objects - # are file descriptors on both platforms. The parent objects - # are None when not using PIPEs. The child objects are None - # when not redirecting. - - (p2cread, p2cwrite, - c2pread, c2pwrite, - errread, errwrite) = self._get_handles(stdin, stdout, stderr) - - self._execute_child(args, executable, preexec_fn, close_fds, - cwd, env, universal_newlines, - startupinfo, creationflags, shell, - p2cread, p2cwrite, - c2pread, c2pwrite, - errread, errwrite) - - if p2cwrite: - self.stdin = os.fdopen(p2cwrite, 'wb', bufsize) - if c2pread: - if universal_newlines: - self.stdout = os.fdopen(c2pread, 'rU', bufsize) - else: - self.stdout = os.fdopen(c2pread, 'rb', bufsize) - if errread: - if universal_newlines: - self.stderr = os.fdopen(errread, 'rU', bufsize) - else: - self.stderr = os.fdopen(errread, 'rb', bufsize) - - - def _translate_newlines(self, data): - data = data.replace("\r\n", "\n") - data = data.replace("\r", "\n") - return data - - - def __del__(self): - if not self._child_created: - # We didn't get to successfully create a child process. - return - # In case the child hasn't been waited on, check if it's done. - self.poll(_deadstate=sys.maxsize) - if self.returncode is None and _active is not None: - # Child is still running, keep us alive until we can wait on it. - _active.append(self) - - - def communicate(self, input=None): - """Interact with process: Send data to stdin. Read data from - stdout and stderr, until end-of-file is reached. Wait for - process to terminate. The optional input argument should be a - string to be sent to the child process, or None, if no data - should be sent to the child. - - communicate() returns a tuple (stdout, stderr).""" - - # Optimization: If we are only using one pipe, or no pipe at - # all, using select() or threads is unnecessary. - if [self.stdin, self.stdout, self.stderr].count(None) >= 2: - stdout = None - stderr = None - if self.stdin: - if input: - self.stdin.write(input) - self.stdin.close() - elif self.stdout: - stdout = self.stdout.read() - elif self.stderr: - stderr = self.stderr.read() - self.wait() - return (stdout, stderr) - - return self._communicate(input) - - - if mswindows: - # - # Windows methods - # - def _get_handles(self, stdin, stdout, stderr): - """Construct and return tupel with IO objects: - p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite - """ - if stdin is None and stdout is None and stderr is None: - return (None, None, None, None, None, None) - - p2cread, p2cwrite = None, None - c2pread, c2pwrite = None, None - errread, errwrite = None, None - - if stdin is None: - p2cread = GetStdHandle(STD_INPUT_HANDLE) - elif stdin == PIPE: - p2cread, p2cwrite = CreatePipe(None, 0) - # Detach and turn into fd - p2cwrite = p2cwrite.Detach() - p2cwrite = msvcrt.open_osfhandle(p2cwrite, 0) - elif is_int(stdin): - p2cread = msvcrt.get_osfhandle(stdin) - else: - # Assuming file-like object - p2cread = msvcrt.get_osfhandle(stdin.fileno()) - p2cread = self._make_inheritable(p2cread) - - if stdout is None: - c2pwrite = GetStdHandle(STD_OUTPUT_HANDLE) - elif stdout == PIPE: - c2pread, c2pwrite = CreatePipe(None, 0) - # Detach and turn into fd - c2pread = c2pread.Detach() - c2pread = msvcrt.open_osfhandle(c2pread, 0) - elif is_int(stdout): - c2pwrite = msvcrt.get_osfhandle(stdout) - else: - # Assuming file-like object - c2pwrite = msvcrt.get_osfhandle(stdout.fileno()) - c2pwrite = self._make_inheritable(c2pwrite) - - if stderr is None: - errwrite = GetStdHandle(STD_ERROR_HANDLE) - elif stderr == PIPE: - errread, errwrite = CreatePipe(None, 0) - # Detach and turn into fd - errread = errread.Detach() - errread = msvcrt.open_osfhandle(errread, 0) - elif stderr == STDOUT: - errwrite = c2pwrite - elif is_int(stderr): - errwrite = msvcrt.get_osfhandle(stderr) - else: - # Assuming file-like object - errwrite = msvcrt.get_osfhandle(stderr.fileno()) - errwrite = self._make_inheritable(errwrite) - - return (p2cread, p2cwrite, - c2pread, c2pwrite, - errread, errwrite) - - - def _make_inheritable(self, handle): - """Return a duplicate of handle, which is inheritable""" - return DuplicateHandle(GetCurrentProcess(), handle, - GetCurrentProcess(), 0, 1, - DUPLICATE_SAME_ACCESS) - - - def _find_w9xpopen(self): - """Find and return absolut path to w9xpopen.exe""" - w9xpopen = os.path.join(os.path.dirname(GetModuleFileName(0)), - "w9xpopen.exe") - if not os.path.exists(w9xpopen): - # Eeek - file-not-found - possibly an embedding - # situation - see if we can locate it in sys.exec_prefix - w9xpopen = os.path.join(os.path.dirname(sys.exec_prefix), - "w9xpopen.exe") - if not os.path.exists(w9xpopen): - raise RuntimeError("Cannot locate w9xpopen.exe, which is " - "needed for Popen to work with your " - "shell or platform.") - return w9xpopen - - - def _execute_child(self, args, executable, preexec_fn, close_fds, - cwd, env, universal_newlines, - startupinfo, creationflags, shell, - p2cread, p2cwrite, - c2pread, c2pwrite, - errread, errwrite): - """Execute program (MS Windows version)""" - - if not isinstance(args, types.StringTypes): - args = list2cmdline(args) - - # Process startup details - if startupinfo is None: - startupinfo = STARTUPINFO() - if None not in (p2cread, c2pwrite, errwrite): - startupinfo.dwFlags = startupinfo.dwFlags | STARTF_USESTDHANDLES - startupinfo.hStdInput = p2cread - startupinfo.hStdOutput = c2pwrite - startupinfo.hStdError = errwrite - - if shell: - startupinfo.dwFlags = startupinfo.dwFlags | STARTF_USESHOWWINDOW - startupinfo.wShowWindow = SW_HIDE - comspec = os.environ.get("COMSPEC", "cmd.exe") - args = comspec + " /c " + args - if (GetVersion() >= 0x80000000L or - os.path.basename(comspec).lower() == "command.com"): - # Win9x, or using command.com on NT. We need to - # use the w9xpopen intermediate program. For more - # information, see KB Q150956 - # (http://web.archive.org/web/20011105084002/http://support.microsoft.com/support/kb/articles/Q150/9/56.asp) - w9xpopen = self._find_w9xpopen() - args = '"%s" %s' % (w9xpopen, args) - # Not passing CREATE_NEW_CONSOLE has been known to - # cause random failures on win9x. Specifically a - # dialog: "Your program accessed mem currently in - # use at xxx" and a hopeful warning about the - # stability of your system. Cost is Ctrl+C wont - # kill children. - creationflags = creationflags | CREATE_NEW_CONSOLE - - # Start the process - try: - hp, ht, pid, tid = CreateProcess(executable, args, - # no special security - None, None, - # must inherit handles to pass std - # handles - 1, - creationflags, - env, - cwd, - startupinfo) - except pywintypes.error, e: - # Translate pywintypes.error to WindowsError, which is - # a subclass of OSError. FIXME: We should really - # translate errno using _sys_errlist (or simliar), but - # how can this be done from Python? - raise WindowsError(*e.args) - - # Retain the process handle, but close the thread handle - self._child_created = True - self._handle = hp - self.pid = pid - ht.Close() - - # Child is launched. Close the parent's copy of those pipe - # handles that only the child should have open. You need - # to make sure that no handles to the write end of the - # output pipe are maintained in this process or else the - # pipe will not close when the child process exits and the - # ReadFile will hang. - if p2cread is not None: - p2cread.Close() - if c2pwrite is not None: - c2pwrite.Close() - if errwrite is not None: - errwrite.Close() - - - def poll(self, _deadstate=None): - """Check if child process has terminated. Returns returncode - attribute.""" - if self.returncode is None: - if WaitForSingleObject(self._handle, 0) == WAIT_OBJECT_0: - self.returncode = GetExitCodeProcess(self._handle) - return self.returncode - - - def wait(self): - """Wait for child process to terminate. Returns returncode - attribute.""" - if self.returncode is None: - obj = WaitForSingleObject(self._handle, INFINITE) - self.returncode = GetExitCodeProcess(self._handle) - return self.returncode - - - def _readerthread(self, fh, buffer): - buffer.append(fh.read()) - - - def _communicate(self, input): - stdout = None # Return - stderr = None # Return - - if self.stdout: - stdout = [] - stdout_thread = threading.Thread(target=self._readerthread, - args=(self.stdout, stdout)) - stdout_thread.setDaemon(True) - stdout_thread.start() - if self.stderr: - stderr = [] - stderr_thread = threading.Thread(target=self._readerthread, - args=(self.stderr, stderr)) - stderr_thread.setDaemon(True) - stderr_thread.start() - - if self.stdin: - if input is not None: - self.stdin.write(input) - self.stdin.close() - - if self.stdout: - stdout_thread.join() - if self.stderr: - stderr_thread.join() - - # All data exchanged. Translate lists into strings. - if stdout is not None: - stdout = stdout[0] - if stderr is not None: - stderr = stderr[0] - - # Translate newlines, if requested. We cannot let the file - # object do the translation: It is based on stdio, which is - # impossible to combine with select (unless forcing no - # buffering). - if self.universal_newlines and hasattr(file, 'newlines'): - if stdout: - stdout = self._translate_newlines(stdout) - if stderr: - stderr = self._translate_newlines(stderr) - - self.wait() - return (stdout, stderr) - - else: - # - # POSIX methods - # - def _get_handles(self, stdin, stdout, stderr): - """Construct and return tupel with IO objects: - p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite - """ - p2cread, p2cwrite = None, None - c2pread, c2pwrite = None, None - errread, errwrite = None, None - - if stdin is None: - pass - elif stdin == PIPE: - p2cread, p2cwrite = os.pipe() - elif is_int(stdin): - p2cread = stdin - else: - # Assuming file-like object - p2cread = stdin.fileno() - - if stdout is None: - pass - elif stdout == PIPE: - c2pread, c2pwrite = os.pipe() - elif is_int(stdout): - c2pwrite = stdout - else: - # Assuming file-like object - c2pwrite = stdout.fileno() - - if stderr is None: - pass - elif stderr == PIPE: - errread, errwrite = os.pipe() - elif stderr == STDOUT: - errwrite = c2pwrite - elif is_int(stderr): - errwrite = stderr - else: - # Assuming file-like object - errwrite = stderr.fileno() - - return (p2cread, p2cwrite, - c2pread, c2pwrite, - errread, errwrite) - - - def _set_cloexec_flag(self, fd): - try: - cloexec_flag = fcntl.FD_CLOEXEC - except AttributeError: - cloexec_flag = 1 - - old = fcntl.fcntl(fd, fcntl.F_GETFD) - fcntl.fcntl(fd, fcntl.F_SETFD, old | cloexec_flag) - - - def _close_fds(self, but): - for i in range(3, MAXFD): - if i == but: - continue - try: - os.close(i) - except KeyboardInterrupt: - raise # SCons: don't swallow keyboard interrupts - except: - pass - - - def _execute_child(self, args, executable, preexec_fn, close_fds, - cwd, env, universal_newlines, - startupinfo, creationflags, shell, - p2cread, p2cwrite, - c2pread, c2pwrite, - errread, errwrite): - """Execute program (POSIX version)""" - - if is_string(args): - args = [args] - - if shell: - args = ["/bin/sh", "-c"] + args - - if executable is None: - executable = args[0] - - # For transferring possible exec failure from child to parent - # The first char specifies the exception type: 0 means - # OSError, 1 means some other error. - errpipe_read, errpipe_write = os.pipe() - self._set_cloexec_flag(errpipe_write) - - self.pid = os.fork() - self._child_created = True - if self.pid == 0: - # Child - try: - # Close parent's pipe ends - if p2cwrite: - os.close(p2cwrite) - if c2pread: - os.close(c2pread) - if errread: - os.close(errread) - os.close(errpipe_read) - - # Dup fds for child - if p2cread: - os.dup2(p2cread, 0) - if c2pwrite: - os.dup2(c2pwrite, 1) - if errwrite: - os.dup2(errwrite, 2) - - # Close pipe fds. Make sure we don't close the same - # fd more than once, or standard fds. - try: - set - except NameError: - # Fall-back for earlier Python versions, so epydoc - # can use this module directly to execute things. - if p2cread: - os.close(p2cread) - if c2pwrite and c2pwrite not in (p2cread,): - os.close(c2pwrite) - if errwrite and errwrite not in (p2cread, c2pwrite): - os.close(errwrite) - else: - for fd in set((p2cread, c2pwrite, errwrite))-set((0,1,2)): - if fd: os.close(fd) - - # Close all other fds, if asked for - if close_fds: - self._close_fds(but=errpipe_write) - - if cwd is not None: - os.chdir(cwd) - - if preexec_fn: - apply(preexec_fn) - - if env is None: - os.execvp(executable, args) - else: - os.execvpe(executable, args, env) - - except KeyboardInterrupt: - raise # SCons: don't swallow keyboard interrupts - - except: - exc_type, exc_value, tb = sys.exc_info() - # Save the traceback and attach it to the exception object - exc_lines = traceback.format_exception(exc_type, - exc_value, - tb) - exc_value.child_traceback = ''.join(exc_lines) - os.write(errpipe_write, pickle.dumps(exc_value)) - - # This exitcode won't be reported to applications, so it - # really doesn't matter what we return. - os._exit(255) - - # Parent - os.close(errpipe_write) - if p2cread and p2cwrite: - os.close(p2cread) - if c2pwrite and c2pread: - os.close(c2pwrite) - if errwrite and errread: - os.close(errwrite) - - # Wait for exec to fail or succeed; possibly raising exception - data = os.read(errpipe_read, 1048576) # Exceptions limited to 1 MB - os.close(errpipe_read) - if data != "": - os.waitpid(self.pid, 0) - child_exception = pickle.loads(data) - raise child_exception - - - def _handle_exitstatus(self, sts): - if os.WIFSIGNALED(sts): - self.returncode = -os.WTERMSIG(sts) - elif os.WIFEXITED(sts): - self.returncode = os.WEXITSTATUS(sts) - else: - # Should never happen - raise RuntimeError("Unknown child exit status!") - - - def poll(self, _deadstate=None): - """Check if child process has terminated. Returns returncode - attribute.""" - if self.returncode is None: - try: - pid, sts = os.waitpid(self.pid, os.WNOHANG) - if pid == self.pid: - self._handle_exitstatus(sts) - except os.error: - if _deadstate is not None: - self.returncode = _deadstate - return self.returncode - - - def wait(self): - """Wait for child process to terminate. Returns returncode - attribute.""" - if self.returncode is None: - pid, sts = os.waitpid(self.pid, 0) - self._handle_exitstatus(sts) - return self.returncode - - - def _communicate(self, input): - read_set = [] - write_set = [] - stdout = None # Return - stderr = None # Return - - if self.stdin: - # Flush stdio buffer. This might block, if the user has - # been writing to .stdin in an uncontrolled fashion. - self.stdin.flush() - if input: - write_set.append(self.stdin) - else: - self.stdin.close() - if self.stdout: - read_set.append(self.stdout) - stdout = [] - if self.stderr: - read_set.append(self.stderr) - stderr = [] - - input_offset = 0 - while read_set or write_set: - rlist, wlist, xlist = select.select(read_set, write_set, []) - - if self.stdin in wlist: - # When select has indicated that the file is writable, - # we can write up to PIPE_BUF bytes without risk - # blocking. POSIX defines PIPE_BUF >= 512 - m = memoryview(input)[input_offset:input_offset+512] - bytes_written = os.write(self.stdin.fileno(), m) - input_offset = input_offset + bytes_written - if input_offset >= len(input): - self.stdin.close() - write_set.remove(self.stdin) - - if self.stdout in rlist: - data = os.read(self.stdout.fileno(), 1024) - if data == "": - self.stdout.close() - read_set.remove(self.stdout) - stdout.append(data) - - if self.stderr in rlist: - data = os.read(self.stderr.fileno(), 1024) - if data == "": - self.stderr.close() - read_set.remove(self.stderr) - stderr.append(data) - - # All data exchanged. Translate lists into strings. - if stdout is not None: - stdout = ''.join(stdout) - if stderr is not None: - stderr = ''.join(stderr) - - # Translate newlines, if requested. We cannot let the file - # object do the translation: It is based on stdio, which is - # impossible to combine with select (unless forcing no - # buffering). - if self.universal_newlines and hasattr(file, 'newlines'): - if stdout: - stdout = self._translate_newlines(stdout) - if stderr: - stderr = self._translate_newlines(stderr) - - self.wait() - return (stdout, stderr) - - -def _demo_posix(): - # - # Example 1: Simple redirection: Get process list - # - plist = Popen(["ps"], stdout=PIPE).communicate()[0] - print "Process list:" - print plist - - # - # Example 2: Change uid before executing child - # - if os.getuid() == 0: - p = Popen(["id"], preexec_fn=lambda: os.setuid(100)) - p.wait() - - # - # Example 3: Connecting several subprocesses - # - print "Looking for 'hda'..." - p1 = Popen(["dmesg"], stdout=PIPE) - p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE) - print repr(p2.communicate()[0]) - - # - # Example 4: Catch execution error - # - print - print "Trying a weird file..." - try: - print Popen(["/this/path/does/not/exist"]).communicate() - except OSError, e: - if e.errno == errno.ENOENT: - print "The file didn't exist. I thought so..." - print "Child traceback:" - print e.child_traceback - else: - print "Error", e.errno - else: - sys.stderr.write( "Gosh. No error.\n" ) - - -def _demo_windows(): - # - # Example 1: Connecting several subprocesses - # - print "Looking for 'PROMPT' in set output..." - p1 = Popen("set", stdout=PIPE, shell=True) - p2 = Popen('find "PROMPT"', stdin=p1.stdout, stdout=PIPE) - print repr(p2.communicate()[0]) - - # - # Example 2: Simple execution of program - # - print "Executing calc..." - p = Popen("calc") - p.wait() - - -if __name__ == "__main__": - if mswindows: - _demo_windows() - else: - _demo_posix() - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: -- cgit v0.12 From 63a9014d1023fd2fdd256cd42e4c4843e5bdcee0 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Thu, 19 Nov 2015 10:41:35 -0800 Subject: removing compat for sets. python 2.7 supports sets --- src/engine/SCons/compat/__init__.py | 8 - src/engine/SCons/compat/_scons_sets.py | 563 --------------------------------- 2 files changed, 571 deletions(-) delete mode 100644 src/engine/SCons/compat/_scons_sets.py diff --git a/src/engine/SCons/compat/__init__.py b/src/engine/SCons/compat/__init__.py index 281392c..ab21faf 100644 --- a/src/engine/SCons/compat/__init__.py +++ b/src/engine/SCons/compat/__init__.py @@ -103,14 +103,6 @@ except ImportError: # can fall back to using timestamp. pass -try: - set -except NameError: - # Pre-2.4 Python has no native set type - import_as('_scons_sets', 'sets') - import builtins, sets - builtins.set = sets.Set - try: import collections diff --git a/src/engine/SCons/compat/_scons_sets.py b/src/engine/SCons/compat/_scons_sets.py deleted file mode 100644 index 0fde994..0000000 --- a/src/engine/SCons/compat/_scons_sets.py +++ /dev/null @@ -1,563 +0,0 @@ -"""Classes to represent arbitrary sets (including sets of sets). - -This module implements sets using dictionaries whose values are -ignored. The usual operations (union, intersection, deletion, etc.) -are provided as both methods and operators. - -Important: sets are not sequences! While they support 'x in s', -'len(s)', and 'for x in s', none of those operations are unique for -sequences; for example, mappings support all three as well. The -characteristic operation for sequences is subscripting with small -integers: s[i], for i in range(len(s)). Sets don't support -subscripting at all. Also, sequences allow multiple occurrences and -their elements have a definite order; sets on the other hand don't -record multiple occurrences and don't remember the order of element -insertion (which is why they don't support s[i]). - -The following classes are provided: - -BaseSet -- All the operations common to both mutable and immutable - sets. This is an abstract class, not meant to be directly - instantiated. - -Set -- Mutable sets, subclass of BaseSet; not hashable. - -ImmutableSet -- Immutable sets, subclass of BaseSet; hashable. - An iterable argument is mandatory to create an ImmutableSet. - -_TemporarilyImmutableSet -- A wrapper around a Set, hashable, - giving the same hash value as the immutable set equivalent - would have. Do not use this class directly. - -Only hashable objects can be added to a Set. In particular, you cannot -really add a Set as an element to another Set; if you try, what is -actually added is an ImmutableSet built from it (it compares equal to -the one you tried adding). - -When you ask if `x in y' where x is a Set and y is a Set or -ImmutableSet, x is wrapped into a _TemporarilyImmutableSet z, and -what's tested is actually `z in y'. - -""" - -# Code history: -# -# - Greg V. Wilson wrote the first version, using a different approach -# to the mutable/immutable problem, and inheriting from dict. -# -# - Alex Martelli modified Greg's version to implement the current -# Set/ImmutableSet approach, and make the data an attribute. -# -# - Guido van Rossum rewrote much of the code, made some API changes, -# and cleaned up the docstrings. -# -# - Raymond Hettinger added a number of speedups and other -# improvements. - -# protect this import from the fixers... -exec('from itertools import ifilterfalse as filterfalse') - -__all__ = ['BaseSet', 'Set', 'ImmutableSet'] - -class BaseSet(object): - """Common base class for mutable and immutable sets.""" - - __slots__ = ['_data'] - - # Constructor - - def __init__(self): - """This is an abstract class.""" - # Don't call this from a concrete subclass! - if self.__class__ is BaseSet: - raise TypeError("BaseSet is an abstract class. " - "Use Set or ImmutableSet.") - - # Standard protocols: __len__, __repr__, __str__, __iter__ - - def __len__(self): - """Return the number of elements of a set.""" - return len(self._data) - - def __repr__(self): - """Return string representation of a set. - - This looks like 'Set([])'. - """ - return self._repr() - - # __str__ is the same as __repr__ - __str__ = __repr__ - - def _repr(self, sort_them=False): - elements = list(self._data.keys()) - if sort_them: - elements.sort() - return '%s(%r)' % (self.__class__.__name__, elements) - - def __iter__(self): - """Return an iterator over the elements or a set. - - This is the keys iterator for the underlying dict. - """ - # Wrapping name in () prevents fixer from "fixing" this - return (self._data.iterkeys)() - - # Three-way comparison is not supported. However, because __eq__ is - # tried before __cmp__, if Set x == Set y, x.__eq__(y) returns True and - # then cmp(x, y) returns 0 (Python doesn't actually call __cmp__ in this - # case). - - def __cmp__(self, other): - raise TypeError("can't compare sets using cmp()") - - # Equality comparisons using the underlying dicts. Mixed-type comparisons - # are allowed here, where Set == z for non-Set z always returns False, - # and Set != z always True. This allows expressions like "x in y" to - # give the expected result when y is a sequence of mixed types, not - # raising a pointless TypeError just because y contains a Set, or x is - # a Set and y contain's a non-set ("in" invokes only __eq__). - # Subtle: it would be nicer if __eq__ and __ne__ could return - # NotImplemented instead of True or False. Then the other comparand - # would get a chance to determine the result, and if the other comparand - # also returned NotImplemented then it would fall back to object address - # comparison (which would always return False for __eq__ and always - # True for __ne__). However, that doesn't work, because this type - # *also* implements __cmp__: if, e.g., __eq__ returns NotImplemented, - # Python tries __cmp__ next, and the __cmp__ here then raises TypeError. - - def __eq__(self, other): - if isinstance(other, BaseSet): - return self._data == other._data - else: - return False - - def __ne__(self, other): - if isinstance(other, BaseSet): - return self._data != other._data - else: - return True - - # Copying operations - - def copy(self): - """Return a shallow copy of a set.""" - result = self.__class__() - result._data.update(self._data) - return result - - __copy__ = copy # For the copy module - - def __deepcopy__(self, memo): - """Return a deep copy of a set; used by copy module.""" - # This pre-creates the result and inserts it in the memo - # early, in case the deep copy recurses into another reference - # to this same set. A set can't be an element of itself, but - # it can certainly contain an object that has a reference to - # itself. - from copy import deepcopy - result = self.__class__() - memo[id(self)] = result - data = result._data - value = True - for elt in self: - data[deepcopy(elt, memo)] = value - return result - - # Standard set operations: union, intersection, both differences. - # Each has an operator version (e.g. __or__, invoked with |) and a - # method version (e.g. union). - # Subtle: Each pair requires distinct code so that the outcome is - # correct when the type of other isn't suitable. For example, if - # we did "union = __or__" instead, then Set().union(3) would return - # NotImplemented instead of raising TypeError (albeit that *why* it - # raises TypeError as-is is also a bit subtle). - - def __or__(self, other): - """Return the union of two sets as a new set. - - (I.e. all elements that are in either set.) - """ - if not isinstance(other, BaseSet): - return NotImplemented - return self.union(other) - - def union(self, other): - """Return the union of two sets as a new set. - - (I.e. all elements that are in either set.) - """ - result = self.__class__(self) - result._update(other) - return result - - def __and__(self, other): - """Return the intersection of two sets as a new set. - - (I.e. all elements that are in both sets.) - """ - if not isinstance(other, BaseSet): - return NotImplemented - return self.intersection(other) - - def intersection(self, other): - """Return the intersection of two sets as a new set. - - (I.e. all elements that are in both sets.) - """ - if not isinstance(other, BaseSet): - other = Set(other) - if len(self) <= len(other): - little, big = self, other - else: - little, big = other, self - common = iter(filter(big._data.has_key, little)) - return self.__class__(common) - - def __xor__(self, other): - """Return the symmetric difference of two sets as a new set. - - (I.e. all elements that are in exactly one of the sets.) - """ - if not isinstance(other, BaseSet): - return NotImplemented - return self.symmetric_difference(other) - - def symmetric_difference(self, other): - """Return the symmetric difference of two sets as a new set. - - (I.e. all elements that are in exactly one of the sets.) - """ - result = self.__class__() - data = result._data - value = True - selfdata = self._data - try: - otherdata = other._data - except AttributeError: - otherdata = Set(other)._data - for elt in filterfalse(otherdata.has_key, selfdata): - data[elt] = value - for elt in filterfalse(selfdata.has_key, otherdata): - data[elt] = value - return result - - def __sub__(self, other): - """Return the difference of two sets as a new Set. - - (I.e. all elements that are in this set and not in the other.) - """ - if not isinstance(other, BaseSet): - return NotImplemented - return self.difference(other) - - def difference(self, other): - """Return the difference of two sets as a new Set. - - (I.e. all elements that are in this set and not in the other.) - """ - result = self.__class__() - data = result._data - try: - otherdata = other._data - except AttributeError: - otherdata = Set(other)._data - value = True - for elt in filterfalse(otherdata.has_key, self): - data[elt] = value - return result - - # Membership test - - def __contains__(self, element): - """Report whether an element is a member of a set. - - (Called in response to the expression `element in self'.) - """ - try: - return element in self._data - except TypeError: - transform = getattr(element, "__as_temporarily_immutable__", None) - if transform is None: - raise # re-raise the TypeError exception we caught - return transform() in self._data - - # Subset and superset test - - def issubset(self, other): - """Report whether another set contains this set.""" - self._binary_sanity_check(other) - if len(self) > len(other): # Fast check for obvious cases - return False - for elt in filterfalse(other._data.has_key, self): - return False - return True - - def issuperset(self, other): - """Report whether this set contains another set.""" - self._binary_sanity_check(other) - if len(self) < len(other): # Fast check for obvious cases - return False - for elt in filterfalse(self._data.has_key, other): - return False - return True - - # Inequality comparisons using the is-subset relation. - __le__ = issubset - __ge__ = issuperset - - def __lt__(self, other): - self._binary_sanity_check(other) - return len(self) < len(other) and self.issubset(other) - - def __gt__(self, other): - self._binary_sanity_check(other) - return len(self) > len(other) and self.issuperset(other) - - # Assorted helpers - - def _binary_sanity_check(self, other): - # Check that the other argument to a binary operation is also - # a set, raising a TypeError otherwise. - if not isinstance(other, BaseSet): - raise TypeError("Binary operation only permitted between sets") - - def _compute_hash(self): - # Calculate hash code for a set by xor'ing the hash codes of - # the elements. This ensures that the hash code does not depend - # on the order in which elements are added to the set. This is - # not called __hash__ because a BaseSet should not be hashable; - # only an ImmutableSet is hashable. - result = 0 - for elt in self: - result ^= hash(elt) - return result - - def _update(self, iterable): - # The main loop for update() and the subclass __init__() methods. - data = self._data - - # Use the fast update() method when a dictionary is available. - if isinstance(iterable, BaseSet): - data.update(iterable._data) - return - - value = True - - if type(iterable) in (list, tuple, xrange): - # Optimized: we know that __iter__() and next() can't - # raise TypeError, so we can move 'try:' out of the loop. - it = iter(iterable) - while True: - try: - for element in it: - data[element] = value - return - except TypeError: - transform = getattr(element, "__as_immutable__", None) - if transform is None: - raise # re-raise the TypeError exception we caught - data[transform()] = value - else: - # Safe: only catch TypeError where intended - for element in iterable: - try: - data[element] = value - except TypeError: - transform = getattr(element, "__as_immutable__", None) - if transform is None: - raise # re-raise the TypeError exception we caught - data[transform()] = value - - -class ImmutableSet(BaseSet): - """Immutable set class.""" - - __slots__ = ['_hashcode'] - - # BaseSet + hashing - - def __init__(self, iterable=None): - """Construct an immutable set from an optional iterable.""" - self._hashcode = None - self._data = {} - if iterable is not None: - self._update(iterable) - - def __hash__(self): - if self._hashcode is None: - self._hashcode = self._compute_hash() - return self._hashcode - - def __getstate__(self): - return self._data, self._hashcode - - def __setstate__(self, state): - self._data, self._hashcode = state - -class Set(BaseSet): - """ Mutable set class.""" - - __slots__ = [] - - # BaseSet + operations requiring mutability; no hashing - - def __init__(self, iterable=None): - """Construct a set from an optional iterable.""" - self._data = {} - if iterable is not None: - self._update(iterable) - - def __getstate__(self): - # getstate's results are ignored if it is not - return self._data, - - def __setstate__(self, data): - self._data, = data - - def __hash__(self): - """A Set cannot be hashed.""" - # We inherit object.__hash__, so we must deny this explicitly - raise TypeError("Can't hash a Set, only an ImmutableSet.") - - # In-place union, intersection, differences. - # Subtle: The xyz_update() functions deliberately return None, - # as do all mutating operations on built-in container types. - # The __xyz__ spellings have to return self, though. - - def __ior__(self, other): - """Update a set with the union of itself and another.""" - self._binary_sanity_check(other) - self._data.update(other._data) - return self - - def union_update(self, other): - """Update a set with the union of itself and another.""" - self._update(other) - - def __iand__(self, other): - """Update a set with the intersection of itself and another.""" - self._binary_sanity_check(other) - self._data = (self & other)._data - return self - - def intersection_update(self, other): - """Update a set with the intersection of itself and another.""" - if isinstance(other, BaseSet): - self &= other - else: - self._data = (self.intersection(other))._data - - def __ixor__(self, other): - """Update a set with the symmetric difference of itself and another.""" - self._binary_sanity_check(other) - self.symmetric_difference_update(other) - return self - - def symmetric_difference_update(self, other): - """Update a set with the symmetric difference of itself and another.""" - data = self._data - value = True - if not isinstance(other, BaseSet): - other = Set(other) - if self is other: - self.clear() - for elt in other: - if elt in data: - del data[elt] - else: - data[elt] = value - - def __isub__(self, other): - """Remove all elements of another set from this set.""" - self._binary_sanity_check(other) - self.difference_update(other) - return self - - def difference_update(self, other): - """Remove all elements of another set from this set.""" - data = self._data - if not isinstance(other, BaseSet): - other = Set(other) - if self is other: - self.clear() - for elt in filter(data.has_key, other): - del data[elt] - - # Python dict-like mass mutations: update, clear - - def update(self, iterable): - """Add all values from an iterable (such as a list or file).""" - self._update(iterable) - - def clear(self): - """Remove all elements from this set.""" - self._data.clear() - - # Single-element mutations: add, remove, discard - - def add(self, element): - """Add an element to a set. - - This has no effect if the element is already present. - """ - try: - self._data[element] = True - except TypeError: - transform = getattr(element, "__as_immutable__", None) - if transform is None: - raise # re-raise the TypeError exception we caught - self._data[transform()] = True - - def remove(self, element): - """Remove an element from a set; it must be a member. - - If the element is not a member, raise a KeyError. - """ - try: - del self._data[element] - except TypeError: - transform = getattr(element, "__as_temporarily_immutable__", None) - if transform is None: - raise # re-raise the TypeError exception we caught - del self._data[transform()] - - def discard(self, element): - """Remove an element from a set if it is a member. - - If the element is not a member, do nothing. - """ - try: - self.remove(element) - except KeyError: - pass - - def pop(self): - """Remove and return an arbitrary set element.""" - return self._data.popitem()[0] - - def __as_immutable__(self): - # Return a copy of self as an immutable set - return ImmutableSet(self) - - def __as_temporarily_immutable__(self): - # Return self wrapped in a temporarily immutable set - return _TemporarilyImmutableSet(self) - - -class _TemporarilyImmutableSet(BaseSet): - # Wrap a mutable set as if it was temporarily immutable. - # This only supplies hashing and equality comparisons. - - def __init__(self, set): - self._set = set - self._data = set._data # Needed by ImmutableSet.__eq__() - - def __hash__(self): - return self._set._compute_hash() - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: -- cgit v0.12 From e806691e1e680d003c47ef6212ca7bf74e437c5b Mon Sep 17 00:00:00 2001 From: William Deegan Date: Thu, 19 Nov 2015 10:43:43 -0800 Subject: remove compat collections. python 2.7 supports collections --- src/engine/SCons/compat/__init__.py | 26 ---------------- src/engine/SCons/compat/_scons_collections.py | 45 --------------------------- 2 files changed, 71 deletions(-) delete mode 100644 src/engine/SCons/compat/_scons_collections.py diff --git a/src/engine/SCons/compat/__init__.py b/src/engine/SCons/compat/__init__.py index ab21faf..06cee57 100644 --- a/src/engine/SCons/compat/__init__.py +++ b/src/engine/SCons/compat/__init__.py @@ -105,32 +105,6 @@ except ImportError: try: - import collections -except ImportError: - # Pre-2.4 Python has no collections module. - import_as('_scons_collections', 'collections') -else: - try: - collections.UserDict - except AttributeError: - exec('from UserDict import UserDict as _UserDict') - collections.UserDict = _UserDict - del _UserDict - try: - collections.UserList - except AttributeError: - exec('from UserList import UserList as _UserList') - collections.UserList = _UserList - del _UserList - try: - collections.UserString - except AttributeError: - exec('from UserString import UserString as _UserString') - collections.UserString = _UserString - del _UserString - - -try: import io except ImportError: # Pre-2.6 Python has no io module. diff --git a/src/engine/SCons/compat/_scons_collections.py b/src/engine/SCons/compat/_scons_collections.py deleted file mode 100644 index 1591b2e..0000000 --- a/src/engine/SCons/compat/_scons_collections.py +++ /dev/null @@ -1,45 +0,0 @@ -# -# __COPYRIGHT__ -# -# 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__ = """ -collections compatibility module for older (pre-2.4) Python versions - -This does not not NOT (repeat, *NOT*) provide complete collections -functionality. It only wraps the portions of collections functionality -used by SCons, in an interface that looks enough like collections for -our purposes. -""" - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -# Use exec to hide old names from fixers. -exec("""if True: - from UserDict import UserDict - from UserList import UserList - from UserString import UserString""") - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: -- cgit v0.12 From 20bbea44264012aa96806c661f904b38ba5639d4 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Thu, 19 Nov 2015 10:49:06 -0800 Subject: remove compat io. python 2.7 supports io --- src/engine/SCons/compat/__init__.py | 7 ------ src/engine/SCons/compat/_scons_io.py | 45 ------------------------------------ 2 files changed, 52 deletions(-) delete mode 100644 src/engine/SCons/compat/_scons_io.py diff --git a/src/engine/SCons/compat/__init__.py b/src/engine/SCons/compat/__init__.py index 06cee57..68fb9e4 100644 --- a/src/engine/SCons/compat/__init__.py +++ b/src/engine/SCons/compat/__init__.py @@ -105,13 +105,6 @@ except ImportError: try: - import io -except ImportError: - # Pre-2.6 Python has no io module. - import_as('_scons_io', 'io') - - -try: os.devnull except AttributeError: # Pre-2.4 Python has no os.devnull attribute diff --git a/src/engine/SCons/compat/_scons_io.py b/src/engine/SCons/compat/_scons_io.py deleted file mode 100644 index 538afb7..0000000 --- a/src/engine/SCons/compat/_scons_io.py +++ /dev/null @@ -1,45 +0,0 @@ -# -# __COPYRIGHT__ -# -# 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__ = """ -io compatibility module for older (pre-2.6) Python versions - -This does not not NOT (repeat, *NOT*) provide complete io -functionality. It only wraps the portions of io functionality used -by SCons, in an interface that looks enough like io for our purposes. -""" - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -# Use the "imp" module to protect the imports below from fixers. -import imp - -_cStringIO = imp.load_module('cStringIO', *imp.find_module('cStringIO')) -StringIO = _cStringIO.StringIO -del _cStringIO - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: -- cgit v0.12 From 861479b454d614af5a7739c5410117aabe01122f Mon Sep 17 00:00:00 2001 From: William Deegan Date: Thu, 19 Nov 2015 10:51:34 -0800 Subject: remove compat os.devnull. python 2.7 supports it --- src/engine/SCons/compat/__init__.py | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/engine/SCons/compat/__init__.py b/src/engine/SCons/compat/__init__.py index 68fb9e4..42c2eaa 100644 --- a/src/engine/SCons/compat/__init__.py +++ b/src/engine/SCons/compat/__init__.py @@ -103,17 +103,6 @@ except ImportError: # can fall back to using timestamp. pass - -try: - os.devnull -except AttributeError: - # Pre-2.4 Python has no os.devnull attribute - _names = sys.builtin_module_names - if 'posix' in _names: - os.devnull = '/dev/null' - elif 'nt' in _names: - os.devnull = 'nul' - os.path.devnull = os.devnull try: os.path.lexists except AttributeError: -- cgit v0.12 From 7715bd898ba997cdd61de2b7404889862601962e Mon Sep 17 00:00:00 2001 From: William Deegan Date: Thu, 19 Nov 2015 11:24:01 -0800 Subject: fix broken cleanup of collections removal from compat --- src/engine/SCons/compat/__init__.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/engine/SCons/compat/__init__.py b/src/engine/SCons/compat/__init__.py index 42c2eaa..249d008 100644 --- a/src/engine/SCons/compat/__init__.py +++ b/src/engine/SCons/compat/__init__.py @@ -146,6 +146,35 @@ except AttributeError: return x sys.intern = intern del intern + + +# Preparing for 3.x. UserDict, UserList, UserString are in +# collections for 3.x, but standalone in 2.7.x +import collections +try: + collections.UserDict +except AttributeError: + exec('from UserDict import UserDict as _UserDict') + collections.UserDict = _UserDict + del _UserDict + +try: + collections.UserList +except AttributeError: + exec('from UserList import UserList as _UserList') + collections.UserList = _UserList + del _UserList + +try: + collections.UserString +except AttributeError: + exec('from UserString import UserString as _UserString') + collections.UserString = _UserString + del _UserString + + + + try: sys.maxsize except AttributeError: -- cgit v0.12 From b828f5d4434615042e81c81051fe5dde3fe4304b Mon Sep 17 00:00:00 2001 From: William Deegan Date: Thu, 19 Nov 2015 11:28:01 -0800 Subject: remove sys.maxsize from compat module. 2.7 has it --- src/engine/SCons/compat/__init__.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/engine/SCons/compat/__init__.py b/src/engine/SCons/compat/__init__.py index 249d008..1bbc1e7 100644 --- a/src/engine/SCons/compat/__init__.py +++ b/src/engine/SCons/compat/__init__.py @@ -174,15 +174,6 @@ except AttributeError: - -try: - sys.maxsize -except AttributeError: - # Pre-2.6 Python has no sys.maxsize attribute - # Wrapping sys in () is silly, but protects it from 2to3 renames fixer - sys.maxsize = (sys).maxint - - if os.environ.get('SCONS_HORRIBLE_REGRESSION_TEST_HACK') is not None: # We can't apply the 'callable' fixer until the floor is 2.6, but the # '-3' option to Python 2.6 and 2.7 generates almost ten thousand -- cgit v0.12 From 2fea16ec321622be084cb511b001e57f7c1bf6d3 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Thu, 19 Nov 2015 11:29:45 -0800 Subject: remove os.path.lexists from compat module. 2.7 has it --- src/engine/SCons/compat/__init__.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/engine/SCons/compat/__init__.py b/src/engine/SCons/compat/__init__.py index 1bbc1e7..1ef2b25 100644 --- a/src/engine/SCons/compat/__init__.py +++ b/src/engine/SCons/compat/__init__.py @@ -103,13 +103,6 @@ except ImportError: # can fall back to using timestamp. pass -try: - os.path.lexists -except AttributeError: - # Pre-2.4 Python has no os.path.lexists function - def lexists(path): - return os.path.exists(path) or os.path.islink(path) - os.path.lexists = lexists # When we're using the '-3' option during regression tests, importing -- cgit v0.12 From 69d99ab6717f017e85da21b11e6898de18023616 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Thu, 19 Nov 2015 11:35:22 -0800 Subject: update logic for sys.intern in compat module. Don't need to support pre 2.7 anymore --- src/engine/SCons/compat/__init__.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/engine/SCons/compat/__init__.py b/src/engine/SCons/compat/__init__.py index 1ef2b25..3d5c835 100644 --- a/src/engine/SCons/compat/__init__.py +++ b/src/engine/SCons/compat/__init__.py @@ -126,19 +126,17 @@ rename_module('queue', 'Queue') rename_module('winreg', '_winreg') +# Python 3 moved builtin intern() to sys package +# To make porting easier, make intern always live +# in sys package (for python 2.7.x) try: sys.intern except AttributeError: - # Pre-2.6 Python has no sys.intern() function. + # We must be using python 2.7.x so monkey patch + # intern into the sys package import builtins - try: - sys.intern = builtins.intern - except AttributeError: - # Pre-2.x Python has no builtin intern() function. - def intern(x): - return x - sys.intern = intern - del intern + sys.intern = builtins.intern + # Preparing for 3.x. UserDict, UserList, UserString are in -- cgit v0.12 From abf1f461c7d34a00fd2a7348c3d91f10bf382c43 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Fri, 20 Nov 2015 13:54:09 -0800 Subject: fix bootstrap.py issue where changes weren't updating bootstrap dir. filecmp.cmp(a,b) returns False when files aren't equal. The opposite of the expected return value --- bootstrap.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bootstrap.py b/bootstrap.py index 90917dc..08df11d 100755 --- a/bootstrap.py +++ b/bootstrap.py @@ -129,7 +129,7 @@ def main(): def must_copy(dst, src): if not os.path.exists(dst): return 1 - return filecmp.cmp(dst,src) + return not filecmp.cmp(dst,src) # Note: We don't use the getopt module to process the command-line # arguments because we'd have to teach it about all of the SCons options. -- cgit v0.12 From 6d8c18bc0b10a41d64296d42214e92e338a9270b Mon Sep 17 00:00:00 2001 From: William Deegan Date: Tue, 24 Nov 2015 09:26:03 -0800 Subject: Fix warning message when running SCons with a python built without sha256 or other required hashlib. Previously it would say no module SCons.Warnings. I can't find an effective way to test for this. --- src/engine/SCons/CacheDir.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/engine/SCons/CacheDir.py b/src/engine/SCons/CacheDir.py index f32b326..3b7d06f 100644 --- a/src/engine/SCons/CacheDir.py +++ b/src/engine/SCons/CacheDir.py @@ -32,6 +32,7 @@ import stat import sys import SCons.Action +import SCons.Warnings cache_enabled = True cache_debug = False -- cgit v0.12 From 647154f4cc4c3a515927de11229a95d666d8b4d6 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Tue, 24 Nov 2015 09:45:52 -0800 Subject: remove logic to get revision from subversion. Long since obsoleted for SCons development --- SConstruct | 25 ++----------------------- 1 file changed, 2 insertions(+), 23 deletions(-) diff --git a/SConstruct b/SConstruct index 3bbaca6..6ad6dd9 100644 --- a/SConstruct +++ b/SConstruct @@ -88,7 +88,6 @@ fakeroot = whereis('fakeroot') gzip = whereis('gzip') rpmbuild = whereis('rpmbuild') hg = os.path.exists('.hg') and whereis('hg') -svn = os.path.exists('.svn') and whereis('svn') unzip = whereis('unzip') zip = whereis('zip') @@ -117,16 +116,11 @@ if not version: version = default_version hg_status_lines = [] -svn_status_lines = [] if hg: cmd = "%s status --all 2> /dev/null" % hg hg_status_lines = os.popen(cmd, "r").readlines() -if svn: - cmd = "%s status --verbose 2> /dev/null" % svn - svn_status_lines = os.popen(cmd, "r").readlines() - revision = ARGUMENTS.get('REVISION', '') def generate_build_id(revision): return revision @@ -145,17 +139,6 @@ if not revision and hg: result = result + '[MODIFIED]' return result -if not revision and svn: - svn_info = os.popen("%s info 2> /dev/null" % svn, "r").read() - m = re.search('Revision: (\d+)', svn_info) - if m: - revision = m.group(1) - def generate_build_id(revision): - result = 'r' + revision - if [l for l in svn_status_lines if l[0] in 'ACDMR']: - result = result + '[MODIFIED]' - return result - checkpoint = ARGUMENTS.get('CHECKPOINT', '') if checkpoint: if checkpoint == 'd': @@ -236,7 +219,7 @@ command_line_variables = [ ("REVISION=", "The revision number of the source being built. " + "The default is the Subversion revision returned " + - "'svn info', with an appended string of " + + "'hg heads', with an appended string of " + "'[MODIFIED]' if there are any changes in the " + "working copy."), @@ -1234,12 +1217,8 @@ sfiles = None if hg_status_lines: slines = [l for l in hg_status_lines if l[0] in 'ACM'] sfiles = [l.split()[-1] for l in slines] -elif svn_status_lines: - slines = [l for l in svn_status_lines if l[0] in ' MA'] - sentries = [l.split()[-1] for l in slines] - sfiles = list(filter(os.path.isfile, sentries)) else: - print "Not building in a Mercurial or Subversion tree; skipping building src package." + print "Not building in a Mercurial tree; skipping building src package." if sfiles: remove_patterns = [ -- cgit v0.12 From e7de9d22c9503cf29e5d8b5e7813f060d59a00e5 Mon Sep 17 00:00:00 2001 From: Dirk Baechle Date: Thu, 10 Dec 2015 18:01:37 +0100 Subject: removed several pre-2.7 methods and imports, including some basic refactorings --- QMTest/TestCmd.py | 14 --- QMTest/TestCommon.py | 25 ----- ReleaseConfig | 2 +- bin/scons-proc.py | 6 +- runtest.py | 15 +-- src/engine/SCons/Action.py | 13 +-- src/engine/SCons/ActionTests.py | 81 ----------------- src/engine/SCons/Environment.py | 19 ---- src/engine/SCons/EnvironmentTests.py | 25 ----- src/engine/SCons/Executor.py | 3 - src/engine/SCons/Job.py | 10 +- src/engine/SCons/Node/FS.py | 53 +---------- src/engine/SCons/Node/FSTests.py | 10 -- src/engine/SCons/Node/NodeTests.py | 2 - src/engine/SCons/Node/__init__.py | 7 +- src/engine/SCons/PathList.py | 2 +- src/engine/SCons/Platform/__init__.py | 2 +- src/engine/SCons/Platform/win32.py | 10 +- src/engine/SCons/SConf.py | 19 +--- src/engine/SCons/SConfTests.py | 5 +- src/engine/SCons/Scanner/C.py | 2 +- src/engine/SCons/Scanner/IDL.py | 2 +- src/engine/SCons/Scanner/RC.py | 2 +- src/engine/SCons/Script/Interactive.py | 6 -- src/engine/SCons/Script/Main.py | 42 ++------- src/engine/SCons/Script/SConsOptions.py | 52 +---------- src/engine/SCons/Script/SConscript.py | 12 +-- src/engine/SCons/Script/__init__.py | 6 -- src/engine/SCons/Subst.py | 9 -- src/engine/SCons/SubstTests.py | 11 --- src/engine/SCons/Taskmaster.py | 12 +-- src/engine/SCons/Tool/BitKeeper.py | 1 - src/engine/SCons/Tool/CVS.py | 1 - src/engine/SCons/Tool/GettextCommon.py | 4 +- src/engine/SCons/Tool/MSCommon/common.py | 31 +------ src/engine/SCons/Tool/MSCommon/netframework.py | 3 +- src/engine/SCons/Tool/MSCommon/sdk.py | 30 +----- src/engine/SCons/Tool/MSCommon/vc.py | 4 +- src/engine/SCons/Tool/MSCommon/vs.py | 8 +- src/engine/SCons/Tool/Perforce.py | 6 +- src/engine/SCons/Tool/PharLapCommon.py | 38 ++------ src/engine/SCons/Tool/PharLapCommonTests.py | 69 -------------- src/engine/SCons/Tool/RCS.py | 1 - src/engine/SCons/Tool/SCCS.py | 1 - src/engine/SCons/Tool/Subversion.py | 1 - src/engine/SCons/Tool/__init__.py | 2 +- src/engine/SCons/Tool/aixf77.py | 2 +- src/engine/SCons/Tool/cyglink.py | 2 +- src/engine/SCons/Tool/docbook/__init__.py | 36 +++----- src/engine/SCons/Tool/gnulink.py | 2 +- src/engine/SCons/Tool/icl.py | 2 +- src/engine/SCons/Tool/install.py | 16 ++-- src/engine/SCons/Tool/intelc.py | 17 +--- src/engine/SCons/Tool/mslink.py | 2 +- src/engine/SCons/Tool/msvs.py | 44 +-------- src/engine/SCons/Tool/packaging/__init__.py | 7 +- src/engine/SCons/Tool/packaging/ipk.py | 8 +- src/engine/SCons/Tool/packaging/msi.py | 16 ++-- src/engine/SCons/Tool/packaging/rpm.py | 20 +--- src/engine/SCons/Tool/sunar.py | 2 +- src/engine/SCons/Tool/tex.py | 6 -- src/engine/SCons/Tool/textfile.py | 4 +- src/engine/SCons/Tool/xgettext.py | 6 +- src/engine/SCons/Tool/yacc.py | 10 +- src/engine/SCons/Util.py | 116 +++++++++++++++--------- src/engine/SCons/UtilTests.py | 43 ++++++--- src/engine/SCons/Variables/BoolVariable.py | 4 +- src/engine/SCons/Variables/EnumVariable.py | 4 +- src/engine/SCons/Variables/ListVariable.py | 8 +- src/engine/SCons/Variables/PackageVariable.py | 10 +- src/engine/SCons/Variables/PathVariable.py | 9 +- src/engine/SCons/Variables/__init__.py | 7 +- src/engine/SCons/compat/__init__.py | 56 +----------- src/engine/SCons/compat/_scons_builtins.py | 107 ---------------------- src/engine/SCons/compat/_scons_hashlib.py | 76 ---------------- src/engine/SCons/cppTests.py | 3 - src/engine/SCons/dblite.py | 8 +- src/script/scons-time.py | 45 +-------- src/script/sconsign.py | 35 ++++++- test/TEX/bibliography.py | 3 - test/compat/all.py | 65 ------------- test/compat/any.py | 63 ------------- test/option/profile.py | 21 ++--- test/sconsign/script/bad.py | 6 +- test/update-release-info/update-release-info.py | 12 +-- 85 files changed, 306 insertions(+), 1276 deletions(-) delete mode 100644 src/engine/SCons/Tool/PharLapCommonTests.py delete mode 100644 src/engine/SCons/compat/_scons_builtins.py delete mode 100644 src/engine/SCons/compat/_scons_hashlib.py delete mode 100644 test/compat/all.py delete mode 100644 test/compat/any.py diff --git a/QMTest/TestCmd.py b/QMTest/TestCmd.py index 3048973..cd559b7 100644 --- a/QMTest/TestCmd.py +++ b/QMTest/TestCmd.py @@ -317,20 +317,6 @@ except ImportError: exec('from UserList import UserList') exec('from UserString import UserString') -try: - # pre-2.7 doesn't have the memoryview() built-in - memoryview -except NameError: - class memoryview: - def __init__(self, obj): - # wrapping buffer in () keeps the fixer from changing it - self.obj = (buffer)(obj) - def __getitem__(self, indx): - if isinstance(indx, slice): - return self.obj[indx.start:indx.stop] - else: - return self.obj[indx] - __all__ = [ 'diff_re', 'fail_test', diff --git a/QMTest/TestCommon.py b/QMTest/TestCommon.py index c4a5373..dc4c97c 100644 --- a/QMTest/TestCommon.py +++ b/QMTest/TestCommon.py @@ -123,31 +123,6 @@ __all__.extend([ 'TestCommon', 'dll_suffix', ]) -try: - sorted -except NameError: - # Pre-2.4 Python has no sorted() function. - # - # The pre-2.4 Python list.sort() method does not support - # list.sort(key=) nor list.sort(reverse=) keyword arguments, so - # we must implement the functionality of those keyword arguments - # by hand instead of passing them to list.sort(). - def sorted(iterable, cmp=None, key=None, reverse=False): - if key is not None: - result = [(key(x), x) for x in iterable] - else: - result = iterable[:] - if cmp is None: - # Pre-2.3 Python does not support list.sort(None). - result.sort() - else: - result.sort(cmp) - if key is not None: - result = [t1 for t0,t1 in result] - if reverse: - result.reverse() - return result - # Variables that describe the prefixes and suffixes on this system. if sys.platform == 'win32': exe_suffix = '.exe' diff --git a/ReleaseConfig b/ReleaseConfig index ced44c6..e1f462a 100644 --- a/ReleaseConfig +++ b/ReleaseConfig @@ -38,7 +38,7 @@ version_tuple = (2, 4, 2, 'alpha', 0) # when that version is used. Python versions prior to deprecate_python_version # cause a warning to be issued (assuming it's not disabled). These values are # mandatory and must be present in the configuration file. -unsupported_python_version = (2, 3, 0) +unsupported_python_version = (2, 6, 0) deprecated_python_version = (2, 7, 0) # If release_date is (yyyy, mm, dd, hh, mm, ss), that is used as the release diff --git a/bin/scons-proc.py b/bin/scons-proc.py index 9567db8..d6a770b 100644 --- a/bin/scons-proc.py +++ b/bin/scons-proc.py @@ -14,11 +14,7 @@ import os import re import string import sys -try: - from io import StringIO # usable as of 2.6; takes unicode only -except ImportError: - # No 'io' module or no StringIO in io - exec('from cStringIO import StringIO') +from io import StringIO # usable as of 2.6; takes unicode only import SConsDoc from SConsDoc import tf as stf diff --git a/runtest.py b/runtest.py index b7cbdc6..1b5c7dd 100755 --- a/runtest.py +++ b/runtest.py @@ -17,8 +17,6 @@ # build directory and sets PYTHONPATH to reference modules unpacked # during build process for testing purposes (build/test-*). # -# -3 Run with the python -3 option, -# # -a Run all tests found under the current directory. # It is also possible to specify a list of # subdirectories to search. @@ -108,7 +106,6 @@ list_only = None printcommand = 1 package = None print_passed_summary = None -python3incompatibilities = None scons = None scons_exec = None testlistfile = None @@ -128,7 +125,6 @@ Usage: runtest.py [OPTIONS] [TEST ...] """ helpstr = usagestr + """\ Options: - -3 Warn about Python 3.x incompatibilities. -a --all Run all tests. -b --baseline BASE Run test scripts against baseline BASE. --builddir DIR Directory in which packages were built. @@ -210,7 +206,7 @@ parser.add_option('--xml', #print "args:", args -opts, args = getopt.getopt(args, "3b:def:hj:klnP:p:qsv:Xx:t", +opts, args = getopt.getopt(args, "b:def:hj:klnP:p:qsv:Xx:t", ['baseline=', 'builddir=', 'debug', 'external', 'file=', 'help', 'no-progress', 'jobs=', @@ -223,9 +219,7 @@ opts, args = getopt.getopt(args, "3b:def:hj:klnP:p:qsv:Xx:t", 'verbose=']) for o, a in opts: - if o in ['-3']: - python3incompatibilities = 1 - elif o in ['-b', '--baseline']: + if o in ['-b', '--baseline']: baseline = a elif o in ['--builddir']: builddir = a @@ -634,9 +628,6 @@ if old_pythonpath: os.pathsep + \ old_pythonpath -if python3incompatibilities: - os.environ['SCONS_HORRIBLE_REGRESSION_TEST_HACK'] = '1' - # ---[ test discovery ]------------------------------------ @@ -769,8 +760,6 @@ def run_test(t, io_lock, async=True): global tests_completed header = "" command_args = ['-tt'] - if python3incompatibilities: - command_args.append('-3') if debug: command_args.append(debug) command_args.append(t.path) diff --git a/src/engine/SCons/Action.py b/src/engine/SCons/Action.py index 5a34825..4dfde31 100644 --- a/src/engine/SCons/Action.py +++ b/src/engine/SCons/Action.py @@ -235,11 +235,7 @@ def _code_contents(code): # The code contents depends on the number of local variables # but not their actual names. contents.append("%s,%s" % (code.co_argcount, len(code.co_varnames))) - try: - contents.append(",%s,%s" % (len(code.co_cellvars), len(code.co_freevars))) - except AttributeError: - # Older versions of Python do not support closures. - contents.append(",0,0") + contents.append(",%s,%s" % (len(code.co_cellvars), len(code.co_freevars))) # The code contents depends on any constants accessed by the # function. Note that we have to call _object_contents on each @@ -276,11 +272,7 @@ def _function_contents(func): contents.append(',()') # The function contents depends on the closure captured cell values. - try: - closure = func.func_closure or [] - except AttributeError: - # Older versions of Python do not support closures. - closure = [] + closure = func.func_closure or [] #xxx = [_object_contents(x.cell_contents) for x in closure] try: @@ -946,7 +938,6 @@ class LazyAction(CommandGeneratorAction, CommandAction): def __init__(self, var, kw): if SCons.Debug.track_instances: logInstanceCreation(self, 'Action.LazyAction') - #FUTURE CommandAction.__init__(self, '${'+var+'}', **kw) CommandAction.__init__(self, '${'+var+'}', **kw) self.var = SCons.Util.to_String(var) self.gen_kw = kw diff --git a/src/engine/SCons/ActionTests.py b/src/engine/SCons/ActionTests.py index e069d51..631d7c1 100644 --- a/src/engine/SCons/ActionTests.py +++ b/src/engine/SCons/ActionTests.py @@ -229,7 +229,6 @@ def test_varlist(pos_call, str_call, cmd, cmdstrfunc, **kw): def test_positional_args(pos_callback, cmd, **kw): """Test that Action() returns the expected type and that positional args work. """ - #FUTURE act = SCons.Action.Action(cmd, **kw) act = SCons.Action.Action(cmd, **kw) pos_callback(act) assert act.varlist is (), act.varlist @@ -237,7 +236,6 @@ def test_positional_args(pos_callback, cmd, **kw): if not isinstance(act, SCons.Action._ActionAction): # only valid cmdstrfunc is None def none(a): pass - #FUTURE test_varlist(pos_callback, none, cmd, None, **kw) test_varlist(pos_callback, none, cmd, None, **kw) else: # _ActionAction should have set these @@ -251,25 +249,21 @@ def test_positional_args(pos_callback, cmd, **kw): def cmdstr(a): assert hasattr(a, 'strfunction') assert a.cmdstr == 'cmdstr', a.cmdstr - #FUTURE test_varlist(pos_callback, cmdstr, cmd, 'cmdstr', **kw) test_varlist(pos_callback, cmdstr, cmd, 'cmdstr', **kw) def fun(): pass def strfun(a, fun=fun): assert a.strfunction is fun, a.strfunction assert a.cmdstr == _null, a.cmdstr - #FUTURE test_varlist(pos_callback, strfun, cmd, fun, **kw) test_varlist(pos_callback, strfun, cmd, fun, **kw) def none(a): assert hasattr(a, 'strfunction') assert a.cmdstr is None, a.cmdstr - #FUTURE test_varlist(pos_callback, none, cmd, None, **kw) test_varlist(pos_callback, none, cmd, None, **kw) """Test handling of bad cmdstrfunc arguments """ try: - #FUTURE a = SCons.Action.Action(cmd, [], **kw) a = SCons.Action.Action(cmd, [], **kw) except SCons.Errors.UserError, e: s = str(e) @@ -1193,81 +1187,6 @@ class CommandActionTestCase(unittest.TestCase): r = act([], [], env) assert r == 0, r - def _DO_NOT_EXECUTE_test_pipe_execute(self): - """Test capturing piped output from an action - - We used to have PIPE_BUILD support built right into - Action.execute() for the benefit of the SConf subsystem, but we've - moved that logic back into SConf itself. We'll leave this code - here, just in case we ever want to resurrect this functionality - in the future, but change the name of the test so it doesn't - get executed as part of the normal test suite. - """ - pipe = open( pipe_file, "w" ) - self.env = Environment(ENV = {'ACTPY_PIPE' : '1'}, PIPE_BUILD = 1, - PSTDOUT = pipe, PSTDERR = pipe) - # everything should also work when piping output - self.test_execute() - self.env['PSTDOUT'].close() - pipe_out = test.read( pipe_file ) - - act_out = "act.py: stdout: executed act.py" - act_err = "act.py: stderr: executed act.py" - - # Since we are now using select(), stdout and stderr can be - # intermixed, so count the lines separately. - outlines = re.findall(act_out, pipe_out) - errlines = re.findall(act_err, pipe_out) - assert len(outlines) == 6, pipe_out + repr(outlines) - assert len(errlines) == 6, pipe_out + repr(errlines) - - # test redirection operators - def test_redirect(self, redir, stdout_msg, stderr_msg): - cmd = r'%s %s %s xyzzy %s' % (_python_, act_py, outfile, redir) - # Write the output and error messages to files because - # Windows can't handle strings that are too big in its - # external environment (os.spawnve() returns EINVAL, - # "Invalid argument"). - stdout_file = test.workpath('stdout_msg') - stderr_file = test.workpath('stderr_msg') - open(stdout_file, 'w').write(stdout_msg) - open(stderr_file, 'w').write(stderr_msg) - pipe = open( pipe_file, "w" ) - act = SCons.Action.CommandAction(cmd) - env = Environment( ENV = {'ACTPY_PIPE' : '1', - 'PIPE_STDOUT_FILE' : stdout_file, - 'PIPE_STDERR_FILE' : stderr_file}, - PIPE_BUILD = 1, - PSTDOUT = pipe, PSTDERR = pipe ) - r = act([], [], env) - pipe.close() - assert r == 0 - return (test.read(outfile2, 'r'), test.read(pipe_file, 'r')) - - (redirected, pipe_out) = test_redirect(self,'> %s' % outfile2, - act_out, act_err) - assert redirected == act_out - assert pipe_out == act_err - - (redirected, pipe_out) = test_redirect(self,'2> %s' % outfile2, - act_out, act_err) - assert redirected == act_err - assert pipe_out == act_out - - (redirected, pipe_out) = test_redirect(self,'> %s 2>&1' % outfile2, - act_out, act_err) - assert (redirected == act_out + act_err or - redirected == act_err + act_out) - assert pipe_out == "" - - act_err = "Long Command Output\n"*3000 - # the size of the string should exceed the system's default block size - act_out = "" - (redirected, pipe_out) = test_redirect(self,'> %s' % outfile2, - act_out, act_err) - assert (redirected == act_out) - assert (pipe_out == act_err) - def test_set_handler(self): """Test setting the command handler... """ diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py index 7e2f896..45b24c5 100644 --- a/src/engine/SCons/Environment.py +++ b/src/engine/SCons/Environment.py @@ -857,25 +857,6 @@ class SubstitutionEnvironment(object): self[key] = t return self -# def MergeShellPaths(self, args, prepend=1): -# """ -# Merge the dict in args into the shell environment in env['ENV']. -# Shell path elements are appended or prepended according to prepend. - -# Uses Pre/AppendENVPath, so it always appends or prepends uniquely. - -# Example: env.MergeShellPaths({'LIBPATH': '/usr/local/lib'}) -# prepends /usr/local/lib to env['ENV']['LIBPATH']. -# """ - -# for pathname, pathval in args.items(): -# if not pathval: -# continue -# if prepend: -# self.PrependENVPath(pathname, pathval) -# else: -# self.AppendENVPath(pathname, pathval) - def default_decide_source(dependency, target, prev_ni): f = SCons.Defaults.DefaultEnvironment().decide_source diff --git a/src/engine/SCons/EnvironmentTests.py b/src/engine/SCons/EnvironmentTests.py index 9a9d2b0..0567906 100644 --- a/src/engine/SCons/EnvironmentTests.py +++ b/src/engine/SCons/EnvironmentTests.py @@ -862,31 +862,6 @@ sys.exit(0) assert env['A'] == ['aaa'], env['A'] assert env['B'] == ['bbb'], env['B'] -# def test_MergeShellPaths(self): -# """Test the MergeShellPaths() method -# """ -# env = Environment() -# env.MergeShellPaths({}) -# assert not env['ENV'].has_key('INCLUDE'), env['INCLUDE'] -# env.MergeShellPaths({'INCLUDE': r'c:\Program Files\Stuff'}) -# assert env['ENV']['INCLUDE'] == r'c:\Program Files\Stuff', env['ENV']['INCLUDE'] -# env.MergeShellPaths({'INCLUDE': r'c:\Program Files\Stuff'}) -# assert env['ENV']['INCLUDE'] == r'c:\Program Files\Stuff', env['ENV']['INCLUDE'] -# env.MergeShellPaths({'INCLUDE': r'xyz'}) -# assert env['ENV']['INCLUDE'] == r'xyz%sc:\Program Files\Stuff'%os.pathsep, env['ENV']['INCLUDE'] - -# env = Environment() -# env['ENV']['INCLUDE'] = 'xyz' -# env.MergeShellPaths({'INCLUDE':['c:/inc1', 'c:/inc2']} ) -# assert env['ENV']['INCLUDE'] == r'c:/inc1%sc:/inc2%sxyz'%(os.pathsep, os.pathsep), env['ENV']['INCLUDE'] - -# # test prepend=0 -# env = Environment() -# env.MergeShellPaths({'INCLUDE': r'c:\Program Files\Stuff'}, prepend=0) -# assert env['ENV']['INCLUDE'] == r'c:\Program Files\Stuff', env['ENV']['INCLUDE'] -# env.MergeShellPaths({'INCLUDE': r'xyz'}, prepend=0) -# assert env['ENV']['INCLUDE'] == r'c:\Program Files\Stuff%sxyz'%os.pathsep, env['ENV']['INCLUDE'] - class BaseTestCase(unittest.TestCase,TestEnvironmentFixture): diff --git a/src/engine/SCons/Executor.py b/src/engine/SCons/Executor.py index 59e57e3..71671bf 100644 --- a/src/engine/SCons/Executor.py +++ b/src/engine/SCons/Executor.py @@ -122,7 +122,6 @@ def execute_action_list(obj, target, kw): kw = obj.get_kw(kw) status = 0 for act in obj.get_action_list(): - #args = (self.get_all_targets(), self.get_all_sources(), env) args = ([], [], env) status = act(*args, **kw) if isinstance(status, SCons.Errors.BuildError): @@ -244,14 +243,12 @@ class Executor(object): return self._changed_targets_list def _get_source(self, *args, **kw): - #return SCons.Util.NodeList([rfile(self.batches[0].sources[0]).get_subst_proxy()]) return rfile(self.batches[0].sources[0]).get_subst_proxy() def _get_sources(self, *args, **kw): return SCons.Util.NodeList([rfile(n).get_subst_proxy() for n in self.get_all_sources()]) def _get_target(self, *args, **kw): - #return SCons.Util.NodeList([self.batches[0].targets[0].get_subst_proxy()]) return self.batches[0].targets[0].get_subst_proxy() def _get_targets(self, *args, **kw): diff --git a/src/engine/SCons/Job.py b/src/engine/SCons/Job.py index 184f5ba..42b009e 100644 --- a/src/engine/SCons/Job.py +++ b/src/engine/SCons/Job.py @@ -70,7 +70,7 @@ class Jobs(object): def __init__(self, num, taskmaster): """ - create 'num' jobs using the given taskmaster. + Create 'num' jobs using the given taskmaster. If 'num' is 1 or less, then a serial job will be used, otherwise a parallel job with 'num' worker threads will @@ -126,10 +126,10 @@ class Jobs(object): c) SIGHUP: Controlling shell exiting We handle all of these cases by stopping the taskmaster. It - turns out that it very difficult to stop the build process + turns out that it's very difficult to stop the build process by throwing asynchronously an exception such as KeyboardInterrupt. For example, the python Condition - variables (threading.Condition) and queue's do not seem to + variables (threading.Condition) and queues do not seem to be asynchronous-exception-safe. It would require adding a whole bunch of try/finally block and except KeyboardInterrupt all over the place. @@ -177,7 +177,7 @@ class Serial(object): The taskmaster's next_task() method should return the next task that needs to be executed, or None if there are no more tasks. The taskmaster's executed() method will be called for each task when it - is successfully executed or failed() will be called if it failed to + is successfully executed, or failed() will be called if it failed to execute (e.g. execute() raised an exception).""" self.taskmaster = taskmaster @@ -351,7 +351,7 @@ else: The taskmaster's next_task() method should return the next task that needs to be executed, or None if there are no more tasks. The taskmaster's executed() method will be called - for each task when it is successfully executed or failed() + for each task when it is successfully executed, or failed() will be called if the task failed to execute (i.e. execute() raised an exception). diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py index 4e78852..4a4942b 100644 --- a/src/engine/SCons/Node/FS.py +++ b/src/engine/SCons/Node/FS.py @@ -186,7 +186,7 @@ needs_normpath_check = re.compile( # We need to renormalize the path if it contains a '.' # directory, but NOT if it is a single '.' '/' characters. We # do not want to match a single '.' because this case is checked - # for explicitely since this is common enough case. + # for explicitly since this is common enough case. # # Note that we check for all the following cases: # @@ -1165,15 +1165,6 @@ class LocalFS(object): return '' -#class RemoteFS: -# # Skeleton for the obvious methods we might need from the -# # abstraction layer for a remote filesystem. -# def upload(self, local_src, remote_dst): -# pass -# def download(self, remote_src, local_dst): -# pass - - class FS(LocalFS): def __init__(self, path = None): @@ -2234,7 +2225,6 @@ class Dir(Base): # the overall list will also be filtered later, # after we exit this loop. if pattern[0] != '.': - #disk_names = [ d for d in disk_names if d[0] != '.' ] disk_names = [x for x in disk_names if x[0] != '.'] disk_names = fnmatch.filter(disk_names, pattern) dirEntry = dir.Entry @@ -2627,13 +2617,6 @@ class File(Base): the directory of this file.""" return self.dir.File(name) - #def generate_build_dict(self): - # """Return an appropriate dictionary of values for building - # this File.""" - # return {'Dir' : self.Dir, - # 'File' : self.File, - # 'RDirs' : self.RDirs} - def _morph(self): """Turn a file system node into a File object.""" self.scanner_paths = {} @@ -2907,9 +2890,7 @@ class File(Base): pass if scanner: - # result = [n.disambiguate() for n in scanner(self, env, path)] - result = scanner(self, env, path) - result = [N.disambiguate() for N in result] + result = [n.disambiguate() for n in scanner(self, env, path)] else: result = [] @@ -3519,36 +3500,6 @@ class FileFinder(object): filedir, filename = os.path.split(filename) if filedir: - # More compact code that we can't use until we drop - # support for Python 1.5.2: - # - #def filedir_lookup(p, fd=filedir): - # """ - # A helper function that looks up a directory for a file - # we're trying to find. This only creates the Dir Node - # if it exists on-disk, since if the directory doesn't - # exist we know we won't find any files in it... :-) - # """ - # dir, name = os.path.split(fd) - # if dir: - # p = filedir_lookup(p, dir) - # if not p: - # return None - # norm_name = _my_normcase(name) - # try: - # node = p.entries[norm_name] - # except KeyError: - # return p.dir_on_disk(name) - # if isinstance(node, Dir): - # return node - # if isinstance(node, Entry): - # node.must_be_same(Dir) - # return node - # if isinstance(node, Dir) or isinstance(node, Entry): - # return node - # return None - #paths = [_f for _f in map(filedir_lookup, paths) if _f] - self.default_filedir = filedir paths = [_f for _f in map(self.filedir_lookup, paths) if _f] diff --git a/src/engine/SCons/Node/FSTests.py b/src/engine/SCons/Node/FSTests.py index 0c1e71f..fc27859 100644 --- a/src/engine/SCons/Node/FSTests.py +++ b/src/engine/SCons/Node/FSTests.py @@ -751,16 +751,6 @@ class FileNodeInfoTestCase(_tempdirTestCase): size = st[stat.ST_SIZE] assert ni.size != size, (ni.size, size) - #fff.clear() - #ni.update(fff) - - #st = os.stat('fff') - - #mtime = st[stat.ST_MTIME] - #assert ni.timestamp == mtime, (ni.timestamp, mtime) - #size = st[stat.ST_SIZE] - #assert ni.size == size, (ni.size, size) - class FileBuildInfoTestCase(_tempdirTestCase): def test___init__(self): """Test File.BuildInfo initialization""" diff --git a/src/engine/SCons/Node/NodeTests.py b/src/engine/SCons/Node/NodeTests.py index 1478419..3802f8c 100644 --- a/src/engine/SCons/Node/NodeTests.py +++ b/src/engine/SCons/Node/NodeTests.py @@ -358,8 +358,6 @@ class NodeTestCase(unittest.TestCase): ggg.path = "ggg" fff.sources = ["hhh", "iii"] ggg.sources = ["hhh", "iii"] - # [Charles C. 1/7/2002] Uhhh, why are there no asserts here? - # [SK, 15 May 2003] I dunno, let's add some... built_it = None fff.build() assert built_it diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py index 5aa9600..40ee8f0 100644 --- a/src/engine/SCons/Node/__init__.py +++ b/src/engine/SCons/Node/__init__.py @@ -577,7 +577,7 @@ class Node(object): self.always_build = None self.includes = None self.attributes = self.Attrs() # Generic place to stick information about the Node. - self.side_effect = 0 # true iff this node is a side effect + self.side_effect = 0 # true if this node is a side effect self.side_effects = [] # the side effects of building this target self.linked = 0 # is this node linked to the variant directory? self.changed_since_last_build = 0 @@ -1281,11 +1281,6 @@ class Node(object): def _add_child(self, collection, set, child): """Adds 'child' to 'collection', first checking 'set' to see if it's already present.""" - #if type(child) is not type([]): - # child = [child] - #for c in child: - # if not isinstance(c, Node): - # raise TypeError, c added = None for c in child: if c not in set: diff --git a/src/engine/SCons/PathList.py b/src/engine/SCons/PathList.py index 350e1ac..77e30c4 100644 --- a/src/engine/SCons/PathList.py +++ b/src/engine/SCons/PathList.py @@ -27,7 +27,7 @@ __doc__ = """SCons.PathList A module for handling lists of directory paths (the sort of things that get set as CPPPATH, LIBPATH, etc.) with as much caching of data and -efficiency as we can while still keeping the evaluation delayed so that we +efficiency as we can, while still keeping the evaluation delayed so that we Do the Right Thing (almost) regardless of how the variable is specified. """ diff --git a/src/engine/SCons/Platform/__init__.py b/src/engine/SCons/Platform/__init__.py index 653f722..7f3e90b 100644 --- a/src/engine/SCons/Platform/__init__.py +++ b/src/engine/SCons/Platform/__init__.py @@ -12,7 +12,7 @@ environment. Consequently, we'll examine both sys.platform and os.name (and anything else that might come in to play) in order to return some specification which is unique enough for our purposes. -Note that because this subsysem just *selects* a callable that can +Note that because this subsystem just *selects* a callable that can modify a construction environment, it's possible for people to define their own "platform specification" in an arbitrary callable function. No one needs to use or tie in to this subsystem in order to roll diff --git a/src/engine/SCons/Platform/win32.py b/src/engine/SCons/Platform/win32.py index 5f20685..4cfabea 100644 --- a/src/engine/SCons/Platform/win32.py +++ b/src/engine/SCons/Platform/win32.py @@ -60,10 +60,8 @@ except AttributeError: else: parallel_msg = None - import builtins - - _builtin_file = builtins.file - _builtin_open = builtins.open + _builtin_file = file + _builtin_open = open class _scons_file(_builtin_file): def __init__(self, *args, **kw): @@ -78,8 +76,8 @@ else: 0) return fp - builtins.file = _scons_file - builtins.open = _scons_open + file = _scons_file + open = _scons_open try: import threading diff --git a/src/engine/SCons/SConf.py b/src/engine/SCons/SConf.py index 987b8ea..286f230 100644 --- a/src/engine/SCons/SConf.py +++ b/src/engine/SCons/SConf.py @@ -254,14 +254,7 @@ class SConfBuildTask(SCons.Taskmaster.AlwaysTask): else: self.display('Caught exception while building "%s":\n' % self.targets[0]) - try: - excepthook = sys.excepthook - except AttributeError: - # Earlier versions of Python don't have sys.excepthook... - def excepthook(type, value, tb): - traceback.print_tb(tb) - print type, value - excepthook(*self.exc_info()) + sys.excepthook(*self.exc_info()) return SCons.Taskmaster.Task.failed(self) def collect_node_states(self): @@ -355,8 +348,6 @@ class SConfBuildTask(SCons.Taskmaster.AlwaysTask): raise SCons.Errors.ExplicitExit(self.targets[0],exc_value.code) except Exception, e: for t in self.targets: - #binfo = t.get_binfo() - #binfo.__class__ = SConfBuildInfo binfo = SConfBuildInfo() binfo.merge(t.get_binfo()) binfo.set_build_result(1, s.getvalue()) @@ -375,8 +366,6 @@ class SConfBuildTask(SCons.Taskmaster.AlwaysTask): raise e else: for t in self.targets: - #binfo = t.get_binfo() - #binfo.__class__ = SConfBuildInfo binfo = SConfBuildInfo() binfo.merge(t.get_binfo()) binfo.set_build_result(0, s.getvalue()) @@ -399,16 +388,16 @@ class SConfBase(object): tests, be sure to call the Finish() method, which returns the modified environment. Some words about caching: In most cases, it is not necessary to cache - Test results explicitely. Instead, we use the scons dependency checking + Test results explicitly. Instead, we use the scons dependency checking mechanism. For example, if one wants to compile a test program (SConf.TryLink), the compiler is only called, if the program dependencies have changed. However, if the program could not be compiled in a former - SConf run, we need to explicitely cache this error. + SConf run, we need to explicitly cache this error. """ def __init__(self, env, custom_tests = {}, conf_dir='$CONFIGUREDIR', log_file='$CONFIGURELOG', config_h = None, _depth = 0): - """Constructor. Pass additional tests in the custom_tests-dictinary, + """Constructor. Pass additional tests in the custom_tests-dictionary, e.g. custom_tests={'CheckPrivate':MyPrivateTest}, where MyPrivateTest defines a custom test. Note also the conf_dir and log_file arguments (you may want to diff --git a/src/engine/SCons/SConfTests.py b/src/engine/SCons/SConfTests.py index 9bdfceb..f9ee0d0 100644 --- a/src/engine/SCons/SConfTests.py +++ b/src/engine/SCons/SConfTests.py @@ -100,11 +100,10 @@ class SConfTestCase(unittest.TestCase): # original builtin functions whenever we have to reset # all of our global state. - import builtins import SCons.Platform.win32 - builtins.file = SCons.Platform.win32._builtin_file - builtins.open = SCons.Platform.win32._builtin_open + file = SCons.Platform.win32._builtin_file + open = SCons.Platform.win32._builtin_open def _baseTryXXX(self, TryFunc): # TryCompile and TryLink are much the same, so we can test them diff --git a/src/engine/SCons/Scanner/C.py b/src/engine/SCons/Scanner/C.py index 3311a09..e6ac720 100644 --- a/src/engine/SCons/Scanner/C.py +++ b/src/engine/SCons/Scanner/C.py @@ -1,6 +1,6 @@ """SCons.Scanner.C -This module implements the depenency scanner for C/C++ code. +This module implements the dependency scanner for C/C++ code. """ diff --git a/src/engine/SCons/Scanner/IDL.py b/src/engine/SCons/Scanner/IDL.py index 18084e8..86ee006 100644 --- a/src/engine/SCons/Scanner/IDL.py +++ b/src/engine/SCons/Scanner/IDL.py @@ -1,6 +1,6 @@ """SCons.Scanner.IDL -This module implements the depenency scanner for IDL (Interface +This module implements the dependency scanner for IDL (Interface Definition Language) files. """ diff --git a/src/engine/SCons/Scanner/RC.py b/src/engine/SCons/Scanner/RC.py index 437b861..61393ae 100644 --- a/src/engine/SCons/Scanner/RC.py +++ b/src/engine/SCons/Scanner/RC.py @@ -1,6 +1,6 @@ """SCons.Scanner.RC -This module implements the depenency scanner for RC (Interface +This module implements the dependency scanner for RC (Interface Definition Language) files. """ diff --git a/src/engine/SCons/Script/Interactive.py b/src/engine/SCons/Script/Interactive.py index ffb5096..5450ff5 100644 --- a/src/engine/SCons/Script/Interactive.py +++ b/src/engine/SCons/Script/Interactive.py @@ -304,14 +304,8 @@ class SConsInteractiveCmd(cmd.Cmd): return self._strip_initial_spaces(doc) def _strip_initial_spaces(self, s): - #lines = s.split('\n') lines = s.split('\n') spaces = re.match(' *', lines[0]).group(0) - #def strip_spaces(l): - # if l.startswith(spaces): - # l = l[len(spaces):] - # return l - #return '\n'.join([ strip_spaces(l) for l in lines ]) def strip_spaces(l, spaces=spaces): if l[:len(spaces)] == spaces: l = l[len(spaces):] diff --git a/src/engine/SCons/Script/Main.py b/src/engine/SCons/Script/Main.py index bd227bd..05c0d75 100644 --- a/src/engine/SCons/Script/Main.py +++ b/src/engine/SCons/Script/Main.py @@ -10,7 +10,7 @@ some other module. If it's specific to the "scons" script invocation, it goes here. """ -unsupported_python_version = (2, 3, 0) +unsupported_python_version = (2, 6, 0) deprecated_python_version = (2, 7, 0) # __COPYRIGHT__ @@ -43,15 +43,6 @@ import sys import time import traceback -# Strip the script directory from sys.path() so on case-insensitive -# (Windows) systems Python doesn't think that the "scons" script is the -# "SCons" package. Replace it with our own version directory so, if -# if they're there, we pick up the right version of the build engine -# modules. -#sys.path = [os.path.join(sys.prefix, -# 'lib', -# 'scons-%d' % SCons.__version__)] + sys.path[1:] - import SCons.CacheDir import SCons.Debug import SCons.Defaults @@ -74,7 +65,7 @@ def fetch_win32_parallel_msg(): # so we don't have to pull it in on all platforms, and so that an # in-line "import" statement in the _main() function below doesn't # cause warnings about local names shadowing use of the 'SCons' - # globl in nest scopes and UnboundLocalErrors and the like in some + # global in nest scopes and UnboundLocalErrors and the like in some # versions (2.1) of Python. import SCons.Platform.win32 return SCons.Platform.win32.parallel_msg @@ -368,7 +359,7 @@ class CleanTask(SCons.Taskmaster.AlwaysTask): # issue, an IOError would indicate something like # the file not existing. In either case, print a # message and keep going to try to remove as many - # targets aa possible. + # targets as possible. print "scons: Could not remove '%s':" % str(t), e.strerror else: if removed: @@ -383,7 +374,7 @@ class CleanTask(SCons.Taskmaster.AlwaysTask): # we don't want, like store .sconsign information. executed = SCons.Taskmaster.Task.executed_without_callbacks - # Have the taskmaster arrange to "execute" all of the targets, because + # Have the Taskmaster arrange to "execute" all of the targets, because # we'll figure out ourselves (in remove() or show() above) whether # anything really needs to be done. make_ready = SCons.Taskmaster.Task.make_ready_all @@ -487,7 +478,6 @@ def SetOption(name, value): def PrintHelp(file=None): OptionsParser.print_help(file=file) -# class Stats(object): def __init__(self): self.stats = [] @@ -711,7 +701,6 @@ def _load_site_scons_dir(topdir, site_dir_name=None): site_tools_dir = os.path.join(site_dir, site_tools_dirname) if os.path.exists(site_init_file): import imp, re - # TODO(2.4): turn this into try:-except:-finally: try: try: fp, pathname, description = imp.find_module(site_init_modname, @@ -1024,7 +1013,7 @@ def _main(parser): # the SConscript file. # # We delay enabling the PythonVersionWarning class until here so that, - # if they explicity disabled it in either in the command line or in + # if they explicitly disabled it in either in the command line or in # $SCONSFLAGS, or in the SConscript file, then the search through # the list of deprecated warning classes will find that disabling # first and not issue the warning. @@ -1232,13 +1221,8 @@ def _build_targets(fs, options, targets, target_top): def order(dependencies): """Randomize the dependencies.""" import random - # This is cribbed from the implementation of - # random.shuffle() in Python 2.X. - d = dependencies - for i in range(len(d)-1, 0, -1): - j = int(random.random() * (i+1)) - d[i], d[j] = d[j], d[i] - return d + random.shuffle(dependencies) + return dependencies else: def order(dependencies): """Leave the order of dependencies alone.""" @@ -1316,18 +1300,6 @@ def _exec_main(parser, values): # compat layer imports "cProfile" for us if it's available. from profile import Profile - # Some versions of Python 2.4 shipped a profiler that had the - # wrong 'c_exception' entry in its dispatch table. Make sure - # we have the right one. (This may put an unnecessary entry - # in the table in earlier versions of Python, but its presence - # shouldn't hurt anything). - try: - dispatch = Profile.dispatch - except AttributeError: - pass - else: - dispatch['c_exception'] = Profile.trace_dispatch_return - prof = Profile() try: prof.runcall(_main, parser) diff --git a/src/engine/SCons/Script/SConsOptions.py b/src/engine/SCons/Script/SConsOptions.py index 68c60cc..f56504a 100644 --- a/src/engine/SCons/Script/SConsOptions.py +++ b/src/engine/SCons/Script/SConsOptions.py @@ -426,7 +426,7 @@ class SConsOptionParser(optparse.OptionParser): result = group.add_option(*args, **kw) if result: - # The option was added succesfully. We now have to add the + # The option was added successfully. We now have to add the # default value to our object that holds the default values # (so that an attempt to fetch the option's attribute will # yield the default value when not overridden) and then @@ -449,11 +449,6 @@ class SConsIndentedHelpFormatter(optparse.IndentedHelpFormatter): "SCons Options." Unfortunately, we have to do this here, because those titles are hard-coded in the optparse calls. """ - if heading == 'options': - # The versions of optparse.py shipped with Pythons 2.3 and - # 2.4 pass this in uncapitalized; override that so we get - # consistent output on all versions. - heading = "Options" if heading == 'Options': heading = "SCons Options" return optparse.IndentedHelpFormatter.format_heading(self, heading) @@ -488,13 +483,7 @@ class SConsIndentedHelpFormatter(optparse.IndentedHelpFormatter): # read data from FILENAME result = [] - try: - opts = self.option_strings[option] - except AttributeError: - # The Python 2.3 version of optparse attaches this to - # to the option argument, not to this object. - opts = option.option_strings - + opts = self.option_strings[option] opt_width = self.help_position - self.current_indent - 2 if len(opts) > opt_width: wrapper = textwrap.TextWrapper(width=self.width, @@ -509,14 +498,7 @@ class SConsIndentedHelpFormatter(optparse.IndentedHelpFormatter): result.append(opts) if option.help: - try: - expand_default = self.expand_default - except AttributeError: - # The HelpFormatter base class in the Python 2.3 version - # of optparse has no expand_default() method. - help_text = option.help - else: - help_text = expand_default(option) + help_text = self.expand_default(option) # SCons: indent every line of the help text but the first. wrapper = textwrap.TextWrapper(width=self.help_width, @@ -530,34 +512,6 @@ class SConsIndentedHelpFormatter(optparse.IndentedHelpFormatter): result.append("\n") return "".join(result) - # For consistent help output across Python versions, we provide a - # subclass copy of format_option_strings() and these two variables. - # This is necessary (?) for Python2.3, which otherwise concatenates - # a short option with its metavar. - _short_opt_fmt = "%s %s" - _long_opt_fmt = "%s=%s" - - def format_option_strings(self, option): - """Return a comma-separated list of option strings & metavariables.""" - if option.takes_value(): - metavar = option.metavar or option.dest.upper() - short_opts = [] - for sopt in option._short_opts: - short_opts.append(self._short_opt_fmt % (sopt, metavar)) - long_opts = [] - for lopt in option._long_opts: - long_opts.append(self._long_opt_fmt % (lopt, metavar)) - else: - short_opts = option._short_opts - long_opts = option._long_opts - - if self.short_first: - opts = short_opts + long_opts - else: - opts = long_opts + short_opts - - return ", ".join(opts) - def Parser(version): """ Returns an options parser object initialized with the standard diff --git a/src/engine/SCons/Script/SConscript.py b/src/engine/SCons/Script/SConscript.py index b832ff7..e696cfa 100644 --- a/src/engine/SCons/Script/SConscript.py +++ b/src/engine/SCons/Script/SConscript.py @@ -52,16 +52,6 @@ import re import sys import traceback -# The following variables used to live in this module. Some -# SConscript files out there may have referred to them directly as -# SCons.Script.SConscript.*. This is now supported by some special -# handling towards the bottom of the SConscript.__init__.py module. -#Arguments = {} -#ArgList = [] -#BuildTargets = TargetList() -#CommandLineTargets = [] -#DefaultTargets = [] - class SConscriptReturn(Exception): pass @@ -446,7 +436,7 @@ class SConsEnvironment(SCons.Environment.Base): # # Public methods of an SConsEnvironment. These get - # entry points in the global name space so they can be called + # entry points in the global namespace so they can be called # as global functions. # diff --git a/src/engine/SCons/Script/__init__.py b/src/engine/SCons/Script/__init__.py index 6bfc36f..a0c61c5 100644 --- a/src/engine/SCons/Script/__init__.py +++ b/src/engine/SCons/Script/__init__.py @@ -270,12 +270,6 @@ def HelpFunction(text, append=False): s.close() else: help_text = "" -# -# Was in original patch but this text is arbitrary and breaks tests -# so I removed it (Deegan) -# help_text = help_text + "\nLocal Build Variables:\n" + text -# else: -# help_text = help_text + text help_text= help_text + text diff --git a/src/engine/SCons/Subst.py b/src/engine/SCons/Subst.py index 318d7d9..236b08e 100644 --- a/src/engine/SCons/Subst.py +++ b/src/engine/SCons/Subst.py @@ -344,7 +344,6 @@ _remove = re.compile(r'\$\([^\$]*(\$[^\)][^\$]*)*\$\)') _regex_remove = [ _rm, None, _remove ] def _rm_list(list): - #return [ l for l in list if not l in ('$(', '$)') ] return [l for l in list if not l in ('$(', '$)')] def _remove_list(list): @@ -580,8 +579,6 @@ def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={ return result -#Subst_List_Strings = {} - def scons_subst_list(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={}, lvars={}, conv=None): """Substitute construction variables in a string (or list or other object) and separate the arguments into a command list. @@ -590,12 +587,6 @@ def scons_subst_list(strSubst, env, mode=SUBST_RAW, target=None, source=None, gv substitutions within strings, so see that function instead if that's what you're looking for. """ -# try: -# Subst_List_Strings[strSubst] = Subst_List_Strings[strSubst] + 1 -# except KeyError: -# Subst_List_Strings[strSubst] = 1 -# import SCons.Debug -# SCons.Debug.caller_trace(1) class ListSubber(collections.UserList): """A class to construct the results of a scons_subst_list() call. diff --git a/src/engine/SCons/SubstTests.py b/src/engine/SCons/SubstTests.py index 6f2eb3f..e625cc7 100644 --- a/src/engine/SCons/SubstTests.py +++ b/src/engine/SCons/SubstTests.py @@ -604,17 +604,6 @@ class scons_subst_TestCase(SubstTestCase): node = scons_subst("$NODE", env, mode=SUBST_SIG, conv=s, gvars=gvars) assert node is n1, node - #def test_subst_function_return(self): - # """Test scons_subst(): returning a function""" - # env = DummyEnv({'FUNCTION' : foo}) - # gvars = env.Dictionary() - # func = scons_subst("$FUNCTION", env, mode=SUBST_RAW, call=None, gvars=gvars) - # assert func is function_foo, func - # func = scons_subst("$FUNCTION", env, mode=SUBST_CMD, call=None, gvars=gvars) - # assert func is function_foo, func - # func = scons_subst("$FUNCTION", env, mode=SUBST_SIG, call=None, gvars=gvars) - # assert func is function_foo, func - def test_subst_overriding_gvars(self): """Test scons_subst(): supplying an overriding gvars dictionary""" env = DummyEnv({'XXX' : 'xxx'}) diff --git a/src/engine/SCons/Taskmaster.py b/src/engine/SCons/Taskmaster.py index 345534e..069ac90 100644 --- a/src/engine/SCons/Taskmaster.py +++ b/src/engine/SCons/Taskmaster.py @@ -122,7 +122,7 @@ class Task(object): aspects of controlling a build, so any given application *should* be able to do what it wants by sub-classing this class and overriding methods as appropriate. If an application - needs to customze something by sub-classing Taskmaster (or + needs to customize something by sub-classing Taskmaster (or some other build engine class), we should first try to migrate that functionality into this class. @@ -147,7 +147,7 @@ class Task(object): This hook gets called as part of preparing a task for execution (that is, a Node to be built). As part of figuring out what Node - should be built next, the actually target list may be altered, + should be built next, the actual target list may be altered, along with a message describing the alteration. The calling interface can subclass Task and provide a concrete implementation of this method to see those messages. @@ -664,9 +664,9 @@ class Taskmaster(object): its parent node. A pending child can occur when the Taskmaster completes a loop - through a cycle. For example, lets imagine a graph made of - three node (A, B and C) making a cycle. The evaluation starts - at node A. The taskmaster first consider whether node A's + through a cycle. For example, let's imagine a graph made of + three nodes (A, B and C) making a cycle. The evaluation starts + at node A. The Taskmaster first considers whether node A's child B is up-to-date. Then, recursively, node B needs to check whether node C is up-to-date. This leaves us with a dependency graph looking like: @@ -951,7 +951,7 @@ class Taskmaster(object): task.make_ready() except: # We had a problem just trying to get this task ready (like - # a child couldn't be linked in to a VariantDir when deciding + # a child couldn't be linked to a VariantDir when deciding # whether this node is current). Arrange to raise the # exception when the Task is "executed." self.ready_exc = sys.exc_info() diff --git a/src/engine/SCons/Tool/BitKeeper.py b/src/engine/SCons/Tool/BitKeeper.py index 191879f..44632d7 100644 --- a/src/engine/SCons/Tool/BitKeeper.py +++ b/src/engine/SCons/Tool/BitKeeper.py @@ -49,7 +49,6 @@ def generate(env): act = SCons.Action.Action("$BITKEEPERCOM", "$BITKEEPERCOMSTR") return SCons.Builder.Builder(action = act, env = env) - #setattr(env, 'BitKeeper', BitKeeperFactory) env.BitKeeper = BitKeeperFactory env['BITKEEPER'] = 'bk' diff --git a/src/engine/SCons/Tool/CVS.py b/src/engine/SCons/Tool/CVS.py index a506231..08cf04c 100644 --- a/src/engine/SCons/Tool/CVS.py +++ b/src/engine/SCons/Tool/CVS.py @@ -55,7 +55,6 @@ def generate(env): CVSREPOSITORY = repos, CVSMODULE = module) - #setattr(env, 'CVS', CVSFactory) env.CVS = CVSFactory env['CVS'] = 'cvs' diff --git a/src/engine/SCons/Tool/GettextCommon.py b/src/engine/SCons/Tool/GettextCommon.py index bdd52c0..f01371a 100644 --- a/src/engine/SCons/Tool/GettextCommon.py +++ b/src/engine/SCons/Tool/GettextCommon.py @@ -251,7 +251,7 @@ class RPaths(object): 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 + The `__call__` method returns paths relative to current working directory, but we assume, that *xgettext(1)* is run from the directory, where target file is going to be created. @@ -330,7 +330,7 @@ def _init_po_files(target, source, env): 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?). + # one has changed (but is this our fault?). for tgt in target: if not tgt.exists(): if autoinit: diff --git a/src/engine/SCons/Tool/MSCommon/common.py b/src/engine/SCons/Tool/MSCommon/common.py index 9549a66..be890e2 100644 --- a/src/engine/SCons/Tool/MSCommon/common.py +++ b/src/engine/SCons/Tool/MSCommon/common.py @@ -93,7 +93,7 @@ def has_reg(value): try: SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_LOCAL_MACHINE, value) ret = True - except WindowsError: + except SCons.Util.WinError: ret = False return ret @@ -180,7 +180,7 @@ def get_output(vcbat, args = None, env = None): stdout = popen.stdout.read() stderr = popen.stderr.read() - # Extra debug logic, uncomment if necessar + # Extra debug logic, uncomment if necessary # debug('get_output():stdout:%s'%stdout) # debug('get_output():stderr:%s'%stderr) @@ -226,33 +226,6 @@ def parse_output(output, keep = ("INCLUDE", "LIB", "LIBPATH", "PATH")): 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 diff --git a/src/engine/SCons/Tool/MSCommon/netframework.py b/src/engine/SCons/Tool/MSCommon/netframework.py index 6124e5b..8fa3c43 100644 --- a/src/engine/SCons/Tool/MSCommon/netframework.py +++ b/src/engine/SCons/Tool/MSCommon/netframework.py @@ -27,6 +27,7 @@ __doc__ = """ import os import re +import SCons.Util from common import read_reg, debug @@ -40,7 +41,7 @@ def find_framework_root(): try: froot = read_reg(_FRAMEWORKDIR_HKEY_ROOT) debug("Found framework install root in registry: %s" % froot) - except WindowsError, e: + except SCons.Util.WinError, e: debug("Could not read reg key %s" % _FRAMEWORKDIR_HKEY_ROOT) return None diff --git a/src/engine/SCons/Tool/MSCommon/sdk.py b/src/engine/SCons/Tool/MSCommon/sdk.py index afb37fe..b8b71a6 100644 --- a/src/engine/SCons/Tool/MSCommon/sdk.py +++ b/src/engine/SCons/Tool/MSCommon/sdk.py @@ -80,7 +80,7 @@ class SDKDefinition(object): try: sdk_dir = common.read_reg(hkey) - except WindowsError, e: + except SCons.Util.WinError, e: debug('find_sdk_dir(): no SDK registry key %s' % repr(hkey)) return None @@ -168,7 +168,7 @@ SDK70VCSetupScripts = { 'x86' : r'bin\vcvars32.bat', # # 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. +# this means we should list SDKs from most recent to oldest. # # If you update this list, update the documentation in Tool/mssdk.xml. SupportedSDKList = [ @@ -306,29 +306,6 @@ def set_sdk_by_directory(env, sdk_dir): 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) @@ -343,9 +320,6 @@ def get_default_sdk(): return None return InstalledSDKList[0] - - - def mssdk_setup_env(env): debug('sdk.py:mssdk_setup_env()') if 'MSSDK_DIR' in env: diff --git a/src/engine/SCons/Tool/MSCommon/vc.py b/src/engine/SCons/Tool/MSCommon/vc.py index 4fb0d5a..97e2ffc 100644 --- a/src/engine/SCons/Tool/MSCommon/vc.py +++ b/src/engine/SCons/Tool/MSCommon/vc.py @@ -244,13 +244,13 @@ def find_vc_pdir(msvc_version): try: # ordinally at win64, try Wow6432Node first. comps = common.read_reg(root + 'Wow6432Node\\' + key, hkroot) - except WindowsError, e: + except SCons.Util.WinError, e: # at Microsoft Visual Studio for Python 2.7, value is not in Wow6432Node pass if not comps: # not Win64, or Microsoft Visual Studio for Python 2.7 comps = common.read_reg(root + key, hkroot) - except WindowsError, e: + except SCons.Util.WinError, e: debug('find_vc_dir(): no VC registry key %s' % repr(key)) else: debug('find_vc_dir(): found VC in registry: %s' % comps) diff --git a/src/engine/SCons/Tool/MSCommon/vs.py b/src/engine/SCons/Tool/MSCommon/vs.py index d9eb1e3..0bdbf0c 100644 --- a/src/engine/SCons/Tool/MSCommon/vs.py +++ b/src/engine/SCons/Tool/MSCommon/vs.py @@ -52,8 +52,6 @@ class VisualStudio(object): self.__dict__.update(kw) self._cache = {} - # - def find_batch_file(self): vs_dir = self.get_vs_dir() if not vs_dir: @@ -85,7 +83,7 @@ class VisualStudio(object): key = root + key try: comps = read_reg(key) - except WindowsError, e: + except SCons.Util.WinError, 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) @@ -116,8 +114,6 @@ class VisualStudio(object): return None return executable - # - def get_batch_file(self): try: return self._cache['batch_file'] @@ -471,7 +467,7 @@ 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 + variable, query all the available visual studios through get_installed_visual_studios, and take the highest one. Return diff --git a/src/engine/SCons/Tool/Perforce.py b/src/engine/SCons/Tool/Perforce.py index 15dd83f..c8cf931 100644 --- a/src/engine/SCons/Tool/Perforce.py +++ b/src/engine/SCons/Tool/Perforce.py @@ -38,9 +38,6 @@ 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', @@ -58,7 +55,6 @@ def generate(env): 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' @@ -87,7 +83,7 @@ def generate(env): 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) + SCons.Util.AddPathIfNotExists(environ, 'PATH', val) except SCons.Util.RegError: # Can't detect where Perforce is, hope the user has it set in the # PATH. diff --git a/src/engine/SCons/Tool/PharLapCommon.py b/src/engine/SCons/Tool/PharLapCommon.py index 9f925b9..864a185 100644 --- a/src/engine/SCons/Tool/PharLapCommon.py +++ b/src/engine/SCons/Tool/PharLapCommon.py @@ -85,28 +85,6 @@ def getPharLapVersion(): # 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.""" @@ -117,14 +95,14 @@ def addPharLapPaths(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'))) + SCons.Util.AddPathIfNotExists(env_dict, 'PATH', + os.path.join(ph_path, 'bin')) + SCons.Util.AddPathIfNotExists(env_dict, 'INCLUDE', + os.path.join(ph_path, 'include')) + SCons.Util.AddPathIfNotExists(env_dict, 'LIB', + os.path.join(ph_path, 'lib')) + SCons.Util.AddPathIfNotExists(env_dict, 'LIB', + os.path.join(ph_path, os.path.normpath('lib/vclib'))) env['PHARLAP_PATH'] = getPharLapPath() env['PHARLAP_VERSION'] = str(getPharLapVersion()) diff --git a/src/engine/SCons/Tool/PharLapCommonTests.py b/src/engine/SCons/Tool/PharLapCommonTests.py deleted file mode 100644 index e67d426..0000000 --- a/src/engine/SCons/Tool/PharLapCommonTests.py +++ /dev/null @@ -1,69 +0,0 @@ -# -# __COPYRIGHT__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import unittest -import os.path -import os -import sys - -import TestUnit - -import SCons.Errors -from SCons.Tool.PharLapCommon import * - -class PharLapCommonTestCase(unittest.TestCase): - def test_addPathIfNotExists(self): - """Test the addPathIfNotExists() function""" - env_dict = { 'FOO' : os.path.normpath('/foo/bar') + os.pathsep + \ - os.path.normpath('/baz/blat'), - 'BAR' : os.path.normpath('/foo/bar') + os.pathsep + \ - os.path.normpath('/baz/blat'), - 'BLAT' : [ os.path.normpath('/foo/bar'), - os.path.normpath('/baz/blat') ] } - addPathIfNotExists(env_dict, 'FOO', os.path.normpath('/foo/bar')) - addPathIfNotExists(env_dict, 'BAR', os.path.normpath('/bar/foo')) - addPathIfNotExists(env_dict, 'BAZ', os.path.normpath('/foo/baz')) - addPathIfNotExists(env_dict, 'BLAT', os.path.normpath('/baz/blat')) - addPathIfNotExists(env_dict, 'BLAT', os.path.normpath('/baz/foo')) - - assert env_dict['FOO'] == os.path.normpath('/foo/bar') + os.pathsep + \ - os.path.normpath('/baz/blat'), env_dict['FOO'] - assert env_dict['BAR'] == os.path.normpath('/bar/foo') + os.pathsep + \ - os.path.normpath('/foo/bar') + os.pathsep + \ - os.path.normpath('/baz/blat'), env_dict['BAR'] - assert env_dict['BAZ'] == os.path.normpath('/foo/baz'), env_dict['BAZ'] - assert env_dict['BLAT'] == [ os.path.normpath('/baz/foo'), - os.path.normpath('/foo/bar'), - os.path.normpath('/baz/blat') ], env_dict['BLAT' ] - -if __name__ == "__main__": - suite = unittest.makeSuite(PharLapCommonTestCase, 'test_') - TestUnit.run(suite) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/RCS.py b/src/engine/SCons/Tool/RCS.py index 6ac1a33..e24b89a 100644 --- a/src/engine/SCons/Tool/RCS.py +++ b/src/engine/SCons/Tool/RCS.py @@ -46,7 +46,6 @@ def generate(env): act = SCons.Action.Action('$RCS_COCOM', '$RCS_COCOMSTR') return SCons.Builder.Builder(action = act, env = env) - #setattr(env, 'RCS', RCSFactory) env.RCS = RCSFactory env['RCS'] = 'rcs' diff --git a/src/engine/SCons/Tool/SCCS.py b/src/engine/SCons/Tool/SCCS.py index 7653468..92ded51 100644 --- a/src/engine/SCons/Tool/SCCS.py +++ b/src/engine/SCons/Tool/SCCS.py @@ -46,7 +46,6 @@ def generate(env): act = SCons.Action.Action('$SCCSCOM', '$SCCSCOMSTR') return SCons.Builder.Builder(action = act, env = env) - #setattr(env, 'SCCS', SCCSFactory) env.SCCS = SCCSFactory env['SCCS'] = 'sccs' diff --git a/src/engine/SCons/Tool/Subversion.py b/src/engine/SCons/Tool/Subversion.py index ee70925..f1b3708 100644 --- a/src/engine/SCons/Tool/Subversion.py +++ b/src/engine/SCons/Tool/Subversion.py @@ -54,7 +54,6 @@ def generate(env): SVNREPOSITORY = repos, SVNMODULE = module) - #setattr(env, 'Subversion', SubversionFactory) env.Subversion = SubversionFactory env['SVN'] = 'svn' diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py index 0594798..f16e9e2 100644 --- a/src/engine/SCons/Tool/__init__.py +++ b/src/engine/SCons/Tool/__init__.py @@ -108,7 +108,7 @@ class Tool(object): self.options = module.options def _tool_module(self): - # TODO: Interchange zipimport with normal initilization for better error reporting + # TODO: Interchange zipimport with normal initialization for better error reporting oldpythonpath = sys.path sys.path = self.toolpath + sys.path diff --git a/src/engine/SCons/Tool/aixf77.py b/src/engine/SCons/Tool/aixf77.py index a667e84..cf07a0b 100644 --- a/src/engine/SCons/Tool/aixf77.py +++ b/src/engine/SCons/Tool/aixf77.py @@ -41,7 +41,7 @@ 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. +# SCons.Platform.aix_get_xlc() call in the function below. packages = [] def get_xlf77(env): diff --git a/src/engine/SCons/Tool/cyglink.py b/src/engine/SCons/Tool/cyglink.py index 5230910..921f0eb 100644 --- a/src/engine/SCons/Tool/cyglink.py +++ b/src/engine/SCons/Tool/cyglink.py @@ -143,7 +143,7 @@ def _versioned_implib_name(env, libnode, version, prefix, suffix, **kw): implib_libtype=kw['libtype']) def _versioned_implib_symlinks(env, libnode, version, prefix, suffix, **kw): - """Generate link names that should be created for a versioned shared lirbrary. + """Generate link names that should be created for a versioned shared library. Returns a list in the form [ (link, linktarget), ... ] """ Verbose = False diff --git a/src/engine/SCons/Tool/docbook/__init__.py b/src/engine/SCons/Tool/docbook/__init__.py index aead43c..71e93a7 100644 --- a/src/engine/SCons/Tool/docbook/__init__.py +++ b/src/engine/SCons/Tool/docbook/__init__.py @@ -10,7 +10,7 @@ selection method. """ # -# Copyright (c) 2001-7,2010 The SCons Foundation +# __COPYRIGHT__ # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -852,30 +852,16 @@ def generate(env): ) _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 + 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") def exists(env): diff --git a/src/engine/SCons/Tool/gnulink.py b/src/engine/SCons/Tool/gnulink.py index 6b0d5b3..2f1aa03 100644 --- a/src/engine/SCons/Tool/gnulink.py +++ b/src/engine/SCons/Tool/gnulink.py @@ -60,7 +60,7 @@ def generate(env): link._setup_versioned_lib_variables(env, tool = 'gnulink', use_soname = use_soname) env['LINKCALLBACKS'] = link._versioned_lib_callbacks() - # For backward-compatiblity with older SCons versions + # For backward-compatibility with older SCons versions env['SHLIBVERSIONFLAGS'] = SCons.Util.CLVar('-Wl,-Bsymbolic') def exists(env): diff --git a/src/engine/SCons/Tool/icl.py b/src/engine/SCons/Tool/icl.py index caa2281..a0bad31 100644 --- a/src/engine/SCons/Tool/icl.py +++ b/src/engine/SCons/Tool/icl.py @@ -35,7 +35,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import SCons.Tool.intelc -# This has been completely superceded by intelc.py, which can +# This has been completely superseded by intelc.py, which can # handle both Windows and Linux versions. def generate(*args, **kw): diff --git a/src/engine/SCons/Tool/install.py b/src/engine/SCons/Tool/install.py index 4226d56..e84ec7a 100644 --- a/src/engine/SCons/Tool/install.py +++ b/src/engine/SCons/Tool/install.py @@ -39,7 +39,7 @@ import stat import SCons.Action import SCons.Tool -from SCons.Util import make_path_relative +import SCons.Util # # We keep track of *all* installed files. @@ -91,7 +91,7 @@ def scons_copytree(src, dst, symlinks=False): errors.extend(err.args[0]) try: shutil.copystat(src, dst) - except WindowsError: + except SCons.Util.WinError: # can't copy file access times on Windows pass except OSError, why: @@ -225,7 +225,7 @@ def stringFunc(target, source, env): # Emitter functions # def add_targets_to_INSTALLED_FILES(target, source, env): - """ an emitter that adds all target files to the list stored in the + """ 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. """ @@ -236,7 +236,7 @@ def add_targets_to_INSTALLED_FILES(target, source, env): 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 + """ 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. """ @@ -254,7 +254,7 @@ def add_versioned_targets_to_INSTALLED_FILES(target, source, env): return (target, source) class DESTDIR_factory(object): - """ a node factory, where all files will be relative to the dir supplied + """ A node factory, where all files will be relative to the dir supplied in the constructor. """ def __init__(self, env, dir): @@ -262,11 +262,11 @@ class DESTDIR_factory(object): self.dir = env.arg2nodes( dir, env.fs.Dir )[0] def Entry(self, name): - name = make_path_relative(name) + name = SCons.Util.make_path_relative(name) return self.dir.Entry(name) def Dir(self, name): - name = make_path_relative(name) + name = SCons.Util.make_path_relative(name) return self.dir.Dir(name) # @@ -304,14 +304,12 @@ def InstallBuilderWrapper(env, target=None, source=None, dir=None, **kw): # '#' 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 diff --git a/src/engine/SCons/Tool/intelc.py b/src/engine/SCons/Tool/intelc.py index 57258f3..b1cb5e3 100644 --- a/src/engine/SCons/Tool/intelc.py +++ b/src/engine/SCons/Tool/intelc.py @@ -62,15 +62,6 @@ class MissingDirError(IntelCError): # dir not found 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 @@ -191,7 +182,7 @@ def get_intel_registry_value(valuename, version=None, abi=None): 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: + except SCons.Util.WinError: raise MissingRegistryError("%s was not found in the registry, for Intel compiler version %s, abi='%s'"%(K, version,abi)) # Get the value: @@ -215,7 +206,7 @@ def get_all_compiler_versions(): try: k = SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_LOCAL_MACHINE, keyname) - except WindowsError: + except SCons.Util.WinError: # For version 13 or later, check for default instance UUID if is_win64: keyname = 'Software\\WoW6432Node\\Intel\\Suites' @@ -224,7 +215,7 @@ def get_all_compiler_versions(): try: k = SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_LOCAL_MACHINE, keyname) - except WindowsError: + except SCons.Util.WinError: return [] i = 0 versions = [] @@ -302,7 +293,7 @@ def get_all_compiler_versions(): """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) + return sorted(SCons.Util.unique(versions), key=keyfunc, reverse=True) def get_intel_compiler_top(version, abi): """ diff --git a/src/engine/SCons/Tool/mslink.py b/src/engine/SCons/Tool/mslink.py index 1390c20..74c20d0 100644 --- a/src/engine/SCons/Tool/mslink.py +++ b/src/engine/SCons/Tool/mslink.py @@ -305,7 +305,7 @@ def generate(env): # 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 + # TODO Future work garyo 27-Feb-11 env['_MANIFEST_SOURCES'] = None # _windowsManifestSources # Set-up ms tools paths diff --git a/src/engine/SCons/Tool/msvs.py b/src/engine/SCons/Tool/msvs.py index 355eeed..113f859 100644 --- a/src/engine/SCons/Tool/msvs.py +++ b/src/engine/SCons/Tool/msvs.py @@ -100,42 +100,6 @@ def msvs_parse_version(s): 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 @@ -204,7 +168,7 @@ class _UserGenerator(object): Base class for .dsp.user file generator ''' # Default instance values. - # Ok ... a bit defensive, but it does not seems reasonable to crash the + # Ok ... a bit defensive, but it does not seem reasonable to crash the # build for a workspace user file. :-) usrhead = None usrdebg = None @@ -212,7 +176,7 @@ class _UserGenerator(object): createfile = False def __init__(self, dspfile, source, env): # DebugSettings should be a list of debug dictionary sorted in the same order - # than the target list and variants + # as the target list and variants if 'variant' not in env: raise SCons.Errors.InternalError("You must specify a 'variant' argument (i.e. 'Debug' or " +\ "'Release') to create an MSVSProject.") @@ -543,9 +507,7 @@ class _DSPGenerator(object): 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()) + self.sources[n].sort(key=lambda a: a.lower()) def AddConfig(self, variant, buildtarget, outdir, runfile, cmdargs, dspfile=dspfile): config = Config() diff --git a/src/engine/SCons/Tool/packaging/__init__.py b/src/engine/SCons/Tool/packaging/__init__.py index 1a979ab..0f9a93d 100644 --- a/src/engine/SCons/Tool/packaging/__init__.py +++ b/src/engine/SCons/Tool/packaging/__init__.py @@ -77,7 +77,6 @@ def Tag(env, target, source, *more_tags, **kw_tags): # 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 t.Tag(k, v) @@ -175,7 +174,7 @@ def Package(env, target=None, source=None, **kw): args=[x for x in args if x not in kw] if len(args)==0: - raise # must be a different error, so reraise + raise # must be a different error, so re-raise elif len(args)==1: raise SCons.Errors.UserError( "Missing Packagetag '%s' for %s packager"\ % (args[0],packager.__name__) ) @@ -232,8 +231,6 @@ def options(opts): 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_' if f1._tags: pattrs = list(filter(copyit, f1._tags)) @@ -278,7 +275,7 @@ def putintopackageroot(target, source, env, pkgroot, honor_install_location=1): return (target, new_source) def stripinstallbuilder(target, source, env): - """ strips the install builder action from the source list and stores + """ 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. diff --git a/src/engine/SCons/Tool/packaging/ipk.py b/src/engine/SCons/Tool/packaging/ipk.py index 84f4e20..c666033 100644 --- a/src/engine/SCons/Tool/packaging/ipk.py +++ b/src/engine/SCons/Tool/packaging/ipk.py @@ -35,7 +35,7 @@ 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 + """ This function prepares the packageroot directory for packaging with the ipkg builder. """ SCons.Tool.Tool('ipkg').generate(env) @@ -45,7 +45,7 @@ def package(env, target, source, PACKAGEROOT, NAME, VERSION, DESCRIPTION, target, source = stripinstallbuilder(target, source, env) target, source = putintopackageroot(target, source, env, PACKAGEROOT) - # This should be overridable from the construction environment, + # This should be overrideable 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. @@ -61,7 +61,7 @@ def package(env, target, source, PACKAGEROOT, NAME, VERSION, DESCRIPTION, if 'ARCHITECTURE' in kw: buildarchitecture = kw['ARCHITECTURE'] - # setup the kw to contain the mandatory arguments to this fucntion. + # setup the kw to contain the mandatory arguments to this function. # do this before calling any builder or setup function loc=locals() del loc['kw'] @@ -104,7 +104,7 @@ def gen_ipk_dir(proot, source, env, kw): return proot def build_specfiles(source, target, env): - """ filter the targets for the needed files and use the variables in env + """ Filter the targets for the needed files and use the variables in env to create the specfile. """ # diff --git a/src/engine/SCons/Tool/packaging/msi.py b/src/engine/SCons/Tool/packaging/msi.py index 172038f..41b7ab7 100644 --- a/src/engine/SCons/Tool/packaging/msi.py +++ b/src/engine/SCons/Tool/packaging/msi.py @@ -70,7 +70,7 @@ def convert_to_id(s, id_set): try: return id_set[id][s] except KeyError: - # no we did not so initialize with the id + # 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 @@ -79,7 +79,7 @@ def convert_to_id(s, id_set): return id_set[id][s] def is_dos_short_file_name(file): - """ examine if the given file is in the 8.3 form. + """ 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 @@ -88,7 +88,7 @@ def is_dos_short_file_name(file): 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 + """ 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 @@ -186,7 +186,7 @@ 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 + """ 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].get_abspath(), 'w') @@ -268,7 +268,7 @@ def create_default_directory_layout(root, NAME, VERSION, VENDOR, filename_set): # 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. + """ 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. @@ -280,7 +280,7 @@ def build_wxsfile_file_section(root, files, NAME, VERSION, VENDOR, filename_set, factory = Document() def get_directory( node, dir ): - """ returns the node under the given node representing the directory. + """ Returns the node under the given node representing the directory. Returns the component node if dir is None or empty. """ @@ -415,7 +415,7 @@ def build_wxsfile_features_section(root, files, NAME, VERSION, SUMMARY, id_set): root.getElementsByTagName('Product')[0].childNodes.append(Feature) def build_wxsfile_default_gui(root): - """ this function adds a default GUI to the wxs file + """ This function adds a default GUI to the wxs file """ factory = Document() Product = root.getElementsByTagName('Product')[0] @@ -429,7 +429,7 @@ def build_wxsfile_default_gui(root): Product.childNodes.append(UIRef) def build_license_file(directory, spec): - """ creates a License.rtf file with the content of "X_MSI_LICENSE_TEXT" + """ Creates a License.rtf file with the content of "X_MSI_LICENSE_TEXT" in the given directory """ name, text = '', '' diff --git a/src/engine/SCons/Tool/packaging/rpm.py b/src/engine/SCons/Tool/packaging/rpm.py index 92977d0..0750113 100644 --- a/src/engine/SCons/Tool/packaging/rpm.py +++ b/src/engine/SCons/Tool/packaging/rpm.py @@ -72,7 +72,6 @@ def package(env, target, source, PACKAGEROOT, NAME, VERSION, # 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 @@ -86,26 +85,21 @@ def package(env, target, source, PACKAGEROOT, NAME, VERSION, 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 + # the rpm tool depends on a source package, until this is changed # 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)) ) + sources.extend( [s for s in source if str(s).rfind('.spec')!=-1] ) # 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] ) @@ -194,7 +188,7 @@ def build_specfile_sections(spec): return str def build_specfile_header(spec): - """ Builds all section but the %file of a rpm specfile + """ Builds all sections but the %file of a rpm specfile """ str = "" @@ -312,11 +306,10 @@ class SimpleTagCompiler(object): self.mandatory = mandatory def compile(self, values): - """ compiles the tagset and returns a str containing the result + """ Compiles the tagset and returns a str containing the result """ def is_international(tag): - #return tag.endswith('_') - return tag[-1:] == '_' + return tag.endswith('_') def get_country_code(tag): return tag[-2:] @@ -327,7 +320,6 @@ class SimpleTagCompiler(object): 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: @@ -336,11 +328,9 @@ class SimpleTagCompiler(object): 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: diff --git a/src/engine/SCons/Tool/sunar.py b/src/engine/SCons/Tool/sunar.py index eb58457..ec076c8 100644 --- a/src/engine/SCons/Tool/sunar.py +++ b/src/engine/SCons/Tool/sunar.py @@ -2,7 +2,7 @@ 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. +instantiations 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() diff --git a/src/engine/SCons/Tool/tex.py b/src/engine/SCons/Tool/tex.py index 053d85d..3d429c9 100644 --- a/src/engine/SCons/Tool/tex.py +++ b/src/engine/SCons/Tool/tex.py @@ -700,12 +700,6 @@ def tex_emitter_core(target, source, env, graphics_extensions): 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, diff --git a/src/engine/SCons/Tool/textfile.py b/src/engine/SCons/Tool/textfile.py index 8dc8f4b..76efbd7 100644 --- a/src/engine/SCons/Tool/textfile.py +++ b/src/engine/SCons/Tool/textfile.py @@ -40,8 +40,8 @@ Textfile/Substfile builder for SCons. 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. + substitution could be further expanded by another substitution, it + is unpredictable whether the expansion will occur. """ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" diff --git a/src/engine/SCons/Tool/xgettext.py b/src/engine/SCons/Tool/xgettext.py index 64436b8..b8a88dc 100644 --- a/src/engine/SCons/Tool/xgettext.py +++ b/src/engine/SCons/Tool/xgettext.py @@ -76,7 +76,7 @@ def _update_pot_file(target, source, env): 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). + # revert each one to its original state). save_cwd = env.fs.getcwd() save_os_cwd = os.getcwd() chdir = target[0].dir @@ -134,7 +134,7 @@ def _update_pot_file(target, source, env): explain = "new file" if needs_update: # Print message employing SCons.Action.Action for that. - msg = "Writting " + repr(str(target[0])) + " (" + explain + ")" + msg = "Writing " + repr(str(target[0])) + " (" + explain + ")" env.Execute(SCons.Action.Action(nop, msg)) f = open(str(target[0]),"w") f.write(new_content) @@ -142,7 +142,7 @@ def _update_pot_file(target, source, env): return 0 else: # Print message employing SCons.Action.Action for that. - msg = "Not writting " + repr(str(target[0])) + " (" + explain + ")" + msg = "Not writing " + repr(str(target[0])) + " (" + explain + ")" env.Execute(SCons.Action.Action(nop, msg)) return 0 ############################################################################# diff --git a/src/engine/SCons/Tool/yacc.py b/src/engine/SCons/Tool/yacc.py index 5896cbe..648433b 100644 --- a/src/engine/SCons/Tool/yacc.py +++ b/src/engine/SCons/Tool/yacc.py @@ -61,7 +61,7 @@ def _yaccEmitter(target, source, env, ysuf, hsuf): 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 + # If -v is specified 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 @@ -118,14 +118,6 @@ def generate(env): 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' diff --git a/src/engine/SCons/Util.py b/src/engine/SCons/Util.py index 4890ba2..a834726 100644 --- a/src/engine/SCons/Util.py +++ b/src/engine/SCons/Util.py @@ -92,7 +92,7 @@ def splitext(path): def updrive(path): """ Make the drive letter (if any) upper case. - This is useful because Windows is inconsitent on the case + This is useful because Windows is inconsistent on the case of the drive letter, which can cause inconsistencies when calculating command signatures. """ @@ -207,7 +207,7 @@ def render_tree(root, child_func, prune=0, margin=[0], visited={}): IDX = lambda N: N and 1 or 0 -def print_tree(root, child_func, prune=0, showtags=0, margin=[0], visited={}): +def print_tree(root, child_func, prune=0, showtags=0, margin=[0], visited=None): """ Print a tree of nodes. This is like render_tree, except it prints lines directly instead of creating a string representation in memory, @@ -224,6 +224,10 @@ def print_tree(root, child_func, prune=0, showtags=0, margin=[0], visited={}): """ rname = str(root) + + # Initialize 'visited' dict, if required + if visited is None: + visited = {} if showtags: @@ -291,7 +295,7 @@ def print_tree(root, child_func, prune=0, showtags=0, margin=[0], visited={}): # often too slow. # We are using the following trick to speed up these -# functions. Default arguments are used to take a snapshot of the +# functions. Default arguments are used to take a snapshot of # the global functions and constants used by these functions. This # transforms accesses to global variable into local variables # accesses (i.e. LOAD_FAST instead of LOAD_GLOBAL). @@ -301,11 +305,11 @@ ListTypes = (list, UserList) SequenceTypes = (list, tuple, UserList) # Note that profiling data shows a speed-up when comparing -# explicitely with str and unicode instead of simply comparing +# explicitly with str and unicode instead of simply comparing # with basestring. (at least on Python 2.5.1) StringTypes = (str, unicode, UserString) -# Empirically, it is faster to check explicitely for str and +# Empirically, it is faster to check explicitly for str and # unicode than for basestring. BaseStringTypes = (str, unicode) @@ -326,11 +330,11 @@ def is_String(obj, isinstance=isinstance, StringTypes=StringTypes): def is_Scalar(obj, isinstance=isinstance, StringTypes=StringTypes, SequenceTypes=SequenceTypes): # Profiling shows that there is an impressive speed-up of 2x - # when explicitely checking for strings instead of just not + # when explicitly checking for strings instead of just not # sequence when the argument (i.e. obj) is already a string. # But, if obj is a not string then it is twice as fast to # check only for 'not sequence'. The following code therefore - # assumes that the obj argument is a string must of the time. + # assumes that the obj argument is a string most of the time. return isinstance(obj, StringTypes) or not isinstance(obj, SequenceTypes) def do_flatten(sequence, result, isinstance=isinstance, @@ -431,7 +435,7 @@ def to_String_for_signature(obj, to_String_for_subst=to_String_for_subst, # # A special case is any object that has a __semi_deepcopy__() method, # which we invoke to create the copy. Currently only used by -# BuilderDict to actually prevent the copy operation (as invalid on that object) +# BuilderDict to actually prevent the copy operation (as invalid on that object). # # The dispatch table approach used here is a direct rip-off from the # normal Python copy module. @@ -571,6 +575,15 @@ except ImportError: pass RegError = _NoError +WinError = None +# Make sure we have a definition of WindowsError so we can +# run platform-independent tests of Windows functionality on +# platforms other than Windows. (WindowsError is, in fact, an +# OSError subclass on Windows.) +class PlainWindowsError(OSError): + pass + + if can_read_reg: HKEY_CLASSES_ROOT = hkey_mod.HKEY_CLASSES_ROOT HKEY_LOCAL_MACHINE = hkey_mod.HKEY_LOCAL_MACHINE @@ -605,18 +618,9 @@ if can_read_reg: return RegQueryValueEx(k,val) else: try: - e = WindowsError + WinError = WindowsError except NameError: - # Make sure we have a definition of WindowsError so we can - # run platform-independent tests of Windows functionality on - # platforms other than Windows. (WindowsError is, in fact, an - # OSError subclass on Windows.) - class WindowsError(OSError): - pass - import builtins - builtins.WindowsError = WindowsError - else: - del e + WinError = PlainWindowsError HKEY_CLASSES_ROOT = None HKEY_LOCAL_MACHINE = None @@ -624,10 +628,10 @@ else: HKEY_USERS = None def RegGetValue(root, key): - raise WindowsError + raise WinError def RegOpenKeyEx(root, key): - raise WindowsError + raise WinError if sys.platform == 'win32': @@ -889,6 +893,28 @@ def AppendPath(oldpath, newpath, sep = os.pathsep, else: return sep.join(paths) +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 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 + if sys.platform == 'cygwin': def get_native_path(path): """Transforms an absolute path into a native path for the system. In @@ -1156,38 +1182,40 @@ def uniquer_hashables(seq): return result +# Recipe 19.11 "Reading Lines with Continuation Characters", +# by Alex Martelli, straight from the Python CookBook (2nd edition). +def logical_lines(physical_lines, joiner=''.join): + logical_line = [] + for line in physical_lines: + stripped = line.rstrip() + if stripped.endswith('\\'): + # a line which continues w/the next physical line + logical_line.append(stripped[:-1]) + else: + # a line which does not continue, end of logical line + logical_line.append(line) + yield joiner(logical_line) + logical_line = [] + if logical_line: + # end of sequence implies end of last logical line + yield joiner(logical_line) -# Much of the logic here was originally based on recipe 4.9 from the -# Python CookBook, but we had to dumb it way down for Python 1.5.2. -class LogicalLines(object): +class LogicalLines(object): + """ Wrapper class for the logical_lines method. + + Allows us to read all "logical" lines at once from a + given file object. + """ + def __init__(self, fileobj): self.fileobj = fileobj - def readline(self): - result = [] - while True: - line = self.fileobj.readline() - if not line: - break - if line[-2:] == '\\\n': - result.append(line[:-2]) - else: - result.append(line) - break - return ''.join(result) - def readlines(self): - result = [] - while True: - line = self.readline() - if not line: - break - result.append(line) + result = [l for l in logical_lines(self.fileobj)] return result - class UniqueList(UserList): def __init__(self, seq = []): UserList.__init__(self, seq) diff --git a/src/engine/SCons/UtilTests.py b/src/engine/SCons/UtilTests.py index 795bc46..d59d40c 100644 --- a/src/engine/SCons/UtilTests.py +++ b/src/engine/SCons/UtilTests.py @@ -190,16 +190,7 @@ class UtilTestCase(unittest.TestCase): assert expect == actual, (expect, actual) sys.stdout = io.StringIO() - # The following call should work here: - # print_tree(node, get_children, 1, showtags=1) - # For some reason I don't understand, though, *this* - # time that we call print_tree, the visited dictionary - # is still populated with the values from the last call! - # I can't see why this would be, short of a bug in Python, - # and rather than continue banging my head against the - # brick wall for a *test*, we're going to going with - # the cheap, easy workaround: - print_tree(node, get_children, 1, showtags=1, visited={}) + print_tree(node, get_children, 1, showtags=1) actual = sys.stdout.getvalue() assert withtags == actual, (withtags, actual) finally: @@ -487,6 +478,30 @@ class UtilTestCase(unittest.TestCase): p1 = AppendPath(p1,r'C:\dir\num\three',sep = ';') assert(p1 == r'C:\dir\num\one;C:\dir\num\two;C:\dir\num\three') + def test_addPathIfNotExists(self): + """Test the AddPathIfNotExists() function""" + env_dict = { 'FOO' : os.path.normpath('/foo/bar') + os.pathsep + \ + os.path.normpath('/baz/blat'), + 'BAR' : os.path.normpath('/foo/bar') + os.pathsep + \ + os.path.normpath('/baz/blat'), + 'BLAT' : [ os.path.normpath('/foo/bar'), + os.path.normpath('/baz/blat') ] } + AddPathIfNotExists(env_dict, 'FOO', os.path.normpath('/foo/bar')) + AddPathIfNotExists(env_dict, 'BAR', os.path.normpath('/bar/foo')) + AddPathIfNotExists(env_dict, 'BAZ', os.path.normpath('/foo/baz')) + AddPathIfNotExists(env_dict, 'BLAT', os.path.normpath('/baz/blat')) + AddPathIfNotExists(env_dict, 'BLAT', os.path.normpath('/baz/foo')) + + assert env_dict['FOO'] == os.path.normpath('/foo/bar') + os.pathsep + \ + os.path.normpath('/baz/blat'), env_dict['FOO'] + assert env_dict['BAR'] == os.path.normpath('/bar/foo') + os.pathsep + \ + os.path.normpath('/foo/bar') + os.pathsep + \ + os.path.normpath('/baz/blat'), env_dict['BAR'] + assert env_dict['BAZ'] == os.path.normpath('/foo/baz'), env_dict['BAZ'] + assert env_dict['BLAT'] == [ os.path.normpath('/baz/foo'), + os.path.normpath('/foo/bar'), + os.path.normpath('/baz/blat') ], env_dict['BLAT' ] + def test_CLVar(self): """Test the command-line construction variable class""" f = SCons.Util.CLVar('a b') @@ -679,11 +694,8 @@ bling \ bling \ bling bling """ - try: - fobj = io.StringIO(content) - except TypeError: - # Python 2.7 and beyond require unicode strings. - fobj = io.StringIO(unicode(content)) + # Python 2.7 and beyond require unicode strings. + fobj = io.StringIO(unicode(content)) lines = LogicalLines(fobj).readlines() assert lines == [ @@ -780,6 +792,7 @@ class flattenTestCase(unittest.TestCase): result = flatten('xyz') assert result == ['xyz'], result + if __name__ == "__main__": suite = unittest.TestSuite() tclasses = [ dictifyTestCase, diff --git a/src/engine/SCons/Variables/BoolVariable.py b/src/engine/SCons/Variables/BoolVariable.py index 6bc66bb..c005a62 100644 --- a/src/engine/SCons/Variables/BoolVariable.py +++ b/src/engine/SCons/Variables/BoolVariable.py @@ -51,7 +51,7 @@ def _text2bool(val): will be returned. See '__true_strings' and '__false_strings' for values considered - 'true' or 'false respectivly. + 'true' or 'false respectively. This is usable as 'converter' for SCons' Variables. """ @@ -74,7 +74,7 @@ def _validator(key, val, env): def BoolVariable(key, help, default): """ - The input parameters describe a boolen option, thus they are + The input parameters describe a boolean option, thus they are returned with the correct converter and validator appended. The 'help' text will by appended by '(yes|no) to show the valid valued. The result is usable for input to opts.Add(). diff --git a/src/engine/SCons/Variables/EnumVariable.py b/src/engine/SCons/Variables/EnumVariable.py index 582be27..9448ba9 100644 --- a/src/engine/SCons/Variables/EnumVariable.py +++ b/src/engine/SCons/Variables/EnumVariable.py @@ -52,7 +52,7 @@ def _validator(key, val, env, vals): def EnumVariable(key, help, default, allowed_values, map={}, ignorecase=0): """ - The input parameters describe a option with only certain values + The input parameters describe an option with only certain values allowed. They are returned with an appropriate converter and validator appended. The result is usable for input to Variables.Add(). @@ -65,7 +65,7 @@ def EnumVariable(key, help, default, allowed_values, map={}, ignorecase=0): for this option. The 'map'-dictionary may be used for converting the input value - into canonical values (eg. for aliases). + into canonical values (e.g. for aliases). 'ignorecase' defines the behaviour of the validator: diff --git a/src/engine/SCons/Variables/ListVariable.py b/src/engine/SCons/Variables/ListVariable.py index 413aacb..f2fdc18 100644 --- a/src/engine/SCons/Variables/ListVariable.py +++ b/src/engine/SCons/Variables/ListVariable.py @@ -4,7 +4,7 @@ This file defines the option type for SCons implementing 'lists'. A 'list' option may either be 'all', 'none' or a list of names separated by comma. After the option has been processed, the option -value holds either the named list elements, all list elemens or no +value holds either the named list elements, all list elements or no list elements at all. Usage example: @@ -48,7 +48,7 @@ Usage example: __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" -# Know Bug: This should behave like a Set-Type, but does not really, +# Known Bug: This should behave like a Set-Type, but does not really, # since elements can occur twice. __all__ = ['ListVariable',] @@ -106,14 +106,14 @@ def _converter(val, allowedElems, mapdict): ## def _validator(key, val, env): ## """ ## """ -## # todo: write validater for pgk list +## # todo: write validator for pgk list ## return 1 def ListVariable(key, help, default, names, map={}): """ The input parameters describe a 'package list' option, thus they - are returned with the correct converter and validater appended. The + are returned with the correct converter and validator appended. The result is usable for input to opts.Add() . A 'package list' option may either be 'all', 'none' or a list of diff --git a/src/engine/SCons/Variables/PackageVariable.py b/src/engine/SCons/Variables/PackageVariable.py index 440d0f6..4ab0856 100644 --- a/src/engine/SCons/Variables/PackageVariable.py +++ b/src/engine/SCons/Variables/PackageVariable.py @@ -11,7 +11,7 @@ Usage example: Examples: x11=no (disables X11 support) x11=yes (will search for the package installation dir) - x11=/usr/local/X11 (will check this path for existance) + x11=/usr/local/X11 (will check this path for existence) To replace autoconf's --with-xxx=yyy @@ -70,10 +70,10 @@ def _converter(val): def _validator(key, val, env, searchfunc): - # NB: searchfunc is currenty undocumented and unsupported + # NB: searchfunc is currently undocumented and unsupported """ """ - # todo: write validator, check for path + # TODO write validator, check for path import os if env[key] is True: if searchfunc: @@ -84,14 +84,14 @@ def _validator(key, val, env, searchfunc): def PackageVariable(key, help, default, searchfunc=None): - # NB: searchfunc is currenty undocumented and unsupported + # NB: searchfunc is currently undocumented and unsupported """ The input parameters describe a 'package list' option, thus they are returned with the correct converter and validator appended. The result is usable for input to opts.Add() . A 'package list' option may either be 'all', 'none' or a list of - package names (seperated by space). + package names (separated by space). """ help = '\n '.join( (help, '( yes | no | /path/to/%s )' % key)) diff --git a/src/engine/SCons/Variables/PathVariable.py b/src/engine/SCons/Variables/PathVariable.py index 951fc75..e615a53 100644 --- a/src/engine/SCons/Variables/PathVariable.py +++ b/src/engine/SCons/Variables/PathVariable.py @@ -2,7 +2,7 @@ This file defines an option type for SCons implementing path settings. -To be used whenever a a user-specified path override should be allowed. +To be used whenever a user-specified path override should be allowed. Arguments to PathVariable are: option-name = name of this option on the command line (e.g. "prefix") @@ -22,7 +22,7 @@ Arguments to PathVariable are: is valid. The arguments to the validator function are: (key, val, env). The key is the name of the option, the val is the path specified for the option, - and the env is the env to which the Otions have been + and the env is the env to which the Options have been added. Usage example: @@ -102,7 +102,7 @@ class _PathVariableClass(object): os.makedirs(val) def PathIsFile(self, key, val, env): - """validator to check if Path is a file""" + """Validator to check if Path is a file""" if not os.path.isfile(val): if os.path.isdir(val): m = 'File path for option %s is a directory: %s' @@ -111,13 +111,12 @@ class _PathVariableClass(object): raise SCons.Errors.UserError(m % (key, val)) def PathExists(self, key, val, env): - """validator to check if Path exists""" + """Validator to check if Path exists""" if not os.path.exists(val): m = 'Path for option %s does not exist: %s' raise SCons.Errors.UserError(m % (key, val)) def __call__(self, key, help, default, validator=None): - # NB: searchfunc is currenty undocumented and unsupported """ The input parameters describe a 'path list' option, thus they are returned with the correct converter and validator appended. The diff --git a/src/engine/SCons/Variables/__init__.py b/src/engine/SCons/Variables/__init__.py index ede7480..10f9cb2 100644 --- a/src/engine/SCons/Variables/__init__.py +++ b/src/engine/SCons/Variables/__init__.py @@ -50,12 +50,17 @@ class Variables(object): Holds all the options, updates the environment with the variables, and renders the help text. """ - def __init__(self, files=[], args={}, is_global=1): + def __init__(self, files=None, args=None, is_global=1): """ files - [optional] List of option configuration files to load (backward compatibility) If a single string is passed it is automatically placed in a file list """ + # initialize arguments + if files is None: + files = [] + if args is None: + args = {} self.options = [] self.args = args if not SCons.Util.is_List(files): diff --git a/src/engine/SCons/compat/__init__.py b/src/engine/SCons/compat/__init__.py index 3d5c835..5f94df2 100644 --- a/src/engine/SCons/compat/__init__.py +++ b/src/engine/SCons/compat/__init__.py @@ -35,9 +35,6 @@ the builtins namespace or the global module list so that the rest of our code can use the objects and names imported here regardless of Python version. -Simply enough, things that go in the builtins name space come from -our _scons_builtins module. - The rest of the things here will be in individual compatibility modules that are either: 1) suitably modified copies of the future modules that we want to use; or 2) backwards compatible re-implementations of the @@ -85,34 +82,8 @@ def rename_module(new, old): except ImportError: return False - -rename_module('builtins', '__builtin__') -import _scons_builtins - - -try: - import hashlib -except ImportError: - # Pre-2.5 Python has no hashlib module. - try: - import_as('_scons_hashlib', 'hashlib') - except ImportError: - # If we failed importing our compatibility module, it probably - # means this version of Python has no md5 module. Don't do - # anything and let the higher layer discover this fact, so it - # can fall back to using timestamp. - pass - - - -# When we're using the '-3' option during regression tests, importing -# cPickle gives a warning no matter how it's done, so always use the -# real profile module, whether it's fast or not. -if os.environ.get('SCONS_HORRIBLE_REGRESSION_TEST_HACK') is None: - # Not a regression test with '-3', so try to use faster version. - # In 3.x, 'pickle' automatically loads the fast version if available. - rename_module('pickle', 'cPickle') - +# In 3.x, 'pickle' automatically loads the fast version if available. +rename_module('pickle', 'cPickle') # In 3.x, 'profile' automatically loads the fast version if available. rename_module('profile', 'cProfile') @@ -134,9 +105,7 @@ try: except AttributeError: # We must be using python 2.7.x so monkey patch # intern into the sys package - import builtins - sys.intern = builtins.intern - + sys.intern = intern # Preparing for 3.x. UserDict, UserList, UserString are in @@ -163,25 +132,6 @@ except AttributeError: collections.UserString = _UserString del _UserString - - -if os.environ.get('SCONS_HORRIBLE_REGRESSION_TEST_HACK') is not None: - # We can't apply the 'callable' fixer until the floor is 2.6, but the - # '-3' option to Python 2.6 and 2.7 generates almost ten thousand - # warnings. This hack allows us to run regression tests with the '-3' - # option by replacing the callable() built-in function with a hack - # that performs the same function but doesn't generate the warning. - # Note that this hack is ONLY intended to be used for regression - # testing, and should NEVER be used for real runs. - from types import ClassType - def callable(obj): - if hasattr(obj, '__call__'): return True - if isinstance(obj, (ClassType, type)): return True - return False - import builtins - builtins.callable = callable - del callable - # Local Variables: # tab-width:4 diff --git a/src/engine/SCons/compat/_scons_builtins.py b/src/engine/SCons/compat/_scons_builtins.py deleted file mode 100644 index 6218cd1..0000000 --- a/src/engine/SCons/compat/_scons_builtins.py +++ /dev/null @@ -1,107 +0,0 @@ -# -# __COPYRIGHT__ -# -# 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. -# - -# Portions of the following are derived from the compat.py file in -# Twisted, under the following copyright: -# -# Copyright (c) 2001-2004 Twisted Matrix Laboratories - -__doc__ = """ -Compatibility idioms for builtins names - -This module adds names to the builtins module for things that we want -to use in SCons but which don't show up until later Python versions than -the earliest ones we support. - -This module checks for the following builtins names: - - all() - any() - memoryview() - -Implementations of functions are *NOT* guaranteed to be fully compliant -with these functions in later versions of Python. We are only concerned -with adding functionality that we actually use in SCons, so be wary -if you lift this code for other uses. (That said, making these more -nearly the same as later, official versions is still a desirable goal, -we just don't need to be obsessive about it.) - -If you're looking at this with pydoc and various names don't show up in -the FUNCTIONS or DATA output, that means those names are already built in -to this version of Python and we don't need to add them from this module. -""" - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import builtins - -try: - all -except NameError: - # Pre-2.5 Python has no all() function. - def all(iterable): - """ - Returns True if all elements of the iterable are true. - """ - for element in iterable: - if not element: - return False - return True - builtins.all = all - all = all - -try: - any -except NameError: - # Pre-2.5 Python has no any() function. - def any(iterable): - """ - Returns True if any element of the iterable is true. - """ - for element in iterable: - if element: - return True - return False - builtins.any = any - any = any - -try: - memoryview -except NameError: - # Pre-2.7 doesn't have the memoryview() built-in. - class memoryview(object): - def __init__(self, obj): - # wrapping buffer in () keeps the fixer from changing it - self.obj = (buffer)(obj) - def __getitem__(self, indx): - if isinstance(indx, slice): - return self.obj[indx.start:indx.stop] - else: - return self.obj[indx] - builtins.memoryview = memoryview - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/compat/_scons_hashlib.py b/src/engine/SCons/compat/_scons_hashlib.py deleted file mode 100644 index 04d31fa..0000000 --- a/src/engine/SCons/compat/_scons_hashlib.py +++ /dev/null @@ -1,76 +0,0 @@ -# -# __COPYRIGHT__ -# -# 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__ = """ -hashlib backwards-compatibility module for older (pre-2.5) Python versions - -This does not not NOT (repeat, *NOT*) provide complete hashlib -functionality. It only wraps the portions of MD5 functionality used -by SCons, in an interface that looks like hashlib (or enough for our -purposes, anyway). In fact, this module will raise an ImportError if -the underlying md5 module isn't available. -""" - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import md5 -from string import hexdigits - -class md5obj(object): - - md5_module = md5 - - def __init__(self, name, string=''): - if not name in ('MD5', 'md5'): - raise ValueError("unsupported hash type") - self.name = 'md5' - self.m = self.md5_module.md5() - - def __repr__(self): - return '<%s HASH object @ %#x>' % (self.name, id(self)) - - def copy(self): - import copy - result = copy.copy(self) - result.m = self.m.copy() - return result - - def digest(self): - return self.m.digest() - - def update(self, arg): - return self.m.update(arg) - - def hexdigest(self): - return self.m.hexdigest() - -new = md5obj - -def md5(string=''): - return md5obj('md5', string) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/cppTests.py b/src/engine/SCons/cppTests.py index 37b4aae..9f4b875 100644 --- a/src/engine/SCons/cppTests.py +++ b/src/engine/SCons/cppTests.py @@ -668,15 +668,12 @@ class fileTestCase(unittest.TestCase): _Cleanup.remove(self.tempdir) def strip_initial_spaces(self, s): - #lines = s.split('\n') lines = s.split('\n') spaces = re.match(' *', lines[0]).group(0) def strip_spaces(l, spaces=spaces): - #if l.startswith(spaces): if l[:len(spaces)] == spaces: l = l[len(spaces):] return l - #return '\n'.join([ strip_spaces(l) for l in lines ]) return '\n'.join(map(strip_spaces, lines)) def write(self, file, contents): diff --git a/src/engine/SCons/dblite.py b/src/engine/SCons/dblite.py index f4ba90a..707a4f8 100644 --- a/src/engine/SCons/dblite.py +++ b/src/engine/SCons/dblite.py @@ -3,7 +3,6 @@ import SCons.compat -import builtins import os # compat layer imports "cPickle" for us if it's available. import pickle @@ -44,7 +43,7 @@ class dblite(object): # See the discussion at: # http://mail.python.org/pipermail/python-bugs-list/2003-March/016877.html - _open = builtins.open + _open = open _pickle_dump = staticmethod(pickle.dump) _os_chmod = os.chmod try: @@ -99,7 +98,10 @@ class dblite(object): if (len(p) > 0): try: self._dict = pickle.loads(p) - except (pickle.UnpicklingError, EOFError): + except (pickle.UnpicklingError, EOFError, KeyError): + # Note how we catch KeyErrors too here, which might happen + # when we don't have cPickle available (default pickle + # throws it). if (ignore_corrupt_dbfiles == 0): raise if (ignore_corrupt_dbfiles == 1): corruption_warning(self._file_name) diff --git a/src/script/scons-time.py b/src/script/scons-time.py index 3b215f9..02168d8 100644 --- a/src/script/scons-time.py +++ b/src/script/scons-time.py @@ -43,53 +43,10 @@ import sys import tempfile import time -try: - sorted -except NameError: - # Pre-2.4 Python has no sorted() function. - # - # The pre-2.4 Python list.sort() method does not support - # list.sort(key=) nor list.sort(reverse=) keyword arguments, so - # we must implement the functionality of those keyword arguments - # by hand instead of passing them to list.sort(). - def sorted(iterable, cmp=None, key=None, reverse=False): - if key is not None: - result = [(key(x), x) for x in iterable] - else: - result = iterable[:] - if cmp is None: - # Pre-2.3 Python does not support list.sort(None). - result.sort() - else: - result.sort(cmp) - if key is not None: - result = [t1 for t0,t1 in result] - if reverse: - result.reverse() - return result - -if os.environ.get('SCONS_HORRIBLE_REGRESSION_TEST_HACK') is not None: - # We can't apply the 'callable' fixer until the floor is 2.6, but the - # '-3' option to Python 2.6 and 2.7 generates almost ten thousand - # warnings. This hack allows us to run regression tests with the '-3' - # option by replacing the callable() built-in function with a hack - # that performs the same function but doesn't generate the warning. - # Note that this hack is ONLY intended to be used for regression - # testing, and should NEVER be used for real runs. - from types import ClassType - def callable(obj): - if hasattr(obj, '__call__'): return True - if isinstance(obj, (ClassType, type)): return True - return False - def make_temp_file(**kw): try: result = tempfile.mktemp(**kw) - try: - result = os.path.realpath(result) - except AttributeError: - # Python 2.1 has no os.path.realpath() method. - pass + result = os.path.realpath(result) except TypeError: try: save_template = tempfile.template diff --git a/src/script/sconsign.py b/src/script/sconsign.py index ef32a93..c95bf74 100644 --- a/src/script/sconsign.py +++ b/src/script/sconsign.py @@ -54,6 +54,14 @@ import sys # followed by generic) so we pick up the right version of the build # engine modules if they're in either directory. + +if sys.version_info >= (3,0,0): + msg = "sconsign: *** Version %s does not run under Python version %s.\n\ +Python 3 is not yet supported.\n" + sys.stderr.write(msg % (__version__, sys.version.split()[0])) + sys.exit(1) + + script_dir = sys.path[0] if script_dir in sys.path: @@ -64,6 +72,11 @@ libs = [] if "SCONS_LIB_DIR" in os.environ: libs.append(os.environ["SCONS_LIB_DIR"]) +# - running from source takes priority (since 2.3.2), excluding SCONS_LIB_DIR settings +script_path = os.path.abspath(os.path.dirname(__file__)) +source_path = os.path.join(script_path, '..', 'engine') +libs.append(source_path) + local_version = 'scons-local-' + __version__ local = 'scons-local' if script_dir: @@ -463,12 +476,22 @@ for o, a in opts: elif o in ('-e', '--entry'): Print_Entries.append(a) elif o in ('-f', '--format'): + # Try to map the given DB format to a known module + # name, that we can then try to import... Module_Map = {'dblite' : 'SCons.dblite', 'sconsign' : None} dbm_name = Module_Map.get(a, a) if dbm_name: try: - dbm = my_import(dbm_name) + if dbm_name != "SCons.dblite": + dbm = my_import(dbm_name) + else: + import SCons.dblite + dbm = SCons.dblite + # Ensure that we don't ignore corrupt DB files, + # this was handled by calling my_import('SCons.dblite') + # again in earlier versions... + SCons.dblite.ignore_corrupt_dbfiles = 0 except: sys.stderr.write("sconsign: illegal file format `%s'\n" % a) print helpstr @@ -500,7 +523,15 @@ else: dbm_name = whichdb.whichdb(a) if dbm_name: Map_Module = {'SCons.dblite' : 'dblite'} - dbm = my_import(dbm_name) + if dbm_name != "SCons.dblite": + dbm = my_import(dbm_name) + else: + import SCons.dblite + dbm = SCons.dblite + # Ensure that we don't ignore corrupt DB files, + # this was handled by calling my_import('SCons.dblite') + # again in earlier versions... + SCons.dblite.ignore_corrupt_dbfiles = 0 Do_SConsignDB(Map_Module.get(dbm_name, dbm_name), dbm)(a) else: Do_SConsignDir(a) diff --git a/test/TEX/bibliography.py b/test/TEX/bibliography.py index 5e26f6e..c26b010 100644 --- a/test/TEX/bibliography.py +++ b/test/TEX/bibliography.py @@ -118,9 +118,6 @@ test.must_not_exist(test.workpath('simple.blg')) test.pass_test() - -# FUTURE: - test.write('SConstruct', """\ env = Environment(tools = ['tex', 'latex', 'dvips']) env.PostScript('d00', 'd00.tex') diff --git a/test/compat/all.py b/test/compat/all.py deleted file mode 100644 index ac7a6ea..0000000 --- a/test/compat/all.py +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env python -# -# __COPYRIGHT__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -""" -Verify that we can use the any() function (in any supported Python -version we happen to be testing). - -This test can be retired at some point in the distant future when Python -2.5 becomes the minimum version supported by SCons. -""" - -import TestSCons - -test = TestSCons.TestSCons() - -test.write('SConstruct', """\ -print all([True, 1]) and "YES" or "NO" -print all([0]) and "YES" or "NO" -SConscript('SConscript') -""") - -test.write('SConscript', """\ -print all([1, False]) and "YES" or "NO" -print all([True, None]) and "YES" or "NO" -""") - -expect = """\ -YES -NO -NO -NO -""" - -test.run(arguments = '-Q -q', stdout = expect) - -test.pass_test() - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/compat/any.py b/test/compat/any.py deleted file mode 100644 index 3c03807..0000000 --- a/test/compat/any.py +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/env python -# -# __COPYRIGHT__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -""" -Verify that we can use the any() function (in any supported Python -version we happen to be testing). - -This test can be retired at some point in the distant future when Python -2.5 becomes the minimum version supported by SCons. -""" - -import TestSCons - -test = TestSCons.TestSCons() - -test.write('SConstruct', """\ -print any([True, False]) and "YES" or "NO" -print any([1]) and "YES" or "NO" -SConscript('SConscript') -""") - -test.write('SConscript', """\ -print any([0, False]) and "YES" or "NO" -""") - -expect = """\ -YES -YES -NO -""" - -test.run(arguments = '-Q -q', stdout = expect) - -test.pass_test() - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/option/profile.py b/test/option/profile.py index d53c690..4d6caae 100644 --- a/test/option/profile.py +++ b/test/option/profile.py @@ -24,19 +24,14 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import sys -try: - import io - _StringIO = io.StringIO -except (ImportError, AttributeError): - # Pre-2.6 Python has no "io" module. - exec('from cStringIO import StringIO') -else: - # TODO(2.6): In 2.6 and beyond, the io.StringIO.write() method - # requires unicode strings. This subclass can probably be removed - # when we drop support for Python 2.6. - class StringIO(_StringIO): - def write(self, s): - _StringIO.write(self, unicode(s)) +import io +_StringIO = io.StringIO +# TODO(2.6): In 2.6 and beyond, the io.StringIO.write() method +# requires unicode strings. This subclass can probably be removed +# when we drop support for Python 2.6. +class StringIO(_StringIO): + def write(self, s): + _StringIO.write(self, unicode(s)) import TestSCons diff --git a/test/sconsign/script/bad.py b/test/sconsign/script/bad.py index fc21577..a384748 100644 --- a/test/sconsign/script/bad.py +++ b/test/sconsign/script/bad.py @@ -47,16 +47,16 @@ test.run_sconsign(arguments = "-f dblite bad1.dblite", stderr = "sconsign: \[Errno 2\] No such file or directory: 'bad1.dblite'\n") test.run_sconsign(arguments = "-f dblite bad2", - stderr = "sconsign: ignoring invalid `dblite' file `bad2'\n") + stderr = "sconsign: ignoring invalid `dblite' file `bad2'.*\n") test.run_sconsign(arguments = "-f dblite bad2.dblite", - stderr = "sconsign: ignoring invalid `dblite' file `bad2.dblite'\n") + stderr = "sconsign: ignoring invalid `dblite' file `bad2.dblite'.*\n") test.run_sconsign(arguments = "-f sconsign no_sconsign", stderr = "sconsign: \[Errno 2\] No such file or directory: 'no_sconsign'\n") test.run_sconsign(arguments = "-f sconsign bad3", - stderr = "sconsign: ignoring invalid .sconsign file `bad3'\n") + stderr = "sconsign: ignoring invalid .sconsign file `bad3'.*\n") test.pass_test() diff --git a/test/update-release-info/update-release-info.py b/test/update-release-info/update-release-info.py index e44aa99..970bcce 100644 --- a/test/update-release-info/update-release-info.py +++ b/test/update-release-info/update-release-info.py @@ -60,10 +60,10 @@ combo_strings = [ """version_tuple = (2, 0, 0, 'bad', 0) """, # Index 1: Python version tuple -"""unsupported_python_version = (2, 3) +"""unsupported_python_version = (2, 6) """, # Index 2: Python version tuple -"""deprecated_python_version = (2, 4) +"""deprecated_python_version = (2, 7) """, # Index 3: alpha version tuple """version_tuple = (2, 0, 0, 'alpha', 0) @@ -223,14 +223,14 @@ These files are a part of 33.22.11: test.must_match(TestSCons, """ copyright_years = '%s' default_version = '2.0.0.alpha.yyyymmdd' -python_version_unsupported = (2, 3) -python_version_deprecated = (2, 4) +python_version_unsupported = (2, 6) +python_version_deprecated = (2, 7) """%years, mode = 'r') # should get Python floors from TestSCons module. test.must_match(Main, """ -unsupported_python_version = (2, 3) -deprecated_python_version = (2, 4) +unsupported_python_version = (2, 6) +deprecated_python_version = (2, 7) """, mode = 'r') #TODO: Release option -- cgit v0.12 From 42ac4c63bd25680c49ff9a7fa6f1e1139d589ced Mon Sep 17 00:00:00 2001 From: Dirk Baechle Date: Mon, 14 Dec 2015 22:44:58 +0100 Subject: - fixed render_tree default argument for "visited" as well - added tests for the new "visited" default arguments of the render_tree and print_tree methods - added simple test for the new "None" default arguments in Variables constructor --- src/CHANGES.txt | 9 ++++- src/engine/SCons/Node/__init__.py | 2 +- src/engine/SCons/Util.py | 6 +++- src/engine/SCons/UtilTests.py | 52 ++++++++++++++++++++++++---- src/engine/SCons/Variables/VariablesTests.py | 16 +++++++++ 5 files changed, 75 insertions(+), 10 deletions(-) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 9e9ec42..9e335f9 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -11,7 +11,14 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER SCons now respects scanner keys for implicit dependencies. - Resolved missing cross-language dependencies for SWIG bindings (fixes #2264). - + + From Dirk Baechle: + - Removed a lot of compatibility methods and workarounds + for Python versions < 2.7, in order to prepare the work + towards a combined 2.7/3.x version. (PR #284) + Also fixed the default arguments for the print_tree and + render_tree methods. (PR #284, too) + RELEASE 2.4.1 - Mon, 07 Nov 2015 10:37:21 -0700 diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py index 40ee8f0..86a5c1d 100644 --- a/src/engine/SCons/Node/__init__.py +++ b/src/engine/SCons/Node/__init__.py @@ -577,7 +577,7 @@ class Node(object): self.always_build = None self.includes = None self.attributes = self.Attrs() # Generic place to stick information about the Node. - self.side_effect = 0 # true if this node is a side effect + self.side_effect = 0 # true iff this node is a side effect self.side_effects = [] # the side effects of building this target self.linked = 0 # is this node linked to the variant directory? self.changed_since_last_build = 0 diff --git a/src/engine/SCons/Util.py b/src/engine/SCons/Util.py index a834726..cd23e6e 100644 --- a/src/engine/SCons/Util.py +++ b/src/engine/SCons/Util.py @@ -167,7 +167,7 @@ class DisplayEngine(object): def set_mode(self, mode): self.print_it = mode -def render_tree(root, child_func, prune=0, margin=[0], visited={}): +def render_tree(root, child_func, prune=0, margin=[0], visited=None): """ Render a tree of nodes into an ASCII tree view. root - the root node of the tree @@ -181,6 +181,10 @@ def render_tree(root, child_func, prune=0, margin=[0], visited={}): rname = str(root) + # Initialize 'visited' dict, if required + if visited is None: + visited = {} + children = child_func(root) retval = "" for pipe in margin[:-1]: diff --git a/src/engine/SCons/UtilTests.py b/src/engine/SCons/UtilTests.py index d59d40c..9f80e86 100644 --- a/src/engine/SCons/UtilTests.py +++ b/src/engine/SCons/UtilTests.py @@ -124,7 +124,9 @@ class UtilTestCase(unittest.TestCase): def tree_case_2(self, prune=1): """Fixture for the render_tree() and print_tree() tests.""" - stdlib_h = self.Node("stdlib.h") + types_h = self.Node('types.h') + malloc_h = self.Node('malloc.h') + stdlib_h = self.Node('stdlib.h', [types_h, malloc_h]) bar_h = self.Node('bar.h', [stdlib_h]) blat_h = self.Node('blat.h', [stdlib_h]) blat_c = self.Node('blat.c', [blat_h, bar_h]) @@ -135,13 +137,18 @@ class UtilTestCase(unittest.TestCase): +-blat.c +-blat.h | +-stdlib.h + | +-types.h + | +-malloc.h +-bar.h - +-[stdlib.h] """ - - if not prune: - expect = expect.replace('[', '') - expect = expect.replace(']', '') + if prune: + expect += """ +-[stdlib.h] +""" + else: + expect += """ +-stdlib.h + +-types.h + +-malloc.h +""" lines = expect.split('\n')[:-1] lines = ['[E BSPACN ]'+l for l in lines] @@ -162,6 +169,13 @@ class UtilTestCase(unittest.TestCase): actual = render_tree(node, get_children, 1) assert expect == actual, (expect, actual) + # Ensure that we can call render_tree on the same Node + # again. This wasn't possible in version 2.4.1 and earlier + # due to a bug in render_tree (visited was set to {} as default + # parameter) + actual = render_tree(node, get_children, 1) + assert expect == actual, (expect, actual) + def test_print_tree(self): """Test the print_tree() function""" def get_children(node): @@ -181,9 +195,33 @@ class UtilTestCase(unittest.TestCase): print_tree(node, get_children, showtags=1) actual = sys.stdout.getvalue() assert withtags == actual, (withtags, actual) - + + # Test that explicitly setting prune to zero works + # the same as the default (see above) node, expect, withtags = self.tree_case_2(prune=0) + + sys.stdout = io.StringIO() + print_tree(node, get_children, 0) + actual = sys.stdout.getvalue() + assert expect == actual, (expect, actual) + + sys.stdout = io.StringIO() + print_tree(node, get_children, 0, showtags=1) + actual = sys.stdout.getvalue() + assert withtags == actual, (withtags, actual) + + # Test output with prune=1 + node, expect, withtags = self.tree_case_2(prune=1) + + sys.stdout = io.StringIO() + print_tree(node, get_children, 1) + actual = sys.stdout.getvalue() + assert expect == actual, (expect, actual) + # Ensure that we can call print_tree on the same Node + # again. This wasn't possible in version 2.4.1 and earlier + # due to a bug in print_tree (visited was set to {} as default + # parameter) sys.stdout = io.StringIO() print_tree(node, get_children, 1) actual = sys.stdout.getvalue() diff --git a/src/engine/SCons/Variables/VariablesTests.py b/src/engine/SCons/Variables/VariablesTests.py index d2110c1..50f7d13 100644 --- a/src/engine/SCons/Variables/VariablesTests.py +++ b/src/engine/SCons/Variables/VariablesTests.py @@ -273,6 +273,22 @@ class VariablesTestCase(unittest.TestCase): opts.Update(env, {}) assert 'ANSWER' not in env + def test_noaggregation(self): + """Test that the 'files' and 'args' attributes of the Variables class + don't aggregate entries from one instance to another. + This used to be a bug in SCons version 2.4.1 and earlier. + """ + + opts = SCons.Variables.Variables() + opts.files.append('custom.py') + opts.args['ANSWER'] = 54 + nopts = SCons.Variables.Variables() + + # Ensure that both attributes are initialized to + # an empty list and dict, respectively. + assert len(nopts.files) == 0 + assert len(nopts.args) == 0 + def test_args(self): """Test updating an Environment with arguments overridden""" -- cgit v0.12 From 8a198d3aa488dc02e77a87354a14fd6c5764184b Mon Sep 17 00:00:00 2001 From: Dirk Baechle Date: Wed, 16 Dec 2015 09:16:58 +0100 Subject: - fixed initialization of Util.WinError for Windows --- src/engine/SCons/Util.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/engine/SCons/Util.py b/src/engine/SCons/Util.py index cd23e6e..7bcd6e2 100644 --- a/src/engine/SCons/Util.py +++ b/src/engine/SCons/Util.py @@ -586,6 +586,10 @@ WinError = None # OSError subclass on Windows.) class PlainWindowsError(OSError): pass +try: + WinError = WindowsError +except NameError: + WinError = PlainWindowsError if can_read_reg: @@ -621,11 +625,6 @@ if can_read_reg: k = RegOpenKeyEx(root, keyp) return RegQueryValueEx(k,val) else: - try: - WinError = WindowsError - except NameError: - WinError = PlainWindowsError - HKEY_CLASSES_ROOT = None HKEY_LOCAL_MACHINE = None HKEY_CURRENT_USER = None -- cgit v0.12 From 8617739fb8bfb9fee2252a02d47c5de220921ae4 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Wed, 16 Dec 2015 17:43:40 -0500 Subject: don't run test for no threading via fake threading.py which throws ImportError on win32. on Win32 other modules import threading and so test fails. This was previously hidden by compat subprocess module which has been removed as obsolete since the base python is being moved to 2.7 --- test/option-j.py | 51 ++++++++++++++++++++++++++------------------------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/test/option-j.py b/test/option-j.py index 3eb7bd3..69ef414 100644 --- a/test/option-j.py +++ b/test/option-j.py @@ -30,9 +30,11 @@ SConscript settable option. __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import os.path +import sys import TestSCons + _python_ = TestSCons._python_ try: @@ -120,42 +122,41 @@ test.fail_test(start2 < finish1) # succeeds. test.run(arguments='-j 2 out') +if sys.platform != 'win32': + # Test breaks on win32 when using real subprocess is not the only + # package to import threading + # + # Test that we fall back and warn properly if there's no threading.py + # module (simulated), which is the case if this version of Python wasn't + # built with threading support. -# Test that we fall back and warn properly if there's no threading.py -# module (simulated), which is the case if this version of Python wasn't -# built with threading support. + test.subdir('pythonlib') -test.subdir('pythonlib') + test.write(['pythonlib', 'threading.py'], "raise ImportError\n") -test.write(['pythonlib', 'threading.py'], """\ -raise ImportError -""") + save_pythonpath = os.environ.get('PYTHONPATH', '') + os.environ['PYTHONPATH'] = test.workpath('pythonlib') -save_pythonpath = os.environ.get('PYTHONPATH', '') -os.environ['PYTHONPATH'] = test.workpath('pythonlib') + #start2, finish1 = RunTest('-j 2 f1, f2', "fifth") -#start2, finish1 = RunTest('-j 2 f1, f2', "fifth") + test.write('f1.in', 'f1.in pythonlib\n') + test.write('f2.in', 'f2.in pythonlib\n') -test.write('f1.in', 'f1.in pythonlib\n') -test.write('f2.in', 'f2.in pythonlib\n') + test.run(arguments = "-j 2 f1 f2", stderr=None) -test.run(arguments = "-j 2 f1 f2", stderr=None) - -warn = \ -"""scons: warning: parallel builds are unsupported by this version of Python; -\tignoring -j or num_jobs option. -""" -test.must_contain_all_lines(test.stderr(), [warn]) + warn = """scons: warning: parallel builds are unsupported by this version of Python; +\tignoring -j or num_jobs option.""" + test.must_contain_all_lines(test.stderr(), [warn]) -str = test.read("f1") -start1,finish1 = list(map(float, str.split("\n"))) + str = test.read("f1") + start1,finish1 = list(map(float, str.split("\n"))) -str = test.read("f2") -start2,finish2 = list(map(float, str.split("\n"))) + str = test.read("f2") + start2,finish2 = list(map(float, str.split("\n"))) -test.fail_test(start2 < finish1) + test.fail_test(start2 < finish1) -os.environ['PYTHONPATH'] = save_pythonpath + os.environ['PYTHONPATH'] = save_pythonpath # Test SetJobs() with no -j: -- cgit v0.12 From 98b9ca9a3abd8c5c5fae9ff92331b63ba4cedd87 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Thu, 17 Dec 2015 09:31:03 -0500 Subject: fix swig test failing on windows due to \r\n line endings --- src/engine/SCons/Tool/swig.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/engine/SCons/Tool/swig.py b/src/engine/SCons/Tool/swig.py index 309585d..ce54e62 100644 --- a/src/engine/SCons/Tool/swig.py +++ b/src/engine/SCons/Tool/swig.py @@ -139,9 +139,13 @@ def _get_swig_version(env, swig): if pipe.wait() != 0: return out = pipe.stdout.read() - match = re.search(r'SWIG Version\s+(\S+)$', out, re.MULTILINE) + match = re.search(r'SWIG Version\s+(\S+).*', out, re.MULTILINE) if match: + # print "Version is:%s"%match.group(1) return match.group(1) + else: + # print "Unable to detect version: [%s]"%out + pass def generate(env): """Add Builders and construction variables for swig to an Environment.""" -- cgit v0.12 From 9d558dd65deacc958edc1f0da2dab1ec56ff4e4e Mon Sep 17 00:00:00 2001 From: William Deegan Date: Thu, 17 Dec 2015 11:02:58 -0500 Subject: added verbose flag to Swig to enable debug output when necessary --- src/engine/SCons/Tool/swig.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/engine/SCons/Tool/swig.py b/src/engine/SCons/Tool/swig.py index ce54e62..3a5a3cc 100644 --- a/src/engine/SCons/Tool/swig.py +++ b/src/engine/SCons/Tool/swig.py @@ -43,6 +43,8 @@ import SCons.Tool import SCons.Util import SCons.Node +verbose = False + swigs = [ 'swig', 'swig3.0', 'swig2.0' ] SwigAction = SCons.Action.Action('$SWIGCOM', '$SWIGCOMSTR') @@ -141,11 +143,10 @@ def _get_swig_version(env, swig): out = pipe.stdout.read() match = re.search(r'SWIG Version\s+(\S+).*', out, re.MULTILINE) if match: - # print "Version is:%s"%match.group(1) + if verbose: print "Version is:%s"%match.group(1) return match.group(1) else: - # print "Unable to detect version: [%s]"%out - pass + if verbose: print "Unable to detect version: [%s]"%out def generate(env): """Add Builders and construction variables for swig to an Environment.""" -- cgit v0.12