diff options
author | Gary Oberbrunner <garyo@oberbrunner.com> | 2014-05-18 19:51:34 -0400 |
---|---|---|
committer | Gary Oberbrunner <garyo@oberbrunner.com> | 2014-05-18 19:51:34 -0400 |
commit | 278c0cfb02eeade2032b819148474a63f8633eb9 (patch) | |
tree | bb47ccb7b4705f82724646b5952c439bdd9f5650 | |
parent | b224e56784d3f5f95a1fca78c4ba7b3a876bee98 (diff) | |
parent | 70122d8609b95fc8b88c6ceba507db2fa9e425fb (diff) | |
download | scons-278c0cfb02eeade2032b819148474a63f8633eb9.tar.gz |
Merged in haubi/scons/aix-xlc_r-is-for-threads (pull request #140)
The _r in AIX xlc_r means reentrant, not relocatable.
-rw-r--r-- | src/CHANGES.txt | 9 | ||||
-rw-r--r-- | src/engine/SCons/Environment.py | 4 | ||||
-rw-r--r-- | src/engine/SCons/Tool/ToolTests.py | 2 | ||||
-rw-r--r-- | src/engine/SCons/Tool/__init__.py | 6 | ||||
-rw-r--r-- | src/engine/SCons/Tool/aixlink.py | 15 | ||||
-rw-r--r-- | src/engine/SCons/Tool/c++.py | 5 | ||||
-rw-r--r-- | src/engine/SCons/Tool/cc.py | 7 | ||||
-rw-r--r-- | src/engine/SCons/Tool/g++.py | 30 | ||||
-rw-r--r-- | src/engine/SCons/Tool/gcc.py | 58 | ||||
-rw-r--r-- | src/engine/SCons/Tool/gnulink.py | 11 | ||||
-rw-r--r-- | test/CC/CC.py | 7 | ||||
-rw-r--r-- | test/CC/CCVERSION.py | 82 | ||||
-rw-r--r-- | test/CXX/CXX.py | 3 | ||||
-rw-r--r-- | test/CXX/CXXVERSION.py | 81 |
14 files changed, 259 insertions, 61 deletions
diff --git a/src/CHANGES.txt b/src/CHANGES.txt index d11fd70b..20c98722 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -6,6 +6,10 @@ RELEASE 2.3.2.alpha.yyyymmdd - NEW DATE WILL BE INSERTED HERE + From Michael Haubenwallner: + - Respect user's CC/CXX values; don't always overwrite in generate() + - Delegate linker Tool.exists() to CC/CXX Tool.exists(). + From Amir Szekely: - Fixed NoClean() for multi-target builders (#2353). @@ -35,6 +39,11 @@ RELEASE 2.3.2.alpha.yyyymmdd - NEW DATE WILL BE INSERTED HERE that were failing because of this extra line in the output * error message when SCons import fails now lists lookup paths - Remove support for QMTest harness from runtest.py + - Remove RPM and m4 from default tools on Windows + - BitKeeper, CVS, Perforce, RCS, SCCS are deprecated from default + tools and will be removed in future SCons versions to speed up + SCons initialization (it will still be possible to use these tools + explicitly) From Dirk Baechle: - Update XML doc editor configuration diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py index 3e499b6c..45c40c39 100644 --- a/src/engine/SCons/Environment.py +++ b/src/engine/SCons/Environment.py @@ -1803,8 +1803,8 @@ class Base(SubstitutionEnvironment): pass elif SCons.Util.is_String(pathext): pathext = self.subst(pathext) - prog = self.subst(prog) - path = SCons.Util.WhereIs(prog, path, pathext, reject) + prog = SCons.Util.CLVar(self.subst(prog)) # support "program --with-args" + path = SCons.Util.WhereIs(prog[0], path, pathext, reject) if path: return path return None diff --git a/src/engine/SCons/Tool/ToolTests.py b/src/engine/SCons/Tool/ToolTests.py index 3e6da5b6..a4353b17 100644 --- a/src/engine/SCons/Tool/ToolTests.py +++ b/src/engine/SCons/Tool/ToolTests.py @@ -51,6 +51,8 @@ class ToolTestCase(unittest.TestCase): return self.dict.__contains__(key) def has_key(self, key): return key in self.dict + def subst(self, string, *args, **kwargs): + return string env = Environment() env['BUILDERS'] = {} env['ENV'] = {} diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py index 31e3d96d..55eb1d31 100644 --- a/src/engine/SCons/Tool/__init__.py +++ b/src/engine/SCons/Tool/__init__.py @@ -772,6 +772,9 @@ def tool_list(platform, env): fortran_compilers = ['gfortran', 'g77', 'ifort', 'ifl', 'f95', 'f90', 'f77'] ars = ['ar', 'mslib'] + if not str(platform) == 'win32': + other_plat_tools += ['m4', 'rpm'] + c_compiler = FindTool(c_compilers, env) or c_compilers[0] # XXX this logic about what tool provides what should somehow be @@ -802,7 +805,6 @@ def tool_list(platform, env): #TODO: merge 'install' into 'filesystem' and # make 'filesystem' the default 'filesystem', - 'm4', 'wix', #'midl', 'msvs', # Parser generators 'lex', 'yacc', @@ -814,7 +816,7 @@ def tool_list(platform, env): 'dvipdf', 'dvips', 'gs', 'tex', 'latex', 'pdflatex', 'pdftex', # Archivers - 'tar', 'zip', 'rpm', + 'tar', 'zip', # SourceCode factories 'BitKeeper', 'CVS', 'Perforce', 'RCS', 'SCCS', # 'Subversion', diff --git a/src/engine/SCons/Tool/aixlink.py b/src/engine/SCons/Tool/aixlink.py index 35125220..4e9db21b 100644 --- a/src/engine/SCons/Tool/aixlink.py +++ b/src/engine/SCons/Tool/aixlink.py @@ -37,7 +37,6 @@ import os.path import SCons.Util -import aixcc import link cplusplus = __import__('c++', globals(), locals(), []) @@ -62,12 +61,14 @@ def generate(env): env['SHLIBSUFFIX'] = '.a' def exists(env): - path, _cc, _shcc, version = aixcc.get_xlc(env) - if path and _cc: - xlc = os.path.join(path, _cc) - if os.path.exists(xlc): - return xlc - return None + # TODO: sync with link.smart_link() to choose a linker + linkers = { 'CXX': ['aixc++'], 'CC': ['aixcc'] } + alltools = [] + for langvar, linktools in linkers.items(): + if langvar in env: # use CC over CXX when user specified CC but not CXX + return SCons.Tool.FindTool(linktools, env) + alltools.extend(linktools) + return SCons.Tool.FindTool(alltools, env) # Local Variables: # tab-width:4 diff --git a/src/engine/SCons/Tool/c++.py b/src/engine/SCons/Tool/c++.py index 82a19c5e..430851c8 100644 --- a/src/engine/SCons/Tool/c++.py +++ b/src/engine/SCons/Tool/c++.py @@ -72,7 +72,8 @@ def generate(env): SCons.Tool.cc.add_common_cc_variables(env) - env['CXX'] = 'c++' + if 'CXX' not in env: + env['CXX'] = env.Detect(compilers) or compilers[0] env['CXXFLAGS'] = SCons.Util.CLVar('') env['CXXCOM'] = '$CXX -o $TARGET -c $CXXFLAGS $CCFLAGS $_CCCOMCOM $SOURCES' env['SHCXX'] = '$CXX' @@ -90,7 +91,7 @@ def generate(env): env['CXXFILESUFFIX'] = '.cc' def exists(env): - return env.Detect(compilers) + return env.Detect(env.get('CXX', compilers)) # Local Variables: # tab-width:4 diff --git a/src/engine/SCons/Tool/cc.py b/src/engine/SCons/Tool/cc.py index 9b404b2b..590ec5fd 100644 --- a/src/engine/SCons/Tool/cc.py +++ b/src/engine/SCons/Tool/cc.py @@ -62,6 +62,8 @@ def add_common_cc_variables(env): if 'SHCCFLAGS' not in env: env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS') +compilers = ['cc'] + def generate(env): """ Add Builders and construction variables for C compilers to an Environment. @@ -76,7 +78,8 @@ def generate(env): add_common_cc_variables(env) - env['CC'] = 'cc' + if 'CC' not in env: + env['CC'] = env.Detect(compilers) or compilers[0] env['CFLAGS'] = SCons.Util.CLVar('') env['CCCOM'] = '$CC -o $TARGET -c $CFLAGS $CCFLAGS $_CCCOMCOM $SOURCES' env['SHCC'] = '$CC' @@ -93,7 +96,7 @@ def generate(env): env['CFILESUFFIX'] = '.c' def exists(env): - return env.Detect('cc') + return env.Detect(env.get('CC', compilers)) # Local Variables: # tab-width:4 diff --git a/src/engine/SCons/Tool/g++.py b/src/engine/SCons/Tool/g++.py index e4da5fe2..5cf3827b 100644 --- a/src/engine/SCons/Tool/g++.py +++ b/src/engine/SCons/Tool/g++.py @@ -40,6 +40,8 @@ import subprocess import SCons.Tool import SCons.Util +import gcc + cplusplus = __import__('c++', globals(), locals(), []) compilers = ['g++'] @@ -48,9 +50,10 @@ def generate(env): """Add Builders and construction variables for g++ to an Environment.""" static_obj, shared_obj = SCons.Tool.createObjBuilders(env) - cplusplus.generate(env) + if 'CXX' not in env: + env['CXX'] = env.Detect(compilers) or compilers[0] - env['CXX'] = env.Detect(compilers) + cplusplus.generate(env) # platform specific settings if env['PLATFORM'] == 'aix': @@ -62,26 +65,13 @@ def generate(env): elif env['PLATFORM'] == 'sunos': env['SHOBJSUFFIX'] = '.pic.o' # determine compiler version - if env['CXX']: - #pipe = SCons.Action._subproc(env, [env['CXX'], '-dumpversion'], - pipe = SCons.Action._subproc(env, [env['CXX'], '--version'], - stdin = 'devnull', - stderr = 'devnull', - stdout = subprocess.PIPE) - if pipe.wait() != 0: return - # -dumpversion was added in GCC 3.0. As long as we're supporting - # GCC versions older than that, we should use --version and a - # regular expression. - #line = pipe.stdout.read().strip() - #if line: - # env['CXXVERSION'] = line - line = pipe.stdout.readline() - match = re.search(r'[0-9]+(\.[0-9]+)+', line) - if match: - env['CXXVERSION'] = match.group(0) + version = gcc.detect_version(env, env['CXX']) + if version: + env['CXXVERSION'] = version def exists(env): - return env.Detect(compilers) + # is executable, and is a GNU compiler (or accepts '--version' at least) + return gcc.detect_version(env, env.Detect(env.get('CXX', compilers))) # Local Variables: # tab-width:4 diff --git a/src/engine/SCons/Tool/gcc.py b/src/engine/SCons/Tool/gcc.py index 71f60a3e..df656470 100644 --- a/src/engine/SCons/Tool/gcc.py +++ b/src/engine/SCons/Tool/gcc.py @@ -44,34 +44,54 @@ compilers = ['gcc', 'cc'] def generate(env): """Add Builders and construction variables for gcc to an Environment.""" + + if 'CC' not in env: + env['CC'] = env.Detect(compilers) or compilers[0] + cc.generate(env) - env['CC'] = env.Detect(compilers) or 'gcc' if env['PLATFORM'] in ['cygwin', 'win32']: env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS') else: env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS -fPIC') # determine compiler version - if env['CC']: - #pipe = SCons.Action._subproc(env, [env['CC'], '-dumpversion'], - pipe = SCons.Action._subproc(env, [env['CC'], '--version'], - stdin = 'devnull', - stderr = 'devnull', - stdout = subprocess.PIPE) - if pipe.wait() != 0: return - # -dumpversion was added in GCC 3.0. As long as we're supporting - # GCC versions older than that, we should use --version and a - # regular expression. - #line = pipe.stdout.read().strip() - #if line: - # env['CCVERSION'] = line - line = pipe.stdout.readline() - match = re.search(r'[0-9]+(\.[0-9]+)+', line) - if match: - env['CCVERSION'] = match.group(0) + version = detect_version(env, env['CC']) + if version: + env['CCVERSION'] = version def exists(env): - return env.Detect(compilers) + # is executable, and is a GNU compiler (or accepts '--version' at least) + return detect_version(env, env.Detect(env.get('CC', compilers))) + +def detect_version(env, cc): + """Return the version of the GNU compiler, or None if it is not a GNU compiler.""" + cc = env.subst(cc) + if not cc: + return None + version = None + #pipe = SCons.Action._subproc(env, SCons.Util.CLVar(cc) + ['-dumpversion'], + pipe = SCons.Action._subproc(env, SCons.Util.CLVar(cc) + ['--version'], + stdin = 'devnull', + stderr = 'devnull', + stdout = subprocess.PIPE) + # -dumpversion was added in GCC 3.0. As long as we're supporting + # GCC versions older than that, we should use --version and a + # regular expression. + #line = pipe.stdout.read().strip() + #if line: + # version = line + line = pipe.stdout.readline() + match = re.search(r'[0-9]+(\.[0-9]+)+', line) + if match: + version = match.group(0) + # Non-GNU compiler's output (like AIX xlc's) may exceed the stdout buffer: + # So continue with reading to let the child process actually terminate. + while pipe.stdout.readline(): + pass + ret = pipe.wait() + if ret != 0: + return None + return version # Local Variables: # tab-width:4 diff --git a/src/engine/SCons/Tool/gnulink.py b/src/engine/SCons/Tool/gnulink.py index bf71270f..3dc8f51b 100644 --- a/src/engine/SCons/Tool/gnulink.py +++ b/src/engine/SCons/Tool/gnulink.py @@ -37,8 +37,6 @@ import SCons.Util import link -linkers = ['g++', 'gcc'] - def generate(env): """Add Builders and construction variables for gnulink to an Environment.""" link.generate(env) @@ -53,7 +51,14 @@ def generate(env): env['_RPATH'] = '${_concat(RPATHPREFIX, RPATH, RPATHSUFFIX, __env__)}' def exists(env): - return env.Detect(linkers) + # TODO: sync with link.smart_link() to choose a linker + linkers = { 'CXX': ['g++'], 'CC': ['gcc'] } + alltools = [] + for langvar, linktools in linkers.items(): + if langvar in env: # use CC over CXX when user specified CC but not CXX + return SCons.Tool.FindTool(linktools, env) + alltools.extend(linktools) + return SCons.Tool.FindTool(alltools, env) # find CXX or CC # Local Variables: # tab-width:4 diff --git a/test/CC/CC.py b/test/CC/CC.py index 73dc4e6f..9500088d 100644 --- a/test/CC/CC.py +++ b/test/CC/CC.py @@ -156,7 +156,8 @@ env.Program(target = 'test2', source = 'test2.C') test.write("wrapper.py", """import os import sys -open('%s', 'wb').write("wrapper.py\\n") +if '--version' not in sys.argv and '-dumpversion' not in sys.argv: + open('%s', 'wb').write("wrapper.py\\n") os.system(" ".join(sys.argv[1:])) """ % test.workpath('wrapper.out').replace('\\', '\\\\')) @@ -197,13 +198,13 @@ main(int argc, char *argv[]) test.run(arguments = 'foo' + _exe) -test.fail_test(os.path.exists(test.workpath('wrapper.out'))) +test.must_not_exist(test.workpath('wrapper.out')) test.up_to_date(arguments = 'foo' + _exe) test.run(arguments = 'bar' + _exe) -test.fail_test(test.read('wrapper.out') != "wrapper.py\n") +test.must_match('wrapper.out', "wrapper.py\n") test.up_to_date(arguments = 'bar' + _exe) diff --git a/test/CC/CCVERSION.py b/test/CC/CCVERSION.py new file mode 100644 index 00000000..ac28e380 --- /dev/null +++ b/test/CC/CCVERSION.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__" + +import os +import sys +import TestSCons + +_python_ = TestSCons._python_ +_exe = TestSCons._exe + +test = TestSCons.TestSCons() + + + +test.write("versioned.py", +"""import os +import sys +if '-dumpversion' in sys.argv: + print '3.9.9' + sys.exit(0) +if '--version' in sys.argv: + print 'this is version 2.9.9 wrapping', sys.argv[2] + sys.exit(0) +if sys.argv[1] not in [ '2.9.9', '3.9.9' ]: + print 'wrong version', sys.argv[1], 'when wrapping', sys.argv[2] + sys.exit(1) +os.system(" ".join(sys.argv[2:])) +""") + +test.write('SConstruct', """ +cc = Environment().Dictionary('CC') +foo = Environment(CC = r'%(_python_)s versioned.py "${CCVERSION}" ' + cc) +foo.Program(target = 'foo', source = 'foo.c') +""" % locals()) + +test.write('foo.c', r""" +#include <stdio.h> +#include <stdlib.h> + +int +main(int argc, char *argv[]) +{ + argv[argc++] = "--"; + printf("foo.c\n"); + exit (0); +} +""") + +test.run(arguments = 'foo' + _exe) + +test.up_to_date(arguments = 'foo' + _exe) + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/CXX/CXX.py b/test/CXX/CXX.py index cd354ae7..79dbde45 100644 --- a/test/CXX/CXX.py +++ b/test/CXX/CXX.py @@ -186,7 +186,8 @@ env.Program(target = 'test6', source = 'test6.C') test.write("wrapper.py", """import os import sys -open('%s', 'wb').write("wrapper.py\\n") +if '--version' not in sys.argv and '-dumpversion' not in sys.argv: + open('%s', 'wb').write("wrapper.py\\n") os.system(" ".join(sys.argv[1:])) """ % test.workpath('wrapper.out').replace('\\', '\\\\')) diff --git a/test/CXX/CXXVERSION.py b/test/CXX/CXXVERSION.py new file mode 100644 index 00000000..8433aa61 --- /dev/null +++ b/test/CXX/CXXVERSION.py @@ -0,0 +1,81 @@ +#!/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 sys +import TestSCons + +_python_ = TestSCons._python_ +_exe = TestSCons._exe + +test = TestSCons.TestSCons() + + + +test.write("versioned.py", +"""import os +import sys +if '-dumpversion' in sys.argv: + print '3.9.9' + sys.exit(0) +if '--version' in sys.argv: + print 'this is version 2.9.9 wrapping', sys.argv[2] + sys.exit(0) +if sys.argv[1] not in [ '2.9.9', '3.9.9' ]: + print 'wrong version', sys.argv[1], 'when wrapping', sys.argv[2] + sys.exit(1) +os.system(" ".join(sys.argv[2:])) +""") + +test.write('SConstruct', """ +cxx = Environment().Dictionary('CXX') +foo = Environment(CXX = r'%(_python_)s versioned.py "${CXXVERSION}" ' + cxx) +foo.Program(target = 'foo', source = 'foo.cpp') +""" % locals()) + +test.write('foo.cpp', r""" +#include <stdio.h> +#include <stdlib.h> + +int +main(int argc, char *argv[]) +{ + printf("foo.c\n"); + exit (0); +} +""") + +test.run(arguments = 'foo' + _exe) + +test.up_to_date(arguments = 'foo' + _exe) + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: |