summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGary Oberbrunner <garyo@oberbrunner.com>2014-05-18 19:51:34 -0400
committerGary Oberbrunner <garyo@oberbrunner.com>2014-05-18 19:51:34 -0400
commit278c0cfb02eeade2032b819148474a63f8633eb9 (patch)
treebb47ccb7b4705f82724646b5952c439bdd9f5650
parentb224e56784d3f5f95a1fca78c4ba7b3a876bee98 (diff)
parent70122d8609b95fc8b88c6ceba507db2fa9e425fb (diff)
downloadscons-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.txt9
-rw-r--r--src/engine/SCons/Environment.py4
-rw-r--r--src/engine/SCons/Tool/ToolTests.py2
-rw-r--r--src/engine/SCons/Tool/__init__.py6
-rw-r--r--src/engine/SCons/Tool/aixlink.py15
-rw-r--r--src/engine/SCons/Tool/c++.py5
-rw-r--r--src/engine/SCons/Tool/cc.py7
-rw-r--r--src/engine/SCons/Tool/g++.py30
-rw-r--r--src/engine/SCons/Tool/gcc.py58
-rw-r--r--src/engine/SCons/Tool/gnulink.py11
-rw-r--r--test/CC/CC.py7
-rw-r--r--test/CC/CCVERSION.py82
-rw-r--r--test/CXX/CXX.py3
-rw-r--r--test/CXX/CXXVERSION.py81
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: