From 98c4c1c7b820bbb42384584bc0d95c7849f71503 Mon Sep 17 00:00:00 2001 From: Thomas Tanner Date: Sat, 11 Feb 2017 14:26:39 +0000 Subject: Allow nested $( $) sections --- src/CHANGES.txt | 5 +++-- src/engine/SCons/ActionTests.py | 6 +++--- src/engine/SCons/Subst.py | 29 +++++++++++++++++++++-------- src/engine/SCons/SubstTests.py | 25 +++++++++++++++++++++++++ 4 files changed, 52 insertions(+), 13 deletions(-) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 4a7576e..ad53d7d 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -62,6 +62,8 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER - Fixed PCHPDBFLAGS causing a deprecation warning on MSVC v8 and later when using PCHs and PDBs together. + From Tom Tanner: + - Allow nested $( ... $) sections RELEASE 2.5.1 - Mon, 03 Nov 2016 13:37:42 -0400 @@ -146,7 +148,7 @@ RELEASE 2.4.1 - Mon, 07 Nov 2015 10:37:21 -0700 and continuing. From Hiroaki Itoh : - - Add support `Microsoft Visual C++ Compiler for Python 2.7' + - 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: @@ -316,7 +318,6 @@ RELEASE 2.3.2 From Paweł Tomulik: - Fix SConf tests that write output ->>>>>>> other From Gary Oberbrunner: - get default RPM architecture more robustly when building RPMs diff --git a/src/engine/SCons/ActionTests.py b/src/engine/SCons/ActionTests.py index b790ccc..f0c48ea 100644 --- a/src/engine/SCons/ActionTests.py +++ b/src/engine/SCons/ActionTests.py @@ -1241,8 +1241,8 @@ class CommandActionTestCase(unittest.TestCase): (env["foo"], env["bar"]) # The number 1 is there to make sure all args get converted to strings. - a = SCons.Action.CommandAction(["|", "$(", "$foo", "|", "$bar", - "$)", "|", "$baz", 1]) + a = SCons.Action.CommandAction(["|", "$(", "$foo", "|", "$(", "$bar", + "$)", "stuff", "$)", "|", "$baz", 1]) c = a.get_contents(target=[], source=[], env=Environment(foo = 'FFF', bar = 'BBB', baz = CmdGen)) @@ -1257,7 +1257,7 @@ class CommandActionTestCase(unittest.TestCase): c = a.get_contents(target=DummyNode('ttt'), source = DummyNode('sss'), env=SpecialEnvironment(foo = 'GGG', bar = 'CCC', baz = 'ZZZ')) - assert c == b'subst_target_source: | $( $foo | $bar $) | $baz 1', c + assert c == b'subst_target_source: | $( $foo | $( $bar $) stuff $) | $baz 1', c # We've discussed using the real target and source names in a # CommandAction's signature contents. This would have have the diff --git a/src/engine/SCons/Subst.py b/src/engine/SCons/Subst.py index 3c9b390..b81d79c 100644 --- a/src/engine/SCons/Subst.py +++ b/src/engine/SCons/Subst.py @@ -338,24 +338,28 @@ SUBST_RAW = 1 SUBST_SIG = 2 _rm = re.compile(r'\$[()]') -_remove = re.compile(r'\$\([^\$]*(\$[^\)][^\$]*)*\$\)') +_rm_split = re.compile(r'(\$[()])') # Indexed by the SUBST_* constants above. -_regex_remove = [ _rm, None, _remove ] +_regex_remove = [ _rm, None, _rm_split ] def _rm_list(list): return [l for l in list if not l in ('$(', '$)')] def _remove_list(list): result = [] - do_append = result.append + depth = 0 for l in list: if l == '$(': - do_append = lambda x: None + depth += 1 elif l == '$)': - do_append = result.append - else: - do_append(l) + depth -= 1 + if depth < 0: + break + elif depth == 0: + result.append(l) + if depth != 0: + return None return result # Indexed by the SUBST_* constants above. @@ -562,12 +566,19 @@ def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={ except KeyError: pass + res = result if is_String(result): # Remove $(-$) pairs and any stuff in between, # if that's appropriate. remove = _regex_remove[mode] if remove: - result = remove.sub('', result) + if mode == SUBST_SIG: + result = _list_remove[mode](remove.split(result)) + if result is None: + raise SCons.Errors.UserError("Unbalanced $(/$) in: " + res) + result = ' '.join(result) + else: + result = remove.sub('', result) if mode != SUBST_RAW: # Compress strings of white space characters into # a single space. @@ -576,6 +587,8 @@ def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={ remove = _list_remove[mode] if remove: result = remove(result) + if result is None: + raise SCons.Errors.UserError("Unbalanced $(/$) in: " + str(res)) return result diff --git a/src/engine/SCons/SubstTests.py b/src/engine/SCons/SubstTests.py index 8eda845..f2cbc3f 100644 --- a/src/engine/SCons/SubstTests.py +++ b/src/engine/SCons/SubstTests.py @@ -183,6 +183,9 @@ class SubstTestCase(unittest.TestCase): 'HHH' : 'III', 'FFFIII' : 'BADNEWS', + 'THING1' : "$(STUFF$)", + 'THING2' : "$THING1", + 'LITERAL' : TestLiteral("$XXX"), # Test that we can expand to and return a function. @@ -405,6 +408,11 @@ class scons_subst_TestCase(SubstTestCase): "test", "test", + "test $( $THING2 $)", + "test $( $(STUFF$) $)", + "test STUFF", + "test", + "$AAA ${AAA}A $BBBB $BBB", "a aA b", "a aA b", @@ -544,6 +552,23 @@ class scons_subst_TestCase(SubstTestCase): else: raise AssertionError("did not catch expected UserError") + def test_subst_balance_errors(self): + """Test scons_subst(): handling syntax errors""" + env = DummyEnv(self.loc) + try: + scons_subst('$(', env, mode=SUBST_SIG) + except SCons.Errors.UserError as e: + assert str(e) == "Unbalanced $(/$) in: $(", str(e) + else: + raise AssertionError("did not catch expected UserError") + + try: + scons_subst('$)', env, mode=SUBST_SIG) + except SCons.Errors.UserError as e: + assert str(e) == "Unbalanced $(/$) in: $)", str(e) + else: + raise AssertionError("did not catch expected UserError") + def test_subst_type_errors(self): """Test scons_subst(): handling type errors""" env = DummyEnv(self.loc) -- cgit v0.12 From 1849ff611b22a55b8933dc9f05db66114e34cd14 Mon Sep 17 00:00:00 2001 From: grbd Date: Thu, 3 Aug 2017 15:53:20 +0100 Subject: Added support for a PyPackageDir function --- src/engine/SCons/Environment.py | 9 ++++ src/engine/SCons/Node/FS.py | 29 +++++++++++ src/engine/SCons/Script/__init__.py | 1 + test/Dir/PyPackageDir/PyPackageDir.py | 56 ++++++++++++++++++++++ test/Dir/PyPackageDir/image/SConstruct | 29 +++++++++++ test/Dir/PyPackageDir/image/sconstest.skip | 0 test/Dir/PyPackageDir/image/syspath/sconstest.skip | 0 .../PyPackageDir/image/syspath/submod1/__init__.py | 0 .../image/syspath/submod1/sconstest.skip | 0 .../image/syspath/submod1/submod2/__init__.py | 0 .../image/syspath/submod1/submod2/sconstest.skip | 0 .../image/syspath/submod1/submod2/testmod4.py | 0 .../PyPackageDir/image/syspath/submod1/testmod3.py | 0 .../image/syspath/testmod1/__init__.py | 0 .../image/syspath/testmod1/sconstest.skip | 0 test/Dir/PyPackageDir/image/syspath/testmod2.py | 0 test/toolpath/nested/image/SConstruct | 7 +++ test/toolpath/nested/nested.py | 3 ++ 18 files changed, 134 insertions(+) create mode 100644 test/Dir/PyPackageDir/PyPackageDir.py create mode 100644 test/Dir/PyPackageDir/image/SConstruct create mode 100644 test/Dir/PyPackageDir/image/sconstest.skip create mode 100644 test/Dir/PyPackageDir/image/syspath/sconstest.skip create mode 100644 test/Dir/PyPackageDir/image/syspath/submod1/__init__.py create mode 100644 test/Dir/PyPackageDir/image/syspath/submod1/sconstest.skip create mode 100644 test/Dir/PyPackageDir/image/syspath/submod1/submod2/__init__.py create mode 100644 test/Dir/PyPackageDir/image/syspath/submod1/submod2/sconstest.skip create mode 100644 test/Dir/PyPackageDir/image/syspath/submod1/submod2/testmod4.py create mode 100644 test/Dir/PyPackageDir/image/syspath/submod1/testmod3.py create mode 100644 test/Dir/PyPackageDir/image/syspath/testmod1/__init__.py create mode 100644 test/Dir/PyPackageDir/image/syspath/testmod1/sconstest.skip create mode 100644 test/Dir/PyPackageDir/image/syspath/testmod2.py diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py index 60a45e4..480a1d6 100644 --- a/src/engine/SCons/Environment.py +++ b/src/engine/SCons/Environment.py @@ -1983,6 +1983,15 @@ class Base(SubstitutionEnvironment): return result return self.fs.Dir(s, *args, **kw) + def PyPackageDir(self, modulename): + s = self.subst(modulename) + if SCons.Util.is_Sequence(s): + result=[] + for e in s: + result.append(self.fs.PyPackageDir(e)) + return result + return self.fs.PyPackageDir(s) + def NoClean(self, *targets): """Tags a target so that it will not be cleaned by -c""" tlist = [] diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py index d98f7d0..8c1161d 100644 --- a/src/engine/SCons/Node/FS.py +++ b/src/engine/SCons/Node/FS.py @@ -1390,6 +1390,35 @@ class FS(LocalFS): if not isinstance(d, SCons.Node.Node): d = self.Dir(d) self.Top.addRepository(d) + + def PyPackageDir(self, modulename): + """Locate the directory of a given python module name + + For example scons might resolve to + Windows: C:\Python27\Lib\site-packages\scons-2.5.1 + Linux: /usr/lib/scons + + This can be useful when we want to determine a toolpath based on a python module name""" + + dirpath = '' + if sys.version_info[0] < 3 or (sys.version_info[0] == 3 and sys.version_info[1] in (0,1,2,3,4)): + # Python2 Code + import imp + splitname = modulename.split('.') + srchpths = sys.path + for item in splitname: + file, path, desc = imp.find_module(item, srchpths) + if file is not None: + path = os.path.dirname(path) + srchpths = [path] + dirpath = path + else: + # Python3 Code + import importlib.util + modspec = importlib.util.find_spec(modulename) + dirpath = os.path.dirname(modspec.origin) + return self._lookup(dirpath, None, Dir, True) + def variant_dir_target_climb(self, orig, dir, tail): """Create targets in corresponding variant directories diff --git a/src/engine/SCons/Script/__init__.py b/src/engine/SCons/Script/__init__.py index 3fa3a48..5bdd63e 100644 --- a/src/engine/SCons/Script/__init__.py +++ b/src/engine/SCons/Script/__init__.py @@ -337,6 +337,7 @@ GlobalDefaultEnvironmentFunctions = [ 'Local', 'ParseDepends', 'Precious', + 'PyPackageDir', 'Repository', 'Requires', 'SConsignFile', diff --git a/test/Dir/PyPackageDir/PyPackageDir.py b/test/Dir/PyPackageDir/PyPackageDir.py new file mode 100644 index 0000000..b215c7b --- /dev/null +++ b/test/Dir/PyPackageDir/PyPackageDir.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__" + +import os.path +import TestSCons + +test = TestSCons.TestSCons() + +test.dir_fixture('image') + +test.run(arguments = '.', stdout = """\ +scons: Reading SConscript files ... +Test identification of directory for a given python package +testmod1 +. +submod1 +submod1/submod2 +Test parameter substitution +submod1/submod2 +submod1/submod2 +scons: done reading SConscript files. +scons: Building targets ... +scons: `.' is up to date. +scons: done building targets. +""") + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/Dir/PyPackageDir/image/SConstruct b/test/Dir/PyPackageDir/image/SConstruct new file mode 100644 index 0000000..90d2a80 --- /dev/null +++ b/test/Dir/PyPackageDir/image/SConstruct @@ -0,0 +1,29 @@ +import sys, os + +oldsyspath = sys.path +dir_path = Dir('.').srcnode().abspath +dir_path = os.path.join(dir_path, 'syspath') +sys.path.append(dir_path) + +def TestPyPackageDir(env, modname): + packagepath = env.PyPackageDir(modname).abspath + # Convert from an absolute path back to a relative one for testing + commonprefix = os.path.commonprefix([dir_path, packagepath]) + relpath = os.path.relpath(packagepath, commonprefix) + relpath = relpath.replace(os.sep, '/') + print(relpath) + +print("Test identification of directory for a given python package") +env = Environment() +TestPyPackageDir(env, 'testmod1') +TestPyPackageDir(env, 'testmod2') +TestPyPackageDir(env, 'submod1.testmod3') +TestPyPackageDir(env, 'submod1.submod2.testmod4') + +print("Test parameter substitution") +env = Environment(FOO = 'submod1.submod2.testmod4') +TestPyPackageDir(env, '${FOO}') +env = Environment(FOO = 'submod1.submod2', BAR = 'testmod4') +TestPyPackageDir(env, '${FOO}.${BAR}') + +sys.path = oldsyspath diff --git a/test/Dir/PyPackageDir/image/sconstest.skip b/test/Dir/PyPackageDir/image/sconstest.skip new file mode 100644 index 0000000..e69de29 diff --git a/test/Dir/PyPackageDir/image/syspath/sconstest.skip b/test/Dir/PyPackageDir/image/syspath/sconstest.skip new file mode 100644 index 0000000..e69de29 diff --git a/test/Dir/PyPackageDir/image/syspath/submod1/__init__.py b/test/Dir/PyPackageDir/image/syspath/submod1/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/test/Dir/PyPackageDir/image/syspath/submod1/sconstest.skip b/test/Dir/PyPackageDir/image/syspath/submod1/sconstest.skip new file mode 100644 index 0000000..e69de29 diff --git a/test/Dir/PyPackageDir/image/syspath/submod1/submod2/__init__.py b/test/Dir/PyPackageDir/image/syspath/submod1/submod2/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/test/Dir/PyPackageDir/image/syspath/submod1/submod2/sconstest.skip b/test/Dir/PyPackageDir/image/syspath/submod1/submod2/sconstest.skip new file mode 100644 index 0000000..e69de29 diff --git a/test/Dir/PyPackageDir/image/syspath/submod1/submod2/testmod4.py b/test/Dir/PyPackageDir/image/syspath/submod1/submod2/testmod4.py new file mode 100644 index 0000000..e69de29 diff --git a/test/Dir/PyPackageDir/image/syspath/submod1/testmod3.py b/test/Dir/PyPackageDir/image/syspath/submod1/testmod3.py new file mode 100644 index 0000000..e69de29 diff --git a/test/Dir/PyPackageDir/image/syspath/testmod1/__init__.py b/test/Dir/PyPackageDir/image/syspath/testmod1/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/test/Dir/PyPackageDir/image/syspath/testmod1/sconstest.skip b/test/Dir/PyPackageDir/image/syspath/testmod1/sconstest.skip new file mode 100644 index 0000000..e69de29 diff --git a/test/Dir/PyPackageDir/image/syspath/testmod2.py b/test/Dir/PyPackageDir/image/syspath/testmod2.py new file mode 100644 index 0000000..e69de29 diff --git a/test/toolpath/nested/image/SConstruct b/test/toolpath/nested/image/SConstruct index 211a0d7..78ae21d 100644 --- a/test/toolpath/nested/image/SConstruct +++ b/test/toolpath/nested/image/SConstruct @@ -55,4 +55,11 @@ print("env3['Toolpath_TestTool1_2'] =", env3.get('Toolpath_TestTool1_2')) print("env3['Toolpath_TestTool2_1'] =", env3.get('Toolpath_TestTool2_1')) print("env3['Toolpath_TestTool2_2'] =", env3.get('Toolpath_TestTool2_2')) + +print('Test using PyPackageDir') +toollist = ['Toolpath_TestTool2_1', 'Toolpath_TestTool2_2'] +env4 = Environment(tools = toollist, toolpath = [PyPackageDir('tools_example.subdir1.subdir2')]) +print("env4['Toolpath_TestTool2_1'] =", env4.get('Toolpath_TestTool2_1')) +print("env4['Toolpath_TestTool2_2'] =", env4.get('Toolpath_TestTool2_2')) + sys.path = oldsyspath diff --git a/test/toolpath/nested/nested.py b/test/toolpath/nested/nested.py index a736d58..df2ba07 100644 --- a/test/toolpath/nested/nested.py +++ b/test/toolpath/nested/nested.py @@ -57,6 +57,9 @@ env3['Toolpath_TestTool1_1'] = 1 env3['Toolpath_TestTool1_2'] = 1 env3['Toolpath_TestTool2_1'] = 1 env3['Toolpath_TestTool2_2'] = 1 +Test using PyPackageDir +env4['Toolpath_TestTool2_1'] = 1 +env4['Toolpath_TestTool2_2'] = 1 scons: done reading SConscript files. scons: Building targets ... scons: `.' is up to date. -- cgit v0.12 From 89091bfadcb56defc897acfa9753470e1eead6a2 Mon Sep 17 00:00:00 2001 From: grbd Date: Thu, 3 Aug 2017 12:33:51 -0700 Subject: Added docs for use of the PyPackageDir function --- doc/generated/functions.gen | 25 +++++++++++++++++++++++++ doc/generated/functions.mod | 4 ++++ doc/generated/tools.gen | 16 ++++++++++++++++ doc/generated/tools.mod | 4 ++++ doc/generated/variables.gen | 29 +++++++++++++++++++++++++++-- doc/generated/variables.mod | 2 ++ doc/scons.mod | 1 + doc/user/environments.xml | 32 ++++++++++++++++++++++++++++++++ src/CHANGES.txt | 1 + src/engine/SCons/Environment.xml | 23 +++++++++++++++++++++++ 10 files changed, 135 insertions(+), 2 deletions(-) diff --git a/doc/generated/functions.gen b/doc/generated/functions.gen index 8181d56..e72740a 100644 --- a/doc/generated/functions.gen +++ b/doc/generated/functions.gen @@ -3320,6 +3320,31 @@ Multiple targets can be passed in to a single call to + + + PyPackageDir(modulename) + + + env.PyPackageDir(modulename) + + + +This returns a Directory Node similar to Dir. +The python module / package is looked up and if located +the directory is returned for the location. +modulename +Is a named python package / module to +lookup the directory for it's location. + + +If +modulename +is a list, SCons returns a list of Dir nodes. +Construction variables are expanded in +modulename. + + + env.Replace(key=val, [...]) diff --git a/doc/generated/functions.mod b/doc/generated/functions.mod index 6183293..e460aaf 100644 --- a/doc/generated/functions.mod +++ b/doc/generated/functions.mod @@ -69,6 +69,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. PrependUnique"> Progress"> Pseudo"> +PyPackageDir"> Replace"> Repository"> Requires"> @@ -152,6 +153,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. env.PrependUnique"> env.Progress"> env.Pseudo"> +env.PyPackageDir"> env.Replace"> env.Repository"> env.Requires"> @@ -245,6 +247,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. PrependUnique"> Progress"> Pseudo"> +PyPackageDir"> Replace"> Repository"> Requires"> @@ -328,6 +331,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. env.PrependUnique"> env.Progress"> env.Pseudo"> +env.PyPackageDir"> env.Replace"> env.Repository"> env.Requires"> diff --git a/doc/generated/tools.gen b/doc/generated/tools.gen index d4b346d..0de9e03 100644 --- a/doc/generated/tools.gen +++ b/doc/generated/tools.gen @@ -95,6 +95,22 @@ 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;. + + clang + + +Set construction variables for the Clang C compiler. + +Sets: &cv-link-CC;, &cv-link-CCVERSION;, &cv-link-SHCCFLAGS;. + + + clangxx + + +Set construction variables for the Clang C++ compiler. + +Sets: &cv-link-CXX;, &cv-link-CXXVERSION;, &cv-link-SHCXXFLAGS;, &cv-link-SHOBJSUFFIX;, &cv-link-STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME;. + cvf diff --git a/doc/generated/tools.mod b/doc/generated/tools.mod index ee387ad..f9bc1d7 100644 --- a/doc/generated/tools.mod +++ b/doc/generated/tools.mod @@ -18,6 +18,8 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. as"> bcc32"> cc"> +clang"> +clangxx"> cvf"> cXX"> cyglink"> @@ -124,6 +126,8 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. as"> bcc32"> cc"> +clang"> +clangxx"> cvf"> cXX"> cyglink"> diff --git a/doc/generated/variables.gen b/doc/generated/variables.gen index e31fde1..0ad4c96 100644 --- a/doc/generated/variables.gen +++ b/doc/generated/variables.gen @@ -3046,7 +3046,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. @@ -3056,7 +3056,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. @@ -4179,6 +4179,29 @@ window and importing the shell's environment variables. + + MSVC_UWP_APP + + +Build libraries for a Universal Windows Platform (UWP) Application. + + + +If $MSVC_UWP_APP is set, the Visual Studio environment will be set up to point +to the Windows Store compatible libraries and Visual Studio runtimes. In doing so, +any libraries that are built will be able to be used in a UWP App and published +to the Windows Store. +This flag will only have an effect with Visual Studio 2015+. +This variable must be passed as an argument to the Environment() +constructor; setting it later has no effect. + + + +Valid values are '1' or '0' + + + + MSVC_VERSION @@ -4196,6 +4219,8 @@ constructor; setting it later has no effect. Valid values for Windows are +14.0, +14.0Exp, 12.0, 12.0Exp, 11.0, diff --git a/doc/generated/variables.mod b/doc/generated/variables.mod index 9d834de..8710f95 100644 --- a/doc/generated/variables.mod +++ b/doc/generated/variables.mod @@ -304,6 +304,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. $MSSDK_VERSION"> $MSVC_BATCH"> $MSVC_USE_SCRIPT"> +$MSVC_UWP_APP"> $MSVC_VERSION"> $MSVS"> $MSVS_ARCH"> @@ -927,6 +928,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. $MSSDK_VERSION"> $MSVC_BATCH"> $MSVC_USE_SCRIPT"> +$MSVC_UWP_APP"> $MSVC_VERSION"> $MSVS"> $MSVS_ARCH"> diff --git a/doc/scons.mod b/doc/scons.mod index 8d64054..448a212 100644 --- a/doc/scons.mod +++ b/doc/scons.mod @@ -243,6 +243,7 @@ PrependENVPath"> PrependUnique"> Progress"> +PyPackageDir"> Replace"> Repository"> Requires"> diff --git a/doc/user/environments.xml b/doc/user/environments.xml index d591dff..4657c05 100644 --- a/doc/user/environments.xml +++ b/doc/user/environments.xml @@ -1887,6 +1887,38 @@ C:\Python35\Lib\site-packages\someinstalledpackage\SomeTool\__init__.py +
+ Using the &PyPackageDir; function to add to the toolpath + + + In some cases you may want to use a tool + located within a installed external pip package. + This is possible by the use of sys.path within the toolpath. + However in that situaion you need to provide a prefix to the toolname + to indicate where it is located within sys.path + + + +# namespaced target using sys.path +env = Environment(tools = ['tools_example.subdir1.subdir2.SomeTool'], toolpath = sys.path) +env.SomeTool(targets, sources) + + + + To avoid the use of a prefix within the name of the tool, + we can use the PyPackageDir(modulename) function to locate the directory of the python package. + PyPackageDir returns a Dir object which represents the path of the directory + for the python package / module specified as a parameter. + + + +# namespaced target using sys.path +env = Environment(tools = ['SomeTool'], toolpath = [PyPackageDir('tools_example.subdir1.subdir2')]) +env.SomeTool(targets, sources) + + +
+ diff --git a/src/CHANGES.txt b/src/CHANGES.txt index d032949..e875a01 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -20,6 +20,7 @@ may cause rebuilds. In no case should rebuilds not happen. - Added a small fix to the python3 tool loader when loading a tool as a package - Added additional documentation to the user manual on using toolpaths with the environment This includes the use of sys.path to search for tools installed via pip or package managers + - Added support for a PyPackageDir function for use with the toolpath From William Blevins: - Updated D language scanner support to latest: 2.071.1. (PR #1924) diff --git a/src/engine/SCons/Environment.xml b/src/engine/SCons/Environment.xml index 92bc21a..ccee68d 100644 --- a/src/engine/SCons/Environment.xml +++ b/src/engine/SCons/Environment.xml @@ -2504,6 +2504,29 @@ env.PrependUnique(CCFLAGS = '-g', FOO = ['foo.yyy']) + + +(modulename) + + + +This returns a Directory Node similar to Dir. +The python module / package is looked up and if located +the directory is returned for the location. +modulename +Is a named python package / module to +lookup the directory for it's location. + + +If +modulename +is a list, SCons returns a list of Dir nodes. +Construction variables are expanded in +modulename. + + + + (key=val, [...]) -- cgit v0.12 From 334b9d54cf6810f55ffb14c2c42a03ac1f2ab433 Mon Sep 17 00:00:00 2001 From: grbd Date: Fri, 4 Aug 2017 02:57:11 -0700 Subject: Added fixes for docs / nested test for use of sys.path in toolpath --- doc/user/environments.xml | 49 ++++++++++++++++++++++------------- test/toolpath/nested/image/SConstruct | 6 ++++- 2 files changed, 36 insertions(+), 19 deletions(-) diff --git a/doc/user/environments.xml b/doc/user/environments.xml index 4657c05..ae670a8 100644 --- a/doc/user/environments.xml +++ b/doc/user/environments.xml @@ -1781,7 +1781,7 @@ env.AppendENVPath('LIB', '/usr/local/lib')
-# Inbuilt tool or tool located within site_tools +# Builtin tool or tool located within site_tools env = Environment(tools = ['SomeTool']) env.SomeTool(targets, sources) @@ -1847,11 +1847,12 @@ SCons/Tool/SubDir1/SubDir2/SomeTool/__init__.py - It's important to note when creating tools within sub-directories, - there needs to be a __init__.py file within each directory. - This file can just be empty. - This is the same constraint used by python when loading modules - from within sub-directories (packages). + For python2 It's important to note when creating tools within sub-directories, + there needs to be a __init__.py file within each directory. + This file can just be empty. + This is the same constraint used by python when loading modules + from within sub-directories (packages). + For python3 this appears to be no longer a requirement. @@ -1859,20 +1860,30 @@ SCons/Tool/SubDir1/SubDir2/SomeTool/__init__.py Using sys.path within the toolpath - Using the toolpath option with sys.path - we can also include tools installed via the pip package manager. - + If we want to access tools externally to scons on the sys.path + (one example would be tools installed via the pip package manager) + One way to do this is to use sys.path with the toolpath. + + One thing to watch out for with this approach is that sys.path + can sometimes contains paths to .egg files instead of directories. + So we need to filter those out with this approach. + # namespaced target using sys.path within toolpath -env = Environment(tools = ['someinstalledpackage.SomeTool'], toolpath = sys.path) + +searchpaths = [] +for item in sys.path: + if os.path.isdir(item): searchpaths.append(item) + +env = Environment(tools = ['someinstalledpackage.SomeTool'], toolpath = searchpaths) env.SomeTool(targets, sources) - By supplying sys.path to the toolpath argument - and by using the nested syntax we can have scons search - the sys.path (which will include packages installed via pip). + By using sys.path with the toolpath argument + and by using the nested syntax we can have scons search + packages installed via pip for Tools. @@ -1893,19 +1904,21 @@ C:\Python35\Lib\site-packages\someinstalledpackage\SomeTool\__init__.py In some cases you may want to use a tool located within a installed external pip package. - This is possible by the use of sys.path within the toolpath. - However in that situaion you need to provide a prefix to the toolname + This is possible by the use of sys.path with the toolpath. + However in that situation you need to provide a prefix to the toolname to indicate where it is located within sys.path -# namespaced target using sys.path -env = Environment(tools = ['tools_example.subdir1.subdir2.SomeTool'], toolpath = sys.path) +searchpaths = [] +for item in sys.path: + if os.path.isdir(item): searchpaths.append(item) +env = Environment(tools = ['tools_example.subdir1.subdir2.SomeTool'], toolpath = searchpaths) env.SomeTool(targets, sources) - To avoid the use of a prefix within the name of the tool, + To avoid the use of a prefix within the name of the tool or filtering sys.path for directories, we can use the PyPackageDir(modulename) function to locate the directory of the python package. PyPackageDir returns a Dir object which represents the path of the directory for the python package / module specified as a parameter. diff --git a/test/toolpath/nested/image/SConstruct b/test/toolpath/nested/image/SConstruct index 78ae21d..a7c6ceb 100644 --- a/test/toolpath/nested/image/SConstruct +++ b/test/toolpath/nested/image/SConstruct @@ -39,6 +39,10 @@ dir_path = Dir('.').srcnode().abspath dir_path = os.path.join(dir_path, 'Libs') sys.path.append(dir_path) +searchpaths = [] +for item in sys.path: + if os.path.isdir(item): searchpaths.append(item) + toollist = ['tools_example.Toolpath_TestTool1', 'tools_example.Toolpath_TestTool2', 'tools_example.subdir1.Toolpath_TestTool1_1', @@ -47,7 +51,7 @@ toollist = ['tools_example.Toolpath_TestTool1', 'tools_example.subdir1.subdir2.Toolpath_TestTool2_2', ] -env3 = Environment(tools=toollist, toolpath=sys.path) +env3 = Environment(tools=toollist, toolpath=searchpaths) print("env3['Toolpath_TestTool1'] =", env3.get('Toolpath_TestTool1')) print("env3['Toolpath_TestTool2'] =", env3.get('Toolpath_TestTool2')) print("env3['Toolpath_TestTool1_1'] =", env3.get('Toolpath_TestTool1_1')) -- cgit v0.12 From ea3e100c14c462a380eca0e73fcd5afbec7b40fe Mon Sep 17 00:00:00 2001 From: William Deegan Date: Fri, 4 Aug 2017 17:34:13 -0700 Subject: Change required python version to 2.7 or above --- debian/changelog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index 0808546..90f3862 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,8 +1,8 @@ -scons (2.5.1) unstable; urgency=low +scons (__VERSION__) unstable; urgency=low * Maintenance Release - -- William Deegan Mon, 03 Nov 2016 13:37:42 -0700 + -- __DEVELOPER__ __DEB_DATE__ scons (2.5.0) unstable; urgency=low -- cgit v0.12 From eb9fd66f82ef92e178a3d3d9142c04272b5afb30 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Fri, 4 Aug 2017 17:35:13 -0700 Subject: Add DEB_DATE for producing debian style date for deb/changelog. Fix version string logic for producing .deb packages --- SConstruct | 14 +++++++++++--- debian/control | 2 +- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/SConstruct b/SConstruct index e92f10e..bfd12ca 100644 --- a/SConstruct +++ b/SConstruct @@ -41,6 +41,7 @@ import re import stat import sys import tempfile +import time import bootstrap @@ -98,9 +99,13 @@ zip = whereis('zip') # date = ARGUMENTS.get('DATE') if not date: - import time date = time.strftime("%Y/%m/%d %H:%M:%S", time.localtime(time.time())) +# Datestring for debian +# Should look like: Mon, 03 Nov 2016 13:37:42 -0700 +deb_date = time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime()) + + developer = ARGUMENTS.get('DEVELOPER') if not developer: for variable in ['USERNAME', 'LOGNAME', 'USER']: @@ -398,6 +403,8 @@ def SCons_revision(target, source, env): contents = contents.replace('__BUILDSYS' + '__', env['BUILDSYS']) contents = contents.replace('__COPYRIGHT' + '__', env['COPYRIGHT']) contents = contents.replace('__DATE' + '__', env['DATE']) + contents = contents.replace('__DEB_DATE' + '__', env['DEB_DATE']) + contents = contents.replace('__DEVELOPER' + '__', env['DEVELOPER']) contents = contents.replace('__FILE' + '__', str(source[0]).replace('\\', '/')) contents = contents.replace('__MONTH_YEAR'+ '__', env['MONTH_YEAR']) @@ -463,6 +470,7 @@ env = Environment( BUILDSYS = build_system, COPYRIGHT = copyright, DATE = date, + DEB_DATE = deb_date, DEVELOPER = developer, DISTDIR = os.path.join(build_dir, 'dist'), MONTH_YEAR = month_year, @@ -1046,9 +1054,9 @@ for p in [ scons ]: # Our Debian packaging builds directly into build/dist, # so we don't need to Install() the .debs. # The built deb is called just x.y.z, not x.y.z.final.0 so strip those off: - deb_version = '.'.join(version.split('.')[0:3]) + deb_version = version #'.'.join(version.split('.')[0:3]) deb = os.path.join(build_dir, 'dist', "%s_%s_all.deb" % (pkg, deb_version)) - # print("Building deb into %s (version=%s)"%(deb, deb_version)) + print("Building deb into %s (version=%s)"%(deb, deb_version)) for d in p['debian_deps']: b = env.SCons_revision(os.path.join(build, d), d) env.Depends(deb, b) diff --git a/debian/control b/debian/control index 5fbf0eb..d0a61fa 100644 --- a/debian/control +++ b/debian/control @@ -7,7 +7,7 @@ Standards-Version: 3.5.6 Package: scons Architecture: all -Depends: python (>> 2.4) +Depends: python (>> 2.7) Description: A replacement for Make SCons is an Open Source software construction tool--that is, a build tool; an improved substitute for the classic Make utility; a better -- cgit v0.12 From 3ed61160828b50e768c99fc70f41a6d115ea082f Mon Sep 17 00:00:00 2001 From: William Deegan Date: Fri, 4 Aug 2017 17:36:01 -0700 Subject: merged --- debian/changelog | 8 ++- src/engine/SCons/EnvironmentValues.py | 97 +++++++++++++++++++++++++++++++ src/engine/SCons/EnvironmentValuesTest.py | 16 +++++ 3 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 src/engine/SCons/EnvironmentValues.py create mode 100644 src/engine/SCons/EnvironmentValuesTest.py diff --git a/debian/changelog b/debian/changelog index 90f3862..4e7470d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -2,7 +2,13 @@ scons (__VERSION__) unstable; urgency=low * Maintenance Release - -- __DEVELOPER__ __DEB_DATE__ + -- __DEVELOPER__ __DATE__ + +scons (2.5.1) unstable; urgency=low + + * Maintenance Release + + -- William Deegan Mon, 03 Nov 2016 13:37:42 -0700 scons (2.5.0) unstable; urgency=low diff --git a/src/engine/SCons/EnvironmentValues.py b/src/engine/SCons/EnvironmentValues.py new file mode 100644 index 0000000..e2efccb --- /dev/null +++ b/src/engine/SCons/EnvironmentValues.py @@ -0,0 +1,97 @@ +import re + +_is_valid_var = re.compile(r'[_a-zA-Z]\w*$') + +_rm = re.compile(r'\$[()]') +_remove = re.compile(r'\$\([^\$]*(\$[^\)][^\$]*)*\$\)') + +# Regular expressions for splitting strings and handling substitutions, +# for use by the scons_subst() and scons_subst_list() functions: +# +# The first expression compiled matches all of the $-introduced tokens +# that we need to process in some way, and is used for substitutions. +# The expressions it matches are: +# +# "$$" +# "$(" +# "$)" +# "$variable" [must begin with alphabetic or underscore] +# "${any stuff}" +# +# The second expression compiled is used for splitting strings into tokens +# to be processed, and it matches all of the tokens listed above, plus +# the following that affect how arguments do or don't get joined together: +# +# " " [white space] +# "non-white-space" [without any dollar signs] +# "$" [single dollar sign] +# +_dollar_exps_str = r'\$[\$\(\)]|\$[_a-zA-Z][\.\w]*|\${[^}]*}' +_dollar_exps = re.compile(r'(%s)' % _dollar_exps_str) +_separate_args = re.compile(r'(%s|\s+|[^\s\$]+|\$)' % _dollar_exps_str) + +# This regular expression is used to replace strings of multiple white +# space characters in the string result from the scons_subst() function. +_space_sep = re.compile(r'[\t ]+(?![^{]*})') + +class ValueTypes(object): + """ + Enum to store what type of value the variable holds. + """ + UNKNOWN = 0 + STRING = 1 + CALLABLE = 2 + VARIABLE = 3 + + +class EnvironmentValue(object): + """ + Hold a single value. We're going to cache parsed version of the file + We're going to keep track of variables which feed into this values evaluation + """ + def __init__(self, value): + self.value = value + self.var_type = ValueTypes.UNKNOWN + + if callable(self.value): + self.var_type = ValueTypes.CALLABLE + else: + self.parse_value() + + + def parse_value(self): + """ + Scan the string and break into component values + """ + + try: + if '$' not in self.value: + self._parsed = self.value + self.var_type = ValueTypes.STRING + else: + # Now we need to parse the specified string + result = _dollar_exps.sub(sub_match, args) + print(result) + pass + except TypeError: + # likely callable? either way we don't parse + self._parsed = self.value + + def parse_trial(self): + """ + Try alternate parsing methods. + :return: + """ + parts = [] + for c in self.value: + + + +class EnvironmentValues(object): + """ + A class to hold all the environment variables + """ + def __init__(self, **kw): + self._dict = {} + for k in kw: + self._dict[k] = EnvironmentValue(kw[k]) diff --git a/src/engine/SCons/EnvironmentValuesTest.py b/src/engine/SCons/EnvironmentValuesTest.py new file mode 100644 index 0000000..58ee9cf --- /dev/null +++ b/src/engine/SCons/EnvironmentValuesTest.py @@ -0,0 +1,16 @@ +import unittest + +from SCons.EnvironmentValues import EnvironmentValues + +class MyTestCase(unittest.TestCase): + def test_simple_environmentValues(self): + """Test comparing SubstitutionEnvironments + """ + + env1 = EnvironmentValues(XXX='x') + env2 = EnvironmentValues(XXX='x',XX="$X", X1="${X}", X2="$($X$)") + + + +if __name__ == '__main__': + unittest.main() -- cgit v0.12 From 07f6e06d93b212b5c6aaf40067405dcc4d426d76 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 7 Aug 2017 11:17:13 -0700 Subject: refer to cxx SCons.Tool and not c++ --- src/engine/SCons/Tool/gxx.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engine/SCons/Tool/gxx.py b/src/engine/SCons/Tool/gxx.py index c5eb579..5bca179 100644 --- a/src/engine/SCons/Tool/gxx.py +++ b/src/engine/SCons/Tool/gxx.py @@ -41,7 +41,7 @@ import SCons.Tool import SCons.Util from . import gcc -cplusplus = __import__(__package__+'.c++', globals(), locals(), ['*']) +import cxx compilers = ['g++'] @@ -52,7 +52,7 @@ def generate(env): if 'CXX' not in env: env['CXX'] = env.Detect(compilers) or compilers[0] - cplusplus.generate(env) + cxx.generate(env) # platform specific settings if env['PLATFORM'] == 'aix': -- cgit v0.12 From bfebb4821ecd56a7fa99c9afe415d75bc1fa691f Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 7 Aug 2017 15:10:06 -0700 Subject: Pull Request contents P$ 489 from Steve Robinson. Manual edit/checkin because pull request was done to merge to 2.5.1 branch and not default. --- src/engine/SCons/Tool/MSCommon/common.py | 7 ++++ src/engine/SCons/Tool/MSCommon/vc.py | 55 +++++++++++++++++++++++++------- src/engine/SCons/Tool/MSCommon/vs.py | 11 +++++++ 3 files changed, 61 insertions(+), 12 deletions(-) diff --git a/src/engine/SCons/Tool/MSCommon/common.py b/src/engine/SCons/Tool/MSCommon/common.py index a846cfc..b60cd5b 100644 --- a/src/engine/SCons/Tool/MSCommon/common.py +++ b/src/engine/SCons/Tool/MSCommon/common.py @@ -130,6 +130,13 @@ def normalize_env(env, keys, force=False): if sys32_dir not in normenv['PATH']: normenv['PATH'] = normenv['PATH'] + os.pathsep + sys32_dir + # Without Wbem in PATH, vcvarsall.bat has a "'wmic' is not recognized" + # error starting with Visual Studio 2017, although the script still + # seems to work anyway. + sys32_wbem_dir = os.path.join(sys32_dir, 'Wbem') + if sys32_wbem_dir not in normenv['PATH']: + normenv['PATH'] = normenv['PATH'] + os.pathsep + sys32_wbem_dir + debug("PATH: %s"%normenv['PATH']) return normenv diff --git a/src/engine/SCons/Tool/MSCommon/vc.py b/src/engine/SCons/Tool/MSCommon/vc.py index 4126314..c76afac 100644 --- a/src/engine/SCons/Tool/MSCommon/vc.py +++ b/src/engine/SCons/Tool/MSCommon/vc.py @@ -37,6 +37,7 @@ __doc__ = """Module for Visual C/C++ detection and configuration. import SCons.compat import SCons.Util +import subprocess import os import platform from string import digits as string_digits @@ -135,9 +136,11 @@ 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 = ["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 = ["14.1", "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.1' : [ + (SCons.Util.HKEY_LOCAL_MACHINE, r'')], # Visual Studio 2017 doesn't set this registry key anymore '14.0' : [ (SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VisualStudio\14.0\Setup\VC\ProductDir')], '14.0Exp' : [ @@ -222,6 +225,29 @@ def is_host_target_supported(host_target, msvc_version): return True + +def find_vc_pdir_vswhere(msvc_version): + """ + Find the vswhere.exe install. + Run it asking for specified version and get MSVS install location + :param msvc_version: + :return: MSVC install dir + """ + vswhere_path = os.path.join( + 'C:\\', + 'Program Files (x86)', + 'Microsoft Visual Studio', + 'Installer', + 'vswhere.exe' + ) + vswhere_cmd = [vswhere_path, '-version', msvc_version, '-property', 'installationPath'] + + sp = subprocess.Popen(vswhere_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + vsdir, err = sp.communicate() + vc_pdir = os.path.join(vsdir.rstrip(), 'VC') + return vc_pdir + + def find_vc_pdir(msvc_version): """Try to find the product directory for the given version. @@ -240,16 +266,19 @@ def find_vc_pdir(msvc_version): for hkroot, key in hkeys: try: comps = None - if common.is_win64(): - try: - # ordinally at win64, try Wow6432Node first. - comps = common.read_reg(root + 'Wow6432Node\\' + key, hkroot) - except SCons.Util.WinError as 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) + if not key: + comps = find_vc_pdir_vswhere(msvc_version) + else: + if common.is_win64(): + try: + # ordinally at win64, try Wow6432Node first. + comps = common.read_reg(root + 'Wow6432Node\\' + key, hkroot) + except SCons.Util.WinError as 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 SCons.Util.WinError as e: debug('find_vc_dir(): no VC registry key {}'.format(repr(key))) else: @@ -281,8 +310,10 @@ def find_batch_file(env,msvc_version,host_arch,target_arch): elif vernum < 7: pdir = os.path.join(pdir, "Bin") batfilename = os.path.join(pdir, "vcvars32.bat") - else: # >= 8 + elif 8 <= vernum <= 14: batfilename = os.path.join(pdir, "vcvarsall.bat") + else: # vernum >= 14.1 VS2017 and above + batfilename = os.path.join(pdir, "Auxiliary", "Build", "vcvarsall.bat") if not os.path.exists(batfilename): debug("Not found: %s" % batfilename) diff --git a/src/engine/SCons/Tool/MSCommon/vs.py b/src/engine/SCons/Tool/MSCommon/vs.py index cff05d5..f9382fb 100644 --- a/src/engine/SCons/Tool/MSCommon/vs.py +++ b/src/engine/SCons/Tool/MSCommon/vs.py @@ -199,6 +199,17 @@ class VisualStudio(object): # Tool/MSCommon/vc.py, and the MSVC_VERSION documentation in Tool/msvc.xml. SupportedVSList = [ + # Visual Studio 2017 + VisualStudio('14.1', + vc_version='14.1', + sdk_version='10.0A', + hkeys=[], + common_tools_var='VS150COMNTOOLS', + executable_path=r'Common7\IDE\devenv.com', + batch_file_path=r'VC\Auxiliary\Build\vsvars32.bat', + supported_arch=['x86', 'amd64', "arm"], + ), + # Visual Studio 2015 VisualStudio('14.0', vc_version='14.0', -- cgit v0.12 From fbe80d5c70f497ed6aa4ae662cc1ace55d2cb8c1 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 7 Aug 2017 15:12:39 -0700 Subject: update with changes.txt info from PR 489 --- src/CHANGES.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index a5bfa31..b8c985e 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -63,6 +63,13 @@ may cause rebuilds. In no case should rebuilds not happen. From Rick Lupton: - Update LaTeX scanner to understand \import and related commands + From Steve Robinson: + - Add support for Visual Studio 2017. This support requires vswhere.exe a helper + tool installed with newer installs of 2017. SCons expects it to be located at + "C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" + It can be downloaded separately at + https://github.com/Microsoft/vswhere + From Paweł Tomulik: - Fixed the issue with LDMODULEVERSIONFLAGS reported by Tim Jennes (https://pairlist4.pair.net/pipermail/scons-users/2016-May/004893.html). -- cgit v0.12 From f54f0f9499c53f5f5981e9397beb288f027aec31 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 7 Aug 2017 15:56:07 -0700 Subject: PR #344 - Use set() where applicable. In many cases this can lead to performance improvements --- src/CHANGES.txt | 1 + src/engine/SCons/Environment.py | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index fd41a75..b0e88c7 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -55,6 +55,7 @@ may cause rebuilds. In no case should rebuilds not happen. From Alexey Klimkin: - Use memoization to optimize PATH evaluation across all dependencies per node. (PR #345) + - Use set() where it is applicable (PR #344) From M. Limber: - Fixed msvs.py for Visual Studio Express editions that would report diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py index 480a1d6..4f8e41b 100644 --- a/src/engine/SCons/Environment.py +++ b/src/engine/SCons/Environment.py @@ -167,7 +167,7 @@ def _set_SCANNERS(env, key, value): def _delete_duplicates(l, keep_last): """Delete duplicates from a sequence, keeping the first or last.""" - seen={} + seen=set() result=[] if keep_last: # reverse in & out, then keep first l.reverse() @@ -175,7 +175,7 @@ def _delete_duplicates(l, keep_last): try: if i not in seen: result.append(i) - seen[i]=1 + seen.add(i) except TypeError: # probably unhashable. Just keep it. result.append(i) -- cgit v0.12 From 550b3f5ae0cb41f83fa68774b8b86558bb7344f1 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 7 Aug 2017 19:19:44 -0700 Subject: Fix cxx import statement --- src/engine/SCons/Tool/gxx.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/SCons/Tool/gxx.py b/src/engine/SCons/Tool/gxx.py index 5bca179..574fd8e 100644 --- a/src/engine/SCons/Tool/gxx.py +++ b/src/engine/SCons/Tool/gxx.py @@ -41,7 +41,7 @@ import SCons.Tool import SCons.Util from . import gcc -import cxx +from . import cxx compilers = ['g++'] -- cgit v0.12 From 64b17052e19da0466cd3b488be650d2ad27f2422 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 7 Aug 2017 19:20:03 -0700 Subject: remove msvc from non windows platforms default list of compilers --- src/engine/SCons/Tool/__init__.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py index 1ab43e7..6408f8b 100644 --- a/src/engine/SCons/Tool/__init__.py +++ b/src/engine/SCons/Tool/__init__.py @@ -1172,12 +1172,12 @@ def tool_list(platform, env): ars = ['ar', 'mslib'] else: "prefer GNU tools on all other platforms" - linkers = ['gnulink', 'mslink', 'ilink'] - c_compilers = ['gcc', 'msvc', 'intelc', 'icc', 'cc'] - cxx_compilers = ['g++', 'msvc', 'intelc', 'icc', 'cxx'] + linkers = ['gnulink', 'ilink'] + c_compilers = ['gcc', 'intelc', 'icc', 'cc'] + cxx_compilers = ['g++', 'intelc', 'icc', 'cxx'] assemblers = ['gas', 'nasm', 'masm'] fortran_compilers = ['gfortran', 'g77', 'ifort', 'ifl', 'f95', 'f90', 'f77'] - ars = ['ar', 'mslib'] + ars = ['ar',] if not str(platform) == 'win32': other_plat_tools += ['m4', 'rpm'] -- cgit v0.12 From bc6d3c10beb08f217df7d9205e5fd678ca1338a7 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 7 Aug 2017 19:20:29 -0700 Subject: Fix VS2017 detection logic to fail properly when run on linux (posix) systems --- src/engine/SCons/Tool/MSCommon/vc.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/engine/SCons/Tool/MSCommon/vc.py b/src/engine/SCons/Tool/MSCommon/vc.py index c76afac..f8e72f5 100644 --- a/src/engine/SCons/Tool/MSCommon/vc.py +++ b/src/engine/SCons/Tool/MSCommon/vc.py @@ -242,10 +242,14 @@ def find_vc_pdir_vswhere(msvc_version): ) vswhere_cmd = [vswhere_path, '-version', msvc_version, '-property', 'installationPath'] - sp = subprocess.Popen(vswhere_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - vsdir, err = sp.communicate() - vc_pdir = os.path.join(vsdir.rstrip(), 'VC') - return vc_pdir + if os.path.exists(vswhere_path): + sp = subprocess.Popen(vswhere_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + vsdir, err = sp.communicate() + vc_pdir = os.path.join(vsdir.rstrip(), 'VC') + return vc_pdir + else: + # No vswhere on system, no install info available + return None def find_vc_pdir(msvc_version): @@ -268,6 +272,9 @@ def find_vc_pdir(msvc_version): comps = None if not key: comps = find_vc_pdir_vswhere(msvc_version) + if not comps: + debug('find_vc_dir(): no VC found via vswhere for version {}'.format(repr(key))) + raise SCons.Util.WinError else: if common.is_win64(): try: -- cgit v0.12 From 90f842616029050abffdabec078fe9a1f1b1d1a9 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 7 Aug 2017 19:22:50 -0700 Subject: fix comment for vswhere logic --- src/engine/SCons/Tool/MSCommon/vc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/SCons/Tool/MSCommon/vc.py b/src/engine/SCons/Tool/MSCommon/vc.py index f8e72f5..7c9eab5 100644 --- a/src/engine/SCons/Tool/MSCommon/vc.py +++ b/src/engine/SCons/Tool/MSCommon/vc.py @@ -228,7 +228,7 @@ def is_host_target_supported(host_target, msvc_version): def find_vc_pdir_vswhere(msvc_version): """ - Find the vswhere.exe install. + Find the MSVC product directory using vswhere.exe . Run it asking for specified version and get MSVS install location :param msvc_version: :return: MSVC install dir -- cgit v0.12