summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGary Oberbrunner <garyo@oberbrunner.com>2014-05-18 18:23:29 -0400
committerGary Oberbrunner <garyo@oberbrunner.com>2014-05-18 18:23:29 -0400
commit43801bc536c1e646603d05949f10281d8ad1258e (patch)
tree44f13b96ea035a0d1838ac884b1f65edee7260f0
parent9e32571c82014c548617a43b09ed4b153b45fca4 (diff)
parentbb182e0aa1ca52754b462eee78514145633013ea (diff)
downloadscons-43801bc536c1e646603d05949f10281d8ad1258e.tar.gz
Merged pull request #138; Respect preset CC/CXX values.
This prevents SCons from overwriting user's selected CC/CXX compiler in the cc/c++/gcc/gcc tools. Fixes issue #1723.
-rw-r--r--src/CHANGES.txt3
-rw-r--r--src/engine/SCons/Environment.py4
-rw-r--r--src/engine/SCons/Tool/ToolTests.py2
-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--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
11 files changed, 233 insertions, 49 deletions
diff --git a/src/CHANGES.txt b/src/CHANGES.txt
index 105269c1..ccc9f7c1 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 Michael Haubenwallner:
+ - Respect user's CC/CXX values; don't always overwrite in generate()
+
From Amir Szekely:
- Fixed NoClean() for multi-target builders (#2353).
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/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/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: