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 74207e0e31f375b33c313194ae64bcde459994f4 Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Mon, 12 Jun 2017 18:44:21 +0100 Subject: Remove the static lib builder creation in the D tools. --- src/engine/SCons/Tool/dmd.py | 2 -- src/engine/SCons/Tool/gdc.py | 2 -- src/engine/SCons/Tool/ldc.py | 2 -- 3 files changed, 6 deletions(-) diff --git a/src/engine/SCons/Tool/dmd.py b/src/engine/SCons/Tool/dmd.py index 64beea5..1becc14 100644 --- a/src/engine/SCons/Tool/dmd.py +++ b/src/engine/SCons/Tool/dmd.py @@ -144,8 +144,6 @@ def generate(env): env['DSHLIBVERSION'] = '$SHLIBVERSION' env['DSHLIBVERSIONFLAGS'] = [] - SCons.Tool.createStaticLibBuilder(env) - env['BUILDERS']['ProgramAllAtOnce'] = SCons.Builder.Builder( action='$DC $_DINCFLAGS $_DVERFLAGS $_DDEBUGFLAGS $_DFLAGS -of$TARGET $DLINKFLAGS $__DRPATH $SOURCES $_DLIBDIRFLAGS $_DLIBFLAGS', emitter=DCommon.allAtOnceEmitter, diff --git a/src/engine/SCons/Tool/gdc.py b/src/engine/SCons/Tool/gdc.py index fdfe867..fc844aa 100644 --- a/src/engine/SCons/Tool/gdc.py +++ b/src/engine/SCons/Tool/gdc.py @@ -128,8 +128,6 @@ def generate(env): env['DSHLIBVERSION'] = '$SHLIBVERSION' env['DSHLIBVERSIONFLAGS'] = '$SHLIBVERSIONFLAGS' - SCons.Tool.createStaticLibBuilder(env) - env['BUILDERS']['ProgramAllAtOnce'] = SCons.Builder.Builder( action='$DC $_DINCFLAGS $_DVERFLAGS $_DDEBUGFLAGS $_DFLAGS -o $TARGET $DLINKFLAGS $__DRPATH $SOURCES $_DLIBDIRFLAGS $_DLIBFLAGS', emitter=DCommon.allAtOnceEmitter, diff --git a/src/engine/SCons/Tool/ldc.py b/src/engine/SCons/Tool/ldc.py index 215c3e7..dfa2d70 100644 --- a/src/engine/SCons/Tool/ldc.py +++ b/src/engine/SCons/Tool/ldc.py @@ -147,8 +147,6 @@ def generate(env): env['DSHLIBVERSION'] = '$SHLIBVERSION' env['DSHLIBVERSIONFLAGS'] = [] - SCons.Tool.createStaticLibBuilder(env) - env['BUILDERS']['ProgramAllAtOnce'] = SCons.Builder.Builder( action='$DC $_DINCFLAGS $_DVERFLAGS $_DDEBUGFLAGS $_DFLAGS -of=$TARGET $DLINKFLAGS $__DRPATH $SOURCES $_DLIBDIRFLAGS $_DLIBFLAGS', emitter=DCommon.allAtOnceEmitter, -- cgit v0.12 From 23433f501b055457cc82ed8536af48cd08ebf219 Mon Sep 17 00:00:00 2001 From: grbd Date: Tue, 13 Jun 2017 14:23:08 +0100 Subject: Added support for nested tools --- src/engine/SCons/Tool/__init__.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py index 61b7788..e15c2f3 100644 --- a/src/engine/SCons/Tool/__init__.py +++ b/src/engine/SCons/Tool/__init__.py @@ -118,6 +118,16 @@ class Tool(object): if hasattr(module, 'options'): self.options = module.options + def _load_dotted_module(self, short_name, full_name, searchpaths=None): + splitname = short_name.split('.') + index = 0 + srchpths = searchpaths + for item in splitname: + file, path, desc = imp.find_module(item, srchpths) + mod = imp.load_module(full_name, file, path, desc) + srchpths = [path] + return mod, file + def _tool_module(self): oldpythonpath = sys.path sys.path = self.toolpath + sys.path @@ -127,10 +137,10 @@ class Tool(object): # Py 2 code try: try: - file, path, desc = imp.find_module(self.name, self.toolpath) + file = None try: - return imp.load_module(self.name, file, path, desc) - + mod, file = self._load_dotted_module(self.name, self.name, self.toolpath) + return mod finally: if file: file.close() @@ -231,8 +241,7 @@ class Tool(object): try: smpath = sys.modules['SCons.Tool'].__path__ try: - file, path, desc = imp.find_module(self.name, smpath) - module = imp.load_module(full_name, file, path, desc) + module, file = self._load_dotted_module(self.name, full_name, smpath) setattr(SCons.Tool, self.name, module) if file: file.close() -- cgit v0.12 From e38f013a4006c6734d57057258b96ce1367554f0 Mon Sep 17 00:00:00 2001 From: grbd Date: Wed, 14 Jun 2017 02:08:48 +0100 Subject: Fix the loading of tools where the tool is a package instead of a module --- src/engine/SCons/Tool/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py index e15c2f3..7eac0e0 100644 --- a/src/engine/SCons/Tool/__init__.py +++ b/src/engine/SCons/Tool/__init__.py @@ -189,6 +189,7 @@ class Tool(object): if debug: print("file_Path:%s FOUND"%file_path) break elif os.path.isdir(file_package): + file_package = os.path.join(file_package, '__init__.py') spec = importlib.util.spec_from_file_location(self.name, file_package) if debug: print("PACKAGE:%s Found"%file_package) break -- cgit v0.12 From a96ff49dee3669b25888e138916b6bb06c6dc363 Mon Sep 17 00:00:00 2001 From: grbd Date: Wed, 14 Jun 2017 02:26:58 +0100 Subject: Nested Tool support under python 3 --- src/engine/SCons/Tool/__init__.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py index 7eac0e0..876b1d2 100644 --- a/src/engine/SCons/Tool/__init__.py +++ b/src/engine/SCons/Tool/__init__.py @@ -118,7 +118,7 @@ class Tool(object): if hasattr(module, 'options'): self.options = module.options - def _load_dotted_module(self, short_name, full_name, searchpaths=None): + def _load_dotted_module_py2(self, short_name, full_name, searchpaths=None): splitname = short_name.split('.') index = 0 srchpths = searchpaths @@ -139,7 +139,7 @@ class Tool(object): try: file = None try: - mod, file = self._load_dotted_module(self.name, self.name, self.toolpath) + mod, file = self._load_dotted_module_py2(self.name, self.name, self.toolpath) return mod finally: if file: @@ -179,8 +179,9 @@ class Tool(object): found_name = self.name add_to_scons_tools_namespace = False for path in self.toolpath: - file_path = os.path.join(path, "%s.py"%self.name) - file_package = os.path.join(path, self.name) + sepname = self.name.replace('.', os.path.sep) + file_path = os.path.join(path, "%s.py"%sepname) + file_package = os.path.join(path, sepname) if debug: sys.stderr.write("Trying:%s %s\n"%(file_path, file_package)) @@ -242,7 +243,7 @@ class Tool(object): try: smpath = sys.modules['SCons.Tool'].__path__ try: - module, file = self._load_dotted_module(self.name, full_name, smpath) + module, file = self._load_dotted_module_py2(self.name, full_name, smpath) setattr(SCons.Tool, self.name, module) if file: file.close() -- cgit v0.12 From 87649e791c9241c2bf6149a16d780d525016afed Mon Sep 17 00:00:00 2001 From: grbd Date: Wed, 14 Jun 2017 19:07:44 +0100 Subject: Additional fix for nested tools under python2 --- src/engine/SCons/Tool/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py index 876b1d2..e5b4b05 100644 --- a/src/engine/SCons/Tool/__init__.py +++ b/src/engine/SCons/Tool/__init__.py @@ -145,7 +145,8 @@ class Tool(object): if file: file.close() except ImportError as e: - if str(e)!="No module named %s"%self.name: + splitname = self.name.split('.') + if str(e)!="No module named %s"%splitname[0]: raise SCons.Errors.EnvironmentError(e) try: import zipimport -- cgit v0.12 From 3015cd81aefb131028d00b9163155f6039f1e865 Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Sat, 17 Jun 2017 15:29:50 +0100 Subject: DMD and LDC do now support shared objects on MacOS. A couple of corrections. --- test/D/SharedObjects/Common/common.py | 5 +---- test/D/SharedObjects/Image/SConstruct_template | 7 ++----- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/test/D/SharedObjects/Common/common.py b/test/D/SharedObjects/Common/common.py index 0322385..a46ea7e 100644 --- a/test/D/SharedObjects/Common/common.py +++ b/test/D/SharedObjects/Common/common.py @@ -63,9 +63,6 @@ def testForTool(tool): elif platform == 'darwin': filename = 'code.o' libraryname = 'libanswer.dylib' - # As at 2014-09-14, DMD 2.066, LDC master head, and GDC 4.9.1 do not support - # shared libraries on OSX. - test.skip_test('Dynamic libraries not yet supported on OSX.\n') elif platform == 'win32': filename = 'code.obj' libraryname = 'answer.dll' @@ -75,7 +72,7 @@ def testForTool(tool): test.dir_fixture('Image') test.write('SConstruct', open('SConstruct_template', 'r').read().format(tool)) - if tool == 'dmd': + if Base()['DC'] == 'gdmd': # The gdmd executable in Debian Unstable as at 2012-05-12, version 4.6.3 puts out messages on stderr # that cause inappropriate failure of the tests, so simply ignore them. test.run(stderr=None) diff --git a/test/D/SharedObjects/Image/SConstruct_template b/test/D/SharedObjects/Image/SConstruct_template index cae8713..d263e63 100644 --- a/test/D/SharedObjects/Image/SConstruct_template +++ b/test/D/SharedObjects/Image/SConstruct_template @@ -1,10 +1,7 @@ # -*- mode:python; coding:utf-8; -*- -import os - environment = Environment( - tools=['{}', 'link']) - -environment['ENV']['HOME'] = os.environ['HOME'] # Hack for gdmd + tools=['{0}', 'link'] +) environment.SharedLibrary('answer', 'code.d') -- cgit v0.12 From f57360b60c20eacb2b39485a3986a79a823a2e67 Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Sat, 17 Jun 2017 15:40:47 +0100 Subject: Always provide a value for DC, never leave it unset: Detect can fail to find an executable. --- src/engine/SCons/Tool/dmd.py | 2 +- src/engine/SCons/Tool/gdc.py | 2 +- src/engine/SCons/Tool/ldc.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/engine/SCons/Tool/dmd.py b/src/engine/SCons/Tool/dmd.py index 64beea5..783640b 100644 --- a/src/engine/SCons/Tool/dmd.py +++ b/src/engine/SCons/Tool/dmd.py @@ -75,7 +75,7 @@ def generate(env): static_obj.add_emitter('.d', SCons.Defaults.StaticObjectEmitter) shared_obj.add_emitter('.d', SCons.Defaults.SharedObjectEmitter) - env['DC'] = env.Detect(['dmd', 'gdmd']) + env['DC'] = env.Detect(['dmd', 'ldmd2', 'gdmd']) or 'dmd' env['DCOM'] = '$DC $_DINCFLAGS $_DVERFLAGS $_DDEBUGFLAGS $_DFLAGS -c -of$TARGET $SOURCES' env['_DINCFLAGS'] = '${_concat(DINCPREFIX, DPATH, DINCSUFFIX, __env__, RDirs, TARGET, SOURCE)}' env['_DVERFLAGS'] = '${_concat(DVERPREFIX, DVERSIONS, DVERSUFFIX, __env__)}' diff --git a/src/engine/SCons/Tool/gdc.py b/src/engine/SCons/Tool/gdc.py index fdfe867..f519428 100644 --- a/src/engine/SCons/Tool/gdc.py +++ b/src/engine/SCons/Tool/gdc.py @@ -65,7 +65,7 @@ def generate(env): static_obj.add_emitter('.d', SCons.Defaults.StaticObjectEmitter) shared_obj.add_emitter('.d', SCons.Defaults.SharedObjectEmitter) - env['DC'] = env.Detect('gdc') + env['DC'] = 'gdc' env['DCOM'] = '$DC $_DINCFLAGS $_DVERFLAGS $_DDEBUGFLAGS $_DFLAGS -c -o $TARGET $SOURCES' env['_DINCFLAGS'] = '${_concat(DINCPREFIX, DPATH, DINCSUFFIX, __env__, RDirs, TARGET, SOURCE)}' env['_DVERFLAGS'] = '${_concat(DVERPREFIX, DVERSIONS, DVERSUFFIX, __env__)}' diff --git a/src/engine/SCons/Tool/ldc.py b/src/engine/SCons/Tool/ldc.py index 215c3e7..7e5d339 100644 --- a/src/engine/SCons/Tool/ldc.py +++ b/src/engine/SCons/Tool/ldc.py @@ -70,7 +70,7 @@ def generate(env): static_obj.add_emitter('.d', SCons.Defaults.StaticObjectEmitter) shared_obj.add_emitter('.d', SCons.Defaults.SharedObjectEmitter) - env['DC'] = env.Detect('ldc2') + env['DC'] = 'ldc2' env['DCOM'] = '$DC $_DINCFLAGS $_DVERFLAGS $_DDEBUGFLAGS $_DFLAGS -c -of=$TARGET $SOURCES' env['_DINCFLAGS'] = '${_concat(DINCPREFIX, DPATH, DINCSUFFIX, __env__, RDirs, TARGET, SOURCE)}' env['_DVERFLAGS'] = '${_concat(DVERPREFIX, DVERSIONS, DVERSUFFIX, __env__)}' -- cgit v0.12 From 9457abb8761928c02c68a1b923bbc16fda9bb2bd Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Sun, 18 Jun 2017 15:14:54 +0100 Subject: LDC does not automatically include the druntime library as dmd does. --- src/engine/SCons/Tool/ldc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/SCons/Tool/ldc.py b/src/engine/SCons/Tool/ldc.py index 7e5d339..ecc3b9e 100644 --- a/src/engine/SCons/Tool/ldc.py +++ b/src/engine/SCons/Tool/ldc.py @@ -111,7 +111,7 @@ def generate(env): env['DSHLINKFLAGS'] = SCons.Util.CLVar('$DLINKFLAGS -shared -defaultlib=phobos-ldc') #### END DEPRECATION 2017-05-21 - env['SHDLINKCOM'] = '$DLINK -of=$TARGET $DSHLINKFLAGS $__DSHLIBVERSIONFLAGS $__DRPATH $SOURCES $_DLIBDIRFLAGS $_DLIBFLAGS' + env['SHDLINKCOM'] = '$DLINK -of=$TARGET $DSHLINKFLAGS $__DSHLIBVERSIONFLAGS $__DRPATH $SOURCES $_DLIBDIRFLAGS $_DLIBFLAGS -L-ldruntime-ldc' env['DLIBLINKPREFIX'] = '' if env['PLATFORM'] == 'win32' else '-L-l' env['DLIBLINKSUFFIX'] = '.lib' if env['PLATFORM'] == 'win32' else '' -- cgit v0.12 From 5729b712bb37571a870f5c3e12a99fddfbf18536 Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Sun, 18 Jun 2017 17:31:56 +0100 Subject: Correct the rpath prefix for LDC on Darwin. --- src/engine/SCons/Tool/ldc.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engine/SCons/Tool/ldc.py b/src/engine/SCons/Tool/ldc.py index 7e5d339..dc56ad8 100644 --- a/src/engine/SCons/Tool/ldc.py +++ b/src/engine/SCons/Tool/ldc.py @@ -111,7 +111,7 @@ def generate(env): env['DSHLINKFLAGS'] = SCons.Util.CLVar('$DLINKFLAGS -shared -defaultlib=phobos-ldc') #### END DEPRECATION 2017-05-21 - env['SHDLINKCOM'] = '$DLINK -of=$TARGET $DSHLINKFLAGS $__DSHLIBVERSIONFLAGS $__DRPATH $SOURCES $_DLIBDIRFLAGS $_DLIBFLAGS' + env['SHDLINKCOM'] = '$DLINK -of=$TARGET $DSHLINKFLAGS $__DSHLIBVERSIONFLAGS $__DRPATH $SOURCES $_DLIBDIRFLAGS $_DLIBFLAGS -L-ldruntime-ldc' env['DLIBLINKPREFIX'] = '' if env['PLATFORM'] == 'win32' else '-L-l' env['DLIBLINKSUFFIX'] = '.lib' if env['PLATFORM'] == 'win32' else '' @@ -132,7 +132,7 @@ def generate(env): # __RPATH is set to $_RPATH in the platform specification if that # platform supports it. - env['DRPATHPREFIX'] = '-L-rpath=' + env['DRPATHPREFIX'] = '-L-Wl,-rpath,' if env['PLATFORM'] == 'darwin' else '-L-rpath=' env['DRPATHSUFFIX'] = '' env['_DRPATH'] = '${_concat(DRPATHPREFIX, RPATH, DRPATHSUFFIX, __env__)}' -- cgit v0.12 From 04796d463904ce278ed09e58517467d8047945f8 Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Sun, 18 Jun 2017 17:35:25 +0100 Subject: Attempt a fix for dmd rpath on OSX. --- src/engine/SCons/Tool/dmd.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/SCons/Tool/dmd.py b/src/engine/SCons/Tool/dmd.py index 783640b..813f949 100644 --- a/src/engine/SCons/Tool/dmd.py +++ b/src/engine/SCons/Tool/dmd.py @@ -129,7 +129,7 @@ def generate(env): # __RPATH is set to $_RPATH in the platform specification if that # platform supports it. - env['DRPATHPREFIX'] = '-L-rpath=' + env['DRPATHPREFIX'] = '-L-rpath,' if env['PLATFORM'] == 'darwin' else '-L-rpath=' env['DRPATHSUFFIX'] = '' env['_DRPATH'] = '${_concat(DRPATHPREFIX, RPATH, DRPATHSUFFIX, __env__)}' -- cgit v0.12 From b3c1a8d197c0353206f14782921e27d3534ec1e3 Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Sun, 18 Jun 2017 17:35:47 +0100 Subject: LDC shared libraries work on OSX. --- test/D/Issues/2940_Ariovistus/Common/correctLinkOptions.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test/D/Issues/2940_Ariovistus/Common/correctLinkOptions.py b/test/D/Issues/2940_Ariovistus/Common/correctLinkOptions.py index 8060add..2bcff1e 100644 --- a/test/D/Issues/2940_Ariovistus/Common/correctLinkOptions.py +++ b/test/D/Issues/2940_Ariovistus/Common/correctLinkOptions.py @@ -50,11 +50,10 @@ def testForTool(tool): libraryname = 'libstuff.so' filename = 'stuff.os' elif platform == 'darwin': + if tool == 'gdc': + test.skip_test('Dynamic libraries not yet supported by dmd and gdc on OSX.\n') libraryname = 'libstuff.dylib' filename = 'stuff.os' - # As at 2014-09-14, DMD 2.066, LDC master head, and GDC 4.9.1 do not support - # shared libraries on OSX. - test.skip_test('Dynamic libraries not yet supported on OSX.\n') elif platform == 'win32': libraryname = 'stuff.dll' filename = 'stuff.obj' -- cgit v0.12 From fda72fd3c1516012ff9d04fb260037fd1bc16abc Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Sun, 18 Jun 2017 19:04:54 +0100 Subject: Remove DMD from the tests on OSX till the correct rpath option is discovered. --- test/D/Issues/2940_Ariovistus/Common/correctLinkOptions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/D/Issues/2940_Ariovistus/Common/correctLinkOptions.py b/test/D/Issues/2940_Ariovistus/Common/correctLinkOptions.py index 2bcff1e..5acd26a 100644 --- a/test/D/Issues/2940_Ariovistus/Common/correctLinkOptions.py +++ b/test/D/Issues/2940_Ariovistus/Common/correctLinkOptions.py @@ -50,7 +50,7 @@ def testForTool(tool): libraryname = 'libstuff.so' filename = 'stuff.os' elif platform == 'darwin': - if tool == 'gdc': + if tool == 'dmd' or tool == 'gdc': test.skip_test('Dynamic libraries not yet supported by dmd and gdc on OSX.\n') libraryname = 'libstuff.dylib' filename = 'stuff.os' -- cgit v0.12 From a25367b4f6151a7888b9446e45e234ed84c9a163 Mon Sep 17 00:00:00 2001 From: grbd Date: Mon, 19 Jun 2017 15:45:03 +0100 Subject: Updated the documentation for nested tools located within subdirs --- doc/man/scons.xml | 16 +++++++++++++++ doc/user/builders-writing.xml | 47 +++++++++++++++++++++++++++++++++++++++++++ src/CHANGES.txt | 4 ++++ 3 files changed, 67 insertions(+) diff --git a/doc/man/scons.xml b/doc/man/scons.xml index b68f27a..3268860 100644 --- a/doc/man/scons.xml +++ b/doc/man/scons.xml @@ -2187,6 +2187,22 @@ platform name when the Environment is constructed. Changing the PATH variable after the Environment is constructed will not cause the tools to be redetected. + One feature now present within Scons is the ability to have nested tools. +Tools which can be located within a subdirectory in the toolpath. +With a nested tool name the dot represents a directory seperator + + +# namespaced builder +env = Environment(ENV = os.environ, tools = ['SubDir1.SubDir2.SomeTool']) +env.SomeTool(targets, sources) + +# Search Paths +# SCons\Tool\SubDir1\SubDir2\SomeTool.py +# SCons\Tool\SubDir1\SubDir2\SomeTool\__init__.py +# .\site_scons\site_tools\SubDir1\SubDir2\SomeTool.py +# .\site_scons\site_tools\SubDir1\SubDir2\SomeTool\__init__.py + + SCons supports the following tool specifications out of the box: diff --git a/doc/user/builders-writing.xml b/doc/user/builders-writing.xml index 07f2dec..35dd989 100644 --- a/doc/user/builders-writing.xml +++ b/doc/user/builders-writing.xml @@ -880,6 +880,53 @@ env2.Foo('file2') +
+ Nested and namespace builders; + + + &SCons; now supports the ability for a Builder to be located within a sub-directory of the toolpath. + This is similar to namespacing within python. + + Normally when loading a tool into the environment, scons will search for the tool within two locations + + + +# Regular non namespace target +env = Environment(ENV = os.environ, tools = ['SomeTool']) +env.SomeTool(targets, sources) + + + + The locations would include + SCons\Tool\SomeTool.py + SCons\Tool\SomeTool\__init__.py + .\site_scons\site_tools\SomeTool.py + .\site_scons\site_tools\SomeTool\__init__.py + + If a toolpath is specified this is also searched as well. + With nested or namespaced tools we can use the dot notation to specify a sub-directoty that the tool is located under + + + +# namespaced target +env = Environment(ENV = os.environ, tools = ['SubDir1.SubDir2.SomeTool']) +env.SomeTool(targets, sources) + + + + With this example the search locations would include + SCons\Tool\SubDir1\SubDir2\SomeTool.py + SCons\Tool\SubDir1\SubDir2\SomeTool\__init__.py + .\site_scons\site_tools\SubDir1\SubDir2\SomeTool.py + .\site_scons\site_tools\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 however. + This is the same constraint used by python when loading modules from within sub-directories (packages). + + +
+ + + +%scons; + +%builders-mod; + +%functions-mod; + +%tools-mod; + +%variables-mod; +]> + + + + + + +Set construction variables for the Clang C++ compiler. + + + +CXX +SHCXXFLAGS + +SHOBJSUFFIX +CXXVERSION + + + + diff --git a/src/engine/SCons/Tool/clang.py b/src/engine/SCons/Tool/clang.py new file mode 100644 index 0000000..3075c46 --- /dev/null +++ b/src/engine/SCons/Tool/clang.py @@ -0,0 +1,83 @@ +# -*- encoding: utf-8 -*- + +"""SCons.Tool.clang + +Tool-specific initialization for clang. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +# __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +# Based on SCons/Tool/gcc.py by Paweł Tomulik 2014 as a separate tool. +# Brought into the SCons mainline by Russel Winder 2017. + +import os +import re +import subprocess +import sys + +import SCons.Util +import SCons.Tool.cc + +compilers = ['clang'] + +def generate(env): + """Add Builders and construction variables for clang to an Environment.""" + SCons.Tool.cc.generate(env) + + env['CC'] = env.Detect(compilers) or 'clang' + 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 + # clang -dumpversion is of no use + line = pipe.stdout.readline() + if sys.version_info[0] > 2: + line = line.decode() + match = re.search(r'clang +version +([0-9]+(?:\.[0-9]+)+)', line) + if match: + env['CCVERSION'] = match.group(1) + +def exists(env): + return env.Detect(compilers) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/clang.xml b/src/engine/SCons/Tool/clang.xml new file mode 100644 index 0000000..e2e50d4 --- /dev/null +++ b/src/engine/SCons/Tool/clang.xml @@ -0,0 +1,39 @@ + + + + +%scons; + +%builders-mod; + +%functions-mod; + +%tools-mod; + +%variables-mod; +]> + + + + + + +Set construction variables for the Clang C compiler. + + + +CC +SHCCFLAGS +CCVERSION + + + + diff --git a/test/Clang/clang++_default_environment.py b/test/Clang/clang++_default_environment.py new file mode 100644 index 0000000..beef1e5 --- /dev/null +++ b/test/Clang/clang++_default_environment.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import TestSCons + +_exe = TestSCons._exe +test = TestSCons.TestSCons() + +if not test.where_is('clang'): + test.skip_test("Could not find 'clang++', skipping test.\n") + +## This will likely NOT use clang++. + +test.write('SConstruct', """\ +env = Environment() +if env['CXX'] != 'clang++': + env['CXX'] = 'clang++' +env.Program('foo.cpp') +""") + +test.write('foo.cpp', """\ +#include +int main(int argc, char ** argv) { + std::cout << "Hello!" << std::endl; + return 0; +} +""") + +test.run() + +test.run(program=test.workpath('foo'+_exe)) + +test.fail_test(not test.stdout() == 'Hello!\n') + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/Clang/clang++_shared_library.py b/test/Clang/clang++_shared_library.py new file mode 100644 index 0000000..d850c98 --- /dev/null +++ b/test/Clang/clang++_shared_library.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 TestSCons + +_exe = TestSCons._exe +test = TestSCons.TestSCons() + +if not test.where_is('clang'): + test.skip_test("Could not find 'clang++', skipping test.\n") + +test.write('SConstruct', """\ +env = Environment(tools=['clang++', 'link']) +env.SharedLibrary('foo', 'foo.cpp') +""") + +test.write('foo.cpp', """\ +int bar() { + return 42; +} +""") + +test.run() + +test.must_exist(test.workpath('libfoo.so')) + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/Clang/clang++_specific_environment.py b/test/Clang/clang++_specific_environment.py new file mode 100644 index 0000000..773fa94 --- /dev/null +++ b/test/Clang/clang++_specific_environment.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import TestSCons + +_exe = TestSCons._exe +test = TestSCons.TestSCons() + +if not test.where_is('clang'): + test.skip_test("Could not find 'clang++', skipping test.\n") + +test.write('SConstruct', """\ +env = Environment(tools=['clang++', 'link']) +env.Program('foo.cpp') +""") + +test.write('foo.cpp', """\ +#include +int main(int argc, char ** argv) { + std::cout << "Hello!" << std::endl; + return 0; +} +""") + +test.run() + +test.run(program=test.workpath('foo'+_exe)) + +test.fail_test(not test.stdout() == 'Hello!\n') + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/Clang/clang++_static_library.py b/test/Clang/clang++_static_library.py new file mode 100644 index 0000000..77ea58e --- /dev/null +++ b/test/Clang/clang++_static_library.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 TestSCons + +_exe = TestSCons._exe +test = TestSCons.TestSCons() + +if not test.where_is('clang'): + test.skip_test("Could not find 'clang++', skipping test.\n") + +test.write('SConstruct', """\ +env = Environment(tools=['clang++', 'ar']) +env.StaticLibrary('foo', 'foo.cpp') +""") + +test.write('foo.cpp', """\ +int bar() { + return 42; +} +""") + +test.run() + +test.must_exist(test.workpath('libfoo.a')) + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/Clang/clang_default_environment.py b/test/Clang/clang_default_environment.py new file mode 100644 index 0000000..4ac1c68 --- /dev/null +++ b/test/Clang/clang_default_environment.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import TestSCons + +_exe = TestSCons._exe +test = TestSCons.TestSCons() + +if not test.where_is('clang'): + test.skip_test("Could not find 'clang', skipping test.\n") + +## This will likely NOT use clang + +test.write('SConstruct', """ +env = Environment() +if env['CC'] != 'clang': + env['CC'] = 'clang' +env.Program('foo.c') +""") + +test.write('foo.c', """\ +#include +int main(int argc, char ** argv) { + printf("Hello!"); + return 0; +} +""") + +test.run() + +test.run(program=test.workpath('foo'+_exe)) + +test.fail_test(not test.stdout() == 'Hello!') + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/Clang/clang_shared_library.py b/test/Clang/clang_shared_library.py new file mode 100644 index 0000000..a0a112a --- /dev/null +++ b/test/Clang/clang_shared_library.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 TestSCons + +_exe = TestSCons._exe +test = TestSCons.TestSCons() + +if not test.where_is('clang'): + test.skip_test("Could not find 'clang', skipping test.\n") + +test.write('SConstruct', """\ +env = Environment(tools=['clang', 'link']) +env.SharedLibrary('foo', 'foo.c') +""") + +test.write('foo.c', """\ +int bar() { + return 42; +} +""") + +test.run() + +test.must_exist(test.workpath('libfoo.so')) + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/Clang/clang_specific_environment.py b/test/Clang/clang_specific_environment.py new file mode 100644 index 0000000..7266a9f --- /dev/null +++ b/test/Clang/clang_specific_environment.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import TestSCons + +_exe = TestSCons._exe +test = TestSCons.TestSCons() + +if not test.where_is('clang'): + test.skip_test("Could not find 'clang', skipping test.\n") + +test.write('SConstruct', """\ +env = Environment(tools=['clang', 'link']) +env.Program('foo.c') +""") + +test.write('foo.c', """\ +#include +int main(int argc, char ** argv) { + printf("Hello!"); + return 0; +} +""") + +test.run() + +test.run(program=test.workpath('foo'+_exe)) + +test.fail_test(not test.stdout() == 'Hello!') + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/Clang/clang_static_library.py b/test/Clang/clang_static_library.py new file mode 100644 index 0000000..39e9931 --- /dev/null +++ b/test/Clang/clang_static_library.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 TestSCons + +_exe = TestSCons._exe +test = TestSCons.TestSCons() + +if not test.where_is('clang'): + test.skip_test("Could not find 'clang', skipping test.\n") + +test.write('SConstruct', """\ +env = Environment(tools=['clang', 'ar']) +env.StaticLibrary('foo', 'foo.c') +""") + +test.write('foo.c', """\ +int bar() { + return 42; +} +""") + +test.run() + +test.must_exist(test.workpath('libfoo.a')) + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: -- cgit v0.12 From 1f1871896e0de86e40135bedf519374d65bbde2e Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Wed, 21 Jun 2017 16:40:40 +0100 Subject: Be more careful about the shared library names. --- test/Clang/clang++_shared_library.py | 18 +++++++++++++++++- test/Clang/clang_shared_library.py | 17 ++++++++++++++++- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/test/Clang/clang++_shared_library.py b/test/Clang/clang++_shared_library.py index d850c98..d6337ba 100644 --- a/test/Clang/clang++_shared_library.py +++ b/test/Clang/clang++_shared_library.py @@ -26,12 +26,27 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import TestSCons +from SCons.Environment import Base + _exe = TestSCons._exe test = TestSCons.TestSCons() if not test.where_is('clang'): test.skip_test("Could not find 'clang++', skipping test.\n") +platform = Base()['PLATFORM'] +if platform == 'posix': + filename = 'foo.os' + libraryname = 'libfoo.so' +elif platform == 'darwin': + filename = 'foo.os' + libraryname = 'libfoo.dylib' +elif platform == 'win32': + filename = 'foo.obj' + libraryname = 'foo.dll' +else: + test.fail_test() + test.write('SConstruct', """\ env = Environment(tools=['clang++', 'link']) env.SharedLibrary('foo', 'foo.cpp') @@ -45,7 +60,8 @@ int bar() { test.run() -test.must_exist(test.workpath('libfoo.so')) +test.must_exist(test.workpath(filename)) +test.must_exist(test.workpath(libraryname)) test.pass_test() diff --git a/test/Clang/clang_shared_library.py b/test/Clang/clang_shared_library.py index a0a112a..5e4d36f 100644 --- a/test/Clang/clang_shared_library.py +++ b/test/Clang/clang_shared_library.py @@ -25,6 +25,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import TestSCons +from SCons.Environment import Base _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -32,6 +33,19 @@ test = TestSCons.TestSCons() if not test.where_is('clang'): test.skip_test("Could not find 'clang', skipping test.\n") +platform = Base()['PLATFORM'] +if platform == 'posix': + filename = 'foo.os' + libraryname = 'libfoo.so' +elif platform == 'darwin': + filename = 'foo.os' + libraryname = 'libfoo.dylib' +elif platform == 'win32': + filename = 'foo.obj' + libraryname = 'foo.dll' +else: + test.fail_test() + test.write('SConstruct', """\ env = Environment(tools=['clang', 'link']) env.SharedLibrary('foo', 'foo.c') @@ -45,7 +59,8 @@ int bar() { test.run() -test.must_exist(test.workpath('libfoo.so')) +test.must_exist(test.workpath(filename)) +test.must_exist(test.workpath(libraryname)) test.pass_test() -- cgit v0.12 From b6e8b657acfdfcbf3672b7c5894bf2166ab0a0c7 Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Wed, 21 Jun 2017 16:49:57 +0100 Subject: Update the CHANGES.txt file. --- src/CHANGES.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 745c69d..9966229 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -82,6 +82,7 @@ RELEASE 3.0.0.alpha.20170614 - Mon, 14 Jun 2017 12:23:56 -0400 - Remove establishing the SharedLibrary builder in the dmd, ldc, and gdc tools, must now include the ar tool to get this builder as is required for other compiler tools. + - Add clang and clang++ tools based on Paweł Tomulik's work. RELEASE 2.5.1 - Mon, 03 Nov 2016 13:37:42 -0400 -- cgit v0.12 From 5c58fce9cf4e0fc3e8d0f44ec9181700f1380092 Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Wed, 21 Jun 2017 17:47:21 +0100 Subject: Change the name of the tool to avoid + in filename. Add alias so clang++ still works as a tool name. --- src/engine/SCons/Tool/__init__.py | 5 ++- src/engine/SCons/Tool/clang++.py | 92 --------------------------------------- src/engine/SCons/Tool/clang++.xml | 41 ----------------- src/engine/SCons/Tool/clangxx.py | 91 ++++++++++++++++++++++++++++++++++++++ src/engine/SCons/Tool/clangxx.xml | 41 +++++++++++++++++ 5 files changed, 136 insertions(+), 134 deletions(-) delete mode 100644 src/engine/SCons/Tool/clang++.py delete mode 100644 src/engine/SCons/Tool/clang++.xml create mode 100644 src/engine/SCons/Tool/clangxx.py create mode 100644 src/engine/SCons/Tool/clangxx.xml diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py index e5b4b05..f022a1f 100644 --- a/src/engine/SCons/Tool/__init__.py +++ b/src/engine/SCons/Tool/__init__.py @@ -101,7 +101,10 @@ for suffix in LaTeXSuffixes: # Tool aliases are needed for those tools whos module names also # occur in the python standard library. This causes module shadowing and # can break using python library functions under python3 -TOOL_ALIASES = {'gettext':'gettext_tool'} +TOOL_ALIASES = { + 'gettext':'gettext_tool', + 'clang++': 'clangxx', +} class Tool(object): def __init__(self, name, toolpath=[], **kw): diff --git a/src/engine/SCons/Tool/clang++.py b/src/engine/SCons/Tool/clang++.py deleted file mode 100644 index 07c89ad..0000000 --- a/src/engine/SCons/Tool/clang++.py +++ /dev/null @@ -1,92 +0,0 @@ -# -*- encoding: utf-8 -*- - -"""SCons.Tool.clang++ - -Tool-specific initialization for clang++. - -There normally shouldn't be any need to import this module directly. -It will usually be imported through the generic SCons.Tool.Tool() -selection method. - -""" - -# -# __COPYRIGHT__ -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be included -# in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY -# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -# __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -# Based on SCons/Tool/g++.py by Paweł Tomulik 2014 as a separate tool. -# Brought into the SCons mainline by Russel Winder 2017. - -import os.path -import re -import subprocess -import sys - -import SCons.Tool -import SCons.Util - -cplusplus = __import__(__package__ + '.c++', globals(), locals(), ['*']) - -compilers = ['clang++'] - -def generate(env): - """Add Builders and construction variables for clang++ to an Environment.""" - static_obj, shared_obj = SCons.Tool.createObjBuilders(env) - - cplusplus.generate(env) - - env['CXX'] = env.Detect(compilers) or 'clang++' - - # platform specific settings - if env['PLATFORM'] == 'aix': - env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS -mminimal-toc') - env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1 - env['SHOBJSUFFIX'] = '$OBJSUFFIX' - elif env['PLATFORM'] == 'hpux': - env['SHOBJSUFFIX'] = '.pic.o' - elif env['PLATFORM'] == 'sunos': - env['SHOBJSUFFIX'] = '.pic.o' - # determine compiler version - if env['CXX']: - pipe = SCons.Action._subproc(env, [env['CXX'], '--version'], - stdin='devnull', - stderr='devnull', - stdout=subprocess.PIPE) - if pipe.wait() != 0: return - # clang -dumpversion is of no use - line = pipe.stdout.readline() - if sys.version_info[0] > 2: - line = line.decode() - match = re.search(r'clang +version +([0-9]+(?:\.[0-9]+)+)', line) - if match: - env['CXXVERSION'] = match.group(1) - -def exists(env): - return env.Detect(compilers) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/clang++.xml b/src/engine/SCons/Tool/clang++.xml deleted file mode 100644 index ad30b26..0000000 --- a/src/engine/SCons/Tool/clang++.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - -%scons; - -%builders-mod; - -%functions-mod; - -%tools-mod; - -%variables-mod; -]> - - - - - - -Set construction variables for the Clang C++ compiler. - - - -CXX -SHCXXFLAGS - -SHOBJSUFFIX -CXXVERSION - - - - diff --git a/src/engine/SCons/Tool/clangxx.py b/src/engine/SCons/Tool/clangxx.py new file mode 100644 index 0000000..60617db --- /dev/null +++ b/src/engine/SCons/Tool/clangxx.py @@ -0,0 +1,91 @@ +# -*- encoding: utf-8 -*- + +"""SCons.Tool.clang++ + +Tool-specific initialization for clang++. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +# __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +# Based on SCons/Tool/g++.py by Paweł Tomulik 2014 as a separate tool. +# Brought into the SCons mainline by Russel Winder 2017. + +import os.path +import re +import subprocess +import sys + +import SCons.Tool +import SCons.Util +import SCons.Tool.cxx + +compilers = ['clang++'] + +def generate(env): + """Add Builders and construction variables for clang++ to an Environment.""" + static_obj, shared_obj = SCons.Tool.createObjBuilders(env) + + SCons.Tool.cxx.generate(env) + + env['CXX'] = env.Detect(compilers) or 'clang++' + + # platform specific settings + if env['PLATFORM'] == 'aix': + env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS -mminimal-toc') + env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1 + env['SHOBJSUFFIX'] = '$OBJSUFFIX' + elif env['PLATFORM'] == 'hpux': + env['SHOBJSUFFIX'] = '.pic.o' + elif env['PLATFORM'] == 'sunos': + env['SHOBJSUFFIX'] = '.pic.o' + # determine compiler version + if env['CXX']: + pipe = SCons.Action._subproc(env, [env['CXX'], '--version'], + stdin='devnull', + stderr='devnull', + stdout=subprocess.PIPE) + if pipe.wait() != 0: return + # clang -dumpversion is of no use + line = pipe.stdout.readline() + if sys.version_info[0] > 2: + line = line.decode() + match = re.search(r'clang +version +([0-9]+(?:\.[0-9]+)+)', line) + if match: + env['CXXVERSION'] = match.group(1) + +def exists(env): + return env.Detect(compilers) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/clangxx.xml b/src/engine/SCons/Tool/clangxx.xml new file mode 100644 index 0000000..25ed1d4 --- /dev/null +++ b/src/engine/SCons/Tool/clangxx.xml @@ -0,0 +1,41 @@ + + + + +%scons; + +%builders-mod; + +%functions-mod; + +%tools-mod; + +%variables-mod; +]> + + + + + + +Set construction variables for the Clang C++ compiler. + + + +CXX +SHCXXFLAGS + +SHOBJSUFFIX +CXXVERSION + + + + -- cgit v0.12 From 640695cfb274dfba41a0c6cc74c95f2a00327f90 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Fri, 23 Jun 2017 09:27:31 -0700 Subject: py2/3 fix version checking for valid versions of python to 2.7.x >=3.5.0: src/script/scons.py --- src/script/scons.py | 10 +- src/setup.py | 304 ++++++++++++++++++++++++++++------------------------ 2 files changed, 166 insertions(+), 148 deletions(-) diff --git a/src/script/scons.py b/src/script/scons.py index 1cf9469..bdf0cea 100644 --- a/src/script/scons.py +++ b/src/script/scons.py @@ -58,11 +58,11 @@ import sys # engine modules if they're in either directory. -## if sys.version_info >= (3,0,0): -## msg = "scons: *** SCons version %s does not run under Python version %s.\n\ -## Python 3 is not yet supported.\n" -## sys.stderr.write(msg % (__version__, sys.version.split()[0])) -## sys.exit(1) +if (3,0,0) < sys.version_info < (3,5,0) or sys.version_info < (2,7,0): + msg = "scons: *** SCons version %s does not run under Python version %s.\n\ +Python < 3.5 is not yet supported.\n" + sys.stderr.write(msg % (__version__, sys.version.split()[0])) + sys.exit(1) script_dir = sys.path[0] diff --git a/src/setup.py b/src/setup.py index 41fc35a..1957db6 100644 --- a/src/setup.py +++ b/src/setup.py @@ -54,7 +54,6 @@ if head: os.chdir(head) sys.argv[0] = tail - # flag if setup.py is run on win32 or _for_ win32 platform, # (when building windows installer on linux, for example) is_win32 = 0 @@ -67,7 +66,6 @@ if not sys.platform == 'win32': else: is_win32 = 1 - import distutils import distutils.core import distutils.command.install @@ -77,6 +75,7 @@ import distutils.command.install_scripts import distutils.command.build_scripts import distutils.msvccompiler + def get_build_version(): """ monkey patch distutils msvc version if we're not on windows. We need to use vc version 9 for python 2.7.x and it defaults to 6 @@ -84,6 +83,7 @@ def get_build_version(): monkey patching""" return 9 + distutils.msvccompiler.get_build_version = get_build_version _install = distutils.command.install.install @@ -92,13 +92,16 @@ _install_lib = distutils.command.install_lib.install_lib _install_scripts = distutils.command.install_scripts.install_scripts _build_scripts = distutils.command.build_scripts.build_scripts + class _options(object): pass + Options = _options() Installed = [] + def set_explicitly(name, args): """ Return if the installation directory was set explicitly by the @@ -119,51 +122,52 @@ def set_explicitly(name, args): break return set + class install(_install): user_options = _install.user_options + [ - ('no-scons-script', None, - "don't install 'scons', only install 'scons-%s'" % Version), - ('no-version-script', None, - "don't install 'scons-%s', only install 'scons'" % Version), - ('install-bat', None, - "install 'scons.bat' script"), - ('no-install-bat', None, - "do not install 'scons.bat' script"), - ('install-man', None, - "install SCons man pages"), - ('no-install-man', None, - "do not install SCons man pages"), - ('standard-lib', None, - "install SCons library in standard Python location"), - ('standalone-lib', None, - "install SCons library in separate standalone directory"), - ('version-lib', None, - "install SCons library in version-numbered directory"), - ] + ('no-scons-script', None, + "don't install 'scons', only install 'scons-%s'" % Version), + ('no-version-script', None, + "don't install 'scons-%s', only install 'scons'" % Version), + ('install-bat', None, + "install 'scons.bat' script"), + ('no-install-bat', None, + "do not install 'scons.bat' script"), + ('install-man', None, + "install SCons man pages"), + ('no-install-man', None, + "do not install SCons man pages"), + ('standard-lib', None, + "install SCons library in standard Python location"), + ('standalone-lib', None, + "install SCons library in separate standalone directory"), + ('version-lib', None, + "install SCons library in version-numbered directory"), + ] boolean_options = _install.boolean_options + [ - 'no-scons-script', - 'no-version-script', - 'install-bat', - 'no-install-bat', - 'install-man', - 'no-install-man', - 'standard-lib', - 'standalone-lib', - 'version-lib' - ] + 'no-scons-script', + 'no-version-script', + 'install-bat', + 'no-install-bat', + 'install-man', + 'no-install-man', + 'standard-lib', + 'standalone-lib', + 'version-lib' + ] if hasattr(os, 'link'): user_options.append( - ('hardlink-scons', None, - "hard link 'scons' to the version-numbered script, don't make a separate 'scons' copy"), - ) + ('hardlink-scons', None, + "hard link 'scons' to the version-numbered script, don't make a separate 'scons' copy"), + ) boolean_options.append('hardlink-script') if hasattr(os, 'symlink'): user_options.append( - ('symlink-scons', None, - "make 'scons' a symbolic link to the version-numbered script, don't make a separate 'scons' copy"), - ) + ('symlink-scons', None, + "make 'scons' a symbolic link to the version-numbered script, don't make a separate 'scons' copy"), + ) boolean_options.append('symlink-script') def initialize_options(self): @@ -201,6 +205,7 @@ class install(_install): Options.hardlink_scons = self.hardlink_scons Options.symlink_scons = self.symlink_scons + def get_scons_prefix(libdir, is_win32): """ Return the right prefix for SCons library installation. Find @@ -225,6 +230,7 @@ def get_scons_prefix(libdir, is_win32): return os.path.join(drive + head) return libdir + def force_to_usr_local(self): """ A hack to decide if we need to "force" the installation directories @@ -236,6 +242,7 @@ def force_to_usr_local(self): (self.install_dir[:9] == '/Library/' or self.install_dir[:16] == '/System/Library/')) + class install_lib(_install_lib): def finalize_options(self): _install_lib.finalize_options(self) @@ -258,6 +265,7 @@ class install_lib(_install_lib): msg = "Installed SCons library modules into %s" % self.install_dir Installed.append(msg) + class install_scripts(_install_scripts): def finalize_options(self): _install_scripts.finalize_options(self) @@ -271,18 +279,24 @@ class install_scripts(_install_scripts): pass def hardlink_scons(self, src, dst, ver): - try: os.unlink(dst) - except OSError: pass + try: + os.unlink(dst) + except OSError: + pass os.link(ver, dst) def symlink_scons(self, src, dst, ver): - try: os.unlink(dst) - except OSError: pass + try: + os.unlink(dst) + except OSError: + pass os.symlink(os.path.split(ver)[1], dst) def copy_scons(self, src, dst, *args): - try: os.unlink(dst) - except OSError: pass + try: + os.unlink(dst) + except OSError: + pass self.copy_file(src, dst) self.outfiles.append(dst) @@ -337,7 +351,7 @@ class install_scripts(_install_scripts): self.copy_scons(src, scons_version_bat) # --- distutils copy/paste --- - if hasattr(os, 'chmod') and hasattr(os,'stat'): + if hasattr(os, 'chmod') and hasattr(os, 'stat'): # Set the executable bits (owner, group, and world) on # all the scripts we just installed. for file in self.get_outputs(): @@ -347,20 +361,23 @@ class install_scripts(_install_scripts): else: # Use symbolic versions of permissions so this script doesn't fail to parse under python3.x exec_and_read_permission = stat.S_IXOTH | stat.S_IXUSR | stat.S_IXGRP | stat.S_IROTH | stat.S_IRUSR | stat.S_IRGRP - mode_mask = 4095 # Octal 07777 used because python3 has different octal syntax than python 2 + mode_mask = 4095 # Octal 07777 used because python3 has different octal syntax than python 2 mode = ((os.stat(file)[stat.ST_MODE]) | exec_and_read_permission) & mode_mask # log.info("changing mode of %s to %o", file, mode) os.chmod(file, mode) - # --- /distutils copy/paste --- + # --- /distutils copy/paste --- + class build_scripts(_build_scripts): def finalize_options(self): _build_scripts.finalize_options(self) self.build_dir = os.path.join('build', 'scripts') + class install_data(_install_data): def initialize_options(self): _install_data.initialize_options(self) + def finalize_options(self): _install_data.finalize_options(self) if force_to_usr_local(self): @@ -377,6 +394,7 @@ class install_data(_install_data): else: self.data_files = [] + description = "Open Source next-generation build tool." long_description = """Open Source next-generation build tool. @@ -398,103 +416,103 @@ scripts = [ ] arguments = { - 'name' : "scons", - 'version' : Version, - 'description' : description, - 'long_description' : long_description, - 'author' : 'Steven Knight', - 'author_email' : 'knight@baldmt.com', - 'url' : "http://www.scons.org/", - 'packages' : ["SCons", - "SCons.compat", - "SCons.Node", - "SCons.Options", - "SCons.Platform", - "SCons.Scanner", - "SCons.Script", - "SCons.Tool", - "SCons.Tool.docbook", - "SCons.Tool.MSCommon", - "SCons.Tool.packaging", - "SCons.Variables", - ], - 'package_dir' : {'' : 'engine', - 'SCons.Tool.docbook' : 'engine/SCons/Tool/docbook'}, - 'package_data' : {'SCons.Tool.docbook' : ['docbook-xsl-1.76.1/*', - 'docbook-xsl-1.76.1/common/*', - 'docbook-xsl-1.76.1/docsrc/*', - 'docbook-xsl-1.76.1/eclipse/*', - 'docbook-xsl-1.76.1/epub/*', - 'docbook-xsl-1.76.1/epub/bin/*', - 'docbook-xsl-1.76.1/epub/bin/lib/*', - 'docbook-xsl-1.76.1/epub/bin/xslt/*', - 'docbook-xsl-1.76.1/extensions/*', - 'docbook-xsl-1.76.1/fo/*', - 'docbook-xsl-1.76.1/highlighting/*', - 'docbook-xsl-1.76.1/html/*', - 'docbook-xsl-1.76.1/htmlhelp/*', - 'docbook-xsl-1.76.1/images/*', - 'docbook-xsl-1.76.1/images/callouts/*', - 'docbook-xsl-1.76.1/images/colorsvg/*', - 'docbook-xsl-1.76.1/javahelp/*', - 'docbook-xsl-1.76.1/lib/*', - 'docbook-xsl-1.76.1/manpages/*', - 'docbook-xsl-1.76.1/params/*', - 'docbook-xsl-1.76.1/profiling/*', - 'docbook-xsl-1.76.1/roundtrip/*', - 'docbook-xsl-1.76.1/slides/browser/*', - 'docbook-xsl-1.76.1/slides/fo/*', - 'docbook-xsl-1.76.1/slides/graphics/*', - 'docbook-xsl-1.76.1/slides/graphics/active/*', - 'docbook-xsl-1.76.1/slides/graphics/inactive/*', - 'docbook-xsl-1.76.1/slides/graphics/toc/*', - 'docbook-xsl-1.76.1/slides/html/*', - 'docbook-xsl-1.76.1/slides/htmlhelp/*', - 'docbook-xsl-1.76.1/slides/keynote/*', - 'docbook-xsl-1.76.1/slides/keynote/xsltsl/*', - 'docbook-xsl-1.76.1/slides/svg/*', - 'docbook-xsl-1.76.1/slides/xhtml/*', - 'docbook-xsl-1.76.1/template/*', - 'docbook-xsl-1.76.1/tests/*', - 'docbook-xsl-1.76.1/tools/bin/*', - 'docbook-xsl-1.76.1/tools/make/*', - 'docbook-xsl-1.76.1/webhelp/*', - 'docbook-xsl-1.76.1/webhelp/docs/*', - 'docbook-xsl-1.76.1/webhelp/docs/common/*', - 'docbook-xsl-1.76.1/webhelp/docs/common/css/*', - 'docbook-xsl-1.76.1/webhelp/docs/common/images/*', - 'docbook-xsl-1.76.1/webhelp/docs/common/jquery/*', - 'docbook-xsl-1.76.1/webhelp/docs/common/jquery/theme-redmond/*', - 'docbook-xsl-1.76.1/webhelp/docs/common/jquery/theme-redmond/images/*', - 'docbook-xsl-1.76.1/webhelp/docs/common/jquery/treeview/*', - 'docbook-xsl-1.76.1/webhelp/docs/common/jquery/treeview/images/*', - 'docbook-xsl-1.76.1/webhelp/docs/content/*', - 'docbook-xsl-1.76.1/webhelp/docs/content/search/*', - 'docbook-xsl-1.76.1/webhelp/docs/content/search/stemmers/*', - 'docbook-xsl-1.76.1/webhelp/docsrc/*', - 'docbook-xsl-1.76.1/webhelp/template/*', - 'docbook-xsl-1.76.1/webhelp/template/common/*', - 'docbook-xsl-1.76.1/webhelp/template/common/css/*', - 'docbook-xsl-1.76.1/webhelp/template/common/images/*', - 'docbook-xsl-1.76.1/webhelp/template/common/jquery/*', - 'docbook-xsl-1.76.1/webhelp/template/common/jquery/theme-redmond/*', - 'docbook-xsl-1.76.1/webhelp/template/common/jquery/theme-redmond/images/*', - 'docbook-xsl-1.76.1/webhelp/template/common/jquery/treeview/*', - 'docbook-xsl-1.76.1/webhelp/template/common/jquery/treeview/images/*', - 'docbook-xsl-1.76.1/webhelp/template/content/search/*', - 'docbook-xsl-1.76.1/webhelp/template/content/search/stemmers/*', - 'docbook-xsl-1.76.1/webhelp/xsl/*', - 'docbook-xsl-1.76.1/website/*', - 'docbook-xsl-1.76.1/xhtml/*', - 'docbook-xsl-1.76.1/xhtml-1_1/*', - 'utils/*']}, - 'data_files' : [('man/man1', man_pages)], - 'scripts' : scripts, - 'cmdclass' : {'install' : install, - 'install_lib' : install_lib, - 'install_data' : install_data, - 'install_scripts' : install_scripts, - 'build_scripts' : build_scripts} + 'name': "scons", + 'version': Version, + 'description': description, + 'long_description': long_description, + 'author': 'Steven Knight', + 'author_email': 'knight@baldmt.com', + 'url': "http://www.scons.org/", + 'packages': ["SCons", + "SCons.compat", + "SCons.Node", + "SCons.Options", + "SCons.Platform", + "SCons.Scanner", + "SCons.Script", + "SCons.Tool", + "SCons.Tool.docbook", + "SCons.Tool.MSCommon", + "SCons.Tool.packaging", + "SCons.Variables", + ], + 'package_dir': {'': 'engine', + 'SCons.Tool.docbook': 'engine/SCons/Tool/docbook'}, + 'package_data': {'SCons.Tool.docbook': ['docbook-xsl-1.76.1/*', + 'docbook-xsl-1.76.1/common/*', + 'docbook-xsl-1.76.1/docsrc/*', + 'docbook-xsl-1.76.1/eclipse/*', + 'docbook-xsl-1.76.1/epub/*', + 'docbook-xsl-1.76.1/epub/bin/*', + 'docbook-xsl-1.76.1/epub/bin/lib/*', + 'docbook-xsl-1.76.1/epub/bin/xslt/*', + 'docbook-xsl-1.76.1/extensions/*', + 'docbook-xsl-1.76.1/fo/*', + 'docbook-xsl-1.76.1/highlighting/*', + 'docbook-xsl-1.76.1/html/*', + 'docbook-xsl-1.76.1/htmlhelp/*', + 'docbook-xsl-1.76.1/images/*', + 'docbook-xsl-1.76.1/images/callouts/*', + 'docbook-xsl-1.76.1/images/colorsvg/*', + 'docbook-xsl-1.76.1/javahelp/*', + 'docbook-xsl-1.76.1/lib/*', + 'docbook-xsl-1.76.1/manpages/*', + 'docbook-xsl-1.76.1/params/*', + 'docbook-xsl-1.76.1/profiling/*', + 'docbook-xsl-1.76.1/roundtrip/*', + 'docbook-xsl-1.76.1/slides/browser/*', + 'docbook-xsl-1.76.1/slides/fo/*', + 'docbook-xsl-1.76.1/slides/graphics/*', + 'docbook-xsl-1.76.1/slides/graphics/active/*', + 'docbook-xsl-1.76.1/slides/graphics/inactive/*', + 'docbook-xsl-1.76.1/slides/graphics/toc/*', + 'docbook-xsl-1.76.1/slides/html/*', + 'docbook-xsl-1.76.1/slides/htmlhelp/*', + 'docbook-xsl-1.76.1/slides/keynote/*', + 'docbook-xsl-1.76.1/slides/keynote/xsltsl/*', + 'docbook-xsl-1.76.1/slides/svg/*', + 'docbook-xsl-1.76.1/slides/xhtml/*', + 'docbook-xsl-1.76.1/template/*', + 'docbook-xsl-1.76.1/tests/*', + 'docbook-xsl-1.76.1/tools/bin/*', + 'docbook-xsl-1.76.1/tools/make/*', + 'docbook-xsl-1.76.1/webhelp/*', + 'docbook-xsl-1.76.1/webhelp/docs/*', + 'docbook-xsl-1.76.1/webhelp/docs/common/*', + 'docbook-xsl-1.76.1/webhelp/docs/common/css/*', + 'docbook-xsl-1.76.1/webhelp/docs/common/images/*', + 'docbook-xsl-1.76.1/webhelp/docs/common/jquery/*', + 'docbook-xsl-1.76.1/webhelp/docs/common/jquery/theme-redmond/*', + 'docbook-xsl-1.76.1/webhelp/docs/common/jquery/theme-redmond/images/*', + 'docbook-xsl-1.76.1/webhelp/docs/common/jquery/treeview/*', + 'docbook-xsl-1.76.1/webhelp/docs/common/jquery/treeview/images/*', + 'docbook-xsl-1.76.1/webhelp/docs/content/*', + 'docbook-xsl-1.76.1/webhelp/docs/content/search/*', + 'docbook-xsl-1.76.1/webhelp/docs/content/search/stemmers/*', + 'docbook-xsl-1.76.1/webhelp/docsrc/*', + 'docbook-xsl-1.76.1/webhelp/template/*', + 'docbook-xsl-1.76.1/webhelp/template/common/*', + 'docbook-xsl-1.76.1/webhelp/template/common/css/*', + 'docbook-xsl-1.76.1/webhelp/template/common/images/*', + 'docbook-xsl-1.76.1/webhelp/template/common/jquery/*', + 'docbook-xsl-1.76.1/webhelp/template/common/jquery/theme-redmond/*', + 'docbook-xsl-1.76.1/webhelp/template/common/jquery/theme-redmond/images/*', + 'docbook-xsl-1.76.1/webhelp/template/common/jquery/treeview/*', + 'docbook-xsl-1.76.1/webhelp/template/common/jquery/treeview/images/*', + 'docbook-xsl-1.76.1/webhelp/template/content/search/*', + 'docbook-xsl-1.76.1/webhelp/template/content/search/stemmers/*', + 'docbook-xsl-1.76.1/webhelp/xsl/*', + 'docbook-xsl-1.76.1/website/*', + 'docbook-xsl-1.76.1/xhtml/*', + 'docbook-xsl-1.76.1/xhtml-1_1/*', + 'utils/*']}, + 'data_files': [('man/man1', man_pages)], + 'scripts': scripts, + 'cmdclass': {'install': install, + 'install_lib': install_lib, + 'install_data': install_data, + 'install_scripts': install_scripts, + 'build_scripts': build_scripts} } distutils.core.setup(**arguments) -- cgit v0.12 From 756ad7b12c04236a6481d1823cea38a345fd73d3 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Fri, 23 Jun 2017 20:23:23 -0700 Subject: py2/3 fix signatures for py2. Note this means that many builds may unneccesarily rebuild on upgrade to 3.0.0 as the signature will have changed for python actions --- src/engine/SCons/ActionTests.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/engine/SCons/ActionTests.py b/src/engine/SCons/ActionTests.py index 82c5e0e..6751091 100644 --- a/src/engine/SCons/ActionTests.py +++ b/src/engine/SCons/ActionTests.py @@ -2055,7 +2055,12 @@ class ObjectContentsTestCase(unittest.TestCase): # See definition above o = TestClass() c = SCons.Action._object_contents(o) - expected = bytearray("(i__main__\nTestClass\np1\n(dp2\nS'a'\nS'a'\nsS'b'\nS'b'\nsb.", 'utf-8') + + if TestCmd.PY3: + expected = bytearray(r'ccopy_reg\n_reconstructor\nq\x00(c__main__\nTestClass\nq\x01c__builtin__\nobject\nq\x02Ntq\x03Rq\x04}q\x05(X\x01\x00\x00\x00bq\x06h\x06X\x01\x00\x00\x00aq\x07h\x07ub.','utf-8') + else: + expected = bytearray(b'(c__main__\nTestClass\nq\x01oq\x02}q\x03(U\x01aU\x01aU\x01bU\x01bub.') + assert expected == c, "Got\n" + repr(c) + "\nExpected\n" + repr(expected) # @unittest.skip("Results vary between py2 and py3, not sure if test makes sense to implement") @@ -2064,7 +2069,10 @@ class ObjectContentsTestCase(unittest.TestCase): code = compile("print('Hello, World!')", '', 'exec') c = SCons.Action._code_contents(code) - expected = bytearray("0, 0, 0, 0,(N.),(),(d\x00\x00GHd\x01\x00S)", 'utf-8') + if TestCmd.PY3: + expected = bytearray(b'0, 0, 0, 0,(N.),(X\x05\x00\x00\x00printq\x00.),(e\x00\x00d\x00\x00\x83\x01\x00\x01d\x01\x00S)','utf-8') + else: + expected = bytearray(b"0, 0, 0, 0,(N.),(),(d\x00\x00GHd\x01\x00S)") assert expected == c, "Got\n" + repr(c) + "\nExpected\n" + repr(expected) -- cgit v0.12 From b91c56c52466622defbc4a7a42be31fe19d79120 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Fri, 23 Jun 2017 20:34:07 -0700 Subject: PY2/3 fixed actiontests for python 3 (turns out it only passes for python 3.5.x for now) --- src/engine/SCons/ActionTests.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/engine/SCons/ActionTests.py b/src/engine/SCons/ActionTests.py index 6751091..8cc579b 100644 --- a/src/engine/SCons/ActionTests.py +++ b/src/engine/SCons/ActionTests.py @@ -1605,7 +1605,6 @@ class FunctionActionTestCase(unittest.TestCase): a = factory(GlobalFunc) c = a.get_contents(target=[], source=[], env=Environment()) - # assert c in func_matches, repr(c) assert c in func_matches, "Got\n"+repr(c)+"\nExpected one of \n"+"\n".join([repr(f) for f in func_matches]) @@ -2057,7 +2056,7 @@ class ObjectContentsTestCase(unittest.TestCase): c = SCons.Action._object_contents(o) if TestCmd.PY3: - expected = bytearray(r'ccopy_reg\n_reconstructor\nq\x00(c__main__\nTestClass\nq\x01c__builtin__\nobject\nq\x02Ntq\x03Rq\x04}q\x05(X\x01\x00\x00\x00bq\x06h\x06X\x01\x00\x00\x00aq\x07h\x07ub.','utf-8') + expected = bytearray(b'ccopy_reg\n_reconstructor\nq\x00(c__main__\nTestClass\nq\x01c__builtin__\nobject\nq\x02Ntq\x03Rq\x04}q\x05(X\x01\x00\x00\x00bq\x06h\x06X\x01\x00\x00\x00aq\x07h\x07ub.') else: expected = bytearray(b'(c__main__\nTestClass\nq\x01oq\x02}q\x03(U\x01aU\x01aU\x01bU\x01bub.') @@ -2070,7 +2069,7 @@ class ObjectContentsTestCase(unittest.TestCase): code = compile("print('Hello, World!')", '', 'exec') c = SCons.Action._code_contents(code) if TestCmd.PY3: - expected = bytearray(b'0, 0, 0, 0,(N.),(X\x05\x00\x00\x00printq\x00.),(e\x00\x00d\x00\x00\x83\x01\x00\x01d\x01\x00S)','utf-8') + expected = bytearray(b'0, 0, 0, 0,(N.),(X\x05\x00\x00\x00printq\x00.),(e\x00\x00d\x00\x00\x83\x01\x00\x01d\x01\x00S)') else: expected = bytearray(b"0, 0, 0, 0,(N.),(),(d\x00\x00GHd\x01\x00S)") assert expected == c, "Got\n" + repr(c) + "\nExpected\n" + repr(expected) -- cgit v0.12 From dac36853a206edc24bbaf2ee8e706f4bd3fd77a8 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Sun, 25 Jun 2017 10:54:46 -0700 Subject: py2/3 fix expected signatures for python actions (functions,classes). Unfortunately it looks like they may vary by platform and by python release, at least on win py3.5 vs py3.6. May be a good idea to take a second look at these signatures and see if there is a way to stabilize by python version. Added note to CHANGES --- QMTest/TestCmd.py | 5 +- src/CHANGES.txt | 4 ++ src/engine/SCons/ActionTests.py | 115 ++++++++++++++++++++++++++++------------ 3 files changed, 88 insertions(+), 36 deletions(-) diff --git a/QMTest/TestCmd.py b/QMTest/TestCmd.py index e4c69a6..61da8b9 100644 --- a/QMTest/TestCmd.py +++ b/QMTest/TestCmd.py @@ -307,7 +307,8 @@ import traceback import types -PY3 = sys.version_info[0] == 3 +IS_PY3 = sys.version_info[0] == 3 +IS_WINDOWS = sys.platform == 'win32' class null(object): @@ -1245,7 +1246,7 @@ class TestCmd(object): file = self.canonicalize(file) if mode[0] != 'r': raise ValueError("mode must begin with 'r'") - if PY3 and 'b' not in mode: + if IS_PY3 and 'b' not in mode: return open(file, mode, newline=newline).read() else: return open(file, mode).read() diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 745c69d..0c72132 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -7,6 +7,10 @@ RELEASE 3.0.0.alpha.20170614 - Mon, 14 Jun 2017 12:23:56 -0400 +NOTE: This is a major release. You should expect that some targets may rebuild when upgrading. +Significant changes in some python action signatures. Also switching between PY 2 and PY 3.5, 3.6 +may cause rebuilds. In no case should rebuilds not happen. + From Richard West: - Added nested / namespace tool support - Added a small fix to the python3 tool loader when loading a tool as a package diff --git a/src/engine/SCons/ActionTests.py b/src/engine/SCons/ActionTests.py index 8cc579b..34d9ffc 100644 --- a/src/engine/SCons/ActionTests.py +++ b/src/engine/SCons/ActionTests.py @@ -1428,10 +1428,16 @@ class CommandGeneratorActionTestCase(unittest.TestCase): def LocalFunc(): pass - func_matches = [ - b"0, 0, 0, 0,(),(),(d\000\000S),(),()", - b"0, 0, 0, 0,(),(),(d\x00\x00S),(),()", - ] + if TestCmd.IS_PY3 and TestCmd.IS_WINDOWS: + func_matches = [ + b'0, 0, 0, 0,(),(),(d\x00S\x00),(),()', # PY 3.6 + b'0, 0, 0, 0,(),(),(d\x00\x00S),(),()', # PY 3.5 + ] + else: + func_matches = [ + b"0, 0, 0, 0,(),(),(d\000\000S),(),()", + b"0, 0, 0, 0,(),(),(d\x00\x00S),(),()", + ] meth_matches = [ b"1, 1, 0, 0,(),(),(d\000\000S),(),()", @@ -1590,15 +1596,26 @@ class FunctionActionTestCase(unittest.TestCase): def LocalFunc(): pass - func_matches = [ - b"0, 0, 0, 0,(),(),(d\000\000S),(),()", - b"0, 0, 0, 0,(),(),(d\x00\x00S),(),()", + if TestCmd.IS_PY3 and TestCmd.IS_WINDOWS: + func_matches = [ + b'0, 0, 0, 0,(),(),(d\x00S\x00),(),()', # py 3.6 + b'0, 0, 0, 0,(),(),(d\x00\x00S),(),()' # py 3.5 + ] + meth_matches = [ + b'1, 1, 0, 0,(),(),(d\x00S\x00),(),()', # py 3.6 + b'1, 1, 0, 0,(),(),(d\x00\x00S),(),()', # py 3.5 ] - meth_matches = [ - b"1, 1, 0, 0,(),(),(d\000\000S),(),()", - b"1, 1, 0, 0,(),(),(d\x00\x00S),(),()", - ] + else: + func_matches = [ + b"0, 0, 0, 0,(),(),(d\000\000S),(),()", + b"0, 0, 0, 0,(),(),(d\x00\x00S),(),()", + ] + + meth_matches = [ + b"1, 1, 0, 0,(),(),(d\000\000S),(),()", + b"1, 1, 0, 0,(),(),(d\x00\x00S),(),()", + ] def factory(act, **kw): return SCons.Action.FunctionAction(act, kw) @@ -1641,7 +1658,7 @@ class FunctionActionTestCase(unittest.TestCase): lc = LocalClass() a = factory(lc.LocalMethod) c = a.get_contents(target=[], source=[], env=Environment()) - assert c in meth_matches, repr(c) + assert c in meth_matches, "Got\n"+repr(c)+"\nExpected one of \n"+"\n".join([repr(f) for f in meth_matches]) def test_strfunction(self): """Test the FunctionAction.strfunction() method @@ -1807,10 +1824,16 @@ class LazyActionTestCase(unittest.TestCase): def LocalFunc(): pass - func_matches = [ - b"0, 0, 0, 0,(),(),(d\000\000S),(),()", - b"0, 0, 0, 0,(),(),(d\x00\x00S),(),()", - ] + if TestCmd.IS_PY3 and TestCmd.IS_WINDOWS: + func_matches = [ + b'0, 0, 0, 0,(),(),(d\x00S\x00),(),()', + b'0, 0, 0, 0,(),(),(d\x00\x00S),(),()' + ] + else: + func_matches = [ + b"0, 0, 0, 0,(),(),(d\000\000S),(),()", + b"0, 0, 0, 0,(),(),(d\x00\x00S),(),()", + ] meth_matches = [ b"1, 1, 0, 0,(),(),(d\000\000S),(),()", @@ -1858,10 +1881,16 @@ class ActionCallerTestCase(unittest.TestCase): def LocalFunc(): pass - matches = [ - b"d\000\000S", - b"d\\x00\\x00S" - ] + if TestCmd.IS_PY3 and TestCmd.IS_WINDOWS: + matches = [ + b'd\x00S\x00', + b'd\x00\x00S' + ] + else: + matches = [ + b"d\000\000S", + b"d\\x00\\x00S" + ] af = SCons.Action.ActionFactory(GlobalFunc, strfunc) ac = SCons.Action.ActionCaller(af, [], {}) @@ -1873,10 +1902,11 @@ class ActionCallerTestCase(unittest.TestCase): c = ac.get_contents([], [], Environment()) assert c in matches, "Got\n"+repr(c)+"\nExpected one of \n"+"\n".join([repr(f) for f in matches]) - matches = [ - b'd\000\000S', - b"d\x00\x00S" - ] + # TODO: Same as above, why redefine? + # matches = [ + # b'd\000\000S', + # b"d\x00\x00S" + # ] class LocalActFunc(object): def __call__(self): @@ -2043,8 +2073,12 @@ class ObjectContentsTestCase(unittest.TestCase): return a c = SCons.Action._function_contents(func1) - expected = bytearray('3, 3, 0, 0,(),(),(|\x00\x00S),(),()','utf-8') - assert expected == c, "Got\n"+repr(c)+"\nExpected \n"+repr(expected)+"\n" + if TestCmd.IS_PY3 and TestCmd.IS_WINDOWS: + expected = [b'3, 3, 0, 0,(),(),(|\x00S\x00),(),()', + b'3, 3, 0, 0,(),(),(|\x00\x00S),(),()'] + else: + expected = [b'3, 3, 0, 0,(),(),(|\x00\x00S),(),()'] + assert c in expected, "Got\n"+repr(c)+"\nExpected one of \n"+"\n".join([repr(e) for e in expected]) # @unittest.skip("Results vary between py2 and py3, not sure if test makes sense to implement") @@ -2055,12 +2089,20 @@ class ObjectContentsTestCase(unittest.TestCase): o = TestClass() c = SCons.Action._object_contents(o) - if TestCmd.PY3: - expected = bytearray(b'ccopy_reg\n_reconstructor\nq\x00(c__main__\nTestClass\nq\x01c__builtin__\nobject\nq\x02Ntq\x03Rq\x04}q\x05(X\x01\x00\x00\x00bq\x06h\x06X\x01\x00\x00\x00aq\x07h\x07ub.') + if TestCmd.IS_PY3: + if TestCmd.IS_WINDOWS: + expected = [b'ccopy_reg\n_reconstructor\nq\x00(c__main__\nTestClass\nq\x01c__builtin__\nobject\nq\x02Ntq\x03Rq\x04}q\x05(X\x01\x00\x00\x00aq\x06h\x06X\x01\x00\x00\x00bq\x07h\x07ub.', # py 3.6 + b'ccopy_reg\n_reconstructor\nq\x00(c__main__\nTestClass\nq\x01c__builtin__\nobject\nq\x02Ntq\x03Rq\x04}q\x05(X\x01\x00\x00\x00bq\x06h\x06X\x01\x00\x00\x00aq\x07h\x07ub.', # py 3.5 + ] + else: + expected = [b'ccopy_reg\n_reconstructor\nq\x00(c__main__\nTestClass\nq\x01c__builtin__\nobject\nq\x02Ntq\x03Rq\x04}q\x05(X\x01\x00\x00\x00bq\x06h\x06X\x01\x00\x00\x00aq\x07h\x07ub.'] else: - expected = bytearray(b'(c__main__\nTestClass\nq\x01oq\x02}q\x03(U\x01aU\x01aU\x01bU\x01bub.') + if TestCmd.IS_WINDOWS: + expected = [b'(c__main__\nTestClass\nq\x01oq\x02}q\x03(U\x01aU\x01aU\x01bU\x01bub.'] + else: + expected = [b'(c__main__\nTestClass\nq\x01oq\x02}q\x03(U\x01aU\x01aU\x01bU\x01bub.'] - assert expected == c, "Got\n" + repr(c) + "\nExpected\n" + repr(expected) + assert c in expected, "Got\n"+repr(c)+"\nExpected one of \n"+"\n".join([repr(e) for e in expected]) # @unittest.skip("Results vary between py2 and py3, not sure if test makes sense to implement") def test_code_contents(self): @@ -2068,11 +2110,16 @@ class ObjectContentsTestCase(unittest.TestCase): code = compile("print('Hello, World!')", '', 'exec') c = SCons.Action._code_contents(code) - if TestCmd.PY3: - expected = bytearray(b'0, 0, 0, 0,(N.),(X\x05\x00\x00\x00printq\x00.),(e\x00\x00d\x00\x00\x83\x01\x00\x01d\x01\x00S)') + if TestCmd.IS_PY3: + if TestCmd.IS_WINDOWS: + expected = [b'0, 0, 0, 0,(N.),(X\x05\x00\x00\x00printq\x00.),(e\x00d\x00\x83\x01\x01\x00d\x01S\x00)', + b'0, 0, 0, 0,(N.),(X\x05\x00\x00\x00printq\x00.),(e\x00\x00d\x00\x00\x83\x01\x00\x01d\x01\x00S)' + ] + else: + expected = [b'0, 0, 0, 0,(N.),(X\x05\x00\x00\x00printq\x00.),(e\x00\x00d\x00\x00\x83\x01\x00\x01d\x01\x00S)'] else: - expected = bytearray(b"0, 0, 0, 0,(N.),(),(d\x00\x00GHd\x01\x00S)") - assert expected == c, "Got\n" + repr(c) + "\nExpected\n" + repr(expected) + expected = [b"0, 0, 0, 0,(N.),(),(d\x00\x00GHd\x01\x00S)"] + assert c in expected, "Got\n"+repr(c)+"\nExpected one of \n"+"\n".join([repr(e) for e in expected]) -- cgit v0.12 From 0acdff80303263a4825e708846c345452324b115 Mon Sep 17 00:00:00 2001 From: Daniel Holth Date: Mon, 26 Jun 2017 23:01:39 -0400 Subject: remove external zip tool, always use stdlib to zip --- src/engine/SCons/Tool/zip.py | 44 ++++++++++++++++++-------------------------- 1 file changed, 18 insertions(+), 26 deletions(-) diff --git a/src/engine/SCons/Tool/zip.py b/src/engine/SCons/Tool/zip.py index 2613bfc..23d540f 100644 --- a/src/engine/SCons/Tool/zip.py +++ b/src/engine/SCons/Tool/zip.py @@ -40,31 +40,23 @@ import SCons.Defaults import SCons.Node.FS import SCons.Util -try: - import zipfile - internal_zip = 1 -except ImportError: - internal_zip = 0 - -if internal_zip: - zipcompression = zipfile.ZIP_DEFLATED - def zip(target, source, env): - compression = env.get('ZIPCOMPRESSION', 0) - zf = zipfile.ZipFile(str(target[0]), 'w', compression) - for s in source: - if s.isdir(): - for dirpath, dirnames, filenames in os.walk(str(s)): - for fname in filenames: - path = os.path.join(dirpath, fname) - if os.path.isfile(path): - zf.write(path, os.path.relpath(path, str(env.get('ZIPROOT', '')))) - else: - zf.write(str(s), os.path.relpath(str(s), str(env.get('ZIPROOT', '')))) - zf.close() -else: - zipcompression = 0 - zip = "$ZIP $ZIPFLAGS ${TARGET.abspath} $SOURCES" - +import zipfile + +zipcompression = zipfile.ZIP_DEFLATED +def zip(target, source, env): + compression = env.get('ZIPCOMPRESSION', 0) + zf = zipfile.ZipFile(str(target[0]), 'w', compression) + for s in source: + if s.isdir(): + for dirpath, dirnames, filenames in os.walk(str(s)): + for fname in filenames: + path = os.path.join(dirpath, fname) + if os.path.isfile(path): + + zf.write(path, os.path.relpath(path, str(env.get('ZIPROOT', '')))) + else: + zf.write(str(s), os.path.relpath(str(s), str(env.get('ZIPROOT', '')))) + zf.close() zipAction = SCons.Action.Action(zip, varlist=['ZIPCOMPRESSION']) @@ -91,7 +83,7 @@ def generate(env): env['ZIPROOT'] = SCons.Util.CLVar('') def exists(env): - return internal_zip or env.Detect('zip') + return True # Local Variables: # tab-width:4 -- cgit v0.12 From e8f5ebd9ec594fa09dd691750abc96220cc1a83b Mon Sep 17 00:00:00 2001 From: Daniel Holth Date: Tue, 27 Jun 2017 07:25:19 -0400 Subject: update CHANGES.txt --- src/CHANGES.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 0c72132..b0a4517 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -9,7 +9,7 @@ RELEASE 3.0.0.alpha.20170614 - Mon, 14 Jun 2017 12:23:56 -0400 NOTE: This is a major release. You should expect that some targets may rebuild when upgrading. Significant changes in some python action signatures. Also switching between PY 2 and PY 3.5, 3.6 -may cause rebuilds. In no case should rebuilds not happen. +may cause rebuilds. In no case should rebuilds not happen. From Richard West: - Added nested / namespace tool support @@ -43,6 +43,7 @@ may cause rebuilds. In no case should rebuilds not happen. avoid too many open files. - Add __main__.py for `python -m SCons` in case it is on PYTHONPATH. - Always use highest available pickle protocol for efficiency. + - Remove unused command line fallback for the zip tool. From Gaurav Juvekar: - Fix issue #2832: Expand construction variables in 'chdir' argument of builders. (PR #463) -- cgit v0.12 From fe8669695dad03dfe0c9e8b322d3ec86d8301229 Mon Sep 17 00:00:00 2001 From: grbd Date: Tue, 27 Jun 2017 22:24:55 +0100 Subject: Added support for relative imports within tools for python3 and tests for relative imports --- src/engine/SCons/Tool/__init__.py | 2 +- test/toolpath/relative_import/image/SConstruct | 10 ++++ .../image/tools/TestTool1/TestTool1_1.py | 4 ++ .../tools/TestTool1/TestTool1_2/TestTool1_2_1.py | 4 ++ .../TestTool1_2/TestTool1_2_2/__init__.py | 4 ++ .../TestTool1_2/TestTool1_2_2/sconstest.skip | 0 .../image/tools/TestTool1/TestTool1_2/__init__.py | 11 +++++ .../tools/TestTool1/TestTool1_2/sconstest.skip | 0 .../image/tools/TestTool1/__init__.py | 9 ++++ .../image/tools/TestTool1/sconstest.skip | 0 test/toolpath/relative_import/relative_import.py | 53 ++++++++++++++++++++++ 11 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 test/toolpath/relative_import/image/SConstruct create mode 100644 test/toolpath/relative_import/image/tools/TestTool1/TestTool1_1.py create mode 100644 test/toolpath/relative_import/image/tools/TestTool1/TestTool1_2/TestTool1_2_1.py create mode 100644 test/toolpath/relative_import/image/tools/TestTool1/TestTool1_2/TestTool1_2_2/__init__.py create mode 100644 test/toolpath/relative_import/image/tools/TestTool1/TestTool1_2/TestTool1_2_2/sconstest.skip create mode 100644 test/toolpath/relative_import/image/tools/TestTool1/TestTool1_2/__init__.py create mode 100644 test/toolpath/relative_import/image/tools/TestTool1/TestTool1_2/sconstest.skip create mode 100644 test/toolpath/relative_import/image/tools/TestTool1/__init__.py create mode 100644 test/toolpath/relative_import/image/tools/TestTool1/sconstest.skip create mode 100644 test/toolpath/relative_import/relative_import.py diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py index e5b4b05..80a16f5 100644 --- a/src/engine/SCons/Tool/__init__.py +++ b/src/engine/SCons/Tool/__init__.py @@ -225,7 +225,7 @@ class Tool(object): # Not sure what to do in the case that there already # exists sys.modules[self.name] but the source file is # different.. ? - spec.loader.exec_module(module) + module = spec.loader.load_module(spec.name) sys.modules[found_name] = module if add_to_scons_tools_namespace: diff --git a/test/toolpath/relative_import/image/SConstruct b/test/toolpath/relative_import/image/SConstruct new file mode 100644 index 0000000..6156929 --- /dev/null +++ b/test/toolpath/relative_import/image/SConstruct @@ -0,0 +1,10 @@ +env = Environment(tools=['TestTool1', 'TestTool1.TestTool1_2'], toolpath=['tools']) + +# Test a relative import within the root of the tools directory +print("env['TestTool1'] =", env.get('TestTool1')) +print("env['TestTool1_1'] =", env.get('TestTool1_1')) + +# Test a relative import within a sub dir +print("env['TestTool1_2'] =", env.get('TestTool1_2')) +print("env['TestTool1_2_1'] =", env.get('TestTool1_2_1')) +print("env['TestTool1_2_2'] =", env.get('TestTool1_2_2')) diff --git a/test/toolpath/relative_import/image/tools/TestTool1/TestTool1_1.py b/test/toolpath/relative_import/image/tools/TestTool1/TestTool1_1.py new file mode 100644 index 0000000..4c9a7bc --- /dev/null +++ b/test/toolpath/relative_import/image/tools/TestTool1/TestTool1_1.py @@ -0,0 +1,4 @@ +def generate(env): + env['TestTool1_1'] = 1 +def exists(env): + return 1 diff --git a/test/toolpath/relative_import/image/tools/TestTool1/TestTool1_2/TestTool1_2_1.py b/test/toolpath/relative_import/image/tools/TestTool1/TestTool1_2/TestTool1_2_1.py new file mode 100644 index 0000000..e65f8cd --- /dev/null +++ b/test/toolpath/relative_import/image/tools/TestTool1/TestTool1_2/TestTool1_2_1.py @@ -0,0 +1,4 @@ +def generate(env): + env['TestTool1_2_1'] = 1 +def exists(env): + return 1 diff --git a/test/toolpath/relative_import/image/tools/TestTool1/TestTool1_2/TestTool1_2_2/__init__.py b/test/toolpath/relative_import/image/tools/TestTool1/TestTool1_2/TestTool1_2_2/__init__.py new file mode 100644 index 0000000..463baee --- /dev/null +++ b/test/toolpath/relative_import/image/tools/TestTool1/TestTool1_2/TestTool1_2_2/__init__.py @@ -0,0 +1,4 @@ +def generate(env): + env['TestTool1_2_2'] = 1 +def exists(env): + return 1 diff --git a/test/toolpath/relative_import/image/tools/TestTool1/TestTool1_2/TestTool1_2_2/sconstest.skip b/test/toolpath/relative_import/image/tools/TestTool1/TestTool1_2/TestTool1_2_2/sconstest.skip new file mode 100644 index 0000000..e69de29 diff --git a/test/toolpath/relative_import/image/tools/TestTool1/TestTool1_2/__init__.py b/test/toolpath/relative_import/image/tools/TestTool1/TestTool1_2/__init__.py new file mode 100644 index 0000000..8bd698f --- /dev/null +++ b/test/toolpath/relative_import/image/tools/TestTool1/TestTool1_2/__init__.py @@ -0,0 +1,11 @@ +from . import TestTool1_2_1 +from . import TestTool1_2_2 + +def generate(env): + env['TestTool1_2'] = 1 + TestTool1_2_1.generate(env) + TestTool1_2_2.generate(env) +def exists(env): + TestTool1_2_1.exists(env) + TestTool1_2_2.exists(env) + return 1 diff --git a/test/toolpath/relative_import/image/tools/TestTool1/TestTool1_2/sconstest.skip b/test/toolpath/relative_import/image/tools/TestTool1/TestTool1_2/sconstest.skip new file mode 100644 index 0000000..e69de29 diff --git a/test/toolpath/relative_import/image/tools/TestTool1/__init__.py b/test/toolpath/relative_import/image/tools/TestTool1/__init__.py new file mode 100644 index 0000000..d5510d2 --- /dev/null +++ b/test/toolpath/relative_import/image/tools/TestTool1/__init__.py @@ -0,0 +1,9 @@ +from . import TestTool1_1 + +def generate(env): + env['TestTool1'] = 1 + # Include another tool within the same directory + TestTool1_1.generate(env) +def exists(env): + TestTool1_1.exists(env) + return 1 diff --git a/test/toolpath/relative_import/image/tools/TestTool1/sconstest.skip b/test/toolpath/relative_import/image/tools/TestTool1/sconstest.skip new file mode 100644 index 0000000..e69de29 diff --git a/test/toolpath/relative_import/relative_import.py b/test/toolpath/relative_import/relative_import.py new file mode 100644 index 0000000..8fa2f62 --- /dev/null +++ b/test/toolpath/relative_import/relative_import.py @@ -0,0 +1,53 @@ +#!/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 ... +env['TestTool1'] = 1 +env['TestTool1_1'] = 1 +env['TestTool1_2'] = 1 +env['TestTool1_2_1'] = 1 +env['TestTool1_2_2'] = 1 +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: -- cgit v0.12 From 646d64748ab28dca9e30823ab6472e06cf9bd981 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Fri, 30 Jun 2017 11:48:48 -0700 Subject: Micro optimization "." in string is approx 10x faster than string.find('.') >= 0 according to timeit testing. --- src/engine/SCons/Subst.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/SCons/Subst.py b/src/engine/SCons/Subst.py index 3c9b390..9aa4bbc 100644 --- a/src/engine/SCons/Subst.py +++ b/src/engine/SCons/Subst.py @@ -438,7 +438,7 @@ def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={ return s else: key = s[1:] - if key[0] == '{' or key.find('.') >= 0: + if key[0] == '{' or '.' in key: if key[0] == '{': key = key[1:-1] try: -- cgit v0.12 From 65c8b89f4255a80e45219724ccd49df445927c3e Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Sun, 2 Jul 2017 19:00:15 +0100 Subject: Remove inappropriate comment. Correct encoding lines. --- src/engine/SCons/Tool/clang.py | 2 +- src/engine/SCons/Tool/clangxx.py | 2 +- src/engine/SCons/Tool/clangxx.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/engine/SCons/Tool/clang.py b/src/engine/SCons/Tool/clang.py index 3075c46..177e6b2 100644 --- a/src/engine/SCons/Tool/clang.py +++ b/src/engine/SCons/Tool/clang.py @@ -1,4 +1,4 @@ -# -*- encoding: utf-8 -*- +# -*- coding: utf-8; -*- """SCons.Tool.clang diff --git a/src/engine/SCons/Tool/clangxx.py b/src/engine/SCons/Tool/clangxx.py index 60617db..dd501af 100644 --- a/src/engine/SCons/Tool/clangxx.py +++ b/src/engine/SCons/Tool/clangxx.py @@ -1,4 +1,4 @@ -# -*- encoding: utf-8 -*- +# -*- coding: utf-8; -*- """SCons.Tool.clang++ diff --git a/src/engine/SCons/Tool/clangxx.xml b/src/engine/SCons/Tool/clangxx.xml index 25ed1d4..2c1c2ca 100644 --- a/src/engine/SCons/Tool/clangxx.xml +++ b/src/engine/SCons/Tool/clangxx.xml @@ -32,7 +32,7 @@ Set construction variables for the Clang C++ compiler. CXX SHCXXFLAGS - +STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME SHOBJSUFFIX CXXVERSION -- cgit v0.12 From 1b54b04a80618be03001274f3ea75a2fdfb9a6e9 Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Sun, 2 Jul 2017 19:06:33 +0100 Subject: Amend the test file names to remove + symbols from file names. --- test/Clang/clang++_default_environment.py | 64 -------------------------- test/Clang/clang++_shared_library.py | 72 ------------------------------ test/Clang/clang++_specific_environment.py | 60 ------------------------- test/Clang/clang++_static_library.py | 56 ----------------------- test/Clang/clangxx_default_environment.py | 64 ++++++++++++++++++++++++++ test/Clang/clangxx_shared_library.py | 72 ++++++++++++++++++++++++++++++ test/Clang/clangxx_specific_environment.py | 60 +++++++++++++++++++++++++ test/Clang/clangxx_static_library.py | 56 +++++++++++++++++++++++ 8 files changed, 252 insertions(+), 252 deletions(-) delete mode 100644 test/Clang/clang++_default_environment.py delete mode 100644 test/Clang/clang++_shared_library.py delete mode 100644 test/Clang/clang++_specific_environment.py delete mode 100644 test/Clang/clang++_static_library.py create mode 100644 test/Clang/clangxx_default_environment.py create mode 100644 test/Clang/clangxx_shared_library.py create mode 100644 test/Clang/clangxx_specific_environment.py create mode 100644 test/Clang/clangxx_static_library.py diff --git a/test/Clang/clang++_default_environment.py b/test/Clang/clang++_default_environment.py deleted file mode 100644 index beef1e5..0000000 --- a/test/Clang/clang++_default_environment.py +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/env python -# -# __COPYRIGHT__ -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be included -# in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY -# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import TestSCons - -_exe = TestSCons._exe -test = TestSCons.TestSCons() - -if not test.where_is('clang'): - test.skip_test("Could not find 'clang++', skipping test.\n") - -## This will likely NOT use clang++. - -test.write('SConstruct', """\ -env = Environment() -if env['CXX'] != 'clang++': - env['CXX'] = 'clang++' -env.Program('foo.cpp') -""") - -test.write('foo.cpp', """\ -#include -int main(int argc, char ** argv) { - std::cout << "Hello!" << std::endl; - return 0; -} -""") - -test.run() - -test.run(program=test.workpath('foo'+_exe)) - -test.fail_test(not test.stdout() == 'Hello!\n') - -test.pass_test() - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/Clang/clang++_shared_library.py b/test/Clang/clang++_shared_library.py deleted file mode 100644 index d6337ba..0000000 --- a/test/Clang/clang++_shared_library.py +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/env python -# -# __COPYRIGHT__ -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be included -# in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY -# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import TestSCons - -from SCons.Environment import Base - -_exe = TestSCons._exe -test = TestSCons.TestSCons() - -if not test.where_is('clang'): - test.skip_test("Could not find 'clang++', skipping test.\n") - -platform = Base()['PLATFORM'] -if platform == 'posix': - filename = 'foo.os' - libraryname = 'libfoo.so' -elif platform == 'darwin': - filename = 'foo.os' - libraryname = 'libfoo.dylib' -elif platform == 'win32': - filename = 'foo.obj' - libraryname = 'foo.dll' -else: - test.fail_test() - -test.write('SConstruct', """\ -env = Environment(tools=['clang++', 'link']) -env.SharedLibrary('foo', 'foo.cpp') -""") - -test.write('foo.cpp', """\ -int bar() { - return 42; -} -""") - -test.run() - -test.must_exist(test.workpath(filename)) -test.must_exist(test.workpath(libraryname)) - -test.pass_test() - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/Clang/clang++_specific_environment.py b/test/Clang/clang++_specific_environment.py deleted file mode 100644 index 773fa94..0000000 --- a/test/Clang/clang++_specific_environment.py +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/env python -# -# __COPYRIGHT__ -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be included -# in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY -# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import TestSCons - -_exe = TestSCons._exe -test = TestSCons.TestSCons() - -if not test.where_is('clang'): - test.skip_test("Could not find 'clang++', skipping test.\n") - -test.write('SConstruct', """\ -env = Environment(tools=['clang++', 'link']) -env.Program('foo.cpp') -""") - -test.write('foo.cpp', """\ -#include -int main(int argc, char ** argv) { - std::cout << "Hello!" << std::endl; - return 0; -} -""") - -test.run() - -test.run(program=test.workpath('foo'+_exe)) - -test.fail_test(not test.stdout() == 'Hello!\n') - -test.pass_test() - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/Clang/clang++_static_library.py b/test/Clang/clang++_static_library.py deleted file mode 100644 index 77ea58e..0000000 --- a/test/Clang/clang++_static_library.py +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/env python -# -# __COPYRIGHT__ -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be included -# in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY -# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import TestSCons - -_exe = TestSCons._exe -test = TestSCons.TestSCons() - -if not test.where_is('clang'): - test.skip_test("Could not find 'clang++', skipping test.\n") - -test.write('SConstruct', """\ -env = Environment(tools=['clang++', 'ar']) -env.StaticLibrary('foo', 'foo.cpp') -""") - -test.write('foo.cpp', """\ -int bar() { - return 42; -} -""") - -test.run() - -test.must_exist(test.workpath('libfoo.a')) - -test.pass_test() - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/Clang/clangxx_default_environment.py b/test/Clang/clangxx_default_environment.py new file mode 100644 index 0000000..beef1e5 --- /dev/null +++ b/test/Clang/clangxx_default_environment.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import TestSCons + +_exe = TestSCons._exe +test = TestSCons.TestSCons() + +if not test.where_is('clang'): + test.skip_test("Could not find 'clang++', skipping test.\n") + +## This will likely NOT use clang++. + +test.write('SConstruct', """\ +env = Environment() +if env['CXX'] != 'clang++': + env['CXX'] = 'clang++' +env.Program('foo.cpp') +""") + +test.write('foo.cpp', """\ +#include +int main(int argc, char ** argv) { + std::cout << "Hello!" << std::endl; + return 0; +} +""") + +test.run() + +test.run(program=test.workpath('foo'+_exe)) + +test.fail_test(not test.stdout() == 'Hello!\n') + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/Clang/clangxx_shared_library.py b/test/Clang/clangxx_shared_library.py new file mode 100644 index 0000000..d6337ba --- /dev/null +++ b/test/Clang/clangxx_shared_library.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import TestSCons + +from SCons.Environment import Base + +_exe = TestSCons._exe +test = TestSCons.TestSCons() + +if not test.where_is('clang'): + test.skip_test("Could not find 'clang++', skipping test.\n") + +platform = Base()['PLATFORM'] +if platform == 'posix': + filename = 'foo.os' + libraryname = 'libfoo.so' +elif platform == 'darwin': + filename = 'foo.os' + libraryname = 'libfoo.dylib' +elif platform == 'win32': + filename = 'foo.obj' + libraryname = 'foo.dll' +else: + test.fail_test() + +test.write('SConstruct', """\ +env = Environment(tools=['clang++', 'link']) +env.SharedLibrary('foo', 'foo.cpp') +""") + +test.write('foo.cpp', """\ +int bar() { + return 42; +} +""") + +test.run() + +test.must_exist(test.workpath(filename)) +test.must_exist(test.workpath(libraryname)) + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/Clang/clangxx_specific_environment.py b/test/Clang/clangxx_specific_environment.py new file mode 100644 index 0000000..773fa94 --- /dev/null +++ b/test/Clang/clangxx_specific_environment.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import TestSCons + +_exe = TestSCons._exe +test = TestSCons.TestSCons() + +if not test.where_is('clang'): + test.skip_test("Could not find 'clang++', skipping test.\n") + +test.write('SConstruct', """\ +env = Environment(tools=['clang++', 'link']) +env.Program('foo.cpp') +""") + +test.write('foo.cpp', """\ +#include +int main(int argc, char ** argv) { + std::cout << "Hello!" << std::endl; + return 0; +} +""") + +test.run() + +test.run(program=test.workpath('foo'+_exe)) + +test.fail_test(not test.stdout() == 'Hello!\n') + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/Clang/clangxx_static_library.py b/test/Clang/clangxx_static_library.py new file mode 100644 index 0000000..77ea58e --- /dev/null +++ b/test/Clang/clangxx_static_library.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 TestSCons + +_exe = TestSCons._exe +test = TestSCons.TestSCons() + +if not test.where_is('clang'): + test.skip_test("Could not find 'clang++', skipping test.\n") + +test.write('SConstruct', """\ +env = Environment(tools=['clang++', 'ar']) +env.StaticLibrary('foo', 'foo.cpp') +""") + +test.write('foo.cpp', """\ +int bar() { + return 42; +} +""") + +test.run() + +test.must_exist(test.workpath('libfoo.a')) + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: -- cgit v0.12 From bb7fd9c6b0348092a6825f3572b557c0b24dd4b5 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 3 Jul 2017 15:06:02 -0400 Subject: Add an alternative to evaluate lvar vs gvar --- bench/lvars-gvars.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/bench/lvars-gvars.py b/bench/lvars-gvars.py index bdb09ef..1511203 100644 --- a/bench/lvars-gvars.py +++ b/bench/lvars-gvars.py @@ -45,6 +45,12 @@ def Func4(var, gvars, lvars): except NameError: x = '' +def Func5(var, gvars, lvars): + """Chained get with default values""" + for i in IterationList: + x = lvars.get(var,gvars.get(var,'')) + + # Data to pass to the functions on each run. Each entry is a # three-element tuple: # -- cgit v0.12 From 3adbe147e6d8dcf9a9b14fddf62f22e067ca5578 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 3 Jul 2017 15:10:01 -0400 Subject: PY2/3 test framework changes. POpen will alway set universal_newlines if encoding is set. So we don't set encoding and pass universal_newlines=False. Then we'll need to do the decode explicitly for PY3 --- QMTest/TestCmd.py | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/QMTest/TestCmd.py b/QMTest/TestCmd.py index 61da8b9..00d61d3 100644 --- a/QMTest/TestCmd.py +++ b/QMTest/TestCmd.py @@ -1407,29 +1407,22 @@ class TestCmd(object): self.timer = threading.Timer(float(timeout), self._timeout) self.timer.start() - if sys.version_info[0] == 3 and sys.platform == 'win32': + if IS_PY3 and sys.platform == 'win32': # Set this otherwist stdout/stderr pipes default to # windows default locale cp1252 which will throw exception # if using non-ascii characters. # For example test/Install/non-ascii-name.py os.environ['PYTHONIOENCODING'] = 'utf-8' - if sys.version_info[0] == 2 or sys.version_info[0:2] < (3, 6): - p = Popen(cmd, - stdin=stdin, - stdout=subprocess.PIPE, - stderr=stderr_value, - env=os.environ, - universal_newlines=False) - else: - # this will only work on py3.6, encoding - p = Popen(cmd, - stdin=stdin, - stdout=subprocess.PIPE, - stderr=stderr_value, - env=os.environ, - universal_newlines=universal_newlines, - encoding='utf-8') + # It seems that all pythons up to py3.6 still set text mode if you set encoding. + # TODO: File enhancement request on python to propagate universal_newlines even + # if encoding is set.hg c + p = Popen(cmd, + stdin=stdin, + stdout=subprocess.PIPE, + stderr=stderr_value, + env=os.environ, + universal_newlines=False) self.process = p return p @@ -1452,7 +1445,9 @@ class TestCmd(object): if not stream: return stream - elif sys.version_info[0] == 3 and sys.version_info[1] < 6: + # TODO: Run full tests on both platforms and see if this fixes failures + # It seems that py3.6 still sets text mode if you set encoding. + elif sys.version_info[0] == 3:# TODO and sys.version_info[1] < 6: stream = stream.decode('utf-8') stream = stream.replace('\r\n', '\n') elif sys.version_info[0] == 2: @@ -1521,7 +1516,7 @@ class TestCmd(object): if is_List(stdin): stdin = ''.join(stdin) - if stdin and sys.version_info[0] == 3 and sys.version_info[1] < 6: + if stdin and IS_PY3 and sys.version_info[1] < 6: stdin = bytearray(stdin,'utf-8') # TODO(sgk): figure out how to re-use the logic in the .finish() -- cgit v0.12 From 6d36db01745c45b107ccaaf57b2768ae3a6b83bd Mon Sep 17 00:00:00 2001 From: Evan Driscoll Date: Wed, 5 Jul 2017 21:39:41 -0500 Subject: Make sure more file objects are explicitly closed --- src/engine/SCons/Debug.py | 4 +++- src/engine/SCons/Tool/linkloc.py | 4 ++-- src/engine/SCons/Util.py | 5 ++--- src/engine/SCons/Variables/__init__.py | 4 +++- src/engine/SCons/cpp.py | 3 ++- 5 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/engine/SCons/Debug.py b/src/engine/SCons/Debug.py index 9e520ff..706b4c4 100644 --- a/src/engine/SCons/Debug.py +++ b/src/engine/SCons/Debug.py @@ -97,7 +97,8 @@ def dumpLoggedInstances(classes, file=sys.stdout): if sys.platform[:5] == "linux": # Linux doesn't actually support memory usage stats from getrusage(). def memory(): - mstr = open('/proc/self/stat').read() + with open('/proc/self/stat') as f: + mstr = f.read() mstr = mstr.split()[22] return int(mstr) elif sys.platform[:6] == 'darwin': @@ -233,6 +234,7 @@ def Trace(msg, file=None, mode='w', tstamp=None): PreviousTime = now fp.write(msg) fp.flush() + fp.close() # Local Variables: # tab-width:4 diff --git a/src/engine/SCons/Tool/linkloc.py b/src/engine/SCons/Tool/linkloc.py index bd643f7..c73852b 100644 --- a/src/engine/SCons/Tool/linkloc.py +++ b/src/engine/SCons/Tool/linkloc.py @@ -52,8 +52,8 @@ def repl_linker_command(m): # Replaces any linker command file directives (e.g. "@foo.lnk") with # the actual contents of the file. try: - f=open(m.group(2), "r") - return m.group(1) + f.read() + with open(m.group(2), "r") as f: + return m.group(1) + f.read() except IOError: # the linker should return an error if it can't # find the linker command file so we will remain quiet. diff --git a/src/engine/SCons/Util.py b/src/engine/SCons/Util.py index 4d0df22..846d06c 100644 --- a/src/engine/SCons/Util.py +++ b/src/engine/SCons/Util.py @@ -1506,9 +1506,8 @@ def MD5signature(s): def MD5filesignature(fname, chunksize=65536): - f = open(fname, "rb") - result = f.read() - f.close() + with open(fname, "rb") as f: + result = f.read() return result try: diff --git a/src/engine/SCons/Variables/__init__.py b/src/engine/SCons/Variables/__init__.py index cd66604..1fe4435 100644 --- a/src/engine/SCons/Variables/__init__.py +++ b/src/engine/SCons/Variables/__init__.py @@ -175,7 +175,9 @@ class Variables(object): sys.path.insert(0, dir) try: values['__name__'] = filename - exec(open(filename, 'r').read(), {}, values) + with open(filename, 'r') as f: + contents = f.read() + exec(contents, {}, values) finally: if dir: del sys.path[0] diff --git a/src/engine/SCons/cpp.py b/src/engine/SCons/cpp.py index f282ba7..2e20017 100644 --- a/src/engine/SCons/cpp.py +++ b/src/engine/SCons/cpp.py @@ -379,7 +379,8 @@ class PreProcessor(object): return None def read_file(self, file): - return open(file).read() + with open(file) as f: + return f.read() # Start and stop processing include lines. -- cgit v0.12 From 0eaef4f2b8064882e7497695ba352c719b543dc8 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Thu, 6 Jul 2017 11:54:40 -0400 Subject: python micro optimization in faster than find --- src/engine/SCons/PathList.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engine/SCons/PathList.py b/src/engine/SCons/PathList.py index 77e30c4..76cbeab 100644 --- a/src/engine/SCons/PathList.py +++ b/src/engine/SCons/PathList.py @@ -104,11 +104,11 @@ class _PathList(object): pl = [] for p in pathlist: try: - index = p.find('$') + found = '$' in p except (AttributeError, TypeError): type = TYPE_OBJECT else: - if index == -1: + if not found: type = TYPE_STRING_NO_SUBST else: type = TYPE_STRING_SUBST -- cgit v0.12 From d2b59cc6d18e5d3139f623ab4285de34b3dd5596 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 10 Jul 2017 15:01:04 -0400 Subject: py2/3 always convert stdin to bytes if py3. Previously was 3.5 only --- QMTest/TestCmd.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/QMTest/TestCmd.py b/QMTest/TestCmd.py index 00d61d3..0aab9a8 100644 --- a/QMTest/TestCmd.py +++ b/QMTest/TestCmd.py @@ -1516,8 +1516,8 @@ class TestCmd(object): if is_List(stdin): stdin = ''.join(stdin) - if stdin and IS_PY3 and sys.version_info[1] < 6: - stdin = bytearray(stdin,'utf-8') + if stdin and IS_PY3:# and sys.version_info[1] < 6: + stdin = to_bytes(stdin) # TODO(sgk): figure out how to re-use the logic in the .finish() # method above. Just calling it from here causes problems with -- cgit v0.12 From 7f45d674f1d288349f48c8218487cc473ce736d9 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Thu, 20 Jul 2017 15:24:49 -0400 Subject: change comment to docstring as it should have been --- src/engine/SCons/Environment.py | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py index 85f9fa7..60a45e4 100644 --- a/src/engine/SCons/Environment.py +++ b/src/engine/SCons/Environment.py @@ -2368,19 +2368,21 @@ class OverrideEnvironment(Base): Environment = Base -# An entry point for returning a proxy subclass instance that overrides -# the subst*() methods so they don't actually perform construction -# variable substitution. This is specifically intended to be the shim -# layer in between global function calls (which don't want construction -# variable substitution) and the DefaultEnvironment() (which would -# substitute variables if left to its own devices).""" -# -# We have to wrap this in a function that allows us to delay definition of -# the class until it's necessary, so that when it subclasses Environment -# it will pick up whatever Environment subclass the wrapper interface -# might have assigned to SCons.Environment.Environment. def NoSubstitutionProxy(subject): + """ + An entry point for returning a proxy subclass instance that overrides + the subst*() methods so they don't actually perform construction + variable substitution. This is specifically intended to be the shim + layer in between global function calls (which don't want construction + variable substitution) and the DefaultEnvironment() (which would + substitute variables if left to its own devices). + + We have to wrap this in a function that allows us to delay definition of + the class until it's necessary, so that when it subclasses Environment + it will pick up whatever Environment subclass the wrapper interface + might have assigned to SCons.Environment.Environment. + """ class _NoSubstitutionProxy(Environment): def __init__(self, subject): self.__dict__['__subject'] = subject -- cgit v0.12 From 506a8fefa9fa26a057e1464be2db8680b90339b4 Mon Sep 17 00:00:00 2001 From: Ibrahim Esmat Date: Fri, 21 Jul 2017 10:54:55 -0700 Subject: Windows: Added the capability to build Windows Store Compatible libraries that can be used with Universal Windows Platform (UWP) Apps and published to the Windows Store --- src/CHANGES.txt | 4 ++++ src/engine/SCons/Tool/MSCommon/vc.py | 21 ++++++++++++++------- src/engine/SCons/Tool/msvc.xml | 25 +++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 7 deletions(-) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 5be0399..c585eaf 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -11,6 +11,10 @@ NOTE: This is a major release. You should expect that some targets may rebuild Significant changes in some python action signatures. Also switching between PY 2 and PY 3.5, 3.6 may cause rebuilds. In no case should rebuilds not happen. + From Ibrahim Esmat: + - Added the capability to build Windows Store Compatible libraries that can be used + with Universal Windows Platform (UWP) Apps and published to the store + From Richard West: - Added nested / namespace tool support - Added a small fix to the python3 tool loader when loading a tool as a package diff --git a/src/engine/SCons/Tool/MSCommon/vc.py b/src/engine/SCons/Tool/MSCommon/vc.py index 7b8dd9d..ff48e01 100644 --- a/src/engine/SCons/Tool/MSCommon/vc.py +++ b/src/engine/SCons/Tool/MSCommon/vc.py @@ -82,7 +82,7 @@ _ARCH_TO_CANONICAL = { "itanium" : "ia64", "x86" : "x86", "x86_64" : "amd64", - "x86_amd64" : "x86_amd64", # Cross compile to 64 bit from 32bits + "x86_amd64" : "x86_amd64", # Cross compile to 64 bit from 32bits } # Given a (host, target) tuple, return the argument for the bat file. Both host @@ -185,18 +185,17 @@ _VCVER_TO_PRODUCT_DIR = { } def msvc_version_to_maj_min(msvc_version): - msvc_version_numeric = ''.join([x for x in msvc_version if x in string_digits + '.']) t = msvc_version_numeric.split(".") if not len(t) == 2: - raise ValueError("Unrecognized version %s (%s)" % (msvc_version,msvc_version_numeric)) + raise ValueError("Unrecognized version %s (%s)" % (msvc_version,msvc_version_numeric)) try: - maj = int(t[0]) - min = int(t[1]) - return maj, min + maj = int(t[0]) + min = int(t[1]) + return maj, min except ValueError as e: - raise ValueError("Unrecognized version %s (%s)" % (msvc_version,msvc_version_numeric)) + raise ValueError("Unrecognized version %s (%s)" % (msvc_version,msvc_version_numeric)) def is_host_target_supported(host_target, msvc_version): """Return True if the given (host, target) tuple is supported given the @@ -435,6 +434,14 @@ def msvc_find_valid_batch_script(env,version): (host_target, version) SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, warn_msg) arg = _HOST_TARGET_ARCH_TO_BAT_ARCH[host_target] + + # Get just version numbers + maj, min = msvc_version_to_maj_min(version) + # VS2015+ + if maj >= 14: + if env.get('UWP_APP') == '1': + # Initialize environment variables with store/universal paths + arg += ' store' # Try to locate a batch file for this host/target platform combo try: diff --git a/src/engine/SCons/Tool/msvc.xml b/src/engine/SCons/Tool/msvc.xml index 2b4619e..18f4fb6 100644 --- a/src/engine/SCons/Tool/msvc.xml +++ b/src/engine/SCons/Tool/msvc.xml @@ -352,6 +352,8 @@ constructor; setting it later has no effect. Valid values for Windows are +14.0, +14.0Exp, 12.0, 12.0Exp, 11.0, @@ -440,4 +442,27 @@ For example, if you want to compile 64-bit binaries, you would set + + + +Build libraries for a Universal Windows Platform (UWP) Application. + + + +If &cv-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' + + + + + -- cgit v0.12 From 990d7e365e97fa5f700aebd97e5ec699a6f69976 Mon Sep 17 00:00:00 2001 From: Ibrahim Esmat Date: Fri, 21 Jul 2017 11:13:24 -0700 Subject: Windows: Added the capability to build Windows Store Compatible libraries Fixed whitespace --- 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 ff48e01..c0a1043 100644 --- a/src/engine/SCons/Tool/MSCommon/vc.py +++ b/src/engine/SCons/Tool/MSCommon/vc.py @@ -82,7 +82,7 @@ _ARCH_TO_CANONICAL = { "itanium" : "ia64", "x86" : "x86", "x86_64" : "amd64", - "x86_amd64" : "x86_amd64", # Cross compile to 64 bit from 32bits + "x86_amd64" : "x86_amd64", # Cross compile to 64 bit from 32bits } # Given a (host, target) tuple, return the argument for the bat file. Both host -- cgit v0.12 From 696fe750f247bb4cadbbf8be6970e15af67e1e4b Mon Sep 17 00:00:00 2001 From: Ibrahim Esmat Date: Mon, 24 Jul 2017 12:09:00 -0700 Subject: Change UWP_APP to be MSVC_UWP_APP --- src/engine/SCons/Tool/MSCommon/vc.py | 2 +- src/engine/SCons/Tool/msvc.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/engine/SCons/Tool/MSCommon/vc.py b/src/engine/SCons/Tool/MSCommon/vc.py index c0a1043..4126314 100644 --- a/src/engine/SCons/Tool/MSCommon/vc.py +++ b/src/engine/SCons/Tool/MSCommon/vc.py @@ -439,7 +439,7 @@ def msvc_find_valid_batch_script(env,version): maj, min = msvc_version_to_maj_min(version) # VS2015+ if maj >= 14: - if env.get('UWP_APP') == '1': + if env.get('MSVC_UWP_APP') == '1': # Initialize environment variables with store/universal paths arg += ' store' diff --git a/src/engine/SCons/Tool/msvc.xml b/src/engine/SCons/Tool/msvc.xml index 18f4fb6..1823a89 100644 --- a/src/engine/SCons/Tool/msvc.xml +++ b/src/engine/SCons/Tool/msvc.xml @@ -442,14 +442,14 @@ For example, if you want to compile 64-bit binaries, you would set - + Build libraries for a Universal Windows Platform (UWP) Application. -If &cv-UWP_APP; is set, the Visual Studio environment will be set up to point +If &cv-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. -- cgit v0.12 From 6537bede8fd7a346865cebfde59d3d4fe8f9cf1f Mon Sep 17 00:00:00 2001 From: Ibrahim Esmat Date: Wed, 26 Jul 2017 00:26:08 -0700 Subject: Added MSVC_UWP_APP test to test setting MSVC_UWP_APP construction variable with desired effect. --- test/MSVC/MSVC_UWP_APP.py | 103 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 test/MSVC/MSVC_UWP_APP.py diff --git a/test/MSVC/MSVC_UWP_APP.py b/test/MSVC/MSVC_UWP_APP.py new file mode 100644 index 0000000..b6012cc --- /dev/null +++ b/test/MSVC/MSVC_UWP_APP.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Test the ability to configure the $MSVC_UWP_APP construction variable with +the desired effect. +""" + +import TestSCons + +def AreVCStoreLibPathsInLIBPATH(output): + lines = output.splitlines() + for line in lines: + if 'env[ENV][LIBPATH]=' in line: + idx_eq = line.find('=') + libpath = line[idx_eq + 1:] + + if not libpath: + # Couldn't find the libpath in the output + return (False, False) + + libpaths = libpath.lower().split(';') + (vclibstore_path_present, vclibstorerefs_path_present) = (False, False) + for path in libpaths: + # Look for the Store VC Lib paths in the LIBPATH: + # [VS install path]\VC\LIB\store\ and + # [VS install path]\VC\LIB\store\references + # For example, + # C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\LIB\store\amd64 + # C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\LIB\store\references + if 'vc\\lib\\store\\references' in path: + vclibstorerefs_path_present = True + elif 'vc\\lib\\store' in path: + vclibstore_path_present = True + + return (vclibstore_path_present, vclibstorerefs_path_present) + +_python_ = TestSCons._python_ + +test = TestSCons.TestSCons() + +test.skip_if_not_msvc() + +test.write('SConstruct', """ +if ARGUMENTS.get('MSVC_UWP_APP'): + help_vars = Variables() + help_vars.Add(EnumVariable( + 'MSVC_UWP_APP', + 'Build for a Universal Windows Platform (UWP) Application', + '0', + allowed_values=('0', '1'))) +else: + help_vars = None +env = Environment(tools=['default', 'msvc'], variables=help_vars) +# Print the ENV LIBPATH to stdout +print ('env[ENV][LIBPATH]=%s' % env.get('ENV').get('LIBPATH')) +""") + +# Test setting MSVC_UWP_APP is '1' (True) +test.run(arguments = "MSVC_UWP_APP=1") +(vclibstore_path_present, vclibstorerefs_path_present) = AreVCStoreLibPathsInLIBPATH(test.stdout()) +test.fail_test((vclibstore_path_present is False) or (vclibstorerefs_path_present is False)) + +# Test setting MSVC_UWP_APP is '0' (False) +test.run(arguments = "MSVC_UWP_APP=0") +(vclibstore_path_present, vclibstorerefs_path_present) = AreVCStoreLibPathsInLIBPATH(test.stdout()) +test.fail_test((vclibstore_path_present is True) or (vclibstorerefs_path_present is True)) + +# Test not setting MSVC_UWP_APP +test.run(arguments = "") +(vclibstore_path_present, vclibstorerefs_path_present) = AreVCStoreLibPathsInLIBPATH(test.stdout()) +test.fail_test((vclibstore_path_present is True) or (vclibstorerefs_path_present is True)) + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: -- cgit v0.12 From 120b1633f2bc371df744fce06f5c5024fe59a174 Mon Sep 17 00:00:00 2001 From: Ibrahim Esmat Date: Wed, 26 Jul 2017 11:39:13 -0700 Subject: Minor changes for Code Review --- test/MSVC/MSVC_UWP_APP.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/MSVC/MSVC_UWP_APP.py b/test/MSVC/MSVC_UWP_APP.py index b6012cc..2521ad6 100644 --- a/test/MSVC/MSVC_UWP_APP.py +++ b/test/MSVC/MSVC_UWP_APP.py @@ -46,14 +46,14 @@ def AreVCStoreLibPathsInLIBPATH(output): (vclibstore_path_present, vclibstorerefs_path_present) = (False, False) for path in libpaths: # Look for the Store VC Lib paths in the LIBPATH: - # [VS install path]\VC\LIB\store\ and + # [VS install path]\VC\LIB\store[\arch] and # [VS install path]\VC\LIB\store\references # For example, # C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\LIB\store\amd64 # C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\LIB\store\references - if 'vc\\lib\\store\\references' in path: + if r'vc\lib\store\references' in path: vclibstorerefs_path_present = True - elif 'vc\\lib\\store' in path: + elif r'vc\lib\store' in path: vclibstore_path_present = True return (vclibstore_path_present, vclibstorerefs_path_present) @@ -76,7 +76,7 @@ else: help_vars = None env = Environment(tools=['default', 'msvc'], variables=help_vars) # Print the ENV LIBPATH to stdout -print ('env[ENV][LIBPATH]=%s' % env.get('ENV').get('LIBPATH')) +print('env[ENV][LIBPATH]=%s' % env.get('ENV').get('LIBPATH')) """) # Test setting MSVC_UWP_APP is '1' (True) -- cgit v0.12 From d9c5836692f8066b7c4fdf42c5a79c32957bff08 Mon Sep 17 00:00:00 2001 From: Ibrahim Esmat Date: Wed, 26 Jul 2017 21:24:10 -0700 Subject: Fix MSVC_UWP_APP test to take into account the MSVC_VERSION. The test should take into account if the MSVC_VERSION is less than 14.0 (VS2015) and check that the LIBPATH doesn't include the store paths. --- test/MSVC/MSVC_UWP_APP.py | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/test/MSVC/MSVC_UWP_APP.py b/test/MSVC/MSVC_UWP_APP.py index 2521ad6..6d33567 100644 --- a/test/MSVC/MSVC_UWP_APP.py +++ b/test/MSVC/MSVC_UWP_APP.py @@ -30,17 +30,23 @@ the desired effect. """ import TestSCons +import SCons.Tool.MSCommon.vc as msvc def AreVCStoreLibPathsInLIBPATH(output): + libpath = None + msvc_version = None lines = output.splitlines() for line in lines: if 'env[ENV][LIBPATH]=' in line: idx_eq = line.find('=') libpath = line[idx_eq + 1:] + elif 'env[MSVC_VERSION]=' in line: + idx_eq = line.find('=') + msvc_version = line[idx_eq + 1:] - if not libpath: - # Couldn't find the libpath in the output - return (False, False) + if not libpath or not msvc_version: + # Couldn't find the libpath or msvc version in the output + return (False, False, None) libpaths = libpath.lower().split(';') (vclibstore_path_present, vclibstorerefs_path_present) = (False, False) @@ -56,7 +62,7 @@ def AreVCStoreLibPathsInLIBPATH(output): elif r'vc\lib\store' in path: vclibstore_path_present = True - return (vclibstore_path_present, vclibstorerefs_path_present) + return (vclibstore_path_present, vclibstorerefs_path_present, msvc_version) _python_ = TestSCons._python_ @@ -77,21 +83,37 @@ else: env = Environment(tools=['default', 'msvc'], variables=help_vars) # Print the ENV LIBPATH to stdout print('env[ENV][LIBPATH]=%s' % env.get('ENV').get('LIBPATH')) +print('env[MSVC_VERSION]=%s' % env.get('MSVC_VERSION')) """) +installed_msvc_versions = msvc.cached_get_installed_vcs() +# MSVC guaranteed to be at least one version on the system or else skip_if_not_msvc() function +# would have skipped the test +greatest_msvc_version_on_system = installed_msvc_versions[0] +maj, min = msvc.msvc_version_to_maj_min(greatest_msvc_version_on_system) + +# We always use the greatest MSVC version installed on the system + # Test setting MSVC_UWP_APP is '1' (True) test.run(arguments = "MSVC_UWP_APP=1") -(vclibstore_path_present, vclibstorerefs_path_present) = AreVCStoreLibPathsInLIBPATH(test.stdout()) -test.fail_test((vclibstore_path_present is False) or (vclibstorerefs_path_present is False)) +(vclibstore_path_present, vclibstorerefs_path_present, msvc_version) = AreVCStoreLibPathsInLIBPATH(test.stdout()) +test.fail_test(msvc_version != greatest_msvc_version_on_system) +# VS2015+ +if maj >= 14: + test.fail_test((vclibstore_path_present is False) or (vclibstorerefs_path_present is False)) +else: + test.fail_test((vclibstore_path_present is True) or (vclibstorerefs_path_present is True)) # Test setting MSVC_UWP_APP is '0' (False) test.run(arguments = "MSVC_UWP_APP=0") -(vclibstore_path_present, vclibstorerefs_path_present) = AreVCStoreLibPathsInLIBPATH(test.stdout()) +(vclibstore_path_present, vclibstorerefs_path_present, msvc_version) = AreVCStoreLibPathsInLIBPATH(test.stdout()) +test.fail_test(msvc_version != greatest_msvc_version_on_system) test.fail_test((vclibstore_path_present is True) or (vclibstorerefs_path_present is True)) # Test not setting MSVC_UWP_APP test.run(arguments = "") -(vclibstore_path_present, vclibstorerefs_path_present) = AreVCStoreLibPathsInLIBPATH(test.stdout()) +(vclibstore_path_present, vclibstorerefs_path_present, msvc_version) = AreVCStoreLibPathsInLIBPATH(test.stdout()) +test.fail_test(msvc_version != greatest_msvc_version_on_system) test.fail_test((vclibstore_path_present is True) or (vclibstorerefs_path_present is True)) test.pass_test() -- cgit v0.12 From b9df77702c7c7c669b29e8a23af8932a2f30492e Mon Sep 17 00:00:00 2001 From: Ibrahim Esmat Date: Thu, 27 Jul 2017 06:00:46 -0700 Subject: Fix MSVC_UWP_APP test to take into account the MSVC_VERSION. Code Review Fixes. --- test/MSVC/MSVC_UWP_APP.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/test/MSVC/MSVC_UWP_APP.py b/test/MSVC/MSVC_UWP_APP.py index 6d33567..1ffc917 100644 --- a/test/MSVC/MSVC_UWP_APP.py +++ b/test/MSVC/MSVC_UWP_APP.py @@ -38,11 +38,9 @@ def AreVCStoreLibPathsInLIBPATH(output): lines = output.splitlines() for line in lines: if 'env[ENV][LIBPATH]=' in line: - idx_eq = line.find('=') - libpath = line[idx_eq + 1:] + libpath = line.split('=')[1] elif 'env[MSVC_VERSION]=' in line: - idx_eq = line.find('=') - msvc_version = line[idx_eq + 1:] + msvc_version = line.split('=')[1] if not libpath or not msvc_version: # Couldn't find the libpath or msvc version in the output @@ -100,21 +98,25 @@ test.run(arguments = "MSVC_UWP_APP=1") test.fail_test(msvc_version != greatest_msvc_version_on_system) # VS2015+ if maj >= 14: - test.fail_test((vclibstore_path_present is False) or (vclibstorerefs_path_present is False)) + test.fail_test((vclibstore_path_present is False) or (vclibstorerefs_path_present is False), + message='VC Store LIBPATHs NOT present when MSVC_UWP_APP=1 (msvc_version=%s)' % msvc_version) else: - test.fail_test((vclibstore_path_present is True) or (vclibstorerefs_path_present is True)) + test.fail_test((vclibstore_path_present is True) or (vclibstorerefs_path_present is True), + message='VC Store LIBPATHs present for unsupported version when MSVC_UWP_APP=1 (msvc_version=%s)' % msvc_version) # Test setting MSVC_UWP_APP is '0' (False) test.run(arguments = "MSVC_UWP_APP=0") (vclibstore_path_present, vclibstorerefs_path_present, msvc_version) = AreVCStoreLibPathsInLIBPATH(test.stdout()) test.fail_test(msvc_version != greatest_msvc_version_on_system) -test.fail_test((vclibstore_path_present is True) or (vclibstorerefs_path_present is True)) +test.fail_test((vclibstore_path_present is True) or (vclibstorerefs_path_present is True), + message='VC Store LIBPATHs present when MSVC_UWP_APP=0 (msvc_version=%s)' % msvc_version) # Test not setting MSVC_UWP_APP test.run(arguments = "") (vclibstore_path_present, vclibstorerefs_path_present, msvc_version) = AreVCStoreLibPathsInLIBPATH(test.stdout()) test.fail_test(msvc_version != greatest_msvc_version_on_system) -test.fail_test((vclibstore_path_present is True) or (vclibstorerefs_path_present is True)) +test.fail_test((vclibstore_path_present is True) or (vclibstorerefs_path_present is True), + message='VC Store LIBPATHs present when MSVC_UWP_APP not set (msvc_version=%s)' % msvc_version) test.pass_test() -- cgit v0.12 From b1a30ba5733531036223946538731a4057bb84e8 Mon Sep 17 00:00:00 2001 From: Ibrahim Esmat Date: Thu, 27 Jul 2017 06:08:05 -0700 Subject: Fix MSVC_UWP_APP test to take into account the MSVC_VERSION. Missed a couple of messages on fail_test --- test/MSVC/MSVC_UWP_APP.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/test/MSVC/MSVC_UWP_APP.py b/test/MSVC/MSVC_UWP_APP.py index 1ffc917..19cd3f7 100644 --- a/test/MSVC/MSVC_UWP_APP.py +++ b/test/MSVC/MSVC_UWP_APP.py @@ -95,7 +95,9 @@ maj, min = msvc.msvc_version_to_maj_min(greatest_msvc_version_on_system) # Test setting MSVC_UWP_APP is '1' (True) test.run(arguments = "MSVC_UWP_APP=1") (vclibstore_path_present, vclibstorerefs_path_present, msvc_version) = AreVCStoreLibPathsInLIBPATH(test.stdout()) -test.fail_test(msvc_version != greatest_msvc_version_on_system) +test.fail_test(msvc_version != greatest_msvc_version_on_system, + message='MSVC_VERSION (%s) does not match expected greatest version on system (%s)' \ + % (msvc_version, greatest_msvc_version_on_system)) # VS2015+ if maj >= 14: test.fail_test((vclibstore_path_present is False) or (vclibstorerefs_path_present is False), @@ -107,14 +109,18 @@ else: # Test setting MSVC_UWP_APP is '0' (False) test.run(arguments = "MSVC_UWP_APP=0") (vclibstore_path_present, vclibstorerefs_path_present, msvc_version) = AreVCStoreLibPathsInLIBPATH(test.stdout()) -test.fail_test(msvc_version != greatest_msvc_version_on_system) +test.fail_test(msvc_version != greatest_msvc_version_on_system, + message='MSVC_VERSION (%s) does not match expected greatest version on system (%s)' \ + % (msvc_version, greatest_msvc_version_on_system)) test.fail_test((vclibstore_path_present is True) or (vclibstorerefs_path_present is True), message='VC Store LIBPATHs present when MSVC_UWP_APP=0 (msvc_version=%s)' % msvc_version) # Test not setting MSVC_UWP_APP test.run(arguments = "") (vclibstore_path_present, vclibstorerefs_path_present, msvc_version) = AreVCStoreLibPathsInLIBPATH(test.stdout()) -test.fail_test(msvc_version != greatest_msvc_version_on_system) +test.fail_test(msvc_version != greatest_msvc_version_on_system, + message='MSVC_VERSION (%s) does not match expected greatest version on system (%s)' \ + % (msvc_version, greatest_msvc_version_on_system)) test.fail_test((vclibstore_path_present is True) or (vclibstorerefs_path_present is True), message='VC Store LIBPATHs present when MSVC_UWP_APP not set (msvc_version=%s)' % msvc_version) -- cgit v0.12 From 8538f41852596fc1407f96d98b1be677aaf36be4 Mon Sep 17 00:00:00 2001 From: grbd Date: Thu, 27 Jul 2017 21:20:30 +0100 Subject: update to tests for nested tools and to add as an example for using sys.path in the toolpath --- .../image/Libs/tools_example/Toolpath_TestTool1.py | 4 ++ .../tools_example/Toolpath_TestTool2/__init__.py | 4 ++ .../Toolpath_TestTool2/sconstest.skip | 0 .../nested/image/Libs/tools_example/__init__.py | 0 .../nested/image/Libs/tools_example/sconstest.skip | 0 .../tools_example/subdir1/Toolpath_TestTool1_1.py | 4 ++ .../subdir1/Toolpath_TestTool1_2/__init__.py | 4 ++ .../subdir1/Toolpath_TestTool1_2/sconstest.skip | 0 .../image/Libs/tools_example/subdir1/__init__.py | 0 .../Libs/tools_example/subdir1/sconstest.skip | 0 .../subdir1/subdir2/Toolpath_TestTool2_1.py | 4 ++ .../subdir2/Toolpath_TestTool2_2/__init__.py | 4 ++ .../subdir2/Toolpath_TestTool2_2/sconstest.skip | 0 .../Libs/tools_example/subdir1/subdir2/__init__.py | 0 .../tools_example/subdir1/subdir2/sconstest.skip | 0 test/toolpath/nested/image/SConstruct | 71 ++++++++++++++++++---- .../site_scons/site_tools/Toolpath_TestTool1.py | 4 ++ .../site_tools/Toolpath_TestTool2/__init__.py | 4 ++ .../site_tools/Toolpath_TestTool2/sconstest.skip | 0 .../nested/image/site_scons/site_tools/__init__.py | 0 .../image/site_scons/site_tools/sconstest.skip | 0 .../site_tools/subdir1/Site_TestTool1.py | 4 -- .../site_tools/subdir1/Site_TestTool3/__init__.py | 4 -- .../subdir1/Site_TestTool3/sconstest.skip | 0 .../site_tools/subdir1/Toolpath_TestTool1_1.py | 4 ++ .../subdir1/Toolpath_TestTool1_2/__init__.py | 4 ++ .../subdir1/Toolpath_TestTool1_2/sconstest.skip | 0 .../site_tools/subdir1/subdir2/Site_TestTool2.py | 4 -- .../subdir1/subdir2/Toolpath_TestTool2_1.py | 4 ++ .../subdir2/Toolpath_TestTool2_2/__init__.py | 4 ++ .../subdir2/Toolpath_TestTool2_2/sconstest.skip | 0 test/toolpath/nested/image/testsrc1.txt | 0 .../image/tools/subdir1/Toolpath_TestTool1.py | 4 -- .../tools/subdir1/Toolpath_TestTool3/__init__.py | 4 -- .../subdir1/Toolpath_TestTool3/sconstest.skip | 0 .../nested/image/tools/subdir1/__init__.py | 0 .../nested/image/tools/subdir1/sconstest.skip | 0 .../tools/subdir1/subdir2/Toolpath_TestTool2.py | 4 -- .../nested/image/tools/subdir1/subdir2/__init__.py | 0 .../image/tools/subdir1/subdir2/sconstest.skip | 0 test/toolpath/nested/nested.py | 27 ++++++-- 41 files changed, 129 insertions(+), 41 deletions(-) create mode 100644 test/toolpath/nested/image/Libs/tools_example/Toolpath_TestTool1.py create mode 100644 test/toolpath/nested/image/Libs/tools_example/Toolpath_TestTool2/__init__.py create mode 100644 test/toolpath/nested/image/Libs/tools_example/Toolpath_TestTool2/sconstest.skip create mode 100644 test/toolpath/nested/image/Libs/tools_example/__init__.py create mode 100644 test/toolpath/nested/image/Libs/tools_example/sconstest.skip create mode 100644 test/toolpath/nested/image/Libs/tools_example/subdir1/Toolpath_TestTool1_1.py create mode 100644 test/toolpath/nested/image/Libs/tools_example/subdir1/Toolpath_TestTool1_2/__init__.py create mode 100644 test/toolpath/nested/image/Libs/tools_example/subdir1/Toolpath_TestTool1_2/sconstest.skip create mode 100644 test/toolpath/nested/image/Libs/tools_example/subdir1/__init__.py create mode 100644 test/toolpath/nested/image/Libs/tools_example/subdir1/sconstest.skip create mode 100644 test/toolpath/nested/image/Libs/tools_example/subdir1/subdir2/Toolpath_TestTool2_1.py create mode 100644 test/toolpath/nested/image/Libs/tools_example/subdir1/subdir2/Toolpath_TestTool2_2/__init__.py create mode 100644 test/toolpath/nested/image/Libs/tools_example/subdir1/subdir2/Toolpath_TestTool2_2/sconstest.skip create mode 100644 test/toolpath/nested/image/Libs/tools_example/subdir1/subdir2/__init__.py create mode 100644 test/toolpath/nested/image/Libs/tools_example/subdir1/subdir2/sconstest.skip create mode 100644 test/toolpath/nested/image/site_scons/site_tools/Toolpath_TestTool1.py create mode 100644 test/toolpath/nested/image/site_scons/site_tools/Toolpath_TestTool2/__init__.py create mode 100644 test/toolpath/nested/image/site_scons/site_tools/Toolpath_TestTool2/sconstest.skip create mode 100644 test/toolpath/nested/image/site_scons/site_tools/__init__.py create mode 100644 test/toolpath/nested/image/site_scons/site_tools/sconstest.skip delete mode 100644 test/toolpath/nested/image/site_scons/site_tools/subdir1/Site_TestTool1.py delete mode 100644 test/toolpath/nested/image/site_scons/site_tools/subdir1/Site_TestTool3/__init__.py delete mode 100644 test/toolpath/nested/image/site_scons/site_tools/subdir1/Site_TestTool3/sconstest.skip create mode 100644 test/toolpath/nested/image/site_scons/site_tools/subdir1/Toolpath_TestTool1_1.py create mode 100644 test/toolpath/nested/image/site_scons/site_tools/subdir1/Toolpath_TestTool1_2/__init__.py create mode 100644 test/toolpath/nested/image/site_scons/site_tools/subdir1/Toolpath_TestTool1_2/sconstest.skip delete mode 100644 test/toolpath/nested/image/site_scons/site_tools/subdir1/subdir2/Site_TestTool2.py create mode 100644 test/toolpath/nested/image/site_scons/site_tools/subdir1/subdir2/Toolpath_TestTool2_1.py create mode 100644 test/toolpath/nested/image/site_scons/site_tools/subdir1/subdir2/Toolpath_TestTool2_2/__init__.py create mode 100644 test/toolpath/nested/image/site_scons/site_tools/subdir1/subdir2/Toolpath_TestTool2_2/sconstest.skip create mode 100644 test/toolpath/nested/image/testsrc1.txt delete mode 100644 test/toolpath/nested/image/tools/subdir1/Toolpath_TestTool1.py delete mode 100644 test/toolpath/nested/image/tools/subdir1/Toolpath_TestTool3/__init__.py delete mode 100644 test/toolpath/nested/image/tools/subdir1/Toolpath_TestTool3/sconstest.skip delete mode 100644 test/toolpath/nested/image/tools/subdir1/__init__.py delete mode 100644 test/toolpath/nested/image/tools/subdir1/sconstest.skip delete mode 100644 test/toolpath/nested/image/tools/subdir1/subdir2/Toolpath_TestTool2.py delete mode 100644 test/toolpath/nested/image/tools/subdir1/subdir2/__init__.py delete mode 100644 test/toolpath/nested/image/tools/subdir1/subdir2/sconstest.skip diff --git a/test/toolpath/nested/image/Libs/tools_example/Toolpath_TestTool1.py b/test/toolpath/nested/image/Libs/tools_example/Toolpath_TestTool1.py new file mode 100644 index 0000000..072daf0 --- /dev/null +++ b/test/toolpath/nested/image/Libs/tools_example/Toolpath_TestTool1.py @@ -0,0 +1,4 @@ +def generate(env): + env['Toolpath_TestTool1'] = 1 +def exists(env): + return 1 diff --git a/test/toolpath/nested/image/Libs/tools_example/Toolpath_TestTool2/__init__.py b/test/toolpath/nested/image/Libs/tools_example/Toolpath_TestTool2/__init__.py new file mode 100644 index 0000000..f4ccefe --- /dev/null +++ b/test/toolpath/nested/image/Libs/tools_example/Toolpath_TestTool2/__init__.py @@ -0,0 +1,4 @@ +def generate(env): + env['Toolpath_TestTool2'] = 1 +def exists(env): + return 1 diff --git a/test/toolpath/nested/image/Libs/tools_example/Toolpath_TestTool2/sconstest.skip b/test/toolpath/nested/image/Libs/tools_example/Toolpath_TestTool2/sconstest.skip new file mode 100644 index 0000000..e69de29 diff --git a/test/toolpath/nested/image/Libs/tools_example/__init__.py b/test/toolpath/nested/image/Libs/tools_example/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/test/toolpath/nested/image/Libs/tools_example/sconstest.skip b/test/toolpath/nested/image/Libs/tools_example/sconstest.skip new file mode 100644 index 0000000..e69de29 diff --git a/test/toolpath/nested/image/Libs/tools_example/subdir1/Toolpath_TestTool1_1.py b/test/toolpath/nested/image/Libs/tools_example/subdir1/Toolpath_TestTool1_1.py new file mode 100644 index 0000000..2a70e67 --- /dev/null +++ b/test/toolpath/nested/image/Libs/tools_example/subdir1/Toolpath_TestTool1_1.py @@ -0,0 +1,4 @@ +def generate(env): + env['Toolpath_TestTool1_1'] = 1 +def exists(env): + return 1 diff --git a/test/toolpath/nested/image/Libs/tools_example/subdir1/Toolpath_TestTool1_2/__init__.py b/test/toolpath/nested/image/Libs/tools_example/subdir1/Toolpath_TestTool1_2/__init__.py new file mode 100644 index 0000000..424991f --- /dev/null +++ b/test/toolpath/nested/image/Libs/tools_example/subdir1/Toolpath_TestTool1_2/__init__.py @@ -0,0 +1,4 @@ +def generate(env): + env['Toolpath_TestTool1_2'] = 1 +def exists(env): + return 1 diff --git a/test/toolpath/nested/image/Libs/tools_example/subdir1/Toolpath_TestTool1_2/sconstest.skip b/test/toolpath/nested/image/Libs/tools_example/subdir1/Toolpath_TestTool1_2/sconstest.skip new file mode 100644 index 0000000..e69de29 diff --git a/test/toolpath/nested/image/Libs/tools_example/subdir1/__init__.py b/test/toolpath/nested/image/Libs/tools_example/subdir1/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/test/toolpath/nested/image/Libs/tools_example/subdir1/sconstest.skip b/test/toolpath/nested/image/Libs/tools_example/subdir1/sconstest.skip new file mode 100644 index 0000000..e69de29 diff --git a/test/toolpath/nested/image/Libs/tools_example/subdir1/subdir2/Toolpath_TestTool2_1.py b/test/toolpath/nested/image/Libs/tools_example/subdir1/subdir2/Toolpath_TestTool2_1.py new file mode 100644 index 0000000..13d0496 --- /dev/null +++ b/test/toolpath/nested/image/Libs/tools_example/subdir1/subdir2/Toolpath_TestTool2_1.py @@ -0,0 +1,4 @@ +def generate(env): + env['Toolpath_TestTool2_1'] = 1 +def exists(env): + return 1 diff --git a/test/toolpath/nested/image/Libs/tools_example/subdir1/subdir2/Toolpath_TestTool2_2/__init__.py b/test/toolpath/nested/image/Libs/tools_example/subdir1/subdir2/Toolpath_TestTool2_2/__init__.py new file mode 100644 index 0000000..3f8fd5e --- /dev/null +++ b/test/toolpath/nested/image/Libs/tools_example/subdir1/subdir2/Toolpath_TestTool2_2/__init__.py @@ -0,0 +1,4 @@ +def generate(env): + env['Toolpath_TestTool2_2'] = 1 +def exists(env): + return 1 diff --git a/test/toolpath/nested/image/Libs/tools_example/subdir1/subdir2/Toolpath_TestTool2_2/sconstest.skip b/test/toolpath/nested/image/Libs/tools_example/subdir1/subdir2/Toolpath_TestTool2_2/sconstest.skip new file mode 100644 index 0000000..e69de29 diff --git a/test/toolpath/nested/image/Libs/tools_example/subdir1/subdir2/__init__.py b/test/toolpath/nested/image/Libs/tools_example/subdir1/subdir2/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/test/toolpath/nested/image/Libs/tools_example/subdir1/subdir2/sconstest.skip b/test/toolpath/nested/image/Libs/tools_example/subdir1/subdir2/sconstest.skip new file mode 100644 index 0000000..e69de29 diff --git a/test/toolpath/nested/image/SConstruct b/test/toolpath/nested/image/SConstruct index 284f21c..b20d8e6 100644 --- a/test/toolpath/nested/image/SConstruct +++ b/test/toolpath/nested/image/SConstruct @@ -1,15 +1,62 @@ -# Test where tools are located under site_scons/site_tools -env1 = Environment(tools=['subdir1.Site_TestTool1', 'subdir1.subdir2.Site_TestTool2', 'subdir1.Site_TestTool3']) -print("env1['Site_TestTool1'] =", env1.get('Site_TestTool1')) -print("env1['Site_TestTool2'] =", env1.get('Site_TestTool2')) -print("env1['Site_TestTool3'] =", env1.get('Site_TestTool3')) - -# Test where toolpath is set in the env constructor -env2 = Environment(tools=['subdir1.Toolpath_TestTool1', 'subdir1.subdir2.Toolpath_TestTool2', 'subdir1.Toolpath_TestTool3'], toolpath=['tools']) +import sys, os + +toollist = ['Toolpath_TestTool1', + 'Toolpath_TestTool2', + 'subdir1.Toolpath_TestTool1_1', + 'subdir1.Toolpath_TestTool1_2', + 'subdir1.subdir2.Toolpath_TestTool2_1', + 'subdir1.subdir2.Toolpath_TestTool2_2', + ] + +print('Test where tools are located under site_scons/site_tools') +env1 = Environment(tools=toollist) +print("env1['Toolpath_TestTool1'] =", env1.get('Toolpath_TestTool1')) +print("env1['Toolpath_TestTool2'] =", env1.get('Toolpath_TestTool2')) +print("env1['Toolpath_TestTool1_1'] =", env1.get('Toolpath_TestTool1_1')) +print("env1['Toolpath_TestTool1_2'] =", env1.get('Toolpath_TestTool1_2')) +print("env1['Toolpath_TestTool2_1'] =", env1.get('Toolpath_TestTool2_1')) +print("env1['Toolpath_TestTool2_2'] =", env1.get('Toolpath_TestTool2_2')) + +print('Test where toolpath is set in the env constructor') +env2 = Environment(tools=toollist, toolpath=['Libs/tools_example']) print("env2['Toolpath_TestTool1'] =", env2.get('Toolpath_TestTool1')) print("env2['Toolpath_TestTool2'] =", env2.get('Toolpath_TestTool2')) -print("env2['Toolpath_TestTool3'] =", env2.get('Toolpath_TestTool3')) +print("env2['Toolpath_TestTool1_1'] =", env2.get('Toolpath_TestTool1_1')) +print("env2['Toolpath_TestTool1_2'] =", env2.get('Toolpath_TestTool1_2')) +print("env2['Toolpath_TestTool2_1'] =", env2.get('Toolpath_TestTool2_1')) +print("env2['Toolpath_TestTool2_2'] =", env2.get('Toolpath_TestTool2_2')) + +print('Test a Clone') +base = Environment(tools=[], toolpath=['Libs/tools_example']) +derived = base.Clone(tools=['subdir1.Toolpath_TestTool1_1']) +print("derived['Toolpath_TestTool1_1'] =", derived.get('Toolpath_TestTool1_1')) + + +print('Test using syspath as the toolpath') +print('Lets pretend that tools_example within Libs is actually a module installed via pip') +oldsyspath = sys.path +dir_path = Dir('.').srcnode().abspath +dir_path = os.path.join(dir_path, 'Libs') +sys.path.append(dir_path) + +toollist = ['tools_example.Toolpath_TestTool1', + 'tools_example.Toolpath_TestTool2', + 'tools_example.subdir1.Toolpath_TestTool1_1', + 'tools_example.subdir1.Toolpath_TestTool1_2', + 'tools_example.subdir1.subdir2.Toolpath_TestTool2_1', + 'tools_example.subdir1.subdir2.Toolpath_TestTool2_2', + ] + +env3 = Environment(tools=toollist, toolpath=sys.path) +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')) +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')) + +sys.path = oldsyspath -base = Environment(tools=[], toolpath=['tools']) -derived = base.Clone(tools=['subdir1.Toolpath_TestTool1']) -print("derived['Toolpath_TestTool1'] =", derived.get('Toolpath_TestTool1')) +# TODO +# 1. add docs for below +# 3. redo test output capture diff --git a/test/toolpath/nested/image/site_scons/site_tools/Toolpath_TestTool1.py b/test/toolpath/nested/image/site_scons/site_tools/Toolpath_TestTool1.py new file mode 100644 index 0000000..072daf0 --- /dev/null +++ b/test/toolpath/nested/image/site_scons/site_tools/Toolpath_TestTool1.py @@ -0,0 +1,4 @@ +def generate(env): + env['Toolpath_TestTool1'] = 1 +def exists(env): + return 1 diff --git a/test/toolpath/nested/image/site_scons/site_tools/Toolpath_TestTool2/__init__.py b/test/toolpath/nested/image/site_scons/site_tools/Toolpath_TestTool2/__init__.py new file mode 100644 index 0000000..f4ccefe --- /dev/null +++ b/test/toolpath/nested/image/site_scons/site_tools/Toolpath_TestTool2/__init__.py @@ -0,0 +1,4 @@ +def generate(env): + env['Toolpath_TestTool2'] = 1 +def exists(env): + return 1 diff --git a/test/toolpath/nested/image/site_scons/site_tools/Toolpath_TestTool2/sconstest.skip b/test/toolpath/nested/image/site_scons/site_tools/Toolpath_TestTool2/sconstest.skip new file mode 100644 index 0000000..e69de29 diff --git a/test/toolpath/nested/image/site_scons/site_tools/__init__.py b/test/toolpath/nested/image/site_scons/site_tools/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/test/toolpath/nested/image/site_scons/site_tools/sconstest.skip b/test/toolpath/nested/image/site_scons/site_tools/sconstest.skip new file mode 100644 index 0000000..e69de29 diff --git a/test/toolpath/nested/image/site_scons/site_tools/subdir1/Site_TestTool1.py b/test/toolpath/nested/image/site_scons/site_tools/subdir1/Site_TestTool1.py deleted file mode 100644 index d4a19a8..0000000 --- a/test/toolpath/nested/image/site_scons/site_tools/subdir1/Site_TestTool1.py +++ /dev/null @@ -1,4 +0,0 @@ -def generate(env): - env['Site_TestTool1'] = 1 -def exists(env): - return 1 diff --git a/test/toolpath/nested/image/site_scons/site_tools/subdir1/Site_TestTool3/__init__.py b/test/toolpath/nested/image/site_scons/site_tools/subdir1/Site_TestTool3/__init__.py deleted file mode 100644 index 60bbd02..0000000 --- a/test/toolpath/nested/image/site_scons/site_tools/subdir1/Site_TestTool3/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -def generate(env): - env['Site_TestTool3'] = 1 -def exists(env): - return 1 diff --git a/test/toolpath/nested/image/site_scons/site_tools/subdir1/Site_TestTool3/sconstest.skip b/test/toolpath/nested/image/site_scons/site_tools/subdir1/Site_TestTool3/sconstest.skip deleted file mode 100644 index e69de29..0000000 diff --git a/test/toolpath/nested/image/site_scons/site_tools/subdir1/Toolpath_TestTool1_1.py b/test/toolpath/nested/image/site_scons/site_tools/subdir1/Toolpath_TestTool1_1.py new file mode 100644 index 0000000..2a70e67 --- /dev/null +++ b/test/toolpath/nested/image/site_scons/site_tools/subdir1/Toolpath_TestTool1_1.py @@ -0,0 +1,4 @@ +def generate(env): + env['Toolpath_TestTool1_1'] = 1 +def exists(env): + return 1 diff --git a/test/toolpath/nested/image/site_scons/site_tools/subdir1/Toolpath_TestTool1_2/__init__.py b/test/toolpath/nested/image/site_scons/site_tools/subdir1/Toolpath_TestTool1_2/__init__.py new file mode 100644 index 0000000..424991f --- /dev/null +++ b/test/toolpath/nested/image/site_scons/site_tools/subdir1/Toolpath_TestTool1_2/__init__.py @@ -0,0 +1,4 @@ +def generate(env): + env['Toolpath_TestTool1_2'] = 1 +def exists(env): + return 1 diff --git a/test/toolpath/nested/image/site_scons/site_tools/subdir1/Toolpath_TestTool1_2/sconstest.skip b/test/toolpath/nested/image/site_scons/site_tools/subdir1/Toolpath_TestTool1_2/sconstest.skip new file mode 100644 index 0000000..e69de29 diff --git a/test/toolpath/nested/image/site_scons/site_tools/subdir1/subdir2/Site_TestTool2.py b/test/toolpath/nested/image/site_scons/site_tools/subdir1/subdir2/Site_TestTool2.py deleted file mode 100644 index adae55b..0000000 --- a/test/toolpath/nested/image/site_scons/site_tools/subdir1/subdir2/Site_TestTool2.py +++ /dev/null @@ -1,4 +0,0 @@ -def generate(env): - env['Site_TestTool2'] = 1 -def exists(env): - return 1 diff --git a/test/toolpath/nested/image/site_scons/site_tools/subdir1/subdir2/Toolpath_TestTool2_1.py b/test/toolpath/nested/image/site_scons/site_tools/subdir1/subdir2/Toolpath_TestTool2_1.py new file mode 100644 index 0000000..13d0496 --- /dev/null +++ b/test/toolpath/nested/image/site_scons/site_tools/subdir1/subdir2/Toolpath_TestTool2_1.py @@ -0,0 +1,4 @@ +def generate(env): + env['Toolpath_TestTool2_1'] = 1 +def exists(env): + return 1 diff --git a/test/toolpath/nested/image/site_scons/site_tools/subdir1/subdir2/Toolpath_TestTool2_2/__init__.py b/test/toolpath/nested/image/site_scons/site_tools/subdir1/subdir2/Toolpath_TestTool2_2/__init__.py new file mode 100644 index 0000000..3f8fd5e --- /dev/null +++ b/test/toolpath/nested/image/site_scons/site_tools/subdir1/subdir2/Toolpath_TestTool2_2/__init__.py @@ -0,0 +1,4 @@ +def generate(env): + env['Toolpath_TestTool2_2'] = 1 +def exists(env): + return 1 diff --git a/test/toolpath/nested/image/site_scons/site_tools/subdir1/subdir2/Toolpath_TestTool2_2/sconstest.skip b/test/toolpath/nested/image/site_scons/site_tools/subdir1/subdir2/Toolpath_TestTool2_2/sconstest.skip new file mode 100644 index 0000000..e69de29 diff --git a/test/toolpath/nested/image/testsrc1.txt b/test/toolpath/nested/image/testsrc1.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/toolpath/nested/image/tools/subdir1/Toolpath_TestTool1.py b/test/toolpath/nested/image/tools/subdir1/Toolpath_TestTool1.py deleted file mode 100644 index 072daf0..0000000 --- a/test/toolpath/nested/image/tools/subdir1/Toolpath_TestTool1.py +++ /dev/null @@ -1,4 +0,0 @@ -def generate(env): - env['Toolpath_TestTool1'] = 1 -def exists(env): - return 1 diff --git a/test/toolpath/nested/image/tools/subdir1/Toolpath_TestTool3/__init__.py b/test/toolpath/nested/image/tools/subdir1/Toolpath_TestTool3/__init__.py deleted file mode 100644 index 26bc748..0000000 --- a/test/toolpath/nested/image/tools/subdir1/Toolpath_TestTool3/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -def generate(env): - env['Toolpath_TestTool3'] = 1 -def exists(env): - return 1 diff --git a/test/toolpath/nested/image/tools/subdir1/Toolpath_TestTool3/sconstest.skip b/test/toolpath/nested/image/tools/subdir1/Toolpath_TestTool3/sconstest.skip deleted file mode 100644 index e69de29..0000000 diff --git a/test/toolpath/nested/image/tools/subdir1/__init__.py b/test/toolpath/nested/image/tools/subdir1/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/test/toolpath/nested/image/tools/subdir1/sconstest.skip b/test/toolpath/nested/image/tools/subdir1/sconstest.skip deleted file mode 100644 index e69de29..0000000 diff --git a/test/toolpath/nested/image/tools/subdir1/subdir2/Toolpath_TestTool2.py b/test/toolpath/nested/image/tools/subdir1/subdir2/Toolpath_TestTool2.py deleted file mode 100644 index f4ccefe..0000000 --- a/test/toolpath/nested/image/tools/subdir1/subdir2/Toolpath_TestTool2.py +++ /dev/null @@ -1,4 +0,0 @@ -def generate(env): - env['Toolpath_TestTool2'] = 1 -def exists(env): - return 1 diff --git a/test/toolpath/nested/image/tools/subdir1/subdir2/__init__.py b/test/toolpath/nested/image/tools/subdir1/subdir2/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/test/toolpath/nested/image/tools/subdir1/subdir2/sconstest.skip b/test/toolpath/nested/image/tools/subdir1/subdir2/sconstest.skip deleted file mode 100644 index e69de29..0000000 diff --git a/test/toolpath/nested/nested.py b/test/toolpath/nested/nested.py index 7304dd5..a736d58 100644 --- a/test/toolpath/nested/nested.py +++ b/test/toolpath/nested/nested.py @@ -33,13 +33,30 @@ test.dir_fixture('image') test.run(arguments = '.', stdout = """\ scons: Reading SConscript files ... -env1['Site_TestTool1'] = 1 -env1['Site_TestTool2'] = 1 -env1['Site_TestTool3'] = 1 +Test where tools are located under site_scons/site_tools +env1['Toolpath_TestTool1'] = 1 +env1['Toolpath_TestTool2'] = 1 +env1['Toolpath_TestTool1_1'] = 1 +env1['Toolpath_TestTool1_2'] = 1 +env1['Toolpath_TestTool2_1'] = 1 +env1['Toolpath_TestTool2_2'] = 1 +Test where toolpath is set in the env constructor env2['Toolpath_TestTool1'] = 1 env2['Toolpath_TestTool2'] = 1 -env2['Toolpath_TestTool3'] = 1 -derived['Toolpath_TestTool1'] = 1 +env2['Toolpath_TestTool1_1'] = 1 +env2['Toolpath_TestTool1_2'] = 1 +env2['Toolpath_TestTool2_1'] = 1 +env2['Toolpath_TestTool2_2'] = 1 +Test a Clone +derived['Toolpath_TestTool1_1'] = 1 +Test using syspath as the toolpath +Lets pretend that tools_example within Libs is actually a module installed via pip +env3['Toolpath_TestTool1'] = 1 +env3['Toolpath_TestTool2'] = 1 +env3['Toolpath_TestTool1_1'] = 1 +env3['Toolpath_TestTool1_2'] = 1 +env3['Toolpath_TestTool2_1'] = 1 +env3['Toolpath_TestTool2_2'] = 1 scons: done reading SConscript files. scons: Building targets ... scons: `.' is up to date. -- cgit v0.12 From e0bc3a04d5010e0c637edc59e034b91feaf343b6 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Sun, 30 Jul 2017 21:32:31 -0700 Subject: PY2/3 Fix action object content signiture to be stable. Note need expected value for each change in python bytecode. Currently that means one for each: py2.7, py3.5, py3.6 --- src/engine/SCons/Action.py | 67 ++++++++++++++++++++++++++++++++++++----- src/engine/SCons/ActionTests.py | 33 +++++++++----------- 2 files changed, 75 insertions(+), 25 deletions(-) diff --git a/src/engine/SCons/Action.py b/src/engine/SCons/Action.py index 118c495..bf611af 100644 --- a/src/engine/SCons/Action.py +++ b/src/engine/SCons/Action.py @@ -105,6 +105,8 @@ import pickle import re import sys import subprocess +import itertools +import inspect import SCons.Debug from SCons.Debug import logInstanceCreation @@ -195,8 +197,11 @@ def _object_contents(obj): except AttributeError as ae: # Should be a pickle-able Python object. try: - return pickle.dumps(obj, ACTION_SIGNATURE_PICKLE_PROTOCOL) - except (pickle.PicklingError, TypeError, AttributeError): + return _object_instance_content(obj) + # pickling an Action instance or object doesn't yield a stable + # content as instance property may be dumped in different orders + # return pickle.dumps(obj, ACTION_SIGNATURE_PICKLE_PROTOCOL) + except (pickle.PicklingError, TypeError, AttributeError) as ex: # This is weird, but it seems that nested classes # are unpickable. The Python docs say it should # always be a PicklingError, but some Python @@ -308,15 +313,12 @@ def _function_contents(func): defaults.extend(b')') contents.append(defaults) - - # contents.append(bytearray(',(','utf-8') + b','.join(function_defaults_contents) + bytearray(')','utf-8')) else: contents.append(b',()') # The function contents depends on the closure captured cell values. closure = func.__closure__ or [] - #xxx = [_object_contents(x.cell_contents) for x in closure] try: closure_contents = [_object_contents(x.cell_contents) for x in closure] except AttributeError: @@ -325,10 +327,61 @@ def _function_contents(func): contents.append(b',(') contents.append(bytearray(b',').join(closure_contents)) contents.append(b')') - # contents.append(b'BBBBBBBB') - return bytearray(b'').join(contents) + retval = bytearray(b'').join(contents) + + # print("ReTVAL:%s"%retval) + return retval + +def _object_instance_content(obj): + """ + Returns consistant content for a action class or an instance thereof + :param obj: Should be either and action class or an instance thereof + :return: bytearray or bytes representing the obj suitable for generating + a signiture from. + """ + retval = bytearray() + + + inst_class = obj.__class__ + inst_class_name = bytearray(obj.__class__.__name__,'utf-8') + inst_class_module = bytearray(obj.__class__.__module__,'utf-8') + inst_class_hierarchy = bytearray(repr(inspect.getclasstree([obj.__class__,])),'utf-8') + # print("ICH:%s : %s"%(inst_class_hierarchy, repr(obj))) + + properties = [(p, getattr(obj, p, "None")) for p in dir(obj) if p[:2] != '__' and not inspect.ismethod(getattr(obj, p))] + properties.sort() + properties_str = ','.join(["%s=%s"%(p[0],p[1]) for p in properties]) + properties_bytes = bytearray(properties_str,'utf-8') + + methods = [p for p in dir(obj) if inspect.ismethod(getattr(obj, p))] + methods.sort() + + method_contents = [] + for m in methods: + # print("Method:%s"%m) + v = _function_contents(getattr(obj, m)) + # print("[%s->]V:%s [%s]"%(m,v,type(v))) + method_contents.append(v) + + retval = bytearray(b'{') + retval.extend(inst_class_name) + retval.extend(b":") + retval.extend(inst_class_module) + retval.extend(b'}[[') + retval.extend(inst_class_hierarchy) + retval.extend(b']]{{') + retval.extend(bytearray(b",").join(method_contents)) + retval.extend(b"}}") + return retval + + # print("class :%s"%inst_class) + # print("class_name :%s"%inst_class_name) + # print("class_module :%s"%inst_class_module) + # print("Class hier :\n%s"%pp.pformat(inst_class_hierarchy)) + # print("Inst Properties:\n%s"%pp.pformat(properties)) + # print("Inst Methods :\n%s"%pp.pformat(methods)) def _actionAppend(act1, act2): # This function knows how to slap two actions together. diff --git a/src/engine/SCons/ActionTests.py b/src/engine/SCons/ActionTests.py index 34d9ffc..7980e39 100644 --- a/src/engine/SCons/ActionTests.py +++ b/src/engine/SCons/ActionTests.py @@ -98,7 +98,9 @@ scons_env = SCons.Environment.Environment() # Capture all the stuff the Actions will print, # so it doesn't clutter the output. -sys.stdout = io.StringIO() + +# TODO.. uncomment +# sys.stdout = io.StringIO() class CmdStringHolder(object): def __init__(self, cmd, literal=None): @@ -2054,7 +2056,7 @@ class ActionCompareTestCase(unittest.TestCase): assert dog.get_name(env) == 'DOG', dog.get_name(env) -class TestClass: +class TestClass(object): """A test class used by ObjectContentsTestCase.test_object_contents""" def __init__(self): self.a = "a" @@ -2081,7 +2083,6 @@ class ObjectContentsTestCase(unittest.TestCase): assert c in expected, "Got\n"+repr(c)+"\nExpected one of \n"+"\n".join([repr(e) for e in expected]) - # @unittest.skip("Results vary between py2 and py3, not sure if test makes sense to implement") def test_object_contents(self): """Test that Action._object_contents works""" @@ -2089,20 +2090,18 @@ class ObjectContentsTestCase(unittest.TestCase): o = TestClass() c = SCons.Action._object_contents(o) + # c = SCons.Action._object_instance_content(o) + + # Since the python bytecode has per version differences, we need different expected results per version if TestCmd.IS_PY3: - if TestCmd.IS_WINDOWS: - expected = [b'ccopy_reg\n_reconstructor\nq\x00(c__main__\nTestClass\nq\x01c__builtin__\nobject\nq\x02Ntq\x03Rq\x04}q\x05(X\x01\x00\x00\x00aq\x06h\x06X\x01\x00\x00\x00bq\x07h\x07ub.', # py 3.6 - b'ccopy_reg\n_reconstructor\nq\x00(c__main__\nTestClass\nq\x01c__builtin__\nobject\nq\x02Ntq\x03Rq\x04}q\x05(X\x01\x00\x00\x00bq\x06h\x06X\x01\x00\x00\x00aq\x07h\x07ub.', # py 3.5 - ] - else: - expected = [b'ccopy_reg\n_reconstructor\nq\x00(c__main__\nTestClass\nq\x01c__builtin__\nobject\nq\x02Ntq\x03Rq\x04}q\x05(X\x01\x00\x00\x00bq\x06h\x06X\x01\x00\x00\x00aq\x07h\x07ub.'] + if sys.version_info[:2] == (3,5): + expected = bytearray(b"{TestClass:__main__}[[[(, ()), [(, (,))]]]]{{1, 1, 0, 0,({str:builtins}[[[(, ()), [(, (,))]]]]{{}},{str:builtins}[[[(, ()), [(, (,))]]]]{{}}),({str:builtins}[[[(, ()), [(, (,))]]]]{{}},{str:builtins}[[[(, ()), [(, (,))]]]]{{}}),(d\x01\x00|\x00\x00_\x00\x00d\x02\x00|\x00\x00_\x01\x00d\x00\x00S),(),(),2, 2, 0, 0,(),(),(d\x00\x00S),(),()}}") + elif sys.version_info[:2] == (3,6): + expected = bytearray(b"{TestClass:__main__}[[[(, ()), [(, (,))]]]]{{1, 1, 0, 0,({str:builtins}[[[(, ()), [(, (,))]]]]{{}},{str:builtins}[[[(, ()), [(, (,))]]]]{{}}),({str:builtins}[[[(, ()), [(, (,))]]]]{{}},{str:builtins}[[[(, ()), [(, (,))]]]]{{}}),(d\x01|\x00_\x00d\x02|\x00_\x01d\x00S\x00),(),(),2, 2, 0, 0,(),(),(d\x00S\x00),(),()}}") else: - if TestCmd.IS_WINDOWS: - expected = [b'(c__main__\nTestClass\nq\x01oq\x02}q\x03(U\x01aU\x01aU\x01bU\x01bub.'] - else: - expected = [b'(c__main__\nTestClass\nq\x01oq\x02}q\x03(U\x01aU\x01aU\x01bU\x01bub.'] + expected = bytearray(b"{TestClass:__main__}[[[(, ()), [(, (,))]]]]{{1, 1, 0, 0,({str:__builtin__}[[[(, (,)), [(, (,))]]]]{{}},{str:__builtin__}[[[(, (,)), [(, (,))]]]]{{}}),({str:__builtin__}[[[(, (,)), [(, (,))]]]]{{}},{str:__builtin__}[[[(, (,)), [(, (,))]]]]{{}}),(d\x01\x00|\x00\x00_\x00\x00d\x02\x00|\x00\x00_\x01\x00d\x00\x00S),(),(),2, 2, 0, 0,(),(),(d\x00\x00S),(),()}}") - assert c in expected, "Got\n"+repr(c)+"\nExpected one of \n"+"\n".join([repr(e) for e in expected]) + assert c == expected, "Got\n"+repr(c)+"\nExpected \n"+"\n"+repr(expected) # @unittest.skip("Results vary between py2 and py3, not sure if test makes sense to implement") def test_code_contents(self): @@ -2122,9 +2121,6 @@ class ObjectContentsTestCase(unittest.TestCase): assert c in expected, "Got\n"+repr(c)+"\nExpected one of \n"+"\n".join([repr(e) for e in expected]) - - - if __name__ == "__main__": suite = unittest.TestSuite() tclasses = [ _ActionActionTestCase, @@ -2142,7 +2138,8 @@ if __name__ == "__main__": names = unittest.getTestCaseNames(tclass, 'test_') suite.addTests(list(map(tclass, names))) - TestUnit.run(suite) + # TestUnit.run(suite) + unittest.main() # Local Variables: # tab-width:4 -- cgit v0.12 From 7fa025432c147333167393d0b88edfe7266b2646 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 31 Jul 2017 15:23:04 -0700 Subject: PY2/3 Add property values for object/instance signature --- src/engine/SCons/Action.py | 8 ++++---- src/engine/SCons/ActionTests.py | 7 +++---- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/engine/SCons/Action.py b/src/engine/SCons/Action.py index bf611af..7f11d7b 100644 --- a/src/engine/SCons/Action.py +++ b/src/engine/SCons/Action.py @@ -329,8 +329,6 @@ def _function_contents(func): contents.append(b')') retval = bytearray(b'').join(contents) - - # print("ReTVAL:%s"%retval) return retval @@ -350,7 +348,7 @@ def _object_instance_content(obj): inst_class_hierarchy = bytearray(repr(inspect.getclasstree([obj.__class__,])),'utf-8') # print("ICH:%s : %s"%(inst_class_hierarchy, repr(obj))) - properties = [(p, getattr(obj, p, "None")) for p in dir(obj) if p[:2] != '__' and not inspect.ismethod(getattr(obj, p))] + properties = [(p, getattr(obj, p, "None")) for p in dir(obj) if not (p[:2] == '__' or inspect.ismethod(getattr(obj, p)) or inspect.isbuiltin(getattr(obj,p))) ] properties.sort() properties_str = ','.join(["%s=%s"%(p[0],p[1]) for p in properties]) properties_bytes = bytearray(properties_str,'utf-8') @@ -373,7 +371,9 @@ def _object_instance_content(obj): retval.extend(inst_class_hierarchy) retval.extend(b']]{{') retval.extend(bytearray(b",").join(method_contents)) - retval.extend(b"}}") + retval.extend(b"}}{{{") + retval.extend(properties_bytes) + retval.extend(b'}}}') return retval # print("class :%s"%inst_class) diff --git a/src/engine/SCons/ActionTests.py b/src/engine/SCons/ActionTests.py index 7980e39..ba3d844 100644 --- a/src/engine/SCons/ActionTests.py +++ b/src/engine/SCons/ActionTests.py @@ -2095,15 +2095,14 @@ class ObjectContentsTestCase(unittest.TestCase): # Since the python bytecode has per version differences, we need different expected results per version if TestCmd.IS_PY3: if sys.version_info[:2] == (3,5): - expected = bytearray(b"{TestClass:__main__}[[[(, ()), [(, (,))]]]]{{1, 1, 0, 0,({str:builtins}[[[(, ()), [(, (,))]]]]{{}},{str:builtins}[[[(, ()), [(, (,))]]]]{{}}),({str:builtins}[[[(, ()), [(, (,))]]]]{{}},{str:builtins}[[[(, ()), [(, (,))]]]]{{}}),(d\x01\x00|\x00\x00_\x00\x00d\x02\x00|\x00\x00_\x01\x00d\x00\x00S),(),(),2, 2, 0, 0,(),(),(d\x00\x00S),(),()}}") + expected = bytearray(b"{TestClass:__main__}[[[(, ()), [(, (,))]]]]{{1, 1, 0, 0,({str:builtins}[[[(, ()), [(, (,))]]]]{{}}{{{}}},{str:builtins}[[[(, ()), [(, (,))]]]]{{}}{{{}}}),({str:builtins}[[[(, ()), [(, (,))]]]]{{}}{{{}}},{str:builtins}[[[(, ()), [(, (,))]]]]{{}}{{{}}}),(d\x01\x00|\x00\x00_\x00\x00d\x02\x00|\x00\x00_\x01\x00d\x00\x00S),(),(),2, 2, 0, 0,(),(),(d\x00\x00S),(),()}}{{{a=a,b=b}}}") elif sys.version_info[:2] == (3,6): - expected = bytearray(b"{TestClass:__main__}[[[(, ()), [(, (,))]]]]{{1, 1, 0, 0,({str:builtins}[[[(, ()), [(, (,))]]]]{{}},{str:builtins}[[[(, ()), [(, (,))]]]]{{}}),({str:builtins}[[[(, ()), [(, (,))]]]]{{}},{str:builtins}[[[(, ()), [(, (,))]]]]{{}}),(d\x01|\x00_\x00d\x02|\x00_\x01d\x00S\x00),(),(),2, 2, 0, 0,(),(),(d\x00S\x00),(),()}}") + expected = bytearray(b"{TestClass:__main__}[[[(, ()), [(, (,))]]]]{{1, 1, 0, 0,({str:builtins}[[[(, ()), [(, (,))]]]]{{}}{{{}}},{str:builtins}[[[(, ()), [(, (,))]]]]{{}}{{{}}}),({str:builtins}[[[(, ()), [(, (,))]]]]{{}}{{{}}},{str:builtins}[[[(, ()), [(, (,))]]]]{{}}{{{}}}),(d\x01|\x00_\x00d\x02|\x00_\x01d\x00S\x00),(),(),2, 2, 0, 0,(),(),(d\x00S\x00),(),()}}{{{a=a,b=b}}}") else: - expected = bytearray(b"{TestClass:__main__}[[[(, ()), [(, (,))]]]]{{1, 1, 0, 0,({str:__builtin__}[[[(, (,)), [(, (,))]]]]{{}},{str:__builtin__}[[[(, (,)), [(, (,))]]]]{{}}),({str:__builtin__}[[[(, (,)), [(, (,))]]]]{{}},{str:__builtin__}[[[(, (,)), [(, (,))]]]]{{}}),(d\x01\x00|\x00\x00_\x00\x00d\x02\x00|\x00\x00_\x01\x00d\x00\x00S),(),(),2, 2, 0, 0,(),(),(d\x00\x00S),(),()}}") + expected = bytearray(b"{TestClass:__main__}[[[(, ()), [(, (,))]]]]{{1, 1, 0, 0,({str:__builtin__}[[[(, (,)), [(, (,))]]]]{{}}{{{}}},{str:__builtin__}[[[(, (,)), [(, (,))]]]]{{}}{{{}}}),({str:__builtin__}[[[(, (,)), [(, (,))]]]]{{}}{{{}}},{str:__builtin__}[[[(, (,)), [(, (,))]]]]{{}}{{{}}}),(d\x01\x00|\x00\x00_\x00\x00d\x02\x00|\x00\x00_\x01\x00d\x00\x00S),(),(),2, 2, 0, 0,(),(),(d\x00\x00S),(),()}}{{{a=a,b=b}}}") assert c == expected, "Got\n"+repr(c)+"\nExpected \n"+"\n"+repr(expected) - # @unittest.skip("Results vary between py2 and py3, not sure if test makes sense to implement") def test_code_contents(self): """Test that Action._code_contents works""" -- cgit v0.12 From 560e375169d9a3b12728b2e31fda8bc725819b74 Mon Sep 17 00:00:00 2001 From: Ibrahim Esmat Date: Mon, 31 Jul 2017 18:18:16 -0700 Subject: Fix MSVC_UWP_APP test to take into account the MSVC_VERSION. Skip test if MSVC_VERSION is less than VS2015 --- test/MSVC/MSVC_UWP_APP.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/test/MSVC/MSVC_UWP_APP.py b/test/MSVC/MSVC_UWP_APP.py index 19cd3f7..c72c739 100644 --- a/test/MSVC/MSVC_UWP_APP.py +++ b/test/MSVC/MSVC_UWP_APP.py @@ -92,19 +92,18 @@ maj, min = msvc.msvc_version_to_maj_min(greatest_msvc_version_on_system) # We always use the greatest MSVC version installed on the system +if maj < 14: + # Skip the test if MSVC version is less than VS2015 + test.skip_test("Available MSVC doesn't support App store ") + # Test setting MSVC_UWP_APP is '1' (True) test.run(arguments = "MSVC_UWP_APP=1") (vclibstore_path_present, vclibstorerefs_path_present, msvc_version) = AreVCStoreLibPathsInLIBPATH(test.stdout()) test.fail_test(msvc_version != greatest_msvc_version_on_system, message='MSVC_VERSION (%s) does not match expected greatest version on system (%s)' \ % (msvc_version, greatest_msvc_version_on_system)) -# VS2015+ -if maj >= 14: - test.fail_test((vclibstore_path_present is False) or (vclibstorerefs_path_present is False), - message='VC Store LIBPATHs NOT present when MSVC_UWP_APP=1 (msvc_version=%s)' % msvc_version) -else: - test.fail_test((vclibstore_path_present is True) or (vclibstorerefs_path_present is True), - message='VC Store LIBPATHs present for unsupported version when MSVC_UWP_APP=1 (msvc_version=%s)' % msvc_version) +test.fail_test((vclibstore_path_present is False) or (vclibstorerefs_path_present is False), + message='VC Store LIBPATHs NOT present when MSVC_UWP_APP=1 (msvc_version=%s)' % msvc_version) # Test setting MSVC_UWP_APP is '0' (False) test.run(arguments = "MSVC_UWP_APP=0") @@ -113,7 +112,7 @@ test.fail_test(msvc_version != greatest_msvc_version_on_system, message='MSVC_VERSION (%s) does not match expected greatest version on system (%s)' \ % (msvc_version, greatest_msvc_version_on_system)) test.fail_test((vclibstore_path_present is True) or (vclibstorerefs_path_present is True), - message='VC Store LIBPATHs present when MSVC_UWP_APP=0 (msvc_version=%s)' % msvc_version) + message='VC Store LIBPATHs present when MSVC_UWP_APP=0 (msvc_version=%s)' % msvc_version) # Test not setting MSVC_UWP_APP test.run(arguments = "") @@ -122,7 +121,7 @@ test.fail_test(msvc_version != greatest_msvc_version_on_system, message='MSVC_VERSION (%s) does not match expected greatest version on system (%s)' \ % (msvc_version, greatest_msvc_version_on_system)) test.fail_test((vclibstore_path_present is True) or (vclibstorerefs_path_present is True), - message='VC Store LIBPATHs present when MSVC_UWP_APP not set (msvc_version=%s)' % msvc_version) + message='VC Store LIBPATHs present when MSVC_UWP_APP not set (msvc_version=%s)' % msvc_version) test.pass_test() -- cgit v0.12 From d3e643a3b7597bb176358dafb8c1717c84c22739 Mon Sep 17 00:00:00 2001 From: grbd Date: Tue, 1 Aug 2017 14:49:43 +0100 Subject: Update to user manual on how to use sys.path for toolpath, and toolpath in general also small update to tests --- doc/user/builders-writing.xml | 47 ------------ doc/user/environments.xml | 124 ++++++++++++++++++++++++++++++++ test/toolpath/nested/image/SConstruct | 4 -- test/toolpath/nested/image/testsrc1.txt | 0 4 files changed, 124 insertions(+), 51 deletions(-) delete mode 100644 test/toolpath/nested/image/testsrc1.txt diff --git a/doc/user/builders-writing.xml b/doc/user/builders-writing.xml index 35dd989..07f2dec 100644 --- a/doc/user/builders-writing.xml +++ b/doc/user/builders-writing.xml @@ -880,53 +880,6 @@ env2.Foo('file2') -
- Nested and namespace builders; - - - &SCons; now supports the ability for a Builder to be located within a sub-directory of the toolpath. - This is similar to namespacing within python. - - Normally when loading a tool into the environment, scons will search for the tool within two locations - - - -# Regular non namespace target -env = Environment(ENV = os.environ, tools = ['SomeTool']) -env.SomeTool(targets, sources) - - - - The locations would include - SCons\Tool\SomeTool.py - SCons\Tool\SomeTool\__init__.py - .\site_scons\site_tools\SomeTool.py - .\site_scons\site_tools\SomeTool\__init__.py - - If a toolpath is specified this is also searched as well. - With nested or namespaced tools we can use the dot notation to specify a sub-directoty that the tool is located under - - - -# namespaced target -env = Environment(ENV = os.environ, tools = ['SubDir1.SubDir2.SomeTool']) -env.SomeTool(targets, sources) - - - - With this example the search locations would include - SCons\Tool\SubDir1\SubDir2\SomeTool.py - SCons\Tool\SubDir1\SubDir2\SomeTool\__init__.py - .\site_scons\site_tools\SubDir1\SubDir2\SomeTool.py - .\site_scons\site_tools\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 however. - This is the same constraint used by python when loading modules from within sub-directories (packages). - - -
-