From a917a83a3f6173a79626de24f560dd472971fe45 Mon Sep 17 00:00:00 2001 From: Joseph Brill <48932340+jcbrill@users.noreply.github.com> Date: Fri, 7 Aug 2020 05:57:51 -0400 Subject: Remove get_installed_vcs call in Visual Studio find_vs_dir_by_vc method. Update CHANGES.txt as well. --- CHANGES.txt | 4 ++++ SCons/Tool/MSCommon/vs.py | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGES.txt b/CHANGES.txt index 7250a9b..d9b4dbe 100755 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -8,6 +8,10 @@ NOTE: The 4.0.0 Release of SCons dropped Python 2.7 Support RELEASE VERSION/DATE TO BE FILLED IN LATER + From Joseph Brill: + - MSVS update: Remove unnecessary calls to find all installed versions of msvc when + constructing the installed visual studios list. + From William Deegan: - Fix yacc tool, not respecting YACC set at time of tool initialization. diff --git a/SCons/Tool/MSCommon/vs.py b/SCons/Tool/MSCommon/vs.py index 0d22e29..cc8946f 100644 --- a/SCons/Tool/MSCommon/vs.py +++ b/SCons/Tool/MSCommon/vs.py @@ -65,7 +65,6 @@ class VisualStudio: return batch_file def find_vs_dir_by_vc(self, env): - SCons.Tool.MSCommon.vc.get_installed_vcs(env) dir = SCons.Tool.MSCommon.vc.find_vc_pdir(env, self.vc_version) if not dir: debug('no installed VC %s' % self.vc_version) -- cgit v0.12 From 784f36c2c1c132c476b09658c5b19f92bce86d87 Mon Sep 17 00:00:00 2001 From: Adam Gross Date: Fri, 13 Nov 2020 13:26:34 -0500 Subject: First draft of teaching Python scanner about dynamic files --- SCons/Node/FS.py | 9 ++++- SCons/Scanner/Python.py | 52 ++++++++++++---------------- test/Scanner/Python.py | 42 ++++++++++++++++++++++ test/Scanner/Python/SConstruct | 13 +++++++ test/Scanner/Python/sconstest.skip | 0 test/Scanner/Python/script.py | 8 +++++ test/Scanner/Python/to_be_copied/__init__.py | 1 + test/Scanner/Python/to_be_copied/helper.py | 0 8 files changed, 94 insertions(+), 31 deletions(-) create mode 100644 test/Scanner/Python.py create mode 100644 test/Scanner/Python/SConstruct create mode 100644 test/Scanner/Python/sconstest.skip create mode 100644 test/Scanner/Python/script.py create mode 100644 test/Scanner/Python/to_be_copied/__init__.py create mode 100644 test/Scanner/Python/to_be_copied/helper.py diff --git a/SCons/Node/FS.py b/SCons/Node/FS.py index 967f007..cc2e75a 100644 --- a/SCons/Node/FS.py +++ b/SCons/Node/FS.py @@ -2664,6 +2664,8 @@ class File(Base): def _morph(self): """Turn a file system node into a File object.""" self.scanner_paths = {} + if self.abspath.endswith('package1'): + raise Exception(self.abspath) if not hasattr(self, '_local'): self._local = 0 if not hasattr(self, 'released_target_info'): @@ -3724,7 +3726,10 @@ class FileFinder: return None def _find_file_key(self, filename, paths, verbose=None): - return (filename, paths) + # Note: paths could be a list, which is not hashable. If it is, convert + # it to a tuple. + paths_entry = tuple(paths) if isinstance(paths, list) else paths + return (filename, paths_entry) @SCons.Memoize.CountDictCall(_find_file_key) def find_file(self, filename, paths, verbose=None): @@ -3773,6 +3778,8 @@ class FileFinder: result = node break + print('value: %s (%s)' % (result, type(result))) + print('key: %s (%s)' % (memo_key, type(memo_key))) memo_dict[memo_key] = result return result diff --git a/SCons/Scanner/Python.py b/SCons/Scanner/Python.py index dc6812c..965b9c1 100644 --- a/SCons/Scanner/Python.py +++ b/SCons/Scanner/Python.py @@ -108,49 +108,41 @@ def scan(node, env, path=()): for i in itertools.repeat(None, num_parents): current_dir = current_dir.up() - search_paths = [current_dir.abspath] + search_paths = [current_dir] search_string = module_lstripped else: - search_paths = path + search_paths = [env.Dir(p) for p in tuple(path)] search_string = module module_components = search_string.split('.') - for search_path in search_paths: - candidate_path = os.path.join(search_path, *module_components) - # The import stored in "module" could refer to a directory or file. - import_dirs = [] - if os.path.isdir(candidate_path): - import_dirs = module_components - - # Because this resolved to a directory, there is a chance that - # additional imports (e.g. from module import A, B) could refer - # to files to import. - if imports: - for imp in imports: - file = os.path.join(candidate_path, imp + '.py') - if os.path.isfile(file): - nodes.append(file) - elif os.path.isfile(candidate_path + '.py'): - nodes.append(candidate_path + '.py') - import_dirs = module_components[:-1] - - # We can ignore imports because this resolved to a file. Any - # additional imports (e.g. from module.file import A, B) would - # only refer to functions in this file. + module_joined = '/'.join(module_components) + print('%s - %s' % (module_joined, [str(s) for s in search_paths])) + node = SCons.Node.FS.find_file(module_joined, search_paths, verbose=True) + if node: + # The fact that we were able to find the node without appending .py + # means that this is a directory import. + nodes.append(env.Dir(node).File('__init__.py')) # Take a dependency on all __init__.py files from all imported # packages unless it's a relative import. If it's a relative # import, we don't need to take the dependency because Python # requires that all referenced packages have already been imported, # which means that the dependency has already been established. - if import_dirs and not is_relative: + # XXX TODO: This part is broken and needs to be fixed. + if not is_relative and len(module_components) > 1: + import_dirs = module_components for i in range(len(import_dirs)): - init_components = module_components[:i+1] + ['__init__.py'] - init_path = os.path.join(search_path, *(init_components)) - if os.path.isfile(init_path): - nodes.append(init_path) - break + init_path = '/'.join(module_components[:i+1] + ['__init__.py']) + # TODO: Passing search_paths is not correct. + init_node = SCons.Node.FS.find_file(init_path, search_paths, verbose=True) + if init_node: + nodes.append(init_node) + else: + node = SCons.Node.FS.find_file(module_joined + '.py', search_paths, verbose=True) + if node: + nodes.append(node) + print('nodes: %s' % [str(n) for n in nodes]) return sorted(nodes) diff --git a/test/Scanner/Python.py b/test/Scanner/Python.py new file mode 100644 index 0000000..74c8a87 --- /dev/null +++ b/test/Scanner/Python.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python +# +# MIT License +# +# Copyright The SCons Foundation +# +# 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. + +""" +Template for end-to-end test file. +Replace this with a description of the test. +""" + +import TestSCons + +test = TestSCons.TestSCons() +test.dir_fixture('Python') +test.run(arguments = '--debug=stacktrace .') +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/Scanner/Python/SConstruct b/test/Scanner/Python/SConstruct new file mode 100644 index 0000000..63fc44b --- /dev/null +++ b/test/Scanner/Python/SConstruct @@ -0,0 +1,13 @@ +import sys + +env = Environment(tools=['python']) +c = [] +for source, target in [ + ('to_be_copied', 'package1'), + ('to_be_copied', 'package2'), +]: + c += env.Command(target, source, Copy('$TARGET', '$SOURCE')) +# Don't set a dependency on the copy actions on purpose. Scanner should find +# the dependencies automatically. +s = env.Command('a.out', 'script.py', '$PYTHON $SOURCE $TARGET', PYTHON=sys.executable) +env.Depends(s, c) \ No newline at end of file diff --git a/test/Scanner/Python/sconstest.skip b/test/Scanner/Python/sconstest.skip new file mode 100644 index 0000000..e69de29 diff --git a/test/Scanner/Python/script.py b/test/Scanner/Python/script.py new file mode 100644 index 0000000..3970f8d --- /dev/null +++ b/test/Scanner/Python/script.py @@ -0,0 +1,8 @@ +import package1 +import package2 +import sys + +raise Exception(sys.argv) + +with open(sys.argv[1], 'w') as f: + f.write('test') diff --git a/test/Scanner/Python/to_be_copied/__init__.py b/test/Scanner/Python/to_be_copied/__init__.py new file mode 100644 index 0000000..34fdc42 --- /dev/null +++ b/test/Scanner/Python/to_be_copied/__init__.py @@ -0,0 +1 @@ +from . import helper \ No newline at end of file diff --git a/test/Scanner/Python/to_be_copied/helper.py b/test/Scanner/Python/to_be_copied/helper.py new file mode 100644 index 0000000..e69de29 -- cgit v0.12 From 03a319cdd0cd092b9f78de136b3bd701c68190bf Mon Sep 17 00:00:00 2001 From: Adam Gross Date: Fri, 13 Nov 2020 13:32:40 -0500 Subject: Change test to follow its own instructions --- test/Scanner/Python/SConstruct | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/test/Scanner/Python/SConstruct b/test/Scanner/Python/SConstruct index 63fc44b..0466d37 100644 --- a/test/Scanner/Python/SConstruct +++ b/test/Scanner/Python/SConstruct @@ -1,13 +1,11 @@ import sys env = Environment(tools=['python']) -c = [] for source, target in [ ('to_be_copied', 'package1'), ('to_be_copied', 'package2'), ]: - c += env.Command(target, source, Copy('$TARGET', '$SOURCE')) + env.Command(target, source, Copy('$TARGET', '$SOURCE')) # Don't set a dependency on the copy actions on purpose. Scanner should find # the dependencies automatically. -s = env.Command('a.out', 'script.py', '$PYTHON $SOURCE $TARGET', PYTHON=sys.executable) -env.Depends(s, c) \ No newline at end of file +env.Command('a.out', 'script.py', '$PYTHON $SOURCE $TARGET', PYTHON=sys.executable) \ No newline at end of file -- cgit v0.12 From 28636490512924ce393ce324a61130d9d43fe54a Mon Sep 17 00:00:00 2001 From: Adam Gross Date: Fri, 13 Nov 2020 13:54:02 -0500 Subject: Remove exception from script.py --- test/Scanner/Python/script.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/Scanner/Python/script.py b/test/Scanner/Python/script.py index 3970f8d..f633f43 100644 --- a/test/Scanner/Python/script.py +++ b/test/Scanner/Python/script.py @@ -2,7 +2,5 @@ import package1 import package2 import sys -raise Exception(sys.argv) - with open(sys.argv[1], 'w') as f: f.write('test') -- cgit v0.12 From fde36127ff949e7efbce321e7ace07707b35e41a Mon Sep 17 00:00:00 2001 From: Adam Gross Date: Mon, 16 Nov 2020 10:17:58 -0500 Subject: Some initial fixes --- SCons/Node/FS.py | 6 +---- SCons/Scanner/Python.py | 57 ++++++++++++++++++++++++------------------ test/Scanner/Python.py | 2 +- test/Scanner/Python/SConstruct | 6 ++--- 4 files changed, 37 insertions(+), 34 deletions(-) diff --git a/SCons/Node/FS.py b/SCons/Node/FS.py index cc2e75a..369ec59 100644 --- a/SCons/Node/FS.py +++ b/SCons/Node/FS.py @@ -2664,8 +2664,6 @@ class File(Base): def _morph(self): """Turn a file system node into a File object.""" self.scanner_paths = {} - if self.abspath.endswith('package1'): - raise Exception(self.abspath) if not hasattr(self, '_local'): self._local = 0 if not hasattr(self, 'released_target_info'): @@ -3727,7 +3725,7 @@ class FileFinder: def _find_file_key(self, filename, paths, verbose=None): # Note: paths could be a list, which is not hashable. If it is, convert - # it to a tuple. + # it to a tuple, which is hashable. paths_entry = tuple(paths) if isinstance(paths, list) else paths return (filename, paths_entry) @@ -3778,8 +3776,6 @@ class FileFinder: result = node break - print('value: %s (%s)' % (result, type(result))) - print('key: %s (%s)' % (memo_key, type(memo_key))) memo_dict[memo_key] = result return result diff --git a/SCons/Scanner/Python.py b/SCons/Scanner/Python.py index 965b9c1..63f5035 100644 --- a/SCons/Scanner/Python.py +++ b/SCons/Scanner/Python.py @@ -116,33 +116,40 @@ def scan(node, env, path=()): module_components = search_string.split('.') module_joined = '/'.join(module_components) - print('%s - %s' % (module_joined, [str(s) for s in search_paths])) - node = SCons.Node.FS.find_file(module_joined, search_paths, verbose=True) - if node: - # The fact that we were able to find the node without appending .py - # means that this is a directory import. - nodes.append(env.Dir(node).File('__init__.py')) - - # Take a dependency on all __init__.py files from all imported - # packages unless it's a relative import. If it's a relative - # import, we don't need to take the dependency because Python - # requires that all referenced packages have already been imported, - # which means that the dependency has already been established. - # XXX TODO: This part is broken and needs to be fixed. - if not is_relative and len(module_components) > 1: - import_dirs = module_components - for i in range(len(import_dirs)): - init_path = '/'.join(module_components[:i+1] + ['__init__.py']) - # TODO: Passing search_paths is not correct. - init_node = SCons.Node.FS.find_file(init_path, search_paths, verbose=True) - if init_node: - nodes.append(init_node) - else: - node = SCons.Node.FS.find_file(module_joined + '.py', search_paths, verbose=True) + + # For an import of "p", it could either result in a directory named + # p or a file named p.py. We can't do two consecutive searches for p + # then p.py because the first search could return a result that is + # lower in the search_paths precedence order. As a result, it is safest + # to iterate over search_paths and check whether p or p.py exists in + # each path. This allows us to cleanly respect the precedence order. + for path in search_paths: + paths = [path] + node = SCons.Node.FS.find_file(module_joined, paths, verbose=True) if node: - nodes.append(node) + # The fact that we were able to find the node without appending .py + # means that this is a directory import. + nodes.append(env.Dir(node).File('__init__.py')) + + # Take a dependency on all __init__.py files from all imported + # packages unless it's a relative import. If it's a relative + # import, we don't need to take the dependency because Python + # requires that all referenced packages have already been imported, + # which means that the dependency has already been established. + # XXX TODO: This part is broken and needs to be fixed. + if not is_relative and len(module_components) > 1: + import_dirs = module_components + for i in range(len(import_dirs)): + init_path = '/'.join(module_components[:i+1] + ['__init__.py']) + # TODO: Passing search_paths is not correct. + init_node = SCons.Node.FS.find_file(init_path, paths, verbose=True) + if init_node: + nodes.append(init_node) + else: + node = SCons.Node.FS.find_file(module_joined + '.py', paths, verbose=True) + if node: + nodes.append(node) - print('nodes: %s' % [str(n) for n in nodes]) return sorted(nodes) diff --git a/test/Scanner/Python.py b/test/Scanner/Python.py index 74c8a87..404967c 100644 --- a/test/Scanner/Python.py +++ b/test/Scanner/Python.py @@ -32,7 +32,7 @@ import TestSCons test = TestSCons.TestSCons() test.dir_fixture('Python') -test.run(arguments = '--debug=stacktrace .') +test.run(arguments = '-n --tree=prune --debug=stacktrace .', stdout='') test.pass_test() # Local Variables: diff --git a/test/Scanner/Python/SConstruct b/test/Scanner/Python/SConstruct index 0466d37..732b55c 100644 --- a/test/Scanner/Python/SConstruct +++ b/test/Scanner/Python/SConstruct @@ -2,10 +2,10 @@ import sys env = Environment(tools=['python']) for source, target in [ - ('to_be_copied', 'package1'), - ('to_be_copied', 'package2'), + ('to_be_copied', 'package1'), + ('to_be_copied', 'package2'), ]: - env.Command(target, source, Copy('$TARGET', '$SOURCE')) + env.Command(env.Dir(target), env.Dir(source), Copy('$TARGET', '$SOURCE')) # Don't set a dependency on the copy actions on purpose. Scanner should find # the dependencies automatically. env.Command('a.out', 'script.py', '$PYTHON $SOURCE $TARGET', PYTHON=sys.executable) \ No newline at end of file -- cgit v0.12 From 69ab257c530f6449a4ec49454500c507437a9dbc Mon Sep 17 00:00:00 2001 From: Adam Gross Date: Mon, 16 Nov 2020 11:35:21 -0500 Subject: Fix up scanner a bit Tests still break --- SCons/Scanner/Python.py | 16 ++++++++++------ test/Scanner/Python.py | 2 +- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/SCons/Scanner/Python.py b/SCons/Scanner/Python.py index 63f5035..5f51a7c 100644 --- a/SCons/Scanner/Python.py +++ b/SCons/Scanner/Python.py @@ -92,10 +92,14 @@ def scan(node, env, path=()): # if the same header is included many times. node.includes = list(map(SCons.Util.silent_intern, includes)) - # XXX TODO: Sort? nodes = [] if callable(path): path = path() + + # If there are no paths, there is no point in parsing includes in the loop. + if not path: + return [] + for module, imports in includes: is_relative = module.startswith('.') if is_relative: @@ -111,7 +115,7 @@ def scan(node, env, path=()): search_paths = [current_dir] search_string = module_lstripped else: - search_paths = [env.Dir(p) for p in tuple(path)] + search_paths = [env.Dir(p) for p in path] search_string = module module_components = search_string.split('.') @@ -123,8 +127,8 @@ def scan(node, env, path=()): # lower in the search_paths precedence order. As a result, it is safest # to iterate over search_paths and check whether p or p.py exists in # each path. This allows us to cleanly respect the precedence order. - for path in search_paths: - paths = [path] + for search_path in search_paths: + paths = [search_path] node = SCons.Node.FS.find_file(module_joined, paths, verbose=True) if node: # The fact that we were able to find the node without appending .py @@ -136,7 +140,6 @@ def scan(node, env, path=()): # import, we don't need to take the dependency because Python # requires that all referenced packages have already been imported, # which means that the dependency has already been established. - # XXX TODO: This part is broken and needs to be fixed. if not is_relative and len(module_components) > 1: import_dirs = module_components for i in range(len(import_dirs)): @@ -150,7 +153,8 @@ def scan(node, env, path=()): if node: nodes.append(node) - return sorted(nodes) + print('returning nodes %s' % ([str(n) for n in nodes])) + return nodes PythonSuffixes = ['.py'] diff --git a/test/Scanner/Python.py b/test/Scanner/Python.py index 404967c..bb6e2c7 100644 --- a/test/Scanner/Python.py +++ b/test/Scanner/Python.py @@ -32,7 +32,7 @@ import TestSCons test = TestSCons.TestSCons() test.dir_fixture('Python') -test.run(arguments = '-n --tree=prune --debug=stacktrace .', stdout='') +test.run(arguments = '--debug=stacktrace .', stdout='') test.pass_test() # Local Variables: -- cgit v0.12 From 1037bb6069612408183e953081c72dac9814f370 Mon Sep 17 00:00:00 2001 From: Adam Gross Date: Mon, 16 Nov 2020 11:47:16 -0500 Subject: [ci skip] Cancel test runs because my tests don't work --- test/Scanner/Python.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Scanner/Python.py b/test/Scanner/Python.py index bb6e2c7..404967c 100644 --- a/test/Scanner/Python.py +++ b/test/Scanner/Python.py @@ -32,7 +32,7 @@ import TestSCons test = TestSCons.TestSCons() test.dir_fixture('Python') -test.run(arguments = '--debug=stacktrace .', stdout='') +test.run(arguments = '-n --tree=prune --debug=stacktrace .', stdout='') test.pass_test() # Local Variables: -- cgit v0.12 From 55b41b5841aaf1f86d8a8380e0f8603b45bcc49f Mon Sep 17 00:00:00 2001 From: Adam Gross Date: Mon, 16 Nov 2020 16:59:20 -0500 Subject: [ci skip] Some fixes to the Python scanner and test --- SCons/Scanner/Python.py | 76 +++++++++++++++++++++++++++---------------------- test/Scanner/Python.py | 2 +- 2 files changed, 43 insertions(+), 35 deletions(-) diff --git a/SCons/Scanner/Python.py b/SCons/Scanner/Python.py index 5f51a7c..ada575e 100644 --- a/SCons/Scanner/Python.py +++ b/SCons/Scanner/Python.py @@ -118,43 +118,51 @@ def scan(node, env, path=()): search_paths = [env.Dir(p) for p in path] search_string = module - module_components = search_string.split('.') - module_joined = '/'.join(module_components) - - # For an import of "p", it could either result in a directory named - # p or a file named p.py. We can't do two consecutive searches for p - # then p.py because the first search could return a result that is - # lower in the search_paths precedence order. As a result, it is safest - # to iterate over search_paths and check whether p or p.py exists in - # each path. This allows us to cleanly respect the precedence order. - for search_path in search_paths: - paths = [search_path] - node = SCons.Node.FS.find_file(module_joined, paths, verbose=True) - if node: - # The fact that we were able to find the node without appending .py - # means that this is a directory import. - nodes.append(env.Dir(node).File('__init__.py')) - - # Take a dependency on all __init__.py files from all imported - # packages unless it's a relative import. If it's a relative - # import, we don't need to take the dependency because Python - # requires that all referenced packages have already been imported, - # which means that the dependency has already been established. - if not is_relative and len(module_components) > 1: - import_dirs = module_components - for i in range(len(import_dirs)): - init_path = '/'.join(module_components[:i+1] + ['__init__.py']) - # TODO: Passing search_paths is not correct. - init_node = SCons.Node.FS.find_file(init_path, paths, verbose=True) - if init_node: - nodes.append(init_node) - else: - node = SCons.Node.FS.find_file(module_joined + '.py', paths, verbose=True) + if not imports: + imports = [None] + + for i in imports: + module_components = search_string.split('.') + import_components = [i] if i is not None else [] + components = [x for x in module_components + import_components if x] + module_path = '/'.join(components) + '.py' + package_path = '/'.join(components + ['__init__.py']) + + # For an import of "p", it could either result in a file named p.py or + # p/__init__.py. We can't do two consecutive searches for p then p.py + # because the first search could return a result that is lower in the + # search_paths precedence order. As a result, it is safest to iterate + # over search_paths and check whether p or p.py exists in each path. + # This allows us to cleanly respect the precedence order. + for search_path in search_paths: + paths = [search_path] + # See if p/__init__.py exists. + node = SCons.Node.FS.find_file(package_path, paths, verbose=True) if node: nodes.append(node) + else: + node = SCons.Node.FS.find_file(module_path, paths, verbose=True) + if node: + nodes.append(node) - print('returning nodes %s' % ([str(n) for n in nodes])) - return nodes + if node: + # Take a dependency on all __init__.py files from all imported + # packages unless it's a relative import. If it's a relative + # import, we don't need to take the dependency because Python + # requires that all referenced packages have already been imported, + # which means that the dependency has already been established. + if not is_relative and len(module_components) > 1: + for i in range(len(module_components[:-1])): + init_path = '/'.join(module_components[:i+1] + ['__init__.py']) + init_node = SCons.Node.FS.find_file(init_path, paths, verbose=True) + if init_node: + nodes.append(init_node) + + # The import was found, so no need to keep iterating through + # search_paths. + break + + return sorted(nodes) PythonSuffixes = ['.py'] diff --git a/test/Scanner/Python.py b/test/Scanner/Python.py index 404967c..bb6e2c7 100644 --- a/test/Scanner/Python.py +++ b/test/Scanner/Python.py @@ -32,7 +32,7 @@ import TestSCons test = TestSCons.TestSCons() test.dir_fixture('Python') -test.run(arguments = '-n --tree=prune --debug=stacktrace .', stdout='') +test.run(arguments = '--debug=stacktrace .', stdout='') test.pass_test() # Local Variables: -- cgit v0.12 From a6fdbf0aa1320f4c2b6f4daa5b9496108d22e0cd Mon Sep 17 00:00:00 2001 From: Adam Gross Date: Mon, 16 Nov 2020 21:17:33 -0500 Subject: Fix all tests This change fixes all tests. It's still a a WIP change because I think the "imports" logic is wrong for file imports. --- SCons/Scanner/Python.py | 22 ++++++++++------------ test/Scanner/Python.py | 9 ++++++--- test/Scanner/Python/SConstruct | 15 ++++++++++----- test/Scanner/Python/to_be_copied/sconstest.skip | 0 4 files changed, 26 insertions(+), 20 deletions(-) create mode 100644 test/Scanner/Python/to_be_copied/sconstest.skip diff --git a/SCons/Scanner/Python.py b/SCons/Scanner/Python.py index ada575e..2d4a211 100644 --- a/SCons/Scanner/Python.py +++ b/SCons/Scanner/Python.py @@ -136,26 +136,24 @@ def scan(node, env, path=()): # This allows us to cleanly respect the precedence order. for search_path in search_paths: paths = [search_path] - # See if p/__init__.py exists. - node = SCons.Node.FS.find_file(package_path, paths, verbose=True) + node = SCons.Node.FS.find_file(package_path, paths) + if not node: + node = SCons.Node.FS.find_file(module_path, paths) + if node: nodes.append(node) - else: - node = SCons.Node.FS.find_file(module_path, paths, verbose=True) - if node: - nodes.append(node) - if node: # Take a dependency on all __init__.py files from all imported # packages unless it's a relative import. If it's a relative # import, we don't need to take the dependency because Python # requires that all referenced packages have already been imported, # which means that the dependency has already been established. - if not is_relative and len(module_components) > 1: - for i in range(len(module_components[:-1])): - init_path = '/'.join(module_components[:i+1] + ['__init__.py']) - init_node = SCons.Node.FS.find_file(init_path, paths, verbose=True) - if init_node: + if not is_relative: + import_dirs = module_components + for i in range(len(import_dirs)): + init_path = '/'.join(import_dirs[:i+1] + ['__init__.py']) + init_node = SCons.Node.FS.find_file(init_path, paths) + if init_node and init_node not in nodes: nodes.append(init_node) # The import was found, so no need to keep iterating through diff --git a/test/Scanner/Python.py b/test/Scanner/Python.py index bb6e2c7..b5b3ae5 100644 --- a/test/Scanner/Python.py +++ b/test/Scanner/Python.py @@ -24,15 +24,18 @@ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ -Template for end-to-end test file. -Replace this with a description of the test. +Functional test for the Python scanner. Validates that the scanner is able to +find dynamically generated dependencies. The SConstruct copies in the +dependencies and runs a script. The expected behavior is that the scanner +picks up these dependencies, so SCons understands that the script shouldn't +be run until the files are copied. """ import TestSCons test = TestSCons.TestSCons() test.dir_fixture('Python') -test.run(arguments = '--debug=stacktrace .', stdout='') +test.run(arguments = '.') test.pass_test() # Local Variables: diff --git a/test/Scanner/Python/SConstruct b/test/Scanner/Python/SConstruct index 732b55c..988cf60 100644 --- a/test/Scanner/Python/SConstruct +++ b/test/Scanner/Python/SConstruct @@ -1,11 +1,16 @@ import sys env = Environment(tools=['python']) -for source, target in [ - ('to_be_copied', 'package1'), - ('to_be_copied', 'package2'), -]: - env.Command(env.Dir(target), env.Dir(source), Copy('$TARGET', '$SOURCE')) + +# Copy each file individually instead of copying the dir. This has the benefit +# of establishing nodes in-memory for each of the resulting files, which helps +# the scanner work correctly. +srcDir = env.Dir('to_be_copied') +for srcNode in srcDir.glob('*'): + for destDir in [env.Dir('package1'), env.Dir('package2')]: + env.Command(destDir.File(srcNode.name), srcNode, + Copy('$TARGET', '$SOURCE')) + # Don't set a dependency on the copy actions on purpose. Scanner should find # the dependencies automatically. env.Command('a.out', 'script.py', '$PYTHON $SOURCE $TARGET', PYTHON=sys.executable) \ No newline at end of file diff --git a/test/Scanner/Python/to_be_copied/sconstest.skip b/test/Scanner/Python/to_be_copied/sconstest.skip new file mode 100644 index 0000000..e69de29 -- cgit v0.12 From 54e4841387c4d3247a6529b259a5db75774311f5 Mon Sep 17 00:00:00 2001 From: Adam Gross Date: Tue, 17 Nov 2020 09:16:12 -0500 Subject: Fix sider issues --- test/Scanner/Python/script.py | 4 ++-- test/Scanner/Python/to_be_copied/__init__.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/Scanner/Python/script.py b/test/Scanner/Python/script.py index f633f43..105a575 100644 --- a/test/Scanner/Python/script.py +++ b/test/Scanner/Python/script.py @@ -1,5 +1,5 @@ -import package1 -import package2 +import package1 # noqa: F401 +import package2 # noqa: F401 import sys with open(sys.argv[1], 'w') as f: diff --git a/test/Scanner/Python/to_be_copied/__init__.py b/test/Scanner/Python/to_be_copied/__init__.py index 34fdc42..3c1c05b 100644 --- a/test/Scanner/Python/to_be_copied/__init__.py +++ b/test/Scanner/Python/to_be_copied/__init__.py @@ -1 +1 @@ -from . import helper \ No newline at end of file +from . import helper # noqa: F401 \ No newline at end of file -- cgit v0.12 From bac3074b9f700a020bfeaad37658d8a2db68cffd Mon Sep 17 00:00:00 2001 From: Adam Gross Date: Tue, 17 Nov 2020 13:44:55 -0500 Subject: Fix tests, implement smarter version of scanner --- SCons/Scanner/Python.py | 115 +++++++++++++-------- SCons/Scanner/PythonTests.py | 72 ++++++++++++- .../from_import_simple_package_module1_func.py | 1 + .../python_scanner/from_nested1_import_multiple.py | 1 + .../python_scanner/imports_unknown_files.py | 3 + .../python_scanner/simple_package/module1.py | 2 + .../python_scanner/simple_package/somefunc.py | 0 7 files changed, 149 insertions(+), 45 deletions(-) create mode 100644 test/fixture/python_scanner/from_import_simple_package_module1_func.py create mode 100644 test/fixture/python_scanner/from_nested1_import_multiple.py create mode 100644 test/fixture/python_scanner/imports_unknown_files.py create mode 100644 test/fixture/python_scanner/simple_package/somefunc.py diff --git a/SCons/Scanner/Python.py b/SCons/Scanner/Python.py index 2d4a211..f8272df 100644 --- a/SCons/Scanner/Python.py +++ b/SCons/Scanner/Python.py @@ -82,6 +82,40 @@ def find_include_names(node): return all_matches +def find_import(import_path, search_paths): + """ + Finds the specified import in the various search paths. + For an import of "p", it could either result in a file named p.py or + p/__init__.py. We can't do two consecutive searches for p then p.py + because the first search could return a result that is lower in the + search_paths precedence order. As a result, it is safest to iterate over + search_paths and check whether p or p.py exists in each path. This allows + us to cleanly respect the precedence order. + + If the import is found, returns a tuple containing: + 1. Discovered dependency node (e.g. p/__init__.py or p.py) + 2. True if the import was a package, False if the import was a module. + 3. The Dir node in search_paths that the import is relative to. + If the import is not found, returns a tuple containing (None, False, None). + Callers should check for failure by checking whether the first entry in the + tuple is not None. + """ + for search_path in search_paths: + paths = [search_path] + # Note: if the same import is present as a package and a module, Python + # prefers the package. As a result, we always look for x/__init__.py + # before looking for x.py. + node = SCons.Node.FS.find_file(import_path + '/__init__.py', paths) + if node: + return node, True, search_path + else: + node = SCons.Node.FS.find_file(import_path + '.py', paths) + if node: + return node, False, search_path + + return None, False, None + + def scan(node, env, path=()): # cache the includes list in node so we only scan it once: if node.includes is not None: @@ -118,47 +152,46 @@ def scan(node, env, path=()): search_paths = [env.Dir(p) for p in path] search_string = module - if not imports: - imports = [None] - - for i in imports: - module_components = search_string.split('.') - import_components = [i] if i is not None else [] - components = [x for x in module_components + import_components if x] - module_path = '/'.join(components) + '.py' - package_path = '/'.join(components + ['__init__.py']) - - # For an import of "p", it could either result in a file named p.py or - # p/__init__.py. We can't do two consecutive searches for p then p.py - # because the first search could return a result that is lower in the - # search_paths precedence order. As a result, it is safest to iterate - # over search_paths and check whether p or p.py exists in each path. - # This allows us to cleanly respect the precedence order. - for search_path in search_paths: - paths = [search_path] - node = SCons.Node.FS.find_file(package_path, paths) - if not node: - node = SCons.Node.FS.find_file(module_path, paths) - - if node: - nodes.append(node) - - # Take a dependency on all __init__.py files from all imported - # packages unless it's a relative import. If it's a relative - # import, we don't need to take the dependency because Python - # requires that all referenced packages have already been imported, - # which means that the dependency has already been established. - if not is_relative: - import_dirs = module_components - for i in range(len(import_dirs)): - init_path = '/'.join(import_dirs[:i+1] + ['__init__.py']) - init_node = SCons.Node.FS.find_file(init_path, paths) - if init_node and init_node not in nodes: - nodes.append(init_node) - - # The import was found, so no need to keep iterating through - # search_paths. - break + module_components = [x for x in search_string.split('.') if x] + package_dir = None + hit_dir = None + if not module_components: + # This is just a "from . import x". + package_dir = search_paths[0] + else: + # Translate something like "import x.y" to a call to find_import + # with 'x/y' as the path. find_import will then determine whether + # we can find 'x/y/__init__.py' or 'x/y.py'. + import_node, is_dir, hit_dir = find_import( + '/'.join(module_components), search_paths) + if import_node: + nodes.append(import_node) + if is_dir: + package_dir = import_node.dir + + # If the statement was something like "from x import y, z", whether we + # iterate over imports depends on whether x was a package or module. + # If it was a module, y and z are just functions so we don't need to + # search for them. If it was a package, y and z are either packages or + # modules and we do need to search for them. + if package_dir and imports: + for i in imports: + import_node, _, _ = find_import(i, [package_dir]) + if import_node: + nodes.append(import_node) + + # Take a dependency on all __init__.py files from all imported + # packages unless it's a relative import. If it's a relative + # import, we don't need to take the dependency because Python + # requires that all referenced packages have already been imported, + # which means that the dependency has already been established. + if hit_dir and not is_relative: + import_dirs = module_components + for i in range(len(import_dirs)): + init_path = '/'.join(import_dirs[:i+1] + ['__init__.py']) + init_node = SCons.Node.FS.find_file(init_path, [hit_dir]) + if init_node and init_node not in nodes: + nodes.append(init_node) return sorted(nodes) diff --git a/SCons/Scanner/PythonTests.py b/SCons/Scanner/PythonTests.py index faf548a..84acd0c 100644 --- a/SCons/Scanner/PythonTests.py +++ b/SCons/Scanner/PythonTests.py @@ -21,6 +21,21 @@ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +""" +Unit tests for the Python scanner. These tests validate proper working of the +Python scanner by confirming that the results of the scan match expectations. + +The absolute path tests have strongly-defined behavior in that there is no real +ambiguity to what they should result in. For example, if you import package x, +you expect to get x/__init__.py as a dependency. + +The relative path tests that reach into ancestor directories do have some +ambiguity in whether to depend upon __init__.py in those referenced ancestor +directories. Python only allows these kinds of relative imports if the file is +part of a package, in which case those ancestor directories' __init__.py files +have already been imported. +""" + import SCons.compat import collections @@ -226,9 +241,6 @@ class PythonScannerTestImportsGrandparentModule(unittest.TestCase): 'nested1/nested2/nested3/imports_grandparent_module.py') path = s.path(env, source=[node]) deps = s(node, env, path) - # Note: there is some ambiguity here in what the scanner should return. - # Relative imports require that the referenced packages have already - # been imported. files = ['nested1/module.py'] deps_match(self, deps, files) @@ -253,7 +265,59 @@ class PythonScannerTestImportsParentThenSubmodule(unittest.TestCase): 'nested1/nested2/nested3/imports_parent_then_submodule.py') path = s.path(env, source=[node]) deps = s(node, env, path) - files = ['nested1/nested2a/module.py'] + files = ['nested1/nested2a/__init__.py', 'nested1/nested2a/module.py'] + deps_match(self, deps, files) + + +class PythonScannerTestImportsModuleWithFunc(unittest.TestCase): + def runTest(self): + """ + This test case tests the following import statement: + `from simple_package.module1 import somefunc` with somefunc.py existing + in the same folder as module1.py. It validates that the scanner doesn't + accidentally take a dependency somefunc.py. + """ + env = DummyEnvironment() + s = SCons.Scanner.Python.PythonScanner + env['ENV']['PYTHONPATH'] = test.workpath('') + deps = s(env.File('from_import_simple_package_module1_func.py'), env, + lambda : s.path(env)) + files = ['simple_package/__init__.py', 'simple_package/module1.py'] + deps_match(self, deps, files) + + +class PythonScannerTestFromNested1ImportNested2(unittest.TestCase): + def runTest(self): + """ + This test case tests the following import statement: + `from nested1 import module, nested2`. In this test, module is a Python + module and nested2 is a package. Validates that the scanner can handle + such mixed imports. + """ + env = DummyEnvironment() + s = SCons.Scanner.Python.PythonScanner + env['ENV']['PYTHONPATH'] = test.workpath('') + deps = s(env.File('from_nested1_import_multiple.py'), env, + lambda : s.path(env)) + files = ['nested1/__init__.py', 'nested1/module.py', + 'nested1/nested2/__init__.py'] + deps_match(self, deps, files) + + +class PythonScannerTestImportUnknownFiles(unittest.TestCase): + def runTest(self): + """ + This test case tests importing files that are not found. If Python + really can't find those files, it will fail. But this is intended to + test the various failure paths in the scanner to make sure that they + don't raise exceptions. + """ + env = DummyEnvironment() + s = SCons.Scanner.Python.PythonScanner + env['ENV']['PYTHONPATH'] = test.workpath('') + deps = s(env.File('imports_unknown_files.py'), env, + lambda : s.path(env)) + files = [] deps_match(self, deps, files) diff --git a/test/fixture/python_scanner/from_import_simple_package_module1_func.py b/test/fixture/python_scanner/from_import_simple_package_module1_func.py new file mode 100644 index 0000000..e9877fb --- /dev/null +++ b/test/fixture/python_scanner/from_import_simple_package_module1_func.py @@ -0,0 +1 @@ +from simple_package.module1 import somefunc # noqa: F401 \ No newline at end of file diff --git a/test/fixture/python_scanner/from_nested1_import_multiple.py b/test/fixture/python_scanner/from_nested1_import_multiple.py new file mode 100644 index 0000000..2cdd47f --- /dev/null +++ b/test/fixture/python_scanner/from_nested1_import_multiple.py @@ -0,0 +1 @@ +from nested1 import module, nested2 # noqa: F401 \ No newline at end of file diff --git a/test/fixture/python_scanner/imports_unknown_files.py b/test/fixture/python_scanner/imports_unknown_files.py new file mode 100644 index 0000000..2059181 --- /dev/null +++ b/test/fixture/python_scanner/imports_unknown_files.py @@ -0,0 +1,3 @@ +import doesntexist +import notthere.something +from notthere import a, few, things \ No newline at end of file diff --git a/test/fixture/python_scanner/simple_package/module1.py b/test/fixture/python_scanner/simple_package/module1.py index e69de29..6880c47 100644 --- a/test/fixture/python_scanner/simple_package/module1.py +++ b/test/fixture/python_scanner/simple_package/module1.py @@ -0,0 +1,2 @@ +def somefunc(): + return \ No newline at end of file diff --git a/test/fixture/python_scanner/simple_package/somefunc.py b/test/fixture/python_scanner/simple_package/somefunc.py new file mode 100644 index 0000000..e69de29 -- cgit v0.12 From a6f317b4301d968cbda2c7fbe903d23347900bf8 Mon Sep 17 00:00:00 2001 From: Adam Gross Date: Tue, 17 Nov 2020 15:31:06 -0500 Subject: [ci skip] Fix flake8 warnings, add description to CHANGES.txt --- CHANGES.txt | 2 ++ test/fixture/python_scanner/imports_unknown_files.py | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 77fb110..e790b67 100755 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -35,6 +35,8 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER User-facing behavior does not change with this fix (GH Issue #3726). - Fix occasional test failures caused by not being able to find a file or directory fixture when running multiple tests with multiple jobs. + - Add support to the Python scanner for finding dynamically generated dependencies. + Previously the scanner only found imports if they existed on disk at scanning time. From Joachim Kuebart: - Suppress missing SConscript deprecation warning if `must_exist=False` diff --git a/test/fixture/python_scanner/imports_unknown_files.py b/test/fixture/python_scanner/imports_unknown_files.py index 2059181..5582e7b 100644 --- a/test/fixture/python_scanner/imports_unknown_files.py +++ b/test/fixture/python_scanner/imports_unknown_files.py @@ -1,3 +1,3 @@ -import doesntexist -import notthere.something -from notthere import a, few, things \ No newline at end of file +import doesntexist # noqa: F401 +import notthere.something # noqa: F401 +from notthere import a, few, things # noqa: F401 \ No newline at end of file -- cgit v0.12 -- cgit v0.12 From b9085adbb23b2083a2064928377931578a456f8c Mon Sep 17 00:00:00 2001 From: Adam Gross Date: Sat, 9 Jan 2021 10:08:36 -0500 Subject: Address review feedback Better handle relative imports if no paths are provided. --- SCons/Scanner/Python.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/SCons/Scanner/Python.py b/SCons/Scanner/Python.py index f8272df..86aa001 100644 --- a/SCons/Scanner/Python.py +++ b/SCons/Scanner/Python.py @@ -130,10 +130,6 @@ def scan(node, env, path=()): if callable(path): path = path() - # If there are no paths, there is no point in parsing includes in the loop. - if not path: - return [] - for module, imports in includes: is_relative = module.startswith('.') if is_relative: @@ -152,6 +148,11 @@ def scan(node, env, path=()): search_paths = [env.Dir(p) for p in path] search_string = module + # If there are no paths, there is no point in parsing includes for this + # iteration of the loop. + if not search_paths: + continue + module_components = [x for x in search_string.split('.') if x] package_dir = None hit_dir = None -- cgit v0.12 From b6e861cc465680f4c1ae5ec3327504da9afd5730 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Fri, 2 Apr 2021 07:43:49 -0600 Subject: Test tweaks to help testing on mingw-only win32 systems On a system where SCons is started from the mingw bash shell, and mingw Python is the interpreter, the secondary self-identification differs. Use that in a few tests which otherwise make the wrong decision. EnvironmentTests used an invalid value for CCFLAGS, and empty string is a better choice. Change a couple of cases where Python code was run directly so it's prefixed by the-Python-in-use, which fails if there is not a Windows-registered program for .py files - we didn't really want to use the Windows-native Python anyway. Signed-off-by: Mats Wichmann --- SCons/EnvironmentTests.py | 2 +- SCons/Tool/link.py | 4 +- test/Decider/MD5-winonly-fixture/test_parse.y | 8 +++- test/LEX/LEXFLAGS.py | 20 +++++----- test/LEX/live_mingw.py | 23 +++++------ test/Libs/SharedLibrary-update-deps.py | 14 ++++--- test/Libs/SharedLibrary.py | 41 +++++++++----------- test/MinGW/MinGWSharedLibrary.py | 16 ++++---- test/MinGW/RCCOM.py | 20 +++++----- test/MinGW/RCCOMSTR.py | 21 +++++----- test/MinGW/WINDOWS_INSERT_DEF.py | 21 +++++----- test/MinGW/bug_2799/SConstruct | 16 ++++---- test/MinGW/mingw_uses_comstr_issue_2799.py | 21 ++++++---- test/Win32/mingw.py | 17 ++++++--- test/Win32/msvc_mingw_env.py | 38 +++++++++--------- test/long-lines/signature.py | 55 +++++++++++++++++---------- test/rebuild-generated.py | 45 ++++++++++------------ test/sconsign/script/SConsignFile.py | 24 +++++++----- test/sconsign/script/Signatures.py | 30 +++++++++------ test/sconsign/script/no-SConsignFile.py | 27 ++++++++----- testing/framework/TestCommon.py | 4 -- 21 files changed, 258 insertions(+), 209 deletions(-) diff --git a/SCons/EnvironmentTests.py b/SCons/EnvironmentTests.py index b4d5d0d..4ea2c66 100644 --- a/SCons/EnvironmentTests.py +++ b/SCons/EnvironmentTests.py @@ -869,7 +869,7 @@ sys.exit(0) # avoid SubstitutionEnvironment for these, has no .Append method, # which is needed for unique=False test - env = Environment(CCFLAGS=None) + env = Environment(CCFLAGS="") # merge with existing but empty flag env.MergeFlags('-X') assert env['CCFLAGS'] == ['-X'], env['CCFLAGS'] diff --git a/SCons/Tool/link.py b/SCons/Tool/link.py index efc84f1..24d17a3 100644 --- a/SCons/Tool/link.py +++ b/SCons/Tool/link.py @@ -21,9 +21,9 @@ # 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. -# + """ -Tool-specific initialization for the generic Posix linker. +Tool-specific initialization for the generic POSIX linker. There normally shouldn't be any need to import this module directly. It will usually be imported through the generic SCons.Tool.Tool() diff --git a/test/Decider/MD5-winonly-fixture/test_parse.y b/test/Decider/MD5-winonly-fixture/test_parse.y index 3ead9d2..2172298 100644 --- a/test/Decider/MD5-winonly-fixture/test_parse.y +++ b/test/Decider/MD5-winonly-fixture/test_parse.y @@ -1,6 +1,9 @@ %{ #include +int yyerror(char *s); +int yylex(); + int regs[26]; int base; @@ -25,11 +28,13 @@ digit: DIGIT; %% +int main() { return(yyparse()); } +int yyerror(s) char *s; { @@ -37,7 +42,8 @@ char *s; return(0); } +int yywrap() { return(1); -} \ No newline at end of file +} diff --git a/test/LEX/LEXFLAGS.py b/test/LEX/LEXFLAGS.py index 2cebca7..efcf9c4 100644 --- a/test/LEX/LEXFLAGS.py +++ b/test/LEX/LEXFLAGS.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,11 +22,9 @@ # 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 sys +import sysconfig import TestSCons @@ -59,10 +59,12 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(LEX = r'%(_python_)s mylex.py', - LEXFLAGS = '-x -I${TARGET.dir} -I${SOURCE.dir}', - tools=['default', 'lex']) -env.CFile(target = 'out/aaa', source = 'in/aaa.l') +env = Environment( + LEX=r'%(_python_)s mylex.py', + LEXFLAGS='-x -I${TARGET.dir} -I${SOURCE.dir}', + tools=['default', 'lex'], +) +env.CFile(target='out/aaa', source='in/aaa.l') """ % locals()) test.write(['in', 'aaa.l'], "aaa.l\nLEXFLAGS\nI_ARGS\n") @@ -70,7 +72,7 @@ test.write(['in', 'aaa.l'], "aaa.l\nLEXFLAGS\nI_ARGS\n") test.run('.', stderr = None) lexflags = ' -x -t' -if sys.platform == 'win32': +if sys.platform == 'win32' and not sysconfig.get_platform() in ("mingw",): lexflags = ' --nounistd' + lexflags # Read in with mode='r' because mylex.py implicitley wrote to stdout # with mode='w'. diff --git a/test/LEX/live_mingw.py b/test/LEX/live_mingw.py index d535065..5c64eb8 100644 --- a/test/LEX/live_mingw.py +++ b/test/LEX/live_mingw.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # 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 LEX and LEXFLAGS and unistd.h with a live lex in mingw environment. @@ -41,7 +40,7 @@ if sys.platform != 'win32': test.skip_test('Not windows environment; skipping test.\n') if not test.where_is('gcc'): - test.skip_test('No mingw or cygwin build environment found; skipping test.\n') + test.skip_test('No mingw or cygwin build environment found; skipping test.\n') lex = test.where_is('lex') or test.where_is('flex') @@ -53,12 +52,14 @@ test.file_fixture('wrapper.py') test.write('SConstruct', """ foo = Environment(tools=['default', 'mingw', 'lex'], LEXUNISTD="") lex = foo.Dictionary('LEX') -bar = Environment(LEX = r'%(_python_)s wrapper.py ' + lex, - LEXFLAGS = '-b', - LEXUNISTD="", - tools=['default', 'mingw', 'lex']) -foo.Program(target = 'foo', source = 'foo.l') -bar.Program(target = 'bar', source = 'bar.l') +bar = Environment( + LEX=r'%(_python_)s wrapper.py ' + lex, + LEXFLAGS='-b', + LEXUNISTD="", + tools=['default', 'mingw', 'lex'], +) +foo.Program(target='foo', source='foo.l') +bar.Program(target='bar', source='bar.l') """ % locals()) lex = r""" diff --git a/test/Libs/SharedLibrary-update-deps.py b/test/Libs/SharedLibrary-update-deps.py index 922d580..f8ab44d 100644 --- a/test/Libs/SharedLibrary-update-deps.py +++ b/test/Libs/SharedLibrary-update-deps.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,16 +22,16 @@ # 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 that SharedLibrary() updates when a different lib is linked, even if it has the same md5. +Test that SharedLibrary() updates when a different lib is linked, +even if it has the same md5. This is https://github.com/SCons/scons/issues/2903 """ import sys +import sysconfig + import TestSCons test = TestSCons.TestSCons() @@ -50,7 +52,7 @@ test.run(arguments='libname=foo') test.must_not_contain_any_line(test.stdout(), ["is up to date"]) # Now try changing the link command line (in an innocuous way); should rebuild. -if sys.platform == 'win32': +if sys.platform == 'win32' and not sysconfig.get_platform() in ("mingw",): extraflags='shlinkflags=/DEBUG' else: extraflags='shlinkflags=-g' diff --git a/test/Libs/SharedLibrary.py b/test/Libs/SharedLibrary.py index 3d2c734..f67d707 100644 --- a/test/Libs/SharedLibrary.py +++ b/test/Libs/SharedLibrary.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import os import sys @@ -33,38 +32,36 @@ test = TestSCons.TestSCons() test.write('SConstruct', """ import sys -env=Environment(WINDOWS_INSERT_DEF=1) -env2 = Environment(LIBS = [ 'foo1', 'foo2', 'foo3' ], - LIBPATH = [ '.' ]) -env.SharedLibrary(target = 'foo1', source = 'f1.c') + +env = Environment(WINDOWS_INSERT_DEF=1) +env2 = Environment(LIBS=['foo1', 'foo2', 'foo3'], LIBPATH=['.']) +env.SharedLibrary(target='foo1', source='f1.c') if sys.platform == 'win32': - env.StaticLibrary(target = 'foo1-static', source = 'f1.c') + env.StaticLibrary(target='foo1-static', source='f1.c') else: - env.StaticLibrary(target = 'foo1', source = 'f1.c') -SharedLibrary(target = 'foo2', - source = Split('f2a.c f2b.c f2c.c'), - WINDOWS_INSERT_DEF = 1) -env.SharedLibrary(target = 'foo3', source = ['f3a.c', 'f3b.c', 'f3c.c'], no_import_lib = 1) -env2.Program(target = 'prog', source = 'prog.c') + env.StaticLibrary(target='foo1', source='f1.c') +SharedLibrary(target='foo2', source=Split('f2a.c f2b.c f2c.c'), WINDOWS_INSERT_DEF=1) +env.SharedLibrary(target='foo3', source=['f3a.c', 'f3b.c', 'f3c.c'], no_import_lib=1) +env2.Program(target='prog', source='prog.c') """) test.write('SConstructFoo', """ -env=Environment() +env = Environment() obj = env.Object('foo', 'foo.c') -Default(env.SharedLibrary(target = 'foo', source = obj)) +Default(env.SharedLibrary(target='foo', source=obj)) """) test.write('SConstructFoo2', """ -env=Environment() +env = Environment() obj = env.SharedObject('bar', 'foo.c') -Default(env.Library(target = 'foo', source = obj)) +Default(env.Library(target='foo', source=obj)) """) test.write('SConstructBaz', """ -env=Environment() +env = Environment() env['SHLIBVERSION'] = '1.0.0' obj = env.SharedObject('baz', 'foo.c') -Default(env.SharedLibrary(target = 'baz', source = obj)) +Default(env.SharedLibrary(target='baz', source=obj)) """) test.write('foo.c', r""" @@ -252,7 +249,7 @@ env2.Program(target = 'progbar', source = 'progbar.c') test.write('f4.c', r""" #include -f4(void) +void f4(void) { printf("f4.c\n"); fflush(stdout); diff --git a/test/MinGW/MinGWSharedLibrary.py b/test/MinGW/MinGWSharedLibrary.py index 9ce4eb3..9fac820 100644 --- a/test/MinGW/MinGWSharedLibrary.py +++ b/test/MinGW/MinGWSharedLibrary.py @@ -41,30 +41,28 @@ _python_ = TestSCons._python_ test = TestSCons.TestSCons() -if sys.platform not in ('cygwin','win32',): - test.skip_test("Skipping mingw test on non-Windows %s platform."%sys.platform) +if sys.platform not in ('cygwin', 'win32',): + test.skip_test("Skipping mingw test on non-Windows platform %s." % sys.platform) -gcc = SCons.Tool.find_program_path(test.Environment(), 'gcc', default_paths=MINGW_DEFAULT_PATHS + CYGWIN_DEFAULT_PATHS ) +dp = MINGW_DEFAULT_PATHS +gcc = SCons.Tool.find_program_path(test.Environment(), 'gcc', default_paths=dp) if not gcc: test.skip_test("Skipping mingw test, no MinGW found.\n") test.write('foobar.cc', """ int abc(int a) { return (a+1); - } - """) +} +""") test.write('SConstruct', """ DefaultEnvironment(tools=[]) -env = Environment(tools=['mingw','link','g++']) -#env.Tool('mingw') +env = Environment(tools=['mingw', 'link', 'g++']) foobar_obj = env.SharedObject('foobar.cc') env.SharedLibrary('foobar', foobar_obj) # Now verify versioned shared library doesn't fail env.SharedLibrary('foobar_ver', foobar_obj, SHLIBVERSION='2.4') - - """ % locals()) test.run(arguments = ".") diff --git a/test/MinGW/RCCOM.py b/test/MinGW/RCCOM.py index a4d9147..ffd58c8 100644 --- a/test/MinGW/RCCOM.py +++ b/test/MinGW/RCCOM.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,13 +22,10 @@ # 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 $RCCOM construction variable -when using MinGW. +when using MinGW. This test does not use a compiler. """ import sys @@ -37,14 +36,17 @@ _python_ = TestSCons._python_ test = TestSCons.TestSCons() if sys.platform in ('irix6',): - test.skip_test("Skipping mingw test on non-Windows %s platform."%sys.platform) + test.skip_test("Skipping mingw test on non-Windows platform %s." % sys.platform) test.file_fixture('mycompile.py') test.write('SConstruct', """ -env = Environment(tools=['default', 'mingw'], - RCCOM = r'%(_python_)s mycompile.py rc $TARGET $SOURCES') -env.RES(target = 'aaa', source = 'aaa.rc') +DefaultEnvironment(tools=[]) +env = Environment( + tools=['default', 'mingw'], + RCCOM=r'%(_python_)s mycompile.py rc $TARGET $SOURCES', +) +env.RES(target='aaa', source='aaa.rc') """ % locals()) test.write('aaa.rc', "aaa.rc\n/*rc*/\n") diff --git a/test/MinGW/RCCOMSTR.py b/test/MinGW/RCCOMSTR.py index 0ed84c2..e661577 100644 --- a/test/MinGW/RCCOMSTR.py +++ b/test/MinGW/RCCOMSTR.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,13 +22,11 @@ # 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 that the $RCCOMSTR construction variable allows you to customize -the displayed string when rc is called. +the displayed string when rc is called when using MinGW. +This test does not use a compiler. """ import sys @@ -42,10 +42,13 @@ if sys.platform in ('irix6',): test.file_fixture('mycompile.py') test.write('SConstruct', """ -env = Environment(tools=['default', 'mingw'], - RCCOM = r'%(_python_)s mycompile.py rc $TARGET $SOURCES', - RCCOMSTR = 'RCing $TARGET from $SOURCE') -env.RES(target = 'aaa', source = 'aaa.rc') +DefaultEnvironment(tools=[]) +env = Environment( + tools=['default', 'mingw'], + RCCOM=r'%(_python_)s mycompile.py rc $TARGET $SOURCES', + RCCOMSTR='RCing $TARGET from $SOURCE', +) +env.RES(target='aaa', source='aaa.rc') """ % locals()) test.write('aaa.rc', "aaa.rc\n/*rc*/\n") diff --git a/test/MinGW/WINDOWS_INSERT_DEF.py b/test/MinGW/WINDOWS_INSERT_DEF.py index f82ebd8..5119c97 100644 --- a/test/MinGW/WINDOWS_INSERT_DEF.py +++ b/test/MinGW/WINDOWS_INSERT_DEF.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # 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__" """ Make sure that WINDOWS_INSERT_DEF isn't ignored when using MinGW. @@ -39,11 +38,11 @@ from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS test = TestSCons.TestSCons() -if sys.platform not in ('cygwin', 'win32'): - test.skip_test( - "Skipping mingw test on non-Windows platform: %s" % sys.platform) +if sys.platform not in ('cygwin', 'win32',): + test.skip_test("Skipping mingw test on non-Windows platform %s\n" % sys.platform) -gcc = SCons.Tool.find_program_path(test.Environment(), 'gcc', default_paths=MINGW_DEFAULT_PATHS + CYGWIN_DEFAULT_PATHS ) +dp = MINGW_DEFAULT_PATHS +gcc = SCons.Tool.find_program_path(test.Environment(), 'gcc', default_paths=dp) if not gcc: test.skip_test("Skipping mingw test, no MinGW found.\n") @@ -53,9 +52,9 @@ int hello_world(void) { return printf("Orbis, te saluto!\n"); } """) test.write('SConstruct', """ -env = Environment(TOOLS = ['mingw']) -hello_dll = env.SharedLibrary(WINDOWS_INSERT_DEF = 0, - target = 'hello', source = 'hello.c') +DefaultEnvironment(tools=[]) +env = Environment(TOOLS=['mingw']) +hello_dll = env.SharedLibrary(WINDOWS_INSERT_DEF=0, target='hello', source='hello.c') """ % locals()) test.run(arguments = ".") diff --git a/test/MinGW/bug_2799/SConstruct b/test/MinGW/bug_2799/SConstruct index a1832f1..f22cacc 100644 --- a/test/MinGW/bug_2799/SConstruct +++ b/test/MinGW/bug_2799/SConstruct @@ -1,12 +1,12 @@ env = Environment( - tools = ['mingw'], - SHCCCOMSTR = 'SHCC $TARGET', - SHLINKCOMSTR = 'SHLINK $TARGET', - LDMODULECOMSTR = 'LDMODULE $TARGET', - SHOBSUFFIX='.o', - SHLIBSUFFIX='.so', - SHLIBPREFIX='lib', - LDMODULESUFFIX='.so', + tools=['mingw'], + SHCCCOMSTR='SHCC $TARGET', + SHLINKCOMSTR='SHLINK $TARGET', + LDMODULECOMSTR='LDMODULE $TARGET', + SHOBSUFFIX='.o', + SHLIBSUFFIX='.so', + SHLIBPREFIX='lib', + LDMODULESUFFIX='.so', ) env.SharedLibrary('testlib', 'shlib.c') diff --git a/test/MinGW/mingw_uses_comstr_issue_2799.py b/test/MinGW/mingw_uses_comstr_issue_2799.py index fc96ad4..ae34f40 100644 --- a/test/MinGW/mingw_uses_comstr_issue_2799.py +++ b/test/MinGW/mingw_uses_comstr_issue_2799.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -37,13 +39,16 @@ test = TestSCons.TestSCons() test.dir_fixture('bug_2799') test.run('-n -Q') -test.must_contain_all_lines(test.stdout(), - [ - 'SHCC shlib.o', - 'SHLINK libtestlib.so', - 'SHCC module.o', - 'LDMODULE libtestmodule.so',''], - ) +test.must_contain_all_lines( + test.stdout(), + [ + 'SHCC shlib.o', + 'SHLINK libtestlib.so', + 'SHCC module.o', + 'LDMODULE libtestmodule.so', + '', + ], +) test.pass_test() diff --git a/test/Win32/mingw.py b/test/Win32/mingw.py index c45b7c6..aca8795 100644 --- a/test/Win32/mingw.py +++ b/test/Win32/mingw.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +# # MIT License # # Copyright The SCons Foundation @@ -21,11 +22,12 @@ # 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. + """ This tests the MinGW C/C++ compiler support. +This test requires MinGW to be installed. """ - import os import sys @@ -39,13 +41,11 @@ if sys.platform != 'win32': msg = "Skipping mingw test on non-Windows platform '%s'\n" % sys.platform test.skip_test(msg) -# This test requires MinGW to be installed: test.write('SConstruct',""" -from SCons.Tool.mingw import exists import sys +from SCons.Tool.mingw import exists DefaultEnvironment(tools=[]) - env = Environment() if exists(env): print('mingw exists') @@ -61,12 +61,17 @@ test.subdir('header') # Do the actual testing: test.write('SConstruct',""" DefaultEnvironment(tools=[]) -env=Environment(tools=['mingw']) +env = Environment(tools=['mingw']) assert env['CC'] == 'gcc' env.StaticLibrary('static', 'static.cpp') env.SharedLibrary('shared', 'shared.cpp') env.SharedLibrary('cshared', ['cshared.c', 'cshared.def'], WINDOWS_INSERT_DEF=1) -env.Program('test', ['test.cpp', env.RES('resource.rc', CPPPATH=['header'])], LIBS=['static', 'shared', 'cshared'], LIBPATH=['.']) +env.Program( + 'test', + ['test.cpp', env.RES('resource.rc', CPPPATH=['header'])], + LIBS=['static', 'shared', 'cshared'], + LIBPATH=['.'], +) """) test.write('test.cpp', ''' diff --git a/test/Win32/msvc_mingw_env.py b/test/Win32/msvc_mingw_env.py index 107cd1e..f278cfa 100644 --- a/test/Win32/msvc_mingw_env.py +++ b/test/Win32/msvc_mingw_env.py @@ -1,10 +1,8 @@ -""" -This tests the MinGW with MSVC tool. -""" - #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -24,9 +22,10 @@ This tests the MinGW with MSVC tool. # 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__" +""" +This tests the MinGW with MSVC tool. +""" import sys @@ -43,21 +42,22 @@ test.skip_if_not_msvc() # control test: check for nologo and cl in env test.write('SConstruct',""" -env=Environment(tools=['default']) +DefaultEnvironment(tools=[]) +env = Environment(tools=['default']) print('CCFLAGS=' + str(env['CCFLAGS']).strip()) print('CC=' + str(env['CC']).strip()) """) test.run(arguments='-Q -s') -if('CCFLAGS=/nologo' not in test.stdout() - or 'CC=cl' not in test.stdout()): +if 'CCFLAGS=/nologo' not in test.stdout() or 'CC=cl' not in test.stdout(): test.fail_test() # make sure windows msvc doesnt add bad mingw flags # and that gcc is selected test.write('SConstruct',""" -env=Environment(tools=['default', 'mingw']) -print('CCFLAGS="' + str(env['CCFLAGS']).strip() + '"') -print('CC=' + str(env['CC']).strip()) +DefaultEnvironment(tools=[]) +env = Environment(tools=['default', 'mingw']) +print('CCFLAGS="' + str(env['CCFLAGS']).strip() + '"') +print('CC=' + str(env['CC']).strip()) """) test.run(arguments='-Q -s') if('CCFLAGS=""' not in test.stdout() @@ -66,18 +66,19 @@ if('CCFLAGS=""' not in test.stdout() # msvc should overwrite the flags and use cl test.write('SConstruct',""" -env=Environment(tools=['mingw', 'default']) +DefaultEnvironment(tools=[]) +env = Environment(tools=['mingw', 'default']) print('CCFLAGS=' + str(env['CCFLAGS']).strip()) print('CC=' + str(env['CC']).strip()) """) test.run(arguments='-Q -s') -if('CCFLAGS=/nologo' not in test.stdout() - or 'CC=cl' not in test.stdout()): +if 'CCFLAGS=/nologo' not in test.stdout() or 'CC=cl' not in test.stdout(): test.fail_test() # test that CCFLAGS are preserved test.write('SConstruct',""" -env=Environment(tools=['mingw'], CCFLAGS='-myflag') +DefaultEnvironment(tools=[]) +env = Environment(tools=['mingw'], CCFLAGS='-myflag') print(env['CCFLAGS']) """) test.run(arguments='-Q -s') @@ -86,7 +87,8 @@ if '-myflag' not in test.stdout(): # test that it handles a list test.write('SConstruct',""" -env=Environment(tools=['mingw'], CCFLAGS=['-myflag', '-myflag2']) +DefaultEnvironment(tools=[]) +env = Environment(tools=['mingw'], CCFLAGS=['-myflag', '-myflag2']) print(str(env['CCFLAGS'])) """) test.run(arguments='-Q -s') diff --git a/test/long-lines/signature.py b/test/long-lines/signature.py index 7f9ba43..68076d4 100644 --- a/test/long-lines/signature.py +++ b/test/long-lines/signature.py @@ -1,5 +1,7 @@ #!/usr/bin/env python # +# MIT License +# # Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining @@ -20,7 +22,6 @@ # 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. -# """ Verify that use of long command lines correctly excludes arguments @@ -36,18 +37,22 @@ test = TestSCons.TestSCons() build_py = test.workpath('build.py') +# create a dummy command which understands a tempfile syntax +# so it doesn't have to be that platform/compiler's specific syntax. test.write(build_py, """\ #!%(_python_)s import sys -if sys.argv[1][0] == '@': - with open(sys.argv[1][1:], 'r') as f: - args = f.read().split() +if sys.argv[1].startswith('@'): + tempfile = sys.argv[1][1:] + with open(tempfile, 'r') as tmp: + args = tmp.read().split() else: args = sys.argv[1:] -with open(args[0], 'w') as fp, open(args[1], 'r') as ifp: - fp.write(ifp.read()) - fp.write('FILEFLAG=%%s\\n' %% args[2]) - fp.write('TIMESTAMP=%%s\\n' %% args[3]) + +with open(args[0], 'w') as ofp, open(args[1], 'r') as ifp: + ofp.write(ifp.read()) + ofp.write('FILEFLAG=%%s\\n' %% args[2]) + ofp.write('TIMESTAMP=%%s\\n' %% args[3]) """ % locals()) os.chmod(build_py, 0o755) @@ -56,21 +61,29 @@ test.write('SConstruct', """\ DefaultEnvironment(tools=[]) arg = 'a_long_ignored_argument' extra_arguments = arg -while len(extra_arguments) <= 1024: +MAXLINE=1024 +while len(extra_arguments) <= MAXLINE: extra_arguments = extra_arguments + ' ' + arg -env = Environment(tools=[], - FILECOM=[r'%(build_py)s', - '$TARGET', '$SOURCE', - '$FILEFLAG', - '$(', '$TIMESTAMP', '$)', - '$EXTRA_ARGUMENTS'], - FILEFLAG=ARGUMENTS.get('FILEFLAG'), - TIMESTAMP=ARGUMENTS.get('TIMESTAMP'), - EXTRA_ARGUMENTS=extra_arguments, - MAXLINELENGTH=1024) +env = Environment( + tools=[], + FILECOM=[ + '%(build_py)s', + '$TARGET', + '$SOURCE', + '$FILEFLAG', + '$(', + '$TIMESTAMP', + '$)', + '$EXTRA_ARGUMENTS', + ], + FILEFLAG=ARGUMENTS.get('FILEFLAG'), + TIMESTAMP=ARGUMENTS.get('TIMESTAMP'), + EXTRA_ARGUMENTS=extra_arguments, + MAXLINELENGTH=MAXLINE, + TEMPFILEPREFIX='@', +) env.PrependENVPath('PATHEXT', '.PY') -env.Command('file.out', 'file.in', - '${TEMPFILE(FILECOM)}') +env.Command('file.out', 'file.in', '%(_python_)s ${TEMPFILE(FILECOM)}') """ % locals()) test.write('file.in', "file.in\n", mode='w') diff --git a/test/rebuild-generated.py b/test/rebuild-generated.py index 6beba74..0b3659e 100644 --- a/test/rebuild-generated.py +++ b/test/rebuild-generated.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # 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 case for the bug report: @@ -52,13 +51,16 @@ This may be a duplicate to bug 1019683. import os import sys +import sysconfig + import TestSCons test = TestSCons.TestSCons() _obj = TestSCons._obj -if sys.platform == 'win32': +if sys.platform == 'win32' and not sysconfig.get_platform() in ("mingw",): + generator_name = 'generator.bat' test.write(generator_name, '@echo #include "header.hh"') kernel_action = "$SOURCES > $TARGET" @@ -67,28 +69,23 @@ else: test.write(generator_name, 'echo \'#include "header.hh"\'') kernel_action = "sh $SOURCES > $TARGET" -test.write('SConstruct', """\ - -env = Environment() - -kernelDefines = env.Command("header.hh", - "header.hh.in", - Copy('$TARGET', '$SOURCE')) +if sysconfig.get_platform() in ("mingw",): + # mingw Python uses a sep of '/', when Command fires, that will not work. + # use its altsep instead, that is the standard Windows separator. + sep = os.altsep +else: + sep = os.sep -kernelImporterSource = env.Command( - "generated.cc", ["%s"], - "%s") -kernelImporter = env.Program( - kernelImporterSource + ["main.cc"]) +test.write('SConstruct', """\ +env = Environment() -kernelImports = env.Command( - "KernelImport.hh", kernelImporter, - ".%s$SOURCE > $TARGET") - -osLinuxModule = env.StaticObject( - ["target.cc"]) -""" % (generator_name, kernel_action, os.sep)) +kernelDefines = env.Command("header.hh", "header.hh.in", Copy('$TARGET', '$SOURCE')) +kernelImporterSource = env.Command("generated.cc", ["%s"], "%s") +kernelImporter = env.Program(kernelImporterSource + ["main.cc"]) +kernelImports = env.Command("KernelImport.hh", kernelImporter, ".%s$SOURCE > $TARGET") +osLinuxModule = env.StaticObject(["target.cc"]) +""" % (generator_name, kernel_action, sep)) test.write('main.cc', """\ int diff --git a/test/sconsign/script/SConsignFile.py b/test/sconsign/script/SConsignFile.py index 47fe94f..1d4cc1e 100644 --- a/test/sconsign/script/SConsignFile.py +++ b/test/sconsign/script/SConsignFile.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # 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__" """ Verify that the sconsign script works with files generated when @@ -99,15 +98,22 @@ sub2_inc2_h = 'sub2/inc2.h' test.write(['SConstruct'], """\ SConsignFile() -env1 = Environment(PROGSUFFIX = '.exe', - OBJSUFFIX = '.obj', - CCCOM = [[r'%(fake_cc_py)s', 'sub2', '$TARGET', '$SOURCE']], - LINKCOM = [[r'%(fake_link_py)s', '$TARGET', '$SOURCE']]) +env1 = Environment( + PROGSUFFIX='.exe', + OBJSUFFIX='.obj', + CCCOM=[['%(fake_cc_py)s', 'sub2', '$TARGET', '$SOURCE']], + LINKCOM=[['%(fake_link_py)s', '$TARGET', '$SOURCE']], +) env1.PrependENVPath('PATHEXT', '.PY') env1.Program('sub1/hello.c') -env2 = env1.Clone(CPPPATH = ['sub2']) +env2 = env1.Clone(CPPPATH=['sub2']) env2.Program('sub2/hello.c') """ % locals()) +# TODO in the above, we would normally want to run a python program +# using "our python" as in: +# CCCOM=[['%(_python_)s', '%(fake_cc_py)s', 'sub2', '$TARGET', '$SOURCE']], +# LINKCOM=[['%(_python_)s', '%(fake_link_py)s', '$TARGET', '$SOURCE']], +# however we're looking at dependencies with sconsign, so that breaks things test.write(['sub1', 'hello.c'], r""" sub1/hello.c diff --git a/test/sconsign/script/Signatures.py b/test/sconsign/script/Signatures.py index 9583cc6..b36292a 100644 --- a/test/sconsign/script/Signatures.py +++ b/test/sconsign/script/Signatures.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # 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__" """ Verify that the sconsign script works when using a .sconsign file in @@ -108,18 +107,25 @@ test.chmod(fake_link_py, 0o755) test.write('SConstruct', """ SConsignFile(None) Decider('timestamp-newer') -env1 = Environment(PROGSUFFIX = '.exe', - OBJSUFFIX = '.obj', - # Specify the command lines with lists-of-lists so - # finding the implicit dependencies works even with - # spaces in the fake_*_py path names. - CCCOM = [[r'%(fake_cc_py)s', 'sub2', '$TARGET', '$SOURCE']], - LINKCOM = [[r'%(fake_link_py)s', '$TARGET', '$SOURCE']]) +env1 = Environment( + PROGSUFFIX='.exe', + OBJSUFFIX='.obj', + # Specify the command lines with lists-of-lists so + # finding the implicit dependencies works even with + # spaces in the fake_*_py path names. + CCCOM=[['%(fake_cc_py)s', 'sub2', '$TARGET', '$SOURCE']], + LINKCOM=[['%(fake_link_py)s', '$TARGET', '$SOURCE']], +) env1.PrependENVPath('PATHEXT', '.PY') env1.Program('sub1/hello.c') -env2 = env1.Clone(CPPPATH = ['sub2']) +env2 = env1.Clone(CPPPATH=['sub2']) env2.Program('sub2/hello.c') """ % locals()) +# TODO in the above, we would normally want to run a python program +# using "our python" as in: +# CCCOM=[['%(_python_)s', '%(fake_cc_py)s', 'sub2', '$TARGET', '$SOURCE']], +# LINKCOM=[['%(_python_)s', '%(fake_link_py)s', '$TARGET', '$SOURCE']], +# however we're looking at dependencies with sconsign, so that breaks things test.write(['sub1', 'hello.c'], r"""\ sub1/hello.c diff --git a/test/sconsign/script/no-SConsignFile.py b/test/sconsign/script/no-SConsignFile.py index 3702c6c..d12d151 100644 --- a/test/sconsign/script/no-SConsignFile.py +++ b/test/sconsign/script/no-SConsignFile.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -110,18 +112,25 @@ sub2_inc2_h = 'sub2/inc2.h' test.write(['SConstruct'], """ SConsignFile(None) -env1 = Environment(PROGSUFFIX = '.exe', - OBJSUFFIX = '.obj', - # Specify the command lines with lists-of-lists so - # finding the implicit dependencies works even with - # spaces in the fake_*_py path names. - CCCOM = [[r'%(fake_cc_py)s', 'sub2', '$TARGET', '$SOURCE']], - LINKCOM = [[r'%(fake_link_py)s', '$TARGET', '$SOURCE']]) +env1 = Environment( + PROGSUFFIX='.exe', + OBJSUFFIX='.obj', + # Specify the command lines with lists-of-lists so + # finding the implicit dependencies works even with + # spaces in the fake_*_py path names. + CCCOM=[['%(fake_cc_py)s', 'sub2', '$TARGET', '$SOURCE']], + LINKCOM=[['%(fake_link_py)s', '$TARGET', '$SOURCE']], +) env1.PrependENVPath('PATHEXT', '.PY') env1.Program('sub1/hello.c') -env2 = env1.Clone(CPPPATH = ['sub2']) +env2 = env1.Clone(CPPPATH=['sub2']) env2.Program('sub2/hello.c') """ % locals()) +# TODO in the above, we would normally want to run a python program +# using "our python" as in: +# CCCOM=[['%(_python_)s', '%(fake_cc_py)s', 'sub2', '$TARGET', '$SOURCE']], +# LINKCOM=[['%(_python_)s', '%(fake_link_py)s', '$TARGET', '$SOURCE']], +# however we're looking at dependencies with sconsign, so that breaks things test.write(['sub1', 'hello.c'], r"""\ sub1/hello.c diff --git a/testing/framework/TestCommon.py b/testing/framework/TestCommon.py index b1630e5..2eeaad0 100644 --- a/testing/framework/TestCommon.py +++ b/testing/framework/TestCommon.py @@ -785,10 +785,6 @@ class TestCommon(TestCmd): sys.stdout.flush() pass_skips = os.environ.get('TESTCOMMON_PASS_SKIPS') if pass_skips in [None, 0, '0']: - # skip=1 means skip this function when showing where this - # result came from. They only care about the line where the - # script called test.skip_test(), not the line number where - # we call test.no_result(). if from_fw: self.no_result(skip=2) else: -- cgit v0.12 From 113de336dc49772552cbd7dbf634b8708ecede88 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Thu, 15 Apr 2021 09:12:00 -0600 Subject: [PR 3930] put back accidentally dropped raw-string indicator Signed-off-by: Mats Wichmann --- test/long-lines/signature.py | 2 +- test/sconsign/script/SConsignFile.py | 4 ++-- test/sconsign/script/Signatures.py | 4 ++-- test/sconsign/script/no-SConsignFile.py | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/test/long-lines/signature.py b/test/long-lines/signature.py index 68076d4..f399279 100644 --- a/test/long-lines/signature.py +++ b/test/long-lines/signature.py @@ -67,7 +67,7 @@ while len(extra_arguments) <= MAXLINE: env = Environment( tools=[], FILECOM=[ - '%(build_py)s', + r'%(build_py)s', '$TARGET', '$SOURCE', '$FILEFLAG', diff --git a/test/sconsign/script/SConsignFile.py b/test/sconsign/script/SConsignFile.py index 1d4cc1e..f7914fe 100644 --- a/test/sconsign/script/SConsignFile.py +++ b/test/sconsign/script/SConsignFile.py @@ -101,8 +101,8 @@ SConsignFile() env1 = Environment( PROGSUFFIX='.exe', OBJSUFFIX='.obj', - CCCOM=[['%(fake_cc_py)s', 'sub2', '$TARGET', '$SOURCE']], - LINKCOM=[['%(fake_link_py)s', '$TARGET', '$SOURCE']], + CCCOM=[[r'%(fake_cc_py)s', 'sub2', '$TARGET', '$SOURCE']], + LINKCOM=[[r'%(fake_link_py)s', '$TARGET', '$SOURCE']], ) env1.PrependENVPath('PATHEXT', '.PY') env1.Program('sub1/hello.c') diff --git a/test/sconsign/script/Signatures.py b/test/sconsign/script/Signatures.py index b36292a..4f1d2b9 100644 --- a/test/sconsign/script/Signatures.py +++ b/test/sconsign/script/Signatures.py @@ -113,8 +113,8 @@ env1 = Environment( # Specify the command lines with lists-of-lists so # finding the implicit dependencies works even with # spaces in the fake_*_py path names. - CCCOM=[['%(fake_cc_py)s', 'sub2', '$TARGET', '$SOURCE']], - LINKCOM=[['%(fake_link_py)s', '$TARGET', '$SOURCE']], + CCCOM=[[r'%(fake_cc_py)s', 'sub2', '$TARGET', '$SOURCE']], + LINKCOM=[[r'%(fake_link_py)s', '$TARGET', '$SOURCE']], ) env1.PrependENVPath('PATHEXT', '.PY') env1.Program('sub1/hello.c') diff --git a/test/sconsign/script/no-SConsignFile.py b/test/sconsign/script/no-SConsignFile.py index d12d151..a33a446 100644 --- a/test/sconsign/script/no-SConsignFile.py +++ b/test/sconsign/script/no-SConsignFile.py @@ -118,8 +118,8 @@ env1 = Environment( # Specify the command lines with lists-of-lists so # finding the implicit dependencies works even with # spaces in the fake_*_py path names. - CCCOM=[['%(fake_cc_py)s', 'sub2', '$TARGET', '$SOURCE']], - LINKCOM=[['%(fake_link_py)s', '$TARGET', '$SOURCE']], + CCCOM=[[r'%(fake_cc_py)s', 'sub2', '$TARGET', '$SOURCE']], + LINKCOM=[[r'%(fake_link_py)s', '$TARGET', '$SOURCE']], ) env1.PrependENVPath('PATHEXT', '.PY') env1.Program('sub1/hello.c') -- cgit v0.12 From 5a2c80ec0e3a89568dea91196064d8d4afe7afa3 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Fri, 16 Apr 2021 09:02:49 -0600 Subject: [PR 3930] more rawstring stuff in tests (Windows) Signed-off-by: Mats Wichmann --- test/long-lines/signature.py | 2 +- test/sconsign/script/SConsignFile.py | 4 ++-- test/sconsign/script/Signatures.py | 4 ++-- test/sconsign/script/no-SConsignFile.py | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/test/long-lines/signature.py b/test/long-lines/signature.py index f399279..ef1b956 100644 --- a/test/long-lines/signature.py +++ b/test/long-lines/signature.py @@ -83,7 +83,7 @@ env = Environment( TEMPFILEPREFIX='@', ) env.PrependENVPath('PATHEXT', '.PY') -env.Command('file.out', 'file.in', '%(_python_)s ${TEMPFILE(FILECOM)}') +env.Command('file.out', 'file.in', r'%(_python_)s ${TEMPFILE(FILECOM)}') """ % locals()) test.write('file.in', "file.in\n", mode='w') diff --git a/test/sconsign/script/SConsignFile.py b/test/sconsign/script/SConsignFile.py index f7914fe..c54e17b 100644 --- a/test/sconsign/script/SConsignFile.py +++ b/test/sconsign/script/SConsignFile.py @@ -111,8 +111,8 @@ env2.Program('sub2/hello.c') """ % locals()) # TODO in the above, we would normally want to run a python program # using "our python" as in: -# CCCOM=[['%(_python_)s', '%(fake_cc_py)s', 'sub2', '$TARGET', '$SOURCE']], -# LINKCOM=[['%(_python_)s', '%(fake_link_py)s', '$TARGET', '$SOURCE']], +# CCCOM=[[r'%(_python_)s', r'%(fake_cc_py)s', 'sub2', '$TARGET', '$SOURCE']], +# LINKCOM=[[r'%(_python_)s', r'%(fake_link_py)s', '$TARGET', '$SOURCE']], # however we're looking at dependencies with sconsign, so that breaks things test.write(['sub1', 'hello.c'], r""" diff --git a/test/sconsign/script/Signatures.py b/test/sconsign/script/Signatures.py index 4f1d2b9..0f21496 100644 --- a/test/sconsign/script/Signatures.py +++ b/test/sconsign/script/Signatures.py @@ -123,8 +123,8 @@ env2.Program('sub2/hello.c') """ % locals()) # TODO in the above, we would normally want to run a python program # using "our python" as in: -# CCCOM=[['%(_python_)s', '%(fake_cc_py)s', 'sub2', '$TARGET', '$SOURCE']], -# LINKCOM=[['%(_python_)s', '%(fake_link_py)s', '$TARGET', '$SOURCE']], +# CCCOM=[[r'%(_python_)s', r'%(fake_cc_py)s', 'sub2', '$TARGET', '$SOURCE']], +# LINKCOM=[[r'%(_python_)s', r'%(fake_link_py)s', '$TARGET', '$SOURCE']], # however we're looking at dependencies with sconsign, so that breaks things test.write(['sub1', 'hello.c'], r"""\ diff --git a/test/sconsign/script/no-SConsignFile.py b/test/sconsign/script/no-SConsignFile.py index a33a446..c345829 100644 --- a/test/sconsign/script/no-SConsignFile.py +++ b/test/sconsign/script/no-SConsignFile.py @@ -128,8 +128,8 @@ env2.Program('sub2/hello.c') """ % locals()) # TODO in the above, we would normally want to run a python program # using "our python" as in: -# CCCOM=[['%(_python_)s', '%(fake_cc_py)s', 'sub2', '$TARGET', '$SOURCE']], -# LINKCOM=[['%(_python_)s', '%(fake_link_py)s', '$TARGET', '$SOURCE']], +# CCCOM=[[r'%(_python_)s', r'%(fake_cc_py)s', 'sub2', '$TARGET', '$SOURCE']], +# LINKCOM=[[r'%(_python_)s', r'%(fake_link_py)s', '$TARGET', '$SOURCE']], # however we're looking at dependencies with sconsign, so that breaks things test.write(['sub1', 'hello.c'], r"""\ -- cgit v0.12 From cdf64ab71a77598629596998c63f39ace13f072b Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Fri, 16 Apr 2021 10:27:34 -0600 Subject: [PR 3930] fix regexes in scons-time tests The regex looking for profile files hardcoded a '/', change to '.' to match either style of separator. Tests started failing on Windows with Python 3.9. Signed-off-by: Mats Wichmann --- test/scons-time/func/chdir.py | 9 ++++----- test/scons-time/func/funcglob.py | 9 ++++----- test/scons-time/func/tail.py | 9 ++++----- 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/test/scons-time/func/chdir.py b/test/scons-time/func/chdir.py index 1aea7ad..412a1c8 100644 --- a/test/scons-time/func/chdir.py +++ b/test/scons-time/func/chdir.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # 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__" """ Verify that the func -C and --chdir options change directory before @@ -52,7 +51,7 @@ for i in range(9): i = str(i) test.subdir(i) test.profile_data('profs/foo-%s.prof' % i, '%s/prof.py' % i, '_main', input) - s = r'\d.\d\d\d %s/prof\.py:1\(_main\)' % re.escape(test.workpath(i)) + s = r'\d.\d\d\d %s.prof\.py:1\(_main\)' % re.escape(test.workpath(i)) expect.append(s + '\n') expect = ''.join(expect) diff --git a/test/scons-time/func/funcglob.py b/test/scons-time/func/funcglob.py index 6240404..3fff746 100644 --- a/test/scons-time/func/funcglob.py +++ b/test/scons-time/func/funcglob.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # 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__" """ Verify that the func subcommands globs for files. @@ -46,7 +45,7 @@ expect = [] for i in range(9): test.subdir(str(i)) test.profile_data('foo-%s.prof' % i, '%s/prof.py' % i, '_main', input) - expect.append((r'\d.\d\d\d %s/prof\.py:1\(_main\)' + '\n') % i) + expect.append((r'\d.\d\d\d %s.prof\.py:1\(_main\)' + '\n') % i) expect = ''.join(expect) diff --git a/test/scons-time/func/tail.py b/test/scons-time/func/tail.py index afd3f83..64d041a 100644 --- a/test/scons-time/func/tail.py +++ b/test/scons-time/func/tail.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # 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__" """ Verify that the func subcommand only prints results for the last number @@ -47,7 +46,7 @@ expect = [] for i in range(9): test.subdir(str(i)) test.profile_data('foo-%s.prof' % i, '%s/prof.py' % i, '_main', input) - expect.append((r'\d.\d\d\d %s/prof\.py:1\(_main\)' + '\n') % i) + expect.append((r'\d.\d\d\d %s.prof\.py:1\(_main\)' + '\n') % i) test.run(arguments = 'func -t 3 foo-*.prof', stdout = ''.join(expect[-3:])) -- cgit v0.12 From 59c4c2ca4fce8392852e5e907bbb9e89b1daae15 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Thu, 15 Apr 2021 08:41:51 -0600 Subject: Restore setting of write bits on Install'd files SCons had undocumented behavior that Install and InstallVersionedLib unconditionally changed the files they copied to writable - shutil.copy2(), the underlying function used for copying, preserves mode bits. Restore this behavior so Install won't fail in a project where it had previously run, if any of the sources were read-only. Fixes #3927 Signed-off-by: Mats Wichmann --- CHANGES.txt | 1 + RELEASE.txt | 3 ++ SCons/Tool/install.py | 82 ++++++++++++++++++++++++++++++++++---------------- SCons/Tool/install.xml | 6 +++- 4 files changed, 65 insertions(+), 27 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index c259c77..e3ed2c4 100755 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -74,6 +74,7 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER - Don't strip spaces in INSTALLSTR by using raw subst (issue 2018) - Deprecate Python 3.5 as a supported version. - CPPDEFINES now expands construction variable references (issue 2363) + - Restore behavior that Install()'d files are writable (issue 3927) From Dillan Mills: - Add support for the (TARGET,SOURCE,TARGETS,SOURCES,CHANGED_TARGETS,CHANGED_SOURCES}.relpath property. diff --git a/RELEASE.txt b/RELEASE.txt index fe4d82f..db64ee8 100755 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -59,6 +59,9 @@ FIXES - DocbookXslt tool: The XSLT stylesheet file is now initialized to an env.File() Node, such that dependencies work correctly in hierarchical builds (eg when using DocbookXslt in SConscript('subdir/SConscript') context. + - The Install builder will now set the writable mode on the file(s) it + copies. This restores the (previously undocumented) SCons behavior + that regressed as of 4.0.0. IMPROVEMENTS diff --git a/SCons/Tool/install.py b/SCons/Tool/install.py index d73d678..9910264 100644 --- a/SCons/Tool/install.py +++ b/SCons/Tool/install.py @@ -31,6 +31,7 @@ selection method. # import os +import stat from shutil import copy2, copymode, copystat import SCons.Action @@ -152,11 +153,14 @@ def scons_copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, # # Functions doing the actual work of the Install Builder. # -def copyFunc(dest, source, env): - """Install a source file or directory into a destination by copying, +def copyFunc(dest, source, env) -> int: + """Install a source file or directory into a destination by copying. - Mode/permissions bits will be copied as well. + Mode/permissions bits will be copied as well, except that the target + will be made writable. + Returns: + POSIX-style error code - 0 for success, non-zero for fail """ if os.path.isdir(source): if os.path.exists(dest): @@ -169,19 +173,24 @@ def copyFunc(dest, source, env): scons_copytree(source, dest, dirs_exist_ok=True) else: copy2(source, dest) - copymode(source, dest) + st = os.stat(source) + os.chmod(dest, stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE) return 0 # # Functions doing the actual work of the InstallVersionedLib Builder. # -def copyFuncVersionedLib(dest, source, env): - """Install a versioned library into a destination by copying, +def copyFuncVersionedLib(dest, source, env) -> int: + """Install a versioned library into a destination by copying. - Mode/permissions bits will be copied as well. Any required symbolic links for other library names are created. + Mode/permissions bits will be copied as well, except that the target + will be made writable. + + Returns: + POSIX-style error code - 0 for success, non-zero for fail """ if os.path.isdir(source): raise SCons.Errors.UserError("cannot install directory `%s' as a version library" % str(source) ) @@ -192,7 +201,8 @@ def copyFuncVersionedLib(dest, source, env): except: pass copy2(source, dest) - copymode(source, dest) + st = os.stat(source) + os.chmod(dest, stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE) installShlibLinks(dest, source, env) return 0 @@ -223,38 +233,58 @@ def installShlibLinks(dest, source, env): CreateLibSymlinks(env, symlinks) return -def installFunc(target, source, env): - """Install a source file into a target using the function specified - as the INSTALL construction variable.""" +def installFunc(target, source, env) -> int: + """Install a source file into a target. + + Uses the function specified in the INSTALL construction variable. + + Returns: + POSIX-style error code - 0 for success, non-zero for fail + """ + try: install = env['INSTALL'] except KeyError: raise SCons.Errors.UserError('Missing INSTALL construction variable.') - assert len(target)==len(source), \ - "Installing source %s into target %s: target and source lists must have same length."%(list(map(str, source)), list(map(str, target))) - for t,s in zip(target,source): - if install(t.get_path(),s.get_path(),env): + assert len(target) == len(source), ( + "Installing source %s into target %s: " + "target and source lists must have same length." + % (list(map(str, source)), list(map(str, target))) + ) + for t, s in zip(target, source): + if install(t.get_path(), s.get_path(), env): return 1 return 0 -def installFuncVersionedLib(target, source, env): - """Install a versioned library into a target using the function specified - as the INSTALLVERSIONEDLIB construction variable.""" +def installFuncVersionedLib(target, source, env) -> int: + """Install a versioned library into a target. + + Uses the function specified in the INSTALL construction variable. + + Returns: + POSIX-style error code - 0 for success, non-zero for fail + """ + try: install = env['INSTALLVERSIONEDLIB'] except KeyError: - raise SCons.Errors.UserError('Missing INSTALLVERSIONEDLIB construction variable.') - - assert len(target)==len(source), \ - "Installing source %s into target %s: target and source lists must have same length."%(list(map(str, source)), list(map(str, target))) - for t,s in zip(target,source): + raise SCons.Errors.UserError( + 'Missing INSTALLVERSIONEDLIB construction variable.' + ) + + assert len(target) == len(source), ( + "Installing source %s into target %s: " + "target and source lists must have same length." + % (list(map(str, source)), list(map(str, target))) + ) + for t, s in zip(target, source): if hasattr(t.attributes, 'shlibname'): tpath = os.path.join(t.get_dir(), t.attributes.shlibname) else: tpath = t.get_path() - if install(tpath,s.get_path(),env): + if install(tpath, s.get_path(), env): return 1 return 0 @@ -461,12 +491,12 @@ def generate(env): try: env['INSTALL'] except KeyError: - env['INSTALL'] = copyFunc + env['INSTALL'] = copyFunc try: env['INSTALLVERSIONEDLIB'] except KeyError: - env['INSTALLVERSIONEDLIB'] = copyFuncVersionedLib + env['INSTALLVERSIONEDLIB'] = copyFuncVersionedLib def exists(env): return 1 diff --git a/SCons/Tool/install.xml b/SCons/Tool/install.xml index f4295a0..81e486f 100644 --- a/SCons/Tool/install.xml +++ b/SCons/Tool/install.xml @@ -46,7 +46,9 @@ which must be a directory. The names of the specified source files or directories remain the same within the destination directory. The sources may be given as a string or as a node returned by -a builder. +a builder. Basic metadata from the source files is +preserved, except that the target files will be marked +as writable. @@ -118,6 +120,8 @@ See the note under &Install;. Installs a versioned shared library. The symlinks appropriate to the architecture will be generated based on symlinks of the source library. +Basic metadata from the source library is preserved, +except that the target file will be marked as writable. -- cgit v0.12 From 85f75affc4b92bdf0db3dd1c35cd875320ba5f26 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Sun, 18 Apr 2021 09:24:03 -0600 Subject: [PR 3931] add a testcase Undo the doc change which describes what happens - seems better not to promise about permissions of installed files. Did the header change on Install tests. Signed-off-by: Mats Wichmann --- SCons/Tool/install.xml | 6 +---- test/Install/Clone.py | 7 +++-- test/Install/INSTALLSTR.py | 7 +++-- test/Install/Install-ro.py | 46 +++++++++++++++++++++++++++++++++ test/Install/Install.py | 7 +++-- test/Install/InstallAs.py | 8 +++--- test/Install/dir-exists.py | 9 +++---- test/Install/directories.py | 31 +++++++++++----------- test/Install/fixture/SConstruct-multi | 24 +++++++++++++++++ test/Install/multi-dir.py | 7 +++-- test/Install/multi.py | 10 +++---- test/Install/no-top-relative.py | 7 +++-- test/Install/non-ascii-name.py | 8 +++--- test/Install/option--install-sandbox.py | 12 +++------ test/Install/tool.py | 11 ++++---- test/Install/wrap-by-attribute.py | 24 ++++++++++------- 16 files changed, 139 insertions(+), 85 deletions(-) create mode 100644 test/Install/Install-ro.py create mode 100644 test/Install/fixture/SConstruct-multi diff --git a/SCons/Tool/install.xml b/SCons/Tool/install.xml index 81e486f..f4295a0 100644 --- a/SCons/Tool/install.xml +++ b/SCons/Tool/install.xml @@ -46,9 +46,7 @@ which must be a directory. The names of the specified source files or directories remain the same within the destination directory. The sources may be given as a string or as a node returned by -a builder. Basic metadata from the source files is -preserved, except that the target files will be marked -as writable. +a builder. @@ -120,8 +118,6 @@ See the note under &Install;. Installs a versioned shared library. The symlinks appropriate to the architecture will be generated based on symlinks of the source library. -Basic metadata from the source library is preserved, -except that the target file will be marked as writable. diff --git a/test/Install/Clone.py b/test/Install/Clone.py index 14e0688..c88a078 100644 --- a/test/Install/Clone.py +++ b/test/Install/Clone.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT Licenxe +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # 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__" """ Verify that we can Install() and InstallAs() from a construction diff --git a/test/Install/INSTALLSTR.py b/test/Install/INSTALLSTR.py index ace04f4..3ce71be 100644 --- a/test/Install/INSTALLSTR.py +++ b/test/Install/INSTALLSTR.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT Licenxe +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # 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 that the $INSTALLSTR variable is displayed when we install a file. diff --git a/test/Install/Install-ro.py b/test/Install/Install-ro.py new file mode 100644 index 0000000..4a929dc --- /dev/null +++ b/test/Install/Install-ro.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python +# +# MIT Licenxe +# +# Copyright The SCons Foundation +# +# 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. + +""" +Test that SCons allows Install on top of an existing read-only file. +""" + +import sys +import os +import os.path +import TestSCons + +test = TestSCons.TestSCons() + +test.file_fixture('fixture/SConstruct-multi', 'SConstruct') +test.run(arguments=["-Q"]) +test.run(arguments=["-Q"]) + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: diff --git a/test/Install/Install.py b/test/Install/Install.py index 0647002..2857c72 100644 --- a/test/Install/Install.py +++ b/test/Install/Install.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT Licenxe +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # 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__" """ Verify that the Install() Builder works diff --git a/test/Install/InstallAs.py b/test/Install/InstallAs.py index 47ee9f6..24a9ddc 100644 --- a/test/Install/InstallAs.py +++ b/test/Install/InstallAs.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT Licenxe +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # 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 InstallAs() Environment method. @@ -83,7 +82,6 @@ test.must_match(install_file1a_out, "file1.in\n", mode='r') test.up_to_date(arguments = '.') -# test.pass_test() # Local Variables: diff --git a/test/Install/dir-exists.py b/test/Install/dir-exists.py index 9882d22..9e9a9b0 100644 --- a/test/Install/dir-exists.py +++ b/test/Install/dir-exists.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT Licenxe +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # 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 using Install() on directories that exist. @@ -49,7 +48,7 @@ Mkdir("b") echo hi > a%sf Install directory: "a" as "b%sa" """%(os.sep, os.sep) -test.run(arguments = ["-Q"], stdout = expect) +test.run(arguments=["-Q"], stdout=expect) test.must_exist(test.workpath('a', 'f')) test.must_exist(test.workpath('b', 'a', 'f')) diff --git a/test/Install/directories.py b/test/Install/directories.py index e980936..66182b7 100644 --- a/test/Install/directories.py +++ b/test/Install/directories.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT Licenxe +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # 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 using Install() on directories. @@ -33,16 +32,18 @@ import TestSCons test = TestSCons.TestSCons() -test.subdir('outside', - 'work', - ['work', 'dir1'], - ['work', 'dir1', 'sub'], - ['work', 'dir2'], - ['work', 'dir2', 'sub'], - ['work', 'dir3'], - ['work', 'dir3', 'sub'], - ['work', 'dir4'], - ['work', 'dir4', 'sub']) +test.subdir( + 'outside', + 'work', + ['work', 'dir1'], + ['work', 'dir1', 'sub'], + ['work', 'dir2'], + ['work', 'dir2', 'sub'], + ['work', 'dir3'], + ['work', 'dir3', 'sub'], + ['work', 'dir4'], + ['work', 'dir4', 'sub'], +) test.write(['work', 'SConstruct'], """\ DefaultEnvironment(tools=[]) @@ -80,7 +81,7 @@ Install directory: "dir3" as "%s" Install directory: "dir4" as "%s" """ % tuple(arguments)) -test.run(chdir = 'work', arguments = arguments, stdout = expect) +test.run(chdir='work', arguments=arguments, stdout=expect) test.must_match(test.workpath('outside', 'dir1', 'f2'), "work/dir1/f2\n") test.must_match(test.workpath('outside', 'dir1', 'sub', 'f3'), "work/dir1/sub/f3\n") diff --git a/test/Install/fixture/SConstruct-multi b/test/Install/fixture/SConstruct-multi new file mode 100644 index 0000000..94de1df --- /dev/null +++ b/test/Install/fixture/SConstruct-multi @@ -0,0 +1,24 @@ +# first run creates a src file, makes it read-only, and installs. +# second run updates src, Install should successfully replace +# the previous install (read-only attr on Windows might fail it) + +import os +import pathlib +import stat + +destdir = pathlib.Path("bin") +destdir.mkdir(exist_ok=True) + +srcfile = pathlib.Path("hello") +try: + srcfile.chmod(stat.S_IREAD | stat.S_IWRITE) +except OSError: + pass + +with srcfile.open(mode="w") as f: + print("Hello from ", os.getpid(), file=f) +srcfile.chmod(stat.S_IREAD) + +DefaultEnvironment(tools=[]) +env = Environment(tools=[]) +env.Install('bin', 'hello') diff --git a/test/Install/multi-dir.py b/test/Install/multi-dir.py index ddb6d0a..648f46f 100644 --- a/test/Install/multi-dir.py +++ b/test/Install/multi-dir.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT Licenxe +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # 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__" """ Verify that using Install to create multiple dir hierarchies outside diff --git a/test/Install/multi.py b/test/Install/multi.py index 1716d17..2d83981 100644 --- a/test/Install/multi.py +++ b/test/Install/multi.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT Licenxe +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # 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__" """ Verify that multiple calls to test.Install() with the same file @@ -42,8 +41,7 @@ env.Install('install', 'file1') test.write('file1', "file1\n") -test.run(arguments = '.') - +test.run(arguments='.') test.must_match(['install', 'file1'], "file1\n") test.pass_test() diff --git a/test/Install/no-top-relative.py b/test/Install/no-top-relative.py index 31c7130..efba365 100644 --- a/test/Install/no-top-relative.py +++ b/test/Install/no-top-relative.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT Licenxe +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # 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__" """ Verify that we can install a file if its file name portion begins diff --git a/test/Install/non-ascii-name.py b/test/Install/non-ascii-name.py index 7e25743..59a7406 100644 --- a/test/Install/non-ascii-name.py +++ b/test/Install/non-ascii-name.py @@ -1,7 +1,8 @@ -# -*- coding: utf-8 -*- #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT Licenxe +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -21,9 +22,6 @@ # 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__" """ Verify that the Install() Builder works diff --git a/test/Install/option--install-sandbox.py b/test/Install/option--install-sandbox.py index 45366c1..bb64c34 100644 --- a/test/Install/option--install-sandbox.py +++ b/test/Install/option--install-sandbox.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT Licenxe +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # 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 --install-sandbox commandline option for Install() and InstallAs(). @@ -43,11 +42,8 @@ _SUBDIR_file3_in = os.path.join('$SUBDIR', 'file3.in') target_file2_out = os.path.join(target, 'file2.out') subdir_file3_in = os.path.join('subdir', 'file3.in') target_subdir_file3_out = os.path.join(target, 'subdir', 'file3.out') -file1_out = target+os.path.join( target, - os.path.splitdrive(destdir)[1], - 'file1.out' ) +file1_out = target + os.path.join(target, os.path.splitdrive(destdir)[1], 'file1.out') -# test.write('SConstruct', r""" DefaultEnvironment(tools=[]) env = Environment(tools=[], SUBDIR='subdir') diff --git a/test/Install/tool.py b/test/Install/tool.py index ba92d0a..0730e37 100644 --- a/test/Install/tool.py +++ b/test/Install/tool.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT Licenxe +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # 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__" """ Verify that we can still call Install() and InstallAs() even when @@ -37,14 +36,14 @@ test.subdir('iii') test.write('SConstruct', """ DefaultEnvironment(tools=[]) -env = Environment(tools = []) +env = Environment(tools=[]) env.Install('iii', 'foo.in') env.InstallAs('foo.out', 'foo.in') """) test.write('foo.in', "foo.in\n") -test.run(arguments = '.') +test.run(arguments='.') test.must_match(['iii', 'foo.in'], "foo.in\n") test.must_match('foo.out', "foo.in\n") diff --git a/test/Install/wrap-by-attribute.py b/test/Install/wrap-by-attribute.py index 014b7a5..c18ea77 100644 --- a/test/Install/wrap-by-attribute.py +++ b/test/Install/wrap-by-attribute.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT Licenxe +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # 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__" """ @@ -45,6 +44,7 @@ test.write('SConstruct', """\ DefaultEnvironment(tools=[]) import os.path + def cat(env, source, target): target = str(target[0]) with open(target, 'wb') as ofp: @@ -52,18 +52,23 @@ def cat(env, source, target): with open(str(src), 'rb') as ifp: ofp.write(ifp.read()) + env = Environment(tools=[], DESTDIR='dest') -env.Append(BUILDERS={'Cat':Builder(action=cat)}) +env.Append(BUILDERS={'Cat': Builder(action=cat)}) env.SconsInternalInstallFunc = env.Install env.SconsInternalInstallAsFunc = env.InstallAs + def InstallWithDestDir(dir, source): abspath = os.path.splitdrive(env.Dir(dir).get_abspath())[1] - return env.SconsInternalInstallFunc('$DESTDIR'+abspath, source) + return env.SconsInternalInstallFunc('$DESTDIR' + abspath, source) + + def InstallAsWithDestDir(target, source): abspath = os.path.splitdrive(env.File(target).get_abspath())[1] - return env.SconsInternalInstallAsFunc('$DESTDIR'+abspath, source) + return env.SconsInternalInstallAsFunc('$DESTDIR' + abspath, source) + # Add the wrappers directly as attributes. env.Install = InstallWithDestDir @@ -82,7 +87,6 @@ t = e2.Cat(target='f3.out', source='f3.in') e2.Install('export', source=t) t = e2.Cat(target='f4.out', source='f4.in') e2.InstallAs('export/f4-new.out', source=t) - """) test.write('f1.in', "f1.in\n") @@ -90,7 +94,7 @@ test.write('f2.in', "f2.in\n") test.write('f3.in', "f3.in\n") test.write('f4.in', "f4.in\n") -test.run(arguments = '.') +test.run(arguments='.') export = os.path.splitdrive(test.workpath('export'))[1] @@ -104,7 +108,7 @@ test.must_match(f2_new_out, "f2.in\n") test.must_match(f3_out, "f3.in\n") test.must_match(f4_new_out, "f4.in\n") -test.up_to_date(arguments = '.') +test.up_to_date(arguments='.') test.pass_test() -- cgit v0.12 From a8516de2f0be55447b00148aba5e8b857933f67d Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Sun, 18 Apr 2021 11:17:35 -0600 Subject: [PR 3931] fix a couple of unneeded imports (sider) [ci skip] Signed-off-by: Mats Wichmann --- test/Install/Install-ro.py | 3 --- test/Install/multi-dir/src/SConstruct | 3 ++- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/test/Install/Install-ro.py b/test/Install/Install-ro.py index 4a929dc..aa7e6f3 100644 --- a/test/Install/Install-ro.py +++ b/test/Install/Install-ro.py @@ -27,9 +27,6 @@ Test that SCons allows Install on top of an existing read-only file. """ -import sys -import os -import os.path import TestSCons test = TestSCons.TestSCons() diff --git a/test/Install/multi-dir/src/SConstruct b/test/Install/multi-dir/src/SConstruct index 05b46a9..44e3589 100644 --- a/test/Install/multi-dir/src/SConstruct +++ b/test/Install/multi-dir/src/SConstruct @@ -1,7 +1,8 @@ # This tests for a bug where installing a sequence dirs and subdirs # outside the source tree can cause SCons to fail to create the dest # dir. -import os, os.path, shutil +import os + DefaultEnvironment(tools=[]) env=Environment(tools=[]) dst='../build' -- cgit v0.12 From 086a553267ad291df3ef7c122391262b36a77eb4 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Sun, 18 Apr 2021 15:58:56 -0700 Subject: Update generated docs. They were broken [skip appveyor][skip travis] --- SCons/__init__.py | 10 +- doc/generated/builders.gen | 72 ++-- doc/generated/examples/caching_ex-random_1.xml | 6 +- .../examples/commandline_ListVariable_1.xml | 4 +- .../examples/commandline_ListVariable_2.xml | 2 +- doc/generated/examples/troubleshoot_Dump_1.xml | 1 + doc/generated/examples/troubleshoot_Dump_2.xml | 1 + doc/generated/examples/troubleshoot_explain1_3.xml | 2 +- .../examples/troubleshoot_stacktrace_2.xml | 2 +- doc/generated/functions.gen | 458 ++++++++++++++------- doc/generated/tools.gen | 151 ++++--- doc/generated/variables.gen | 387 +++++++++-------- doc/generated/variables.mod | 16 +- 13 files changed, 660 insertions(+), 452 deletions(-) diff --git a/SCons/__init__.py b/SCons/__init__.py index a87bb16..bc0f428 100644 --- a/SCons/__init__.py +++ b/SCons/__init__.py @@ -1,9 +1,9 @@ __version__="4.1.1a" __copyright__="Copyright (c) 2001 - 2021 The SCons Foundation" -__developer__="millsd" -__date__="2021-03-18 01:11:29" -__buildsys__="chn-cad-vnc31" -__revision__="fc3946a217f29407c65291c5358262a7b3cc78cd" -__build__="fc3946a217f29407c65291c5358262a7b3cc78cd" +__developer__="bdbaddog" +__date__="2021-04-18 22:22:37" +__buildsys__="ProDog2020" +__revision__="1850bdd13c7668aac493b9f5b896578813e60ca9" +__build__="1850bdd13c7668aac493b9f5b896578813e60ca9" # make sure compatibility is always in place import SCons.compat # noqa \ No newline at end of file diff --git a/doc/generated/builders.gen b/doc/generated/builders.gen index bfb1ff1..14508ea 100644 --- a/doc/generated/builders.gen +++ b/doc/generated/builders.gen @@ -172,8 +172,8 @@ env.DocbookHtml('manual') DocbookHtmlChunked() env.DocbookHtmlChunked() -A pseudo-Builder, providing a Docbook toolchain for chunked HTML output. -It supports the base.dir parameter. The +A pseudo-Builder providing a Docbook toolchain for chunked HTML output. +It supports the base.dir parameter. The chunkfast.xsl file (requires "EXSLT") is used as the default stylesheet. Basic syntax: @@ -184,22 +184,23 @@ env.DocbookHtmlChunked('manual') where manual.xml is the input file. -If you use the root.filename +If you use the root.filename parameter in your own stylesheets you have to specify the new target name. This ensures that the dependencies get correct, especially for the cleanup via scons -c: env = Environment(tools=['docbook']) env.DocbookHtmlChunked('mymanual.html', 'manual', xsl='htmlchunk.xsl') -Some basic support for the base.dir is provided. You -can add the base_dir keyword to your Builder -call, and the given prefix gets prepended to all the created filenames: +Some basic support for the base.dir parameter +is provided. You can add the base_dir keyword to +your Builder call, and the given prefix gets prepended to all the +created filenames: env = Environment(tools=['docbook']) env.DocbookHtmlChunked('manual', xsl='htmlchunk.xsl', base_dir='output/') Make sure that you don't forget the trailing slash for the base folder, else -your files get renamed only! +your files get renamed only! @@ -218,15 +219,15 @@ env.DocbookHtmlhelp('manual') where manual.xml is the input file. -If you use the root.filename +If you use the root.filename parameter in your own stylesheets you have to specify the new target name. -This ensures that the dependencies get correct, especially for the cleanup via scons -c: +This ensures that the dependencies get correct, especially for the cleanup via scons -c: env = Environment(tools=['docbook']) env.DocbookHtmlhelp('mymanual.html', 'manual', xsl='htmlhelp.xsl') -Some basic support for the base.dir parameter -is provided. You can add the base_dir keyword to +Some basic support for the base.dir parameter +is provided. You can add the base_dir keyword to your Builder call, and the given prefix gets prepended to all the created filenames: @@ -234,7 +235,7 @@ created filenames: env.DocbookHtmlhelp('manual', xsl='htmlhelp.xsl', base_dir='output/') Make sure that you don't forget the trailing slash for the base folder, else -your files get renamed only! +your files get renamed only! @@ -251,7 +252,7 @@ Its basic syntax is: env.DocbookMan('manual') -where manual.xml is the input file. Note, that +where manual.xml is the input file. Note, that you can specify a target name, but the actual output names are automatically set from the refname entries in your XML source. @@ -289,25 +290,25 @@ A pseudo-Builder, providing a Docbook toolchain for HTML slides output. env.DocbookSlidesHtml('manual') -If you use the titlefoil.html parameter in +If you use the titlefoil.html parameter in your own stylesheets you have to give the new target name. This ensures -that the dependencies get correct, especially for the cleanup via -scons -c: +that the dependencies get correct, especially for the cleanup via +scons -c: env = Environment(tools=['docbook']) env.DocbookSlidesHtml('mymanual.html','manual', xsl='slideshtml.xsl') -Some basic support for the base.dir parameter +Some basic support for the base.dir parameter is provided. You -can add the base_dir keyword to your Builder +can add the base_dir keyword to your Builder call, and the given prefix gets prepended to all the created filenames: env = Environment(tools=['docbook']) env.DocbookSlidesHtml('manual', xsl='slideshtml.xsl', base_dir='output/') Make sure that you don't forget the trailing slash for the base folder, else -your files get renamed only! +your files get renamed only! @@ -355,7 +356,7 @@ A pseudo-Builder, applying a given XSL transformation to the input file. env.DocbookXslt('manual_transformed.xml', 'manual.xml', xsl='transform.xslt') -Note, that this builder requires the xsl parameter +Note, that this builder requires the xsl parameter to be set. @@ -418,15 +419,18 @@ env.DVI(target = 'ccc.dvi', source = 'ccc.latex') Gs() env.Gs() -A Builder for explicitly calling the gs executable. -Depending on the underlying OS, the different names gs, -gsos2 and gswin32c +A Builder for explicitly calling the gs executable. +Depending on the underlying OS, the different names gs, +gsos2 and gswin32c are tried. -env = Environment(tools=['gs']) -env.Gs('cover.jpg','scons-scons.pdf', - GSFLAGS='-dNOPAUSE -dBATCH -sDEVICE=jpeg -dFirstPage=1 -dLastPage=1 -q') - ) + +env = Environment(tools=['gs']) +env.Gs( + 'cover.jpg', + 'scons-scons.pdf', + GSFLAGS='-dNOPAUSE -dBATCH -sDEVICE=jpeg -dFirstPage=1 -dLastPage=1 -q', +) @@ -1232,7 +1236,7 @@ builder method. env.Package() Builds software distribution packages. -A Package is a container format which +A package is a container format which includes files to install along with metadata. Packaging is optional, and must be enabled by specifying the &t-link-packaging; tool. For example: @@ -1322,7 +1326,7 @@ env.Package( SUMMARY="balalalalal", DESCRIPTION="this should be really really long", X_RPM_GROUP="Application/fu", - SOURCE_URL="http://foo.org/foo-1.2.3.tar.gz", + SOURCE_URL="https://foo.org/foo-1.2.3.tar.gz", ) @@ -1333,7 +1337,7 @@ since it is not under the project top directory. However, since no source is specified to the &b-Package; builder, it is selected for packaging by the default sources rule. -Since packaging is done using &cv-PACKAGEROOT;, no write is +Since packaging is done using &cv-link-PACKAGEROOT;, no write is actually done to the system's /bin directory, and the target will be selected since after rebasing to underneath &cv-PACKAGEROOT; it is now under @@ -1347,13 +1351,13 @@ the top directory of the project. env.PCH() Builds a Microsoft Visual C++ precompiled header. -Calling this builder method +Calling this builder returns a list of two targets: the PCH as the first element, and the object file as the second element. Normally the object file is ignored. -This builder method is only +This builder is only provided when Microsoft Visual C++ is being used as the compiler. -The PCH builder method is generally used in -conjunction with the PCH construction variable to force object files to use +The &b-PCH; builder is generally used in +conjunction with the &cv-link-PCH; construction variable to force object files to use the precompiled header: diff --git a/doc/generated/examples/caching_ex-random_1.xml b/doc/generated/examples/caching_ex-random_1.xml index 27c8771..a5593d3 100644 --- a/doc/generated/examples/caching_ex-random_1.xml +++ b/doc/generated/examples/caching_ex-random_1.xml @@ -1,8 +1,8 @@ % scons -Q -cc -o f4.o -c f4.c -cc -o f5.o -c f5.c -cc -o f3.o -c f3.c cc -o f2.o -c f2.c cc -o f1.o -c f1.c +cc -o f3.o -c f3.c +cc -o f4.o -c f4.c +cc -o f5.o -c f5.c cc -o prog f1.o f2.o f3.o f4.o f5.o diff --git a/doc/generated/examples/commandline_ListVariable_1.xml b/doc/generated/examples/commandline_ListVariable_1.xml index 1e68e02..8e023d1 100644 --- a/doc/generated/examples/commandline_ListVariable_1.xml +++ b/doc/generated/examples/commandline_ListVariable_1.xml @@ -1,5 +1,5 @@ % scons -Q COLORS=red,blue foo.o -cc -o foo.o -c -DCOLORS="red blue" foo.c +cc -o foo.o -c -DCOLORS="red -Dblue" foo.c % scons -Q COLORS=blue,green,red foo.o -cc -o foo.o -c -DCOLORS="blue green red" foo.c +cc -o foo.o -c -DCOLORS="blue -Dgreen -Dred" foo.c diff --git a/doc/generated/examples/commandline_ListVariable_2.xml b/doc/generated/examples/commandline_ListVariable_2.xml index c31d16b..87dd3c6 100644 --- a/doc/generated/examples/commandline_ListVariable_2.xml +++ b/doc/generated/examples/commandline_ListVariable_2.xml @@ -1,5 +1,5 @@ % scons -Q COLORS=all foo.o -cc -o foo.o -c -DCOLORS="red green blue" foo.c +cc -o foo.o -c -DCOLORS="red -Dgreen -Dblue" foo.c % scons -Q COLORS=none foo.o cc -o foo.o -c -DCOLORS="" foo.c diff --git a/doc/generated/examples/troubleshoot_Dump_1.xml b/doc/generated/examples/troubleshoot_Dump_1.xml index 0b7bd05..8f4e624 100644 --- a/doc/generated/examples/troubleshoot_Dump_1.xml +++ b/doc/generated/examples/troubleshoot_Dump_1.xml @@ -58,6 +58,7 @@ scons: Reading SConscript files ... 'TARGET_ARCH': None, 'TARGET_OS': None, 'TEMPFILE': <class 'SCons.Platform.TempFileMunge'>, + 'TEMPFILEARGESCFUNC': <function quote_spaces at 0x700000>, 'TEMPFILEARGJOIN': ' ', 'TEMPFILEPREFIX': '@', 'TOOLS': ['install', 'install'], diff --git a/doc/generated/examples/troubleshoot_Dump_2.xml b/doc/generated/examples/troubleshoot_Dump_2.xml index 4272d0a..f2fc5e6 100644 --- a/doc/generated/examples/troubleshoot_Dump_2.xml +++ b/doc/generated/examples/troubleshoot_Dump_2.xml @@ -101,6 +101,7 @@ scons: Reading SConscript files ... 'TARGET_ARCH': None, 'TARGET_OS': None, 'TEMPFILE': <class 'SCons.Platform.TempFileMunge'>, + 'TEMPFILEARGESCFUNC': <function quote_spaces at 0x700000>, 'TEMPFILEARGJOIN': '\n', 'TEMPFILEPREFIX': '@', 'TOOLS': ['msvc', 'install', 'install'], diff --git a/doc/generated/examples/troubleshoot_explain1_3.xml b/doc/generated/examples/troubleshoot_explain1_3.xml index 85556b1..6b90e1c 100644 --- a/doc/generated/examples/troubleshoot_explain1_3.xml +++ b/doc/generated/examples/troubleshoot_explain1_3.xml @@ -2,5 +2,5 @@ cp file.in file.oout scons: warning: Cannot find target file.out after building -File "/Users/bdbaddog/devel/scons/git/scons-bugfixes-3/scripts/scons.py", line 96, in <module> +File "/Users/bdbaddog/devel/scons/git/as_scons/scripts/scons.py", line 96, in <module> diff --git a/doc/generated/examples/troubleshoot_stacktrace_2.xml b/doc/generated/examples/troubleshoot_stacktrace_2.xml index 41e53c5..8e8809c 100644 --- a/doc/generated/examples/troubleshoot_stacktrace_2.xml +++ b/doc/generated/examples/troubleshoot_stacktrace_2.xml @@ -3,7 +3,7 @@ scons: *** [prog.o] Source `prog.c' not found, needed by target `prog.o'. scons: internal stack trace: File "SCons/Job.py", line 195, in start task.prepare() - File "SCons/Script/Main.py", line 177, in prepare + File "SCons/Script/Main.py", line 179, in prepare return SCons.Taskmaster.OutOfDateTask.prepare(self) File "SCons/Taskmaster.py", line 186, in prepare executor.prepare() diff --git a/doc/generated/functions.gen b/doc/generated/functions.gen index 61b1fed..1af4bae 100644 --- a/doc/generated/functions.gen +++ b/doc/generated/functions.gen @@ -425,37 +425,153 @@ Multiple targets can be passed in to a single call to env.Append(key=val, [...]) -Appends the specified keyword arguments -to the end of construction variables in the environment. -If the Environment does not have -the specified construction variable, -it is simply added to the environment. -If the values of the construction variable -and the keyword argument are the same type, -then the two values will be simply added together. -Otherwise, the construction variable -and the value of the keyword argument -are both coerced to lists, -and the lists are added together. -(See also the &Prepend; method). +Intelligently append values to &consvars; in the &consenv; +named by env. +The &consvars; and values to add to them are passed as +key=val pairs (Python keyword arguments). +&f-env-Append; is designed to allow adding values +without normally having to know the data type of an existing &consvar;. +Regular Python syntax can also be used to manipulate the &consvar;, +but for that you must know the type of the &consvar;: +for example, different Python syntax is needed to combine +a list of values with a single string value, or vice versa. +Some pre-defined &consvars; do have type expectations +based on how &SCons; will use them, +for example &cv-link-CPPDEFINES; is normally a string or a list of strings, +but can be a string, +a list of strings, +a list of tuples, +or a dictionary, while &cv-link-LIBEMITTER; +would expect a callable or list of callables, +and &cv-link-BUILDERS; would expect a mapping type. +Consult the documentation for the various &consvars; for more details. + + + +The following descriptions apply to both the append +and prepend functions, the only difference being +the insertion point of the added values. + + +If env. does not have a &consvar; +indicated by key, +val +is added to the environment under that key as-is. + + + +val can be almost any type, +and &SCons; will combine it with an existing value into an appropriate type, +but there are a few special cases to be aware of. +When two strings are combined, +the result is normally a new string, +with the caller responsible for supplying any needed separation. +The exception to this is the &consvar; &cv-link-CPPDEFINES;, +in which each item will be postprocessed by adding a prefix +and/or suffix, +so the contents are treated as a list of strings, that is, +adding a string will result in a separate string entry, +not a combined string. For &cv-CPPDEFINES; as well as +for &cv-link-LIBS;, and the various *PATH +variables, &SCons; will supply the compiler-specific +syntax (e.g. adding a -D or /D +prefix for &cv-CPPDEFINES;), so this syntax should be omitted when +adding values to these variables. +Example (gcc syntax shown in the expansion of &CPPDEFINES;): + +env = Environment(CXXFLAGS="-std=c11", CPPDEFINES="RELEASE") +print("CXXFLAGS={}, CPPDEFINES={}".format(env['CXXFLAGS'], env['CPPDEFINES'])) +# notice including a leading space in CXXFLAGS value +env.Append(CXXFLAGS=" -O", CPPDEFINES="EXTRA") +print("CXXFLAGS={}, CPPDEFINES={}".format(env['CXXFLAGS'], env['CPPDEFINES'])) +print("CPPDEFINES will expand to {}".format(env.subst("$_CPPDEFFLAGS"))) + + + +$ scons -Q +CXXFLAGS=-std=c11, CPPDEFINES=RELEASE +CXXFLAGS=-std=c11 -O, CPPDEFINES=['RELEASE', 'EXTRA'] +CPPDEFINES will expand to -DRELEASE -DEXTRA +scons: `.' is up to date. + + -Example: +Because &cv-link-CPPDEFINES; is intended to +describe C/C++ pre-processor macro definitions, +it accepts additional syntax. +Preprocessor macros can be valued, or un-valued, as in +-DBAR=1 or +-DFOO. +The macro can be be supplied as a complete string including the value, +or as a tuple (or list) of macro, value, or as a dictionary. +Example (again gcc syntax in the expanded defines): + + + +env = Environment(CPPDEFINES="FOO") +print("CPPDEFINES={}".format(env['CPPDEFINES'])) +env.Append(CPPDEFINES="BAR=1") +print("CPPDEFINES={}".format(env['CPPDEFINES'])) +env.Append(CPPDEFINES=("OTHER", 2)) +print("CPPDEFINES={}".format(env['CPPDEFINES'])) +env.Append(CPPDEFINES={"EXTRA": "arg"}) +print("CPPDEFINES={}".format(env['CPPDEFINES'])) +print("CPPDEFINES will expand to {}".format(env.subst("$_CPPDEFFLAGS"))) + + + +$ scons -Q +CPPDEFINES=FOO +CPPDEFINES=['FOO', 'BAR=1'] +CPPDEFINES=['FOO', 'BAR=1', ('OTHER', 2)] +CPPDEFINES=['FOO', 'BAR=1', ('OTHER', 2), {'EXTRA': 'arg'}] +CPPDEFINES will expand to -DFOO -DBAR=1 -DOTHER=2 -DEXTRA=arg +scons: `.' is up to date. + + + +Adding a string val +to a dictonary &consvar; will enter +val as the key in the dict, +and None as its value. +Using a tuple type to supply a key + value only works +for the special case of &cv-link-CPPDEFINES; +described above. + + + +Although most combinations of types work without +needing to know the details, some combinations +do not make sense and a Python exception will be raised. + + + +When using &f-env-Append; to modify &consvars; +which are path specifications (normally, +those names which end in PATH), +it is recommended to add the values as a list of strings, +even if there is only a single string to add. +The same goes for adding library names to &cv-LIBS;. -env.Append(CCFLAGS = ' -g', FOO = ['foo.yyy']) +env.Append(CPPPATH=["#/include"]) + + +See also &f-link-env-AppendUnique;, +&f-link-env-Prepend; and &f-link-env-PrependUnique;. + + - env.AppendENVPath(name, newpath, [envname, sep, delete_existing]) + env.AppendENVPath(name, newpath, [envname, sep, delete_existing=False]) -This appends new path elements to the given path in the -specified external environment -(ENV -by default). +Append new path elements to the given path in the +specified external environment (&cv-link-ENV; by default). This will only add any particular path once (leaving the last one it encounters and ignoring the rest, to preserve path order), @@ -472,7 +588,7 @@ string, in which case a list will be returned instead of a string. If delete_existing -is 0, then adding a path that already exists +is False, then adding a path that already exists will not move it to the end; it will stay where it is in the list. @@ -485,29 +601,28 @@ print('before:', env['ENV']['INCLUDE']) include_path = '/foo/bar:/foo' env.AppendENVPath('INCLUDE', include_path) print('after:', env['ENV']['INCLUDE']) + -yields: +Yields: + before: /foo:/biz after: /biz:/foo/bar:/foo - + - env.AppendUnique(key=val, [...], delete_existing=0) + env.AppendUnique(key=val, [...], delete_existing=False) -Appends the specified keyword arguments -to the end of construction variables in the environment. -If the Environment does not have -the specified construction variable, -it is simply added to the environment. -If the construction variable being appended to is a list, -then any value(s) that already exist in the -construction variable will -not -be added again to the list. -However, if delete_existing is 1, -existing matching values are removed first, so -existing values in the arg list move to the end of the list. +Append values to &consvars; in the current &consenv;, +maintaining uniqueness. +Works like &f-link-env-Append; (see for details), +except that values already present in the &consvar; +will not be added again. +If delete_existing +is True, +the existing matching value is first removed, +and the requested value is added, +having the effect of moving such values to the end. @@ -515,8 +630,14 @@ Example: -env.AppendUnique(CCFLAGS = '-g', FOO = ['foo.yyy']) +env.AppendUnique(CCFLAGS='-g', FOO=['foo.yyy']) + + +See also &f-link-env-Append;, +&f-link-env-Prepend; +and &f-link-env-PrependUnique;. + @@ -540,7 +661,7 @@ including the argument, at the time it is called using the construction variables in the -env +env construction environment through which &f-env-Builder; was called. The @@ -551,8 +672,8 @@ until after the Builder object is actually called. - CacheDir(cache_dir) - env.CacheDir(cache_dir) + CacheDir(cache_dir, custom_class=None) + env.CacheDir(cache_dir, custom_class=None) Direct &scons; @@ -569,6 +690,15 @@ disables derived file caching. +When specifying a +custom_class which should be a class type which is a subclass of +SCons.CacheDir.CacheDir, SCons will +internally invoke this class to use for performing caching operations. +This argument is optional and if left to default None, will use the +default SCons.CacheDir.CacheDir class. + + + Calling the environment method &f-link-env-CacheDir; limits the effect to targets built @@ -737,7 +867,7 @@ Example: env2 = env.Clone() -env3 = env.Clone(CCFLAGS = '-g') +env3 = env.Clone(CCFLAGS='-g') @@ -746,8 +876,10 @@ the &f-link-Environment; constructor: -def MyTool(env): env['FOO'] = 'bar' -env4 = env.Clone(tools = ['msvc', MyTool]) +def MyTool(env): + env['FOO'] = 'bar' + +env4 = env.Clone(tools=['msvc', MyTool]) @@ -949,24 +1081,24 @@ timestamp, such as can happen when restoring files from backup archives. -"MD5" +"content" Specifies that a target shall be considered out of date and rebuilt if the dependency's content has changed since the last time the target was built, -as determined be performing an MD5 checksum +as determined be performing an checksum on the dependency's contents and comparing it to the checksum recorded the last time the target was built. -content +MD5 can be used as a synonym for -MD5. +content, but it is deprecated. -"MD5-timestamp" +"content-timestamp" Specifies that a target shall be considered out of date and rebuilt @@ -979,7 +1111,7 @@ assumed to be up-to-date and rebuilt. This provides behavior very similar to the -MD5 +content behavior of always checksumming file contents, with an optimization of not checking the contents of files whose timestamps haven't changed. @@ -992,6 +1124,9 @@ that runs a build, updates a file, and runs the build again, all within a single second. +MD5-timestamp +can be used as a synonym for +content-timestamp, but it is deprecated. @@ -1006,7 +1141,7 @@ Examples: # Use exact timestamp matches by default. Decider('timestamp-match') -# Use MD5 content signatures for any targets built +# Use hash content signatures for any targets built # with the attached construction environment. env.Decider('content') @@ -1121,32 +1256,46 @@ env.Decider(my_decider) - Default(targets...) - env.Default(targets...) + Default(target[, ...]) + env.Default(target[, ...]) -This specifies a list of default targets, -which will be built by -&scons; -if no explicit targets are given on the command line. -Multiple calls to +Specify default targets to the &SCons; target selection mechanism. +Any call to &f-Default; will cause &SCons; to use the +defined default target list instead of +its built-in algorithm for determining default targets +(see the manpage section "Target Selection"). + + + +target may be one or more strings, +a list of strings, +a NodeList as returned by a Builder, +or None. +A string target may be the name of +a file or directory, or a target previously defined by a call to +&f-link-Alias; (defining the alias later will still create +the alias, but it will not be recognized as a default). +Calls to &f-Default; are additive. +A target of +None +will clear any existing default target list; +subsequent calls to &f-Default; -are legal, -and add to the list of default targets. -As noted above, both forms of this call affect the +will add to the (now empty) default target list +like normal. + + + +Both forms of this call affect the same global list of default targets; the construction environment method applies construction variable expansion to the targets. -Multiple targets should be specified as -separate arguments to the -&f-Default; -method, or as a list. -&f-Default; -will also accept the Node returned by any -of a construction environment's -builder methods. +The current list of targets added using +&f-Default; is available in the +&DEFAULT_TARGETS; list (see below). @@ -1160,26 +1309,6 @@ hello = env.Program('hello', 'hello.c') env.Default(hello) - -An argument to -&f-Default; -of -None -will clear all default targets. -Later calls to -&f-Default; -will add to the (now empty) default-target list -like normal. - - - -The current list of targets added using the -&f-Default; -function or method is available in the -DEFAULT_TARGETS -list; -see below. - @@ -1262,9 +1391,9 @@ Find an executable from one or more choices: Returns the first value from progs that was found, or None. Executable is searched by checking the paths specified -by env['ENV']['PATH']. +by env['ENV']['PATH']. On Windows systems, additionally applies the filename suffixes found in -env['ENV']['PATHEXT'] +env['ENV']['PATHEXT'] but will not include any such extension in the return value. &f-env-Detect; is a wrapper around &f-link-env-WhereIs;. @@ -1384,7 +1513,7 @@ While this SConstruct: -env=Environment() +env = Environment() print(env.Dump()) @@ -1677,16 +1806,16 @@ Example: -Install( '/bin', [ 'executable_a', 'executable_b' ] ) +Install('/bin', ['executable_a', 'executable_b']) # will return the file node list -# [ '/bin/executable_a', '/bin/executable_b' ] +# ['/bin/executable_a', '/bin/executable_b'] FindInstalledFiles() -Install( '/lib', [ 'some_library' ] ) +Install('/lib', ['some_library']) # will return the file node list -# [ '/bin/executable_a', '/bin/executable_b', '/lib/some_library' ] +# ['/bin/executable_a', '/bin/executable_b', '/lib/some_library'] FindInstalledFiles() @@ -1774,15 +1903,15 @@ Example: -Program( 'src/main_a.c' ) -Program( 'src/main_b.c' ) -Program( 'main_c.c' ) +Program('src/main_a.c') +Program('src/main_b.c') +Program('main_c.c') # returns ['main_c.c', 'src/main_a.c', 'SConstruct', 'src/main_b.c'] FindSourceFiles() # returns ['src/main_b.c', 'src/main_a.c' ] -FindSourceFiles( 'src' ) +FindSourceFiles('src') @@ -2445,8 +2574,8 @@ Examples: env.Ignore('foo', 'foo.c') env.Ignore('bar', ['bar1.h', 'bar2.h']) -env.Ignore('.','foobar.obj') -env.Ignore('bar','bar/foobar.obj') +env.Ignore('.', 'foobar.obj') +env.Ignore('bar', 'bar/foobar.obj') @@ -2864,7 +2993,7 @@ Example: -env = Environment(platform = Platform('win32')) +env = Environment(platform=Platform('win32')) @@ -2916,19 +3045,10 @@ Multiple targets can be passed in to a single call to env.Prepend(key=val, [...]) -Appends the specified keyword arguments -to the beginning of construction variables in the environment. -If the Environment does not have -the specified construction variable, -it is simply added to the environment. -If the values of the construction variable -and the keyword argument are the same type, -then the two values will be simply added together. -Otherwise, the construction variable -and the value of the keyword argument -are both coerced to lists, -and the lists are added together. -(See also the Append method, above.) +Prepend values to &consvars; in the current &consenv;, +Works like &f-link-env-Append; (see for details), +except that values are added to the front, +rather than the end, of any existing value of the &consvar; @@ -2936,25 +3056,29 @@ Example: -env.Prepend(CCFLAGS = '-g ', FOO = ['foo.yyy']) +env.Prepend(CCFLAGS='-g ', FOO=['foo.yyy']) + + +See also &f-link-env-Append;, +&f-link-env-AppendUnique; +and &f-link-env-PrependUnique;. + env.PrependENVPath(name, newpath, [envname, sep, delete_existing]) -This appends new path elements to the given path in the -specified external environment -(&cv-ENV; -by default). +Prepend new path elements to the given path in the +specified external environment (&cv-link-ENV; by default). This will only add any particular path once (leaving the first one it encounters and ignoring the rest, to preserve path order), and to help assure this, will normalize all paths (using -os.path.normpath +os.path.normpath and -os.path.normcase). +os.path.normcase). This can also handle the case where the given old path variable is a list instead of a string, in which case a list will be returned instead of a string. @@ -2963,7 +3087,8 @@ string, in which case a list will be returned instead of a string. If delete_existing -is 0, then adding a path that already exists +is False, +then adding a path that already exists will not move it to the beginning; it will stay where it is in the list. @@ -2979,32 +3104,29 @@ env.PrependENVPath('INCLUDE', include_path) print('after:', env['ENV']['INCLUDE']) - -The above example will print: - +Yields: - + before: /biz:/foo after: /foo/bar:/foo:/biz - + - env.PrependUnique(key=val, delete_existing=0, [...]) + env.PrependUnique(key=val, delete_existing=False, [...]) -Appends the specified keyword arguments -to the beginning of construction variables in the environment. -If the Environment does not have -the specified construction variable, -it is simply added to the environment. -If the construction variable being appended to is a list, -then any value(s) that already exist in the -construction variable will -not -be added again to the list. -However, if delete_existing is 1, -existing matching values are removed first, so -existing values in the arg list move to the front of the list. +Prepend values to &consvars; in the current &consenv;, +maintaining uniqueness. +Works like &f-link-env-Append; (see for details), +except that values are added to the front, +rather than the end, of any existing value of the the &consvar;, +and values already present in the &consvar; +will not be added again. +If delete_existing +is True, +the existing matching value is first removed, +and the requested value is inserted, +having the effect of moving such values to the front. @@ -3012,8 +3134,14 @@ Example: -env.PrependUnique(CCFLAGS = '-g', FOO = ['foo.yyy']) +env.PrependUnique(CCFLAGS='-g', FOO=['foo.yyy']) + + +See also &f-link-env-Append;, +&f-link-env-AppendUnique; +and &f-link-env-Prepend;. + @@ -3200,7 +3328,7 @@ Example: -env.Replace(CCFLAGS = '-g', FOO = 'foo.xxx') +env.Replace(CCFLAGS='-g', FOO='foo.xxx') @@ -3738,9 +3866,9 @@ The following statements are equivalent: -env.SetDefault(FOO = 'foo') - -if 'FOO' not in env: env['FOO'] = 'foo' +env.SetDefault(FOO='foo') +if 'FOO' not in env: + env['FOO'] = 'foo' @@ -3782,11 +3910,24 @@ The settable variables with their associated command-line options are: - + + duplicate + + + + + experimental + + + + + + + help @@ -4070,12 +4211,13 @@ Example: print(env.subst("The C compiler is: $CC")) def compile(target, source, env): - sourceDir = env.subst("${SOURCE.srcdir}", - target=target, - source=source) + sourceDir = env.subst( + "${SOURCE.srcdir}", + target=target, + source=source + ) -source_nodes = env.subst('$EXPAND_TO_NODELIST', - conv=lambda x: x) +source_nodes = env.subst('$EXPAND_TO_NODELIST', conv=lambda x: x) @@ -4368,11 +4510,11 @@ searches the paths in the path keyword argument, or if None (the default) the paths listed in the &consenv; -(env['ENV']['PATH']). +(env['ENV']['PATH']). The external environment's path list (os.environ['PATH']) is used as a fallback if the key -env['ENV']['PATH'] +env['ENV']['PATH'] does not exist. @@ -4381,11 +4523,11 @@ programs with any of the file extensions listed in the pathext keyword argument, or if None (the default) the pathname extensions listed in the &consenv; -(env['ENV']['PATHEXT']). +(env['ENV']['PATHEXT']). The external environment's pathname extensions list (os.environ['PATHEXT']) is used as a fallback if the key -env['ENV']['PATHEXT'] +env['ENV']['PATHEXT'] does not exist. diff --git a/doc/generated/tools.gen b/doc/generated/tools.gen index 625e7d7..dc15b6e 100644 --- a/doc/generated/tools.gen +++ b/doc/generated/tools.gen @@ -144,67 +144,79 @@ the platform and on the software installed on the platform. Some tools will not initialize if an underlying command is not found, and some tools are selected from a list of choices on a first-found basis. The finished tool list can be -examined by inspecting the TOOLS &consvar; +examined by inspecting the &cv-link-TOOLS; &consvar; in the &consenv;. -On all platforms, all tools from the following list -are selected whose respective conditions are met: -filesystem, wix, lex, yacc, rpcgen, swig, -jar, javac, javah, rmic, dvipdf, dvips, gs, -tex, latex, pdflatex, pdftex, tar, zip, textfile. +On all platforms, the tools from the following list +are selected if their respective conditions are met: + filesystem;, + wix, +&t-link-lex;, &t-link-yacc;, +&t-link-rpcgen;, &t-link-swig;, +&t-link-jar;, &t-link-javac;, &t-link-javah;, &t-link-rmic;, +&t-link-dvipdf;, &t-link-dvips;, &t-link-gs;, +&t-link-tex;, &t-link-latex;, &t-link-pdflatex;, &t-link-pdftex;, +&t-link-tar;, &t-link-zip;, &t-link-textfile;. On Linux systems, the default tools list selects (first-found): a C compiler from -gcc, intelc, icc, cc; +&t-link-gcc;, &t-link-intelc;, &t-link-icc;, &t-link-cc;; a C++ compiler from -g++, intelc, icc, cxx; +&t-link-gXX;, &t-link-intelc;, &t-link-icc;, &t-link-cXX;; an assembler from -gas, nasm, masm; +&t-link-gas;, &t-link-nasm;, &t-link-masm;; a linker from -gnulink, ilink; +&t-link-gnulink;, &t-link-ilink;; a Fortran compiler from -gfortran, g77, ifort, ifl, f95, f90, f77; -and a static archiver 'ar'. +&t-link-gfortran;, &t-link-g77;, &t-link-ifort;, &t-link-ifl;, +&t-link-f95;, &t-link-f90;, &t-link-f77;; +and a static archiver &t-link-ar;. It also selects all found from the list -m4, rpm. +&t-link-m4; + rpm. On Windows systems, the default tools list selects (first-found): a C compiler from -msvc, mingw, gcc, intelc, icl, icc, cc, bcc32; +&t-link-msvc;, &t-link-mingw;, &t-link-gcc;, &t-link-intelc;, +&t-link-icl;, &t-link-icc;, &t-link-cc;, &t-link-bcc32;; a C++ compiler from -msvc, intelc, icc, g++, cxx, bcc32; +&t-link-msvc;, &t-link-intelc;, &t-link-icc;, &t-link-gXX;, +&t-link-cXX;, &t-link-bcc32;; an assembler from -masm, nasm, gas, 386asm; +&t-link-masm;, &t-link-nasm;, &t-link-gas;, &t-link-386asm;; a linker from -mslink, gnulink, ilink, linkloc, ilink32; +&t-link-mslink;, &t-link-gnulink;, &t-link-ilink;, +&t-link-linkloc;, &t-link-ilink32;; a Fortran compiler from -gfortran, g77, ifl, cvf, f95, f90, fortran; +&t-link-gfortran;, &t-link-g77;, &t-link-ifl;, &t-link-cvf;, +&t-link-f95;, &t-link-f90;, &t-link-fortran;; and a static archiver from -mslib, ar, tlib; +&t-link-mslib;, &t-link-ar;, &t-link-tlib;; It also selects all found from the list -msvs, midl. +&t-link-msvs;, &t-link-midl;. On MacOS systems, the default tools list selects (first-found): a C compiler from -gcc, cc; +&t-link-gcc;, &t-link-cc;; a C++ compiler from -g++, cxx; -an assembler 'as'; +&t-link-gXX;, &t-link-cXX;; +an assembler &t-link-as;; a linker from -applelink, gnulink; +&t-link-applelink;, &t-link-gnulink;; a Fortran compiler from -gfortran, f95, f90, g77; -and a static archiver ar. +&t-link-gfortran;, &t-link-f95;, &t-link-f90;, &t-link-g77;; +and a static archiver &t-link-ar;. It also selects all found from the list -m4, rpm. +&t-link-m4;, + rpm. @@ -240,29 +252,29 @@ stylesheet utils/xmldepend.xsl by Paul DuBois is used for t Note, that there is no support for XML catalog resolving offered! This tool calls the XSLT processors and PDF renderers with the stylesheets you specified, that's it. The rest lies in your hands and you still have to know what you're doing when -resolving names via a catalog. +resolving names via a catalog. For activating the tool "docbook", you have to add its name to the Environment constructor, like this env = Environment(tools=['docbook']) -On its startup, the Docbook tool tries to find a required xsltproc processor, and -a PDF renderer, e.g. fop. So make sure that these are added to your system's environment -PATH and can be called directly, without specifying their full path. +On its startup, the &t-docbook; tool tries to find a required xsltproc processor, and +a PDF renderer, e.g. fop. So make sure that these are added to your system's environment +PATH and can be called directly without specifying their full path. For the most basic processing of Docbook to HTML, you need to have installed -the Python lxml binding to libxml2, or - +the Python lxml +binding to libxml2, or -a standalone XSLT processor, currently detected are xsltproc, saxon, saxon-xslt -and xalan. +a standalone XSLT processor, currently detected are xsltproc, saxon, saxon-xslt +and xalan. Rendering to PDF requires you to have one of the applications -fop or xep installed. +fop or xep installed. Creating a HTML or PDF document is very simple and straightforward. Say @@ -293,14 +305,14 @@ Tool uses the given names as file stems, and adds the suffixes for target and so accordingly. -The rules given above are valid for the Builders &b-link-DocbookHtml;, -&b-link-DocbookPdf;, &b-link-DocbookEpub;, &b-link-DocbookSlidesPdf; and &b-link-DocbookXInclude;. For the +The rules given above are valid for the Builders &b-link-DocbookHtml;, +&b-link-DocbookPdf;, &b-link-DocbookEpub;, &b-link-DocbookSlidesPdf; and &b-link-DocbookXInclude;. For the &b-link-DocbookMan; transformation you can specify a target name, but the actual output names are automatically set from the refname entries in your XML source. -The Builders &b-link-DocbookHtmlChunked;, &b-link-DocbookHtmlhelp; and +The Builders &b-link-DocbookHtmlChunked;, &b-link-DocbookHtmlhelp; and &b-link-DocbookSlidesHtml; are special, in that: they create a large set of files, where the exact names and their number depend @@ -312,7 +324,7 @@ XSL transformation is not picked up by the stylesheets. -As a result, there is simply no use in specifying a target HTML name. +As a result, there is simply no use in specifying a target HTML name. So the basic syntax for these builders is always: env = Environment(tools=['docbook']) @@ -320,7 +332,7 @@ env.DocbookHtmlhelp('manual') If you want to use a specific XSL file, you can set the -additional xsl parameter to your +additional xsl parameter to your Builder call as follows: env.DocbookHtml('other.html', 'manual.xml', xsl='html.xsl') @@ -329,28 +341,31 @@ Builder call as follows: e.g. html.xsl for HTML and pdf.xsl for PDF output, a set of variables for setting the default XSL name is provided. These are: -DOCBOOK_DEFAULT_XSL_HTML -DOCBOOK_DEFAULT_XSL_HTMLCHUNKED -DOCBOOK_DEFAULT_XSL_HTMLHELP -DOCBOOK_DEFAULT_XSL_PDF -DOCBOOK_DEFAULT_XSL_EPUB -DOCBOOK_DEFAULT_XSL_MAN -DOCBOOK_DEFAULT_XSL_SLIDESPDF -DOCBOOK_DEFAULT_XSL_SLIDESHTML +DOCBOOK_DEFAULT_XSL_HTML +DOCBOOK_DEFAULT_XSL_HTMLCHUNKED +DOCBOOK_DEFAULT_XSL_HTMLHELP +DOCBOOK_DEFAULT_XSL_PDF +DOCBOOK_DEFAULT_XSL_EPUB +DOCBOOK_DEFAULT_XSL_MAN +DOCBOOK_DEFAULT_XSL_SLIDESPDF +DOCBOOK_DEFAULT_XSL_SLIDESHTML and you can set them when constructing your environment: -env = Environment(tools=['docbook'], - DOCBOOK_DEFAULT_XSL_HTML='html.xsl', - DOCBOOK_DEFAULT_XSL_PDF='pdf.xsl') -env.DocbookHtml('manual') # now uses html.xsl + +env = Environment( + tools=['docbook'], + DOCBOOK_DEFAULT_XSL_HTML='html.xsl', + DOCBOOK_DEFAULT_XSL_PDF='pdf.xsl', +) +env.DocbookHtml('manual') # now uses html.xsl Sets: &cv-link-DOCBOOK_DEFAULT_XSL_EPUB;, &cv-link-DOCBOOK_DEFAULT_XSL_HTML;, &cv-link-DOCBOOK_DEFAULT_XSL_HTMLCHUNKED;, &cv-link-DOCBOOK_DEFAULT_XSL_HTMLHELP;, &cv-link-DOCBOOK_DEFAULT_XSL_MAN;, &cv-link-DOCBOOK_DEFAULT_XSL_PDF;, &cv-link-DOCBOOK_DEFAULT_XSL_SLIDESHTML;, &cv-link-DOCBOOK_DEFAULT_XSL_SLIDESPDF;, &cv-link-DOCBOOK_FOP;, &cv-link-DOCBOOK_FOPCOM;, &cv-link-DOCBOOK_FOPFLAGS;, &cv-link-DOCBOOK_XMLLINT;, &cv-link-DOCBOOK_XMLLINTCOM;, &cv-link-DOCBOOK_XMLLINTFLAGS;, &cv-link-DOCBOOK_XSLTPROC;, &cv-link-DOCBOOK_XSLTPROCCOM;, &cv-link-DOCBOOK_XSLTPROCFLAGS;, &cv-link-DOCBOOK_XSLTPROCPARAMS;.Uses: &cv-link-DOCBOOK_FOPCOMSTR;, &cv-link-DOCBOOK_XMLLINTCOMSTR;, &cv-link-DOCBOOK_XSLTPROCCOMSTR;. dvi -Attaches the &b-DVI; builder to the +Attaches the &b-link-DVI; builder to the construction environment. @@ -431,7 +446,7 @@ to set variables. gas Sets construction variables for the &gas; assembler. -Calls the &t-as; module. +Calls the &t-link-as; tool. Sets: &cv-link-AS;. @@ -485,8 +500,8 @@ so you're encouraged to see their individual documentation. Each of the above tools provides its own builder(s) which may be used to perform particular activities related to software internationalization. You -may be however interested in top-level builder -&b-Translate; described few paragraphs later. +may be however interested in top-level +&b-link-Translate; builder. @@ -516,11 +531,11 @@ Set construction variables for GNU linker/loader. gs This Tool sets the required construction variables for working with -the Ghostscript command. It also registers an appropriate Action -with the PDF Builder (&b-link-PDF;), such that the conversion from +the Ghostscript software. It also registers an appropriate Action +with the &b-link-PDF; Builder, such that the conversion from PS/EPS to PDF happens automatically for the TeX/LaTeX toolchain. -Finally, it adds an explicit Ghostscript Builder (&b-link-Gs;) to the -environment. +Finally, it adds an explicit &b-link-Gs; Builder for Ghostscript +to the environment. Sets: &cv-link-GS;, &cv-link-GSCOM;, &cv-link-GSFLAGS;.Uses: &cv-link-GSCOMSTR;. @@ -534,9 +549,9 @@ Set construction variables for the compilers aCC on HP/UX systems. hpcc -Set construction variables for the -aCC on HP/UX systems. -Calls the &t-cXX; tool for additional variables. +Set construction variables for +aCC compilers on HP/UX systems. +Calls the &t-link-cXX; tool for additional variables. Sets: &cv-link-CXX;, &cv-link-CXXVERSION;, &cv-link-SHCXXFLAGS;. @@ -607,9 +622,9 @@ and directory installation. Sets construction variables for the Intel C/C++ compiler (Linux and Windows, version 7 and later). -Calls the &t-gcc; or &t-msvc; +Calls the &t-link-gcc; or &t-link-msvc; (on Linux and Windows, respectively) -to set underlying variables. +tool to set underlying variables. Sets: &cv-link-AR;, &cv-link-CC;, &cv-link-CXX;, &cv-link-INTEL_C_COMPILER_VERSION;, &cv-link-LINK;. @@ -744,7 +759,7 @@ library archiver. Sets construction variables for the Microsoft linker. -Sets: &cv-link-LDMODULE;, &cv-link-LDMODULECOM;, &cv-link-LDMODULEFLAGS;, &cv-link-LDMODULEPREFIX;, &cv-link-LDMODULESUFFIX;, &cv-link-LIBDIRPREFIX;, &cv-link-LIBDIRSUFFIX;, &cv-link-LIBLINKPREFIX;, &cv-link-LIBLINKSUFFIX;, &cv-link-LINK;, &cv-link-LINKCOM;, &cv-link-LINKFLAGS;, &cv-link-REGSVR;, &cv-link-REGSVRCOM;, &cv-link-REGSVRFLAGS;, &cv-link-SHLINK;, &cv-link-SHLINKCOM;, &cv-link-SHLINKFLAGS;, &cv-link-WIN32DEFPREFIX;, &cv-link-WIN32DEFSUFFIX;, &cv-link-WIN32EXPPREFIX;, &cv-link-WIN32EXPSUFFIX;, &cv-link-WINDOWSDEFPREFIX;, &cv-link-WINDOWSDEFSUFFIX;, &cv-link-WINDOWSEXPPREFIX;, &cv-link-WINDOWSEXPSUFFIX;, &cv-link-WINDOWSPROGMANIFESTPREFIX;, &cv-link-WINDOWSPROGMANIFESTSUFFIX;, &cv-link-WINDOWSSHLIBMANIFESTPREFIX;, &cv-link-WINDOWSSHLIBMANIFESTSUFFIX;, &cv-link-WINDOWS_INSERT_DEF;.Uses: &cv-link-LDMODULECOMSTR;, &cv-link-LINKCOMSTR;, &cv-link-REGSVRCOMSTR;, &cv-link-SHLINKCOMSTR;. +Sets: &cv-link-LDMODULE;, &cv-link-LDMODULECOM;, &cv-link-LDMODULEFLAGS;, &cv-link-LDMODULEPREFIX;, &cv-link-LDMODULESUFFIX;, &cv-link-LIBDIRPREFIX;, &cv-link-LIBDIRSUFFIX;, &cv-link-LIBLINKPREFIX;, &cv-link-LIBLINKSUFFIX;, &cv-link-LINK;, &cv-link-LINKCOM;, &cv-link-LINKFLAGS;, &cv-link-REGSVR;, &cv-link-REGSVRCOM;, &cv-link-REGSVRFLAGS;, &cv-link-SHLINK;, &cv-link-SHLINKCOM;, &cv-link-SHLINKFLAGS;, &cv-link-WINDOWSDEFPREFIX;, &cv-link-WINDOWSDEFSUFFIX;, &cv-link-WINDOWSEXPPREFIX;, &cv-link-WINDOWSEXPSUFFIX;, &cv-link-WINDOWSPROGMANIFESTPREFIX;, &cv-link-WINDOWSPROGMANIFESTSUFFIX;, &cv-link-WINDOWSSHLIBMANIFESTPREFIX;, &cv-link-WINDOWSSHLIBMANIFESTSUFFIX;, &cv-link-WINDOWS_INSERT_DEF;.Uses: &cv-link-LDMODULECOMSTR;, &cv-link-LINKCOMSTR;, &cv-link-REGSVRCOMSTR;, &cv-link-SHLINKCOMSTR;. mssdk @@ -799,7 +814,7 @@ Sets construction variables for the packaging -Sets construction variables for the &b-Package; Builder. +Sets construction variables for the &b-link-Package; Builder. If this tool is enabled, the command-line option is also enabled. diff --git a/doc/generated/variables.gen b/doc/generated/variables.gen index 84ef3b1..a24fd34 100644 --- a/doc/generated/variables.gen +++ b/doc/generated/variables.gen @@ -152,6 +152,7 @@ and the BuildArch: field in the RPM .spec file, as well as forming part of the name of a generated RPM package file. +See the &b-link-Package; builder. @@ -368,6 +369,17 @@ env['BUILDERS']['NewBuilder'] = bld + + + CACHEDIR_CLASS + + +The class type that SCons should use when instantiating a +new &f-link-CacheDir; for the given environment. It must be +a subclass of the SCons.CacheDir.CacheDir class. + + + CC @@ -527,6 +539,7 @@ the .wxs for MSI). If set, the function will be called after the SCons template for the file has been written. +See the &b-link-Package; builder. @@ -565,6 +578,7 @@ This is included as the section of the RPM .spec file. +See the &b-link-Package; builder. @@ -572,7 +586,7 @@ section of the RPM COMPILATIONDB_COMSTR - The string displayed when the &b-CompilationDatabase; + The string displayed when the &b-link-CompilationDatabase; builder's action is run. @@ -613,7 +627,7 @@ section of the RPM _concat -A function used to produce variables like &cv-_CPPINCFLAGS;. It takes +A function used to produce variables like &cv-link-_CPPINCFLAGS;. It takes four or five arguments: a prefix to concatenate onto each element, a list of elements, a suffix to concatenate onto each element, an environment @@ -647,7 +661,7 @@ file. CONFIGURELOG -The name of the Configure context log file. +The name of the &Configure; context log file. The default is config.log in the top-level directory @@ -662,14 +676,13 @@ file. _CPPDEFFLAGS -An automatically-generated construction variable +An automatically-generated &consvar; containing the C preprocessor command-line options to define values. -The value of &cv-_CPPDEFFLAGS; is created +The value of &cv-link-_CPPDEFFLAGS; is created by respectively prepending and appending -&cv-CPPDEFPREFIX; and &cv-CPPDEFSUFFIX; -to the beginning and end -of each definition in &cv-CPPDEFINES;. +&cv-link-CPPDEFPREFIX; and &cv-link-CPPDEFSUFFIX; +to each definition in &cv-link-CPPDEFINES;. @@ -678,10 +691,10 @@ of each definition in &cv-CPPDEFINES;. CPPDEFINES -A platform independent specification of C preprocessor definitions. +A platform independent specification of C preprocessor macro definitions. The definitions will be added to command lines through the automatically-generated -&cv-_CPPDEFFLAGS; construction variable (see above), +&cv-link-_CPPDEFFLAGS; &consvar; (see above), which is constructed according to the type of value of &cv-CPPDEFINES;: @@ -689,10 +702,9 @@ the type of value of &cv-CPPDEFINES;: If &cv-CPPDEFINES; is a string, the values of the -&cv-CPPDEFPREFIX; and &cv-CPPDEFSUFFIX; -construction variables -will be respectively prepended and appended to the beginning and end -of each definition in &cv-CPPDEFINES;. +&cv-link-CPPDEFPREFIX; and &cv-link-CPPDEFSUFFIX; &consvars; +will be respectively prepended and appended to +each definition in &cv-link-CPPDEFINES;. @@ -704,10 +716,9 @@ env = Environment(CPPDEFINES='xyz') If &cv-CPPDEFINES; is a list, the values of the -&cv-CPPDEFPREFIX; and &cv-CPPDEFSUFFIX; -construction variables -will be respectively prepended and appended to the beginning and end -of each element in the list. +&cv-CPPDEFPREFIX; and &cv-CPPDEFSUFFIX; &consvars; +will be respectively prepended and appended to +each element in the list. If any element is a list or tuple, then the first item is the name being defined and the second item is its value: @@ -722,10 +733,9 @@ env = Environment(CPPDEFINES=[('B', 2), 'A']) If &cv-CPPDEFINES; is a dictionary, the values of the -&cv-CPPDEFPREFIX; and &cv-CPPDEFSUFFIX; -construction variables -will be respectively prepended and appended to the beginning and end -of each item from the dictionary. +&cv-CPPDEFPREFIX; and &cv-CPPDEFSUFFIX; &consvars; +will be respectively prepended and appended to +each item from the dictionary. The key of each dictionary item is a name being defined to the dictionary item's corresponding value; @@ -751,11 +761,11 @@ env = Environment(CPPDEFINES={'B':2, 'A':None}) CPPDEFPREFIX -The prefix used to specify preprocessor definitions +The prefix used to specify preprocessor macro definitions on the C compiler command line. -This will be prepended to the beginning of each definition -in the &cv-CPPDEFINES; construction variable -when the &cv-_CPPDEFFLAGS; variable is automatically generated. +This will be prepended to each definition +in the &cv-link-CPPDEFINES; &consvar; +when the &cv-link-_CPPDEFFLAGS; variable is automatically generated. @@ -764,11 +774,11 @@ when the &cv-_CPPDEFFLAGS; variable is automatically generated. CPPDEFSUFFIX -The suffix used to specify preprocessor definitions +The suffix used to specify preprocessor macro definitions on the C compiler command line. -This will be appended to the end of each definition -in the &cv-CPPDEFINES; construction variable -when the &cv-_CPPDEFFLAGS; variable is automatically generated. +This will be appended to each definition +in the &cv-link-CPPDEFINES; &consvar; +when the &cv-link-_CPPDEFFLAGS; variable is automatically generated. @@ -808,13 +818,13 @@ for the variable that expands to those options. _CPPINCFLAGS -An automatically-generated construction variable +An automatically-generated &consvar; containing the C preprocessor command-line options for specifying directories to be searched for include files. The value of &cv-_CPPINCFLAGS; is created -by respectively prepending and appending &cv-INCPREFIX; and &cv-INCSUFFIX; -to the beginning and end -of each directory in &cv-CPPPATH;. +by respectively prepending and appending +&cv-link-INCPREFIX; and &cv-link-INCSUFFIX; +to each directory in &cv-link-CPPPATH;. @@ -825,13 +835,24 @@ of each directory in &cv-CPPPATH;. The list of directories that the C preprocessor will search for include directories. The C/C++ implicit dependency scanner will search these -directories for include files. Don't explicitly put include directory -arguments in CCFLAGS or CXXFLAGS because the result will be non-portable -and the directories will not be searched by the dependency scanner. Note: -directory names in CPPPATH will be looked-up relative to the SConscript -directory when they are used in a command. To force -&scons; -to look-up a directory relative to the root of the source tree use #: +directories for include files. +In general it's not advised to put include directory directives +directly into &cv-link-CCFLAGS; or &cv-link-CXXFLAGS; +as the result will be non-portable +and the directories will not be searched by the dependency scanner. +&cv-CPPPATH; should be a list of path strings, +or a single string, not a pathname list joined by +Python's os.sep. + + + +Note: +directory names in &cv-CPPPATH; +will be looked-up relative to the directory of the SConscript file +when they are used in a command. +To force &scons; +to look-up a directory relative to the root of the source tree use +the # prefix: @@ -840,7 +861,7 @@ env = Environment(CPPPATH='#/include') The directory look-up can also be forced using the -&Dir;() +&f-link-Dir; function: @@ -852,17 +873,14 @@ env = Environment(CPPPATH=include) The directory list will be added to command lines through the automatically-generated -&cv-_CPPINCFLAGS; -construction variable, +&cv-link-_CPPINCFLAGS; &consvar;, which is constructed by -respectively prepending and appending the value of the -&cv-INCPREFIX; and &cv-INCSUFFIX; -construction variables -to the beginning and end -of each directory in &cv-CPPPATH;. +respectively prepending and appending the values of the +&cv-link-INCPREFIX; and &cv-link-INCSUFFIX; &consvars; +to each directory in &cv-link-CPPPATH;. Any command lines you define that need -the CPPPATH directory list should -include &cv-_CPPINCFLAGS;: +the &cv-CPPPATH; directory list should +include &cv-link-_CPPINCFLAGS;: @@ -1052,6 +1070,7 @@ A long description of the project being packaged. This is included in the relevant section of the file that controls the packaging build. +See the &b-link-Package; builder. @@ -1066,6 +1085,7 @@ This is used to populate a section of an RPM .spec file. +See the &b-link-Package; builder. @@ -1443,7 +1463,7 @@ no lxml Python binding can be imported in the current system. The full command-line for the external executable -xsltproc (or saxon, +xsltproc (or saxon, xalan). @@ -1464,7 +1484,7 @@ an XML file via a given XSLT stylesheet. Additonal command-line flags for the external executable -xsltproc (or saxon, +xsltproc (or saxon, xalan). @@ -3016,7 +3036,7 @@ env.AppendUnique(FRAMEWORKS=Split('System Cocoa SystemConfiguration')) GS -The Ghostscript program used, e.g. to convert PostScript to PDF files. +The Ghostscript program used to, for example, convert PostScript to PDF files. @@ -3268,9 +3288,9 @@ env = Environment(IMPLICIT_COMMAND_DEPENDENCIES=False) The prefix used to specify an include directory on the C compiler command line. -This will be prepended to the beginning of each directory -in the &cv-CPPPATH; and &cv-FORTRANPATH; construction variables -when the &cv-_CPPINCFLAGS; and &cv-_FORTRANINCFLAGS; +This will be prepended to each directory +in the &cv-link-CPPPATH; and &cv-link-FORTRANPATH; &consvars; +when the &cv-link-_CPPINCFLAGS; and &cv-link-_FORTRANINCFLAGS; variables are automatically generated. @@ -3282,9 +3302,9 @@ variables are automatically generated. The suffix used to specify an include directory on the C compiler command line. -This will be appended to the end of each directory -in the &cv-CPPPATH; and &cv-FORTRANPATH; construction variables -when the &cv-_CPPINCFLAGS; and &cv-_FORTRANINCFLAGS; +This will be appended to each directory +in the &cv-link-CPPPATH; and &cv-link-FORTRANPATH; &consvars; +when the &cv-link-_CPPINCFLAGS; and &cv-link-_FORTRANINCFLAGS; variables are automatically generated. @@ -3337,7 +3357,7 @@ Install file: "$SOURCE" as "$TARGET" INTEL_C_COMPILER_VERSION -Set by the "intelc" Tool +Set by the &t-link-intelc; Tool to the major version number of the Intel C compiler selected for use. @@ -3924,9 +3944,9 @@ An automatically-generated construction variable containing the linker command-line options for specifying directories to be searched for library. The value of &cv-_LIBDIRFLAGS; is created -by respectively prepending and appending &cv-LIBDIRPREFIX; and &cv-LIBDIRSUFFIX; -to the beginning and end -of each directory in &cv-LIBPATH;. +by respectively prepending and appending &cv-link-LIBDIRPREFIX; +and &cv-link-LIBDIRSUFFIX; +to each directory in &cv-link-LIBPATH;. @@ -3936,9 +3956,9 @@ of each directory in &cv-LIBPATH;. The prefix used to specify a library directory on the linker command line. -This will be prepended to the beginning of each directory -in the &cv-LIBPATH; construction variable -when the &cv-_LIBDIRFLAGS; variable is automatically generated. +This will be prepended to each directory +in the &cv-link-LIBPATH; construction variable +when the &cv-link-_LIBDIRFLAGS; variable is automatically generated. @@ -3948,9 +3968,9 @@ when the &cv-_LIBDIRFLAGS; variable is automatically generated. The suffix used to specify a library directory on the linker command line. -This will be appended to the end of each directory -in the &cv-LIBPATH; construction variable -when the &cv-_LIBDIRFLAGS; variable is automatically generated. +This will be appended to each directory +in the &cv-link-LIBPATH; construction variable +when the &cv-link-_LIBDIRFLAGS; variable is automatically generated. @@ -3974,10 +3994,10 @@ general information on specifying emitters. An automatically-generated construction variable containing the linker command-line options for specifying libraries to be linked with the resulting target. -The value of &cv-_LIBFLAGS; is created -by respectively prepending and appending &cv-LIBLINKPREFIX; and &cv-LIBLINKSUFFIX; -to the beginning and end -of each filename in &cv-LIBS;. +The value of &cv-link-_LIBFLAGS; is created +by respectively prepending and appending &cv-link-LIBLINKPREFIX; +and &cv-link-LIBLINKSUFFIX; +to each filename in &cv-link-LIBS;. @@ -3987,9 +4007,9 @@ of each filename in &cv-LIBS;. The prefix used to specify a library to link on the linker command line. -This will be prepended to the beginning of each library -in the &cv-LIBS; construction variable -when the &cv-_LIBFLAGS; variable is automatically generated. +This will be prepended to each library +in the &cv-link-LIBS; construction variable +when the &cv-link-_LIBFLAGS; variable is automatically generated. @@ -3999,9 +4019,9 @@ when the &cv-_LIBFLAGS; variable is automatically generated. The suffix used to specify a library to link on the linker command line. -This will be appended to the end of each library -in the &cv-LIBS; construction variable -when the &cv-_LIBFLAGS; variable is automatically generated. +This will be appended to each library +in the &cv-link-LIBS; construction variable +when the &cv-link-_LIBFLAGS; variable is automatically generated. @@ -4010,16 +4030,33 @@ when the &cv-_LIBFLAGS; variable is automatically generated. LIBPATH -The list of directories that will be searched for libraries. +The list of directories that will be searched for libraries +specified by the &cv-link-LIBS; &consvar;. +&cv-LIBPATH; should be a list of path strings, +or a single string, not a pathname list joined by +Python's os.sep. + + +Do not put library search directives directly +into &cv-LINKFLAGS; or &cv-SHLINKFLAGS; +as the result will be non-portable. + + + + +Note: +directory names in &cv-LIBPATH; will be looked-up relative to the +directory of the SConscript file +when they are used in a command. +To force &scons; +to look-up a directory relative to the root of the source tree use +the # prefix: @@ -4028,8 +4065,7 @@ env = Environment(LIBPATH='#/libs') The directory look-up can also be forced using the -&Dir;() -function: +&f-link-Dir; function: @@ -4040,16 +4076,15 @@ env = Environment(LIBPATH=libs) The directory list will be added to command lines through the automatically-generated -&cv-_LIBDIRFLAGS; +&cv-link-_LIBDIRFLAGS; construction variable, which is constructed by respectively prepending and appending the values of the -&cv-LIBDIRPREFIX; and &cv-LIBDIRSUFFIX; +&cv-link-LIBDIRPREFIX; and &cv-link-LIBDIRSUFFIX; construction variables -to the beginning and end -of each directory in &cv-LIBPATH;. +to each directory in &cv-LIBPATH;. Any command lines you define that need -the LIBPATH directory list should +the &cv-LIBPATH; directory list should include &cv-_LIBDIRFLAGS;: @@ -4081,7 +4116,7 @@ A list of all legal prefixes for library file names. When searching for library dependencies, SCons will look for files with these prefixes, the base library name, -and suffixes in the &cv-LIBSUFFIXES; list. +and suffixes from the &cv-link-LIBSUFFIXES; list. @@ -4091,24 +4126,32 @@ and suffixes in the &cv-LIBSUFFIXES; list. A list of one or more libraries -that will be linked with -any executable programs -created by this environment. +that will be added to the link line +for linking with any executable program, shared library, or loadable module +created by the &consenv; or override. +String-valued library names should include +only the library base names, +without prefixes such as lib +or suffixes such as .so or .dll. The library list will be added to command lines through the automatically-generated -&cv-_LIBFLAGS; -construction variable, +&cv-_LIBFLAGS; &consvar; which is constructed by respectively prepending and appending the values of the -&cv-LIBLINKPREFIX; and &cv-LIBLINKSUFFIX; -construction variables -to the beginning and end -of each filename in &cv-LIBS;. +&cv-LIBLINKPREFIX; and &cv-LIBLINKSUFFIX; &consvars; +to each library name in &cv-LIBS;. +Library name strings should not include a +path component, instead the compiler will be +directed to look for libraries in the paths +specified by &cv-link-LIBPATH;. + + + Any command lines you define that need -the LIBS library list should +the &cv-LIBS; library list should include &cv-_LIBFLAGS;: @@ -4118,12 +4161,12 @@ env = Environment(LINKCOM="my_linker $_LIBDIRFLAGS $_LIBFLAGS -o $TARGET $SOURCE If you add a -File +File object to the &cv-LIBS; list, the name of that file will be added to &cv-_LIBFLAGS;, -and thus the link line, as is, without +and thus to the link line, as-is, without &cv-LIBLINKPREFIX; or &cv-LIBLINKSUFFIX;. @@ -4161,7 +4204,7 @@ to reflect the names of the libraries they create. A list of all legal suffixes for library file names. When searching for library dependencies, -SCons will look for files with prefixes, in the &cv-LIBPREFIXES; list, +SCons will look for files with prefixes from the &cv-link-LIBPREFIXES; list, the base library name, and these suffixes. @@ -4174,9 +4217,12 @@ and these suffixes. The abbreviated name, preferably the SPDX code, of the license under which this project is released (GPL-3.0, LGPL-2.1, BSD-2-Clause etc.). -See http://www.opensource.org/licenses/alphabetical +See + +http://www.opensource.org/licenses/alphabetical for a list of license names and SPDX codes. +See the &b-link-Package; builder. @@ -4215,6 +4261,16 @@ default file named The linker. See also &cv-link-SHLINK; for linking shared objects. + +On POSIX systems (those using the &t-link-link; tool), +you should normally not change this value as it defaults +to a "smart" linker tool which selects a compiler +driver matching the type of source files in use. +So for example, if you set &cv-link-CXX; to a specific +compiler name, and are compiling C++ sources, +the smartlink function will automatically select the same compiler +for linking. + @@ -5097,6 +5153,7 @@ on this system. Specfies the name of the project to package. +See the &b-link-Package; builder. @@ -5139,8 +5196,9 @@ The suffix used for (static) object file names. Specifies the directory where all files in resulting archive will be -placed if applicable. The default value is "$NAME-$VERSION". +placed if applicable. The default value is &cv-NAME;-&cv-VERSION;. +See the &b-link-Package; builder. @@ -5157,6 +5215,7 @@ for the builder for the currently supported types. &cv-PACKAGETYPE; may be overridden with the command line option. +See the &b-link-Package; builder. @@ -5169,6 +5228,7 @@ This is currently only used by the rpm packager and should reflect changes in the packaging, not the underlying project code itself. +See the &b-link-Package; builder. @@ -5276,15 +5336,6 @@ see the entry for that variable for specific examples. - - - PDFCOM - - -A deprecated synonym for &cv-link-DVIPDFCOM;. - - - PDFLATEX @@ -6046,7 +6097,7 @@ If this is not set, then &cv-link-RCCOM; (the command line) is displayed. RCFLAGS -The flags passed to the resource compiler by the RES builder. +The flags passed to the resource compiler by the &b-link-RES; builder. @@ -7167,6 +7218,16 @@ set. The linker for programs that use shared libraries. See also &cv-link-LINK; for linking static objects. + +On POSIX systems (those using the &t-link-link; tool), +you should normally not change this value as it defaults +to a "smart" linker tool which selects a compiler +driver matching the type of source files in use. +So for example, if you set &cv-link-SHCXX; to a specific +compiler name, and are compiling C++ sources, +the smartlink function will automatically select the same compiler +for linking. + @@ -7276,6 +7337,7 @@ This is used to fill in the Source: field in the controlling information for Ipkg and RPM packages. +See the &b-link-Package; builder. @@ -7393,6 +7455,7 @@ and as the Description: field in MSI packages. +See the &b-link-Package; builder. @@ -7759,6 +7822,35 @@ The suffix used for tar file names. + + + TEMPFILEARGESCFUNC + + +A default argument escape function is ``SCons.Subst.quote_spaces``. +If you need to apply extra operations on a command argument before +writing to a temporary file(fix Windows slashes, normalize paths, etc.), +please set `TEMPFILEARGESCFUNC` variable to a custom function. Example:: + + + +import sys +import re +from SCons.Subst import quote_spaces + +WINPATHSEP_RE = re.compile(r"\\([^\"'\\]|$)") + +def tempfile_arg_esc_func(arg): + arg = quote_spaces(arg) + if sys.platform != "win32": + return arg + # GCC requires double Windows slashes, let's use UNIX separator + return WINPATHSEP_RE.sub(r"/\1", arg) + +env["TEMPFILEARGESCFUNC"] = tempfile_arg_esc_func + + + TEMPFILEARGJOIN @@ -7931,6 +8023,7 @@ and the Manufacturer: field in the controlling information for MSI packages. +See the &b-link-Package; builder. @@ -7940,6 +8033,7 @@ field in the controlling information for MSI packages. The version of the project, specified as a string. +See the &b-link-Package; builder. @@ -7992,51 +8086,6 @@ and also before &f-link-env-Tool; is called to ininitialize any of those tools: - - - WIN32_INSERT_DEF - - -A deprecated synonym for &cv-link-WINDOWS_INSERT_DEF;. - - - - - - WIN32DEFPREFIX - - -A deprecated synonym for &cv-link-WINDOWSDEFPREFIX;. - - - - - - WIN32DEFSUFFIX - - -A deprecated synonym for &cv-link-WINDOWSDEFSUFFIX;. - - - - - - WIN32EXPPREFIX - - -A deprecated synonym for &cv-link-WINDOWSEXPSUFFIX;. - - - - - - WIN32EXPSUFFIX - - -A deprecated synonym for &cv-link-WINDOWSEXPSUFFIX;. - - - WINDOWS_EMBED_MANIFEST @@ -8164,6 +8213,7 @@ This is used to fill in the Depends: field in the controlling information for Ipkg packages. +See the &b-link-Package; builder. @@ -8175,7 +8225,7 @@ This is used to fill in the Description: field in the controlling information for Ipkg packages. The default value is -$SUMMARY\n$DESCRIPTION +&cv-SUMMARY;\n&cv-DESCRIPTION; @@ -8221,6 +8271,7 @@ This is used to fill in the Language: attribute in the controlling information for MSI packages. +See the &b-link-Package; builder. @@ -8232,6 +8283,7 @@ The text of the software license in RTF format. Carriage return characters will be replaced with the RTF equivalent \\par. +See the &b-link-Package; builder. @@ -8253,6 +8305,7 @@ This is used to fill in the field in the RPM .spec file. +See the &b-link-Package; builder. @@ -8315,7 +8368,7 @@ field in the RPM This value is used as the default attributes for the files in the RPM package. The default value is -(-,root,root). +(-,root,root). diff --git a/doc/generated/variables.mod b/doc/generated/variables.mod index 10b62e7..a3dbc0d 100644 --- a/doc/generated/variables.mod +++ b/doc/generated/variables.mod @@ -33,6 +33,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. $BIBTEXCOMSTR"> $BIBTEXFLAGS"> $BUILDERS"> +$CACHEDIR_CLASS"> $CC"> $CCCOM"> $CCCOMSTR"> @@ -360,7 +361,6 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. $PCHPDBFLAGS"> $PCHSTOP"> $PDB"> -$PDFCOM"> $PDFLATEX"> $PDFLATEXCOM"> $PDFLATEXCOMSTR"> @@ -549,6 +549,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. $TARGET_OS"> $TARGETS"> $TARSUFFIX"> +$TEMPFILEARGESCFUNC"> $TEMPFILEARGJOIN"> $TEMPFILEDIR"> $TEMPFILEPREFIX"> @@ -566,11 +567,6 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. $VENDOR"> $VERSION"> $VSWHERE"> -$WIN32_INSERT_DEF"> -$WIN32DEFPREFIX"> -$WIN32DEFSUFFIX"> -$WIN32EXPPREFIX"> -$WIN32EXPSUFFIX"> $WINDOWS_EMBED_MANIFEST"> $WINDOWS_INSERT_DEF"> $WINDOWS_INSERT_MANIFEST"> @@ -677,6 +673,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. $BIBTEXCOMSTR"> $BIBTEXFLAGS"> $BUILDERS"> +$CACHEDIR_CLASS"> $CC"> $CCCOM"> $CCCOMSTR"> @@ -1004,7 +1001,6 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. $PCHPDBFLAGS"> $PCHSTOP"> $PDB"> -$PDFCOM"> $PDFLATEX"> $PDFLATEXCOM"> $PDFLATEXCOMSTR"> @@ -1193,6 +1189,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. $TARGET_OS"> $TARGETS"> $TARSUFFIX"> +$TEMPFILEARGESCFUNC"> $TEMPFILEARGJOIN"> $TEMPFILEDIR"> $TEMPFILEPREFIX"> @@ -1210,11 +1207,6 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. $VENDOR"> $VERSION"> $VSWHERE"> -$WIN32_INSERT_DEF"> -$WIN32DEFPREFIX"> -$WIN32DEFSUFFIX"> -$WIN32EXPPREFIX"> -$WIN32EXPSUFFIX"> $WINDOWS_EMBED_MANIFEST"> $WINDOWS_INSERT_DEF"> $WINDOWS_INSERT_MANIFEST"> -- cgit v0.12 From 83b9b9dab10922224d64b84cc1d6c70429e93f3c Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 19 Apr 2021 07:51:07 -0700 Subject: [ci skip] Move info on PR 3723 to Current version section of CHANGES.txt --- CHANGES.txt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 22f73c8..d907867 100755 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -9,6 +9,10 @@ NOTE: The 4.2.0 Release of SCons will drop Python 3.5 Support RELEASE VERSION/DATE TO BE FILLED IN LATER + From Joseph Brill: + - Internal MSVS update: Remove unnecessary calls to find all installed versions of msvc + when constructing the installed visual studios list. + From William Deegan: - Improve Subst()'s logic to check for proper callable function or class's argument list. It will now allow callables with expected args, and any extra args as long as they @@ -21,7 +25,6 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER - Added --experimental flag, to enable various experimental features/tools. You can specify 'all', 'none', or any combination of available experimental features. - From David H: - Fix Issue #3906 - `IMPLICIT_COMMAND_DEPENDENCIES` was not properly disabled when set to any string value (For example ['none','false','no','off']) @@ -92,8 +95,6 @@ RELEASE 4.1.0 - Tues, 19 Jan 2021 15:04:42 -0700 is not exposed externally and update external references accordingly. - Modify the MSCommon internal-use only debug logging records to contain the correct relative file path when the debug function is called from outside the MSCommon module. - - Internal MSVS update: Remove unnecessary calls to find all installed versions of msvc - when constructing the installed visual studios list. From William Deegan: - Fix yacc tool, not respecting YACC set at time of tool initialization. -- cgit v0.12 From f5c69f68871141018bd09f7ca499ff6724946173 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Fri, 23 Apr 2021 12:22:52 -0600 Subject: Avoid exception if tool set to empty When the reproducer in issue #1742 was run on git head, it failed in a different way than in the issue: an exception "list index out of range", caused by the test setting CC="" in the Environment call(). While this is a rather unuseful thing to do in general, the resulting call to env.WhereIs should not throw an exception because the general WhereIs function ends up indexing into something that can't be indexed. Avoid this by returning None immediately if the list of names to look for is empty. Note this does _not_ fix issue 1742, it just avoids the new problem it was failing on. Signed-off-by: Mats Wichmann --- CHANGES.txt | 1 + SCons/Environment.py | 12 +++++++----- SCons/Util.py | 12 +++++++++--- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 22f73c8..4ea3c88 100755 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -75,6 +75,7 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER - Deprecate Python 3.5 as a supported version. - CPPDEFINES now expands construction variable references (issue 2363) - Restore behavior that Install()'d files are writable (issue 3927) + - Avoid WhereIs exception if user set a tool name to empty (from issue 1742) From Dillan Mills: - Add support for the (TARGET,SOURCE,TARGETS,SOURCES,CHANGED_TARGETS,CHANGED_SOURCES}.relpath property. diff --git a/SCons/Environment.py b/SCons/Environment.py index 92fd583..8a31b33 100644 --- a/SCons/Environment.py +++ b/SCons/Environment.py @@ -1877,9 +1877,10 @@ class Base(SubstitutionEnvironment): tool = SCons.Tool.Tool(tool, toolpath, **kw) tool(self) - def WhereIs(self, prog, path=None, pathext=None, reject=[]): - """Find prog in the path. - """ + def WhereIs(self, prog, path=None, pathext=None, reject=None): + """Find prog in the path. """ + if not prog: # nothing to search for, just give up + return None if path is None: try: path = self['ENV']['PATH'] @@ -1894,9 +1895,10 @@ class Base(SubstitutionEnvironment): pass elif is_String(pathext): pathext = self.subst(pathext) - prog = CLVar(self.subst(prog)) # support "program --with-args" + prog = CLVar(self.subst(prog)) # support "program --with-args" path = WhereIs(prog[0], path, pathext, reject) - if path: return path + if path: + return path return None ####################################################################### diff --git a/SCons/Util.py b/SCons/Util.py index 37107c9..af43220 100644 --- a/SCons/Util.py +++ b/SCons/Util.py @@ -745,7 +745,7 @@ else: if sys.platform == 'win32': - def WhereIs(file, path=None, pathext=None, reject=[]): + def WhereIs(file, path=None, pathext=None, reject=None): if path is None: try: path = os.environ['PATH'] @@ -764,6 +764,8 @@ if sys.platform == 'win32': if ext.lower() == file[-len(ext):].lower(): pathext = [''] break + if reject is None: + reject = [] if not is_List(reject) and not is_Tuple(reject): reject = [reject] for dir in path: @@ -780,7 +782,7 @@ if sys.platform == 'win32': elif os.name == 'os2': - def WhereIs(file, path=None, pathext=None, reject=[]): + def WhereIs(file, path=None, pathext=None, reject=None): if path is None: try: path = os.environ['PATH'] @@ -794,6 +796,8 @@ elif os.name == 'os2': if ext.lower() == file[-len(ext):].lower(): pathext = [''] break + if reject is None: + reject = [] if not is_List(reject) and not is_Tuple(reject): reject = [reject] for dir in path: @@ -810,7 +814,7 @@ elif os.name == 'os2': else: - def WhereIs(file, path=None, pathext=None, reject=[]): + def WhereIs(file, path=None, pathext=None, reject=None): import stat if path is None: try: @@ -819,6 +823,8 @@ else: return None if is_String(path): path = path.split(os.pathsep) + if reject is None: + reject = [] if not is_List(reject) and not is_Tuple(reject): reject = [reject] for d in path: -- cgit v0.12 From 143687c8b6c20684e50696d0431d972706178c63 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Fri, 23 Apr 2021 13:35:36 -0600 Subject: Add simple unit-test for env.Whereis('') Signed-off-by: Mats Wichmann --- SCons/EnvironmentTests.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SCons/EnvironmentTests.py b/SCons/EnvironmentTests.py index 4ea2c66..7155969 100644 --- a/SCons/EnvironmentTests.py +++ b/SCons/EnvironmentTests.py @@ -2583,6 +2583,8 @@ def generate(env): path = os.pathsep.join(pathdirs_1234) env = self.TestEnvironment(ENV = {'PATH' : path}) + wi = env.WhereIs('') + assert wi is None wi = env.WhereIs('xxx.exe') assert wi == test.workpath(sub3_xxx_exe), wi wi = env.WhereIs('xxx.exe', pathdirs_1243) -- cgit v0.12 From 6624c057abbd9f29cf296e4a53ef4021c9b64df4 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Mon, 19 Apr 2021 10:12:19 -0600 Subject: Tweaking of Action Objects docu, update Mkdir() Mostly it's just fiddling; did add a pointer to information on Chmod() on Windows, and that Mkdir() makes intermediate dirs and takes a list as well as a string. While resolving some doc questions, found the function used by Makedir() could be simplified by passing exist_ok=True to os.makedirs(). Signed-off-by: Mats Wichmann --- CHANGES.txt | 2 + SCons/Defaults.py | 11 +-- SCons/Environment.xml | 2 +- doc/man/scons.xml | 242 +++++++++++++++++++++++++++----------------------- 4 files changed, 133 insertions(+), 124 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index d907867..9ce5a8a 100755 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -78,6 +78,8 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER - Deprecate Python 3.5 as a supported version. - CPPDEFINES now expands construction variable references (issue 2363) - Restore behavior that Install()'d files are writable (issue 3927) + - Simplified Mkdir(), the internal mkdir_func no longer needs to handle + existing directories, it can now pass exist_ok=True to os.makedirs(). From Dillan Mills: - Add support for the (TARGET,SOURCE,TARGETS,SOURCES,CHANGED_TARGETS,CHANGED_SOURCES}.relpath property. diff --git a/SCons/Defaults.py b/SCons/Defaults.py index 6dabfb5..50c30c6 100644 --- a/SCons/Defaults.py +++ b/SCons/Defaults.py @@ -309,16 +309,7 @@ def mkdir_func(dest): if not SCons.Util.is_List(dest): dest = [dest] for entry in dest: - try: - os.makedirs(str(entry)) - except os.error as e: - p = str(entry) - if (e.args[0] == errno.EEXIST or - (sys.platform == 'win32' and e.args[0] == 183)) \ - and os.path.isdir(str(entry)): - pass # not an error if already exists - else: - raise + os.makedirs(str(entry), exist_ok=True) Mkdir = ActionFactory(mkdir_func, diff --git a/SCons/Environment.xml b/SCons/Environment.xml index 945ed9c..27e7302 100644 --- a/SCons/Environment.xml +++ b/SCons/Environment.xml @@ -258,7 +258,7 @@ a subclass of the SCons.CacheDir.CacheDir class. -(action, [cmd/str/fun, [var, ...]] [option=value, ...]) +(action, [output, [var, ...]] [key=value, ...]) diff --git a/doc/man/scons.xml b/doc/man/scons.xml index 3f7eef9..1ffc1a4 100644 --- a/doc/man/scons.xml +++ b/doc/man/scons.xml @@ -2753,14 +2753,15 @@ Builder methods take two required arguments: and source. Either can be passed as a scalar or as a list. -The target and source arguments +The target and +source arguments can be specified either as positional arguments, in which case target comes first, or as keyword arguments, using target= and source=. -Although both arguments are required, -in one particular case the target argument can actually be omitted -because it can be inferred and &SCons; supplies it (see below). +Although both arguments are nominally required, +if there is a single source and the target can be inferred +the target argument can be omitted (see below). Builder methods also take a variety of keyword arguments, described below. @@ -2830,7 +2831,8 @@ to a relative or absolute path first. -Target and source pathnames can be absolute, relative, or +target and source +can be absolute, relative, or top-relative. Relative pathnames are searched considering the directory of the SConscript file currently being processed as the "current directory". @@ -3098,9 +3100,10 @@ bar_obj_list = env.StaticObject('bar.c', CPPDEFINES='-DBAR') print("The path to bar_obj is:", str(bar_obj_list[0])) -Note again that because the Builder call returns a list, -you have to access the first element in the list -((bar_obj_list[0])) +Note that because the Builder call returns a +NodeList, +you have to access the first element in the list, +(bar_obj_list[0] in the example) to get at the Node that actually represents the object file. @@ -3162,6 +3165,19 @@ and to use just the filename portion of the targets and source. + +When trying to handle errors that may occur in a builder method, +consider that the corresponding Action is executed at a different +time than the SConscript file statement calling the builder. +It is not useful to wrap a builder call in a +try block, +since success in the builder call is not the same as +the builder itself succeeding. +If necessary, a Builder's Action should be coded to exit with +a useful exception message indicating the problem in the SConscript files - +programmatically recovering from build errors is rarely useful. + + &scons; predefines the following builder methods. Depending on the setup of a particular @@ -5785,25 +5801,25 @@ you need to create the action object using &f-Action;. The &Action; factory function returns an appropriate object for the action -represented by the type of the action argument +represented by the type of the +action argument (the first positional parmeter): -If the action argument is already an Action object, +If action is already an Action object, the object is simply returned. -If the action argument is a string, +If action is a string, a command-line Action is returned. -If such a string begins with -@, -it indicates printing of the command line is to be suppressed. -If the string begins with -- (hyphen), -it indicates the exit status from the specified command -is to be ignored, allowing execution to continue +If such a string begins with @, +the command line is not printed. +If the string begins with hyphen +(-), +the exit status from the specified command +is ignored, allowing execution to continue even if the command reports failure: @@ -5818,14 +5834,13 @@ Action('-build $TARGET $SOURCES') -If the action argument is a list, +If action is a list, then a list of Action objects is returned. An Action object is created as necessary for each element in the list. -If an element -within +If an element within the list is itself a list, -the internal list is taken as the +the embedded list is taken as the command and arguments to be executed via the command line. This allows white space to be enclosed @@ -5838,18 +5853,22 @@ Action([['cc', '-c', '-DWHITE SPACE', '-o', '$TARGET', '$SOURCES']]) -If the action argument is a Python function, -a function Action is returned. -The Python function must accept three keyword arguments: +If action is a Python callable +a Function Action is returned. +The callable must accept three keyword arguments: +target, +source and +env. + - - target - - a Node object representing the target file. - source - - a Node object representing the source file. - env - - the &consenv; used for building the target file. - + +target +is a Node object representing the target file, +source +is a Node object representing the source file and +env +is the &consenv; used for building the target file. + The @@ -5886,17 +5905,22 @@ a = Action(build_it) -If the action argument is not one of the above types, -None is returned. +If +action +is not one of the above types, +no action object is generated and &f-Action; +returns None. -As usual the environment method form &f-link-env-Action; +The environment method form &f-link-env-Action; will expand &consvars; in any argument strings, -including the action argument, at the time it is called, +including +action, +at the time it is called, using the construction variables in the &consenv; through which it was called. The global function form &f-link-Action; -delays variable expansion until +delays variable expansion until the Action object is actually used. @@ -5912,30 +5936,7 @@ The following argument types are accepted: -If the output argument is a function, -the function will be called to obtain a string -describing the action being executed. -The function -must accept these three keyword arguments: - - - source - - a Node object representing the source file. - target - - a Node object representing the target file. - env - the &consenv;. - - -The -target -and -source -arguments may be lists of Node objects if there is -more than one target file or source file. - - - -If the output argument is a string, +If output is a string, substitution is performed on the string before it is printed. The string typically contains variables, notably $TARGET(S) and $SOURCE(S), @@ -5945,7 +5946,21 @@ variable, which is optionally defined somewhere else. -If the argument is None, +If output is a function, +the function will be called to obtain a string +describing the action being executed. +The function +must accept three keyword arguments: +target, +source and +env, +with the same interpretation as for a callable +action argument above. + + + + +If outputis None, output is suppressed entirely. @@ -6022,30 +6037,25 @@ to modify the Action object's behavior: chdir -Specifies that -scons will execute the action -after changing to the specified directory. -If the -chdir -argument is -a string or a directory Node, -scons will change to the specified directory. -If the -chdir -argument -is not a string or Node -and is non-zero, -then scons will change to the +If chdir is true +(the default is False), +&SCons; will change directories before +executing the action. +If the value of chdir +is a string or a directory Node, +&SCons; will change to the specified directory. +Otherwise, if chdir evaluates true, +&SCons; will change to the target file's directory. -Note that scons will +Note that &SCons; will not automatically modify its expansion of &consvars; like &cv-TARGET; and &cv-SOURCE; when using the chdir -keyword argument--that is, +parameter - that is, the expanded file names will still be relative to the top-level directory containing the &SConstruct; file, @@ -6061,8 +6071,7 @@ to use just the filename portion of the targets and source. Example: -a = Action("build < ${SOURCE.file} > ${TARGET.file}", - chdir=1) +a = Action("build < ${SOURCE.file} > ${TARGET.file}", chdir=True) @@ -6070,11 +6079,10 @@ a = Action("build < ${SOURCE.file} > ${TARGET.file}", exitstatfunc -A function -that is passed the exit status -(or return value) -from the specified action -and can return an arbitrary +If provided, must be a callable which accepts a single parameter, +the exit status (or return value) +from the specified action, +and which returns an arbitrary or modified value. This can be used, for example, to specify that an Action object's @@ -6097,7 +6105,7 @@ a = Action("build < ${SOURCE.file} > ${TARGET.file}", batch_key -Specifies that the Action can create multiple target files +If provided, indicates that the Action can create multiple target files by processing multiple independent source files simultaneously. (The canonical example is "batch compilation" of multiple object files @@ -6134,33 +6142,33 @@ will be used to identify different for batch building. A batch_key -function must accept the following arguments: - - - action - The action object. - env - - The &consenv; configured for the target. - target - - The list of targets for a particular configured action. - source - - The list of source for a particular configured action. - +function must accept four parameters: +action, +env, +target and +source. +The first parameter, action, +is the active action object. +The second parameter, env, +is the &consenv; configured for the target. +The target and source +parameters are the lists of targets and sources +for the configured action. + The returned key should typically be a tuple of values derived from the arguments, using any appropriate logic to decide how multiple invocations should be batched. For example, a -batch_key +batch_key function may decide to return -the value of a specific construction -variable from the -env -argument +the value of a specific &consvar; +from env which will cause &scons; to batch-build targets -with matching values of that variable, +with matching values of that &consvar;, or perhaps return the Python id() of the entire &consenv;, @@ -6197,8 +6205,8 @@ a = Action('build $CHANGED_SOURCES', batch_key=batch_key) Miscellaneous Action Functions -&scons; -supplies a number of functions +&SCons; +supplies Action functions that arrange for various common file and directory manipulations to be performed. @@ -6213,8 +6221,8 @@ return an Action object that can be executed at the appropriate time. -In practice, -there are two natural ways + +There are two natural ways that these Action Functions are intended to be used. @@ -6226,7 +6234,7 @@ at the time the SConscript file is being read, you can use the &f-link-Execute; -global function to do so: +global function: Execute(Touch('file')) @@ -6284,6 +6292,12 @@ env.Command('foo.out', 'foo.in', Chmod('$TARGET', "ugo+w")]) + +The behavior of Chmod is limited on Windows, +see the notes in the Python documentation for +os.chmod, which is the underlying function. + + @@ -6346,12 +6360,14 @@ Execute(Delete('file_that_must_exist', must_exist=True)) - Mkdir(dir) + Mkdir(name) Returns an Action -that creates the specified -directory -dir. +that creates the directory +name +and all needed intermediate directories. +name may also be a list +of directories to create. Examples: -- cgit v0.12 From 721606ac024a0bedefc9929f60f5053ee6de9a51 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Mon, 26 Apr 2021 09:41:43 -0600 Subject: Further manpage tweaking of Builder and Action objects [skip travis] [skip appveypr] Signed-off-by: Mats Wichmann --- doc/man/scons.xml | 198 +++++++++++++++++++++++++++--------------------------- 1 file changed, 99 insertions(+), 99 deletions(-) diff --git a/doc/man/scons.xml b/doc/man/scons.xml index 1ffc1a4..c34e7b1 100644 --- a/doc/man/scons.xml +++ b/doc/man/scons.xml @@ -5189,21 +5189,27 @@ to a &consenv;. In general, you should only need to add a new Builder object when you want to build a new type of file or other external target. -If you just want to invoke a different compiler or other tool -to build &Program;, &Object;, &Library;, or any other -type of output file for which -&scons; -already has an existing Builder, -it is generally much easier to -use those existing Builders -in a &consenv; -that sets the appropriate &consvars; -(CC, LINK, etc.). +For output file types &scons; already knows about, +you can usually modify the behavior of premade Builders +such as &b-link-Program;, &b-link-Object; or &b-link-Library; +by changing the &consvars; they use +(&cv-link-CC;, &cv-link-LINK;, etc.). +In this manner you can, for example, change the compiler to use, +which is simpler and less error-prone than writing a new builder. +The documentation for each Builder lists which +&consvars; it uses. + Builder objects are created using the &f-link-Builder; factory function. +Once created, a builder is added to an environment +by entering it in the &cv-link-BUILDERS; dictionary +in that environment (some of the examples +in this section illustrate that). + + The &f-Builder; function accepts the following keyword arguments: @@ -5212,33 +5218,33 @@ function accepts the following keyword arguments: action -The command line string used to build the target from the source. +The command used to build the target from the source. action -can also be: +may be a string representing a template command line to execute, a list of strings representing the command -to be executed and its arguments +to execute with its arguments (suitable for enclosing white space in an argument), a dictionary mapping source file name suffixes to any combination of command line strings (if the builder should accept multiple source file extensions), -a Python function; +a Python function, an Action object -(see the next section); +(see ) or a list of any of the above. -An action function takes three arguments: - - - source - a list of source nodes;. - target - a list of target nodes;. - env - the &consenv;. - +An action function must accept three arguments: +source, +target and +env. +source is a list of source nodes; +target is a list of target nodes; +env is the &consenv; to use for context. + -The -action -and -generator + +The action +and generator arguments must not both be used for the same Builder. @@ -5247,36 +5253,30 @@ arguments must not both be used for the same Builder. prefix The prefix to prepend to the target file name. -prefix may be: - - - a string - a callable object - -a function or other callable that takes +prefix may be +a string, a function (or other callable) that takes two arguments (a &consenv; and a list of sources) -and returns a prefix - a dictionary - -specifies a mapping from a specific source suffix (of the first -source specified) to a corresponding target prefix. Both the source -suffix and target prefix specifications may use environment variable -substitution, and the target prefix (the 'value' entries in the -dictionary) may also be a callable object. The default target prefix -may be indicated by a dictionary entry with a key value of None. - - +and returns a prefix string, +or a dictionary specifying a mapping from a specific source suffix +(of the first source specified) +to a corresponding target prefix string. For the dictionary form, both the source +suffix (key) and target prefix (value) specifications may use environment variable +substitution, and the target prefix +may also be a callable object. The default target prefix +may be indicated by a dictionary entry with a key of None. b = Builder("build_it < $SOURCE > $TARGET", - prefix = "file-") + prefix="file-") def gen_prefix(env, sources): return "file-" + env['PLATFORM'] + '-' + b = Builder("build_it < $SOURCE > $TARGET", - prefix = gen_prefix) + prefix=gen_prefix) b = Builder("build_it < $SOURCE > $TARGET", - suffix = { None: "file-", - "$SRC_SFX_A": gen_prefix }) + suffix={None: "file-", "$SRC_SFX_A": gen_prefix}) @@ -5285,26 +5285,26 @@ b = Builder("build_it < $SOURCE > $TARGET", suffix The suffix to append to the target file name. -This may be specified in the same manner as the prefix above. +Specified in the same manner as for prefix above. If the suffix is a string, then &scons; -prepends a '.' to the suffix if it's not already there. -The string returned by the callable object (or obtained from the -dictionary) is untouched and you need to manually prepend a '.' -if one is desired. +prepends a '.' to the suffix if it's not already there. +The string returned by the callable object or obtained from the +dictionary is untouched and you need to manually prepend a '.' +if one is required. b = Builder("build_it < $SOURCE > $TARGET" - suffix = "-file") + suffix="-file") def gen_suffix(env, sources): return "." + env['PLATFORM'] + "-file" + b = Builder("build_it < $SOURCE > $TARGET", - suffix = gen_suffix) + suffix=gen_suffix) b = Builder("build_it < $SOURCE > $TARGET", - suffix = { None: ".sfx1", - "$SRC_SFX_A": gen_suffix }) + suffix={None: ".sfx1", "$SRC_SFX_A": gen_suffix}) @@ -5312,21 +5312,21 @@ b = Builder("build_it < $SOURCE > $TARGET", ensure_suffix -When set to any true value, causes -&scons; -to add the target suffix specified by the -suffix -keyword to any target strings -that have a different suffix. -(The default behavior is to leave untouched -any target file name that looks like it already has any suffix.) +If set to a true value, +ensures that targets will end in +suffix. +Thus, the suffix will also be added to any target strings +that have a suffix that is not already suffix. +The default behavior (also indicated by a false value) +is to leave unchanged +any target string that looks like it already has a suffix. b1 = Builder("build_it < $SOURCE > $TARGET" suffix = ".out") b2 = Builder("build_it < $SOURCE > $TARGET" suffix = ".out", - ensure_suffix) + ensure_suffix=True) env = Environment() env['BUILDERS']['B1'] = b1 env['BUILDERS']['B2'] = b2 @@ -5344,8 +5344,9 @@ env.B2('bar.txt', 'bar.in') src_suffix -The expected source file name suffix. This may be a string or a list -of strings. +The expected source file name suffix. +src_suffix +may be a string or a list of strings. @@ -5472,13 +5473,15 @@ to emitter functions. is used to select the actual emitter function from an emitter dictionary.) -An emitter function takes three arguments: - - - source - a list of source nodes. - target - a list of target nodes. - env - the &consenv;. - +A function passed as emitter +must accept three arguments: +source, +target and +env. +source is a list of source nodes, +target is a list of target nodes, +env is the &consenv; to use for context. + An emitter must return a tuple containing two lists, the list of targets to be built by this builder, @@ -5528,7 +5531,7 @@ b = Builder("my_build < $TARGET > $SOURCE", multi Specifies whether this builder is allowed to be called multiple times for -the same target file(s). The default is 0, +the same target file(s). The default is False, which means the builder can not be called multiple times for the same target file(s). Calling a builder multiple times for the same target simply adds additional source @@ -5562,18 +5565,21 @@ an Action object, or anything that can be converted into an Action object (see the next section). -The generator function takes four arguments: - - - source - A list of source nodes;. - target - A list of target nodes;. - env - the &consenv;. - for_signature - - A Boolean value that specifies - whether the generator is being called - for generating a build signature - (as opposed to actually executing the command). - +A function passed as generator +must accept four arguments: +source, +target, +env and +for_signature. +source is a list of source nodes, +target is a list of target nodes, +env is the &consenv; to use for context, +for_signature is +a Boolean value that specifies +whether the generator is being called +for generating a build signature +(as opposed to actually executing the command). + Example: @@ -5627,12 +5633,9 @@ called with a list of source files with different extensions, this check can be suppressed by setting source_ext_match to -None +False or some other non-true value. -When -source_ext_match -is disable, -&scons; +In this case, &scons; will use the suffix of the first specified source file to select the appropriate action from the action @@ -5651,7 +5654,7 @@ and b = Builder(action={'.in' : 'build $SOURCES > $TARGET'}, - source_ext_match = None) + source_ext_match=False) env = Environment(BUILDERS={'MyBuild':b}) env.MyBuild('foo.out', ['foo.in', 'foo.extra']) @@ -5779,7 +5782,7 @@ and emitter functions. The &f-link-Builder; -function will turn its +factory function will turn its action keyword argument into an appropriate internal Action object, as will @@ -5853,15 +5856,12 @@ Action([['cc', '-c', '-DWHITE SPACE', '-o', '$TARGET', '$SOURCES']]) -If action is a Python callable +If action is a callable object, a Function Action is returned. The callable must accept three keyword arguments: target, source and env. - - - target is a Node object representing the target file, source @@ -5970,8 +5970,8 @@ Instead of using a positional argument, the cmdstr keyword argument may be used to specify the output string, or the strfunction keyword argument -may be used to specify a function to return the output string, -Use cmdstr=None to suppress output. +may be used to specify a function to return the output string. +cmdstr=None suppresses output entirely. Examples: -- cgit v0.12 From 75871f612051f0b12ac54e82990aea928cec5b11 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Sun, 2 May 2021 18:51:07 -0700 Subject: Fix Issue #3933 debug output removed from SharedLibrary when SHLIBVERSION is specified. Also fixed shared library file naming, and symlink naming for applelink. Was libxyz.dylib.1.2.3 for example, is now libxyz.1.2.3.dylib --- CHANGES.txt | 5 +++++ SCons/Tool/applelink.py | 22 +++++++++++++++++++++- SCons/Tool/linkCommon/SharedLibrary.py | 6 +++++- test/LINK/SHLIBVERSIONFLAGS.py | 4 ++-- 4 files changed, 33 insertions(+), 4 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index d907867..782def8 100755 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -24,6 +24,11 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER IMPLIBNOVERSIONSYMLINKS and LDMODULENOVERSIONSYMLINKS to True. - Added --experimental flag, to enable various experimental features/tools. You can specify 'all', 'none', or any combination of available experimental features. + - Fix Issue #3933 - Remove unguarded print of debug information in SharedLibrary logic when + SHLIBVERSION is specified. + - Fix versioned shared library naming for MacOS platform. (Previously was libxyz.dylib.1.2.3, + has been fixed to libxyz.1.2.3.dylib. Additionally the sonamed symlink had the same issue, + that is now resolved as well) From David H: - Fix Issue #3906 - `IMPLICIT_COMMAND_DEPENDENCIES` was not properly disabled when diff --git a/SCons/Tool/applelink.py b/SCons/Tool/applelink.py index 2cdbd50..b81d2b3 100644 --- a/SCons/Tool/applelink.py +++ b/SCons/Tool/applelink.py @@ -36,7 +36,7 @@ selection method. # Even though the Mac is based on the GNU toolchain, it doesn't understand # the -rpath option, so we use the "link" tool instead of "gnulink". from SCons.Util import CLVar - +from SCons.Errors import UserError from . import link # User programmatically describes how SHLIBVERSION maps to values for compat/current. @@ -141,6 +141,24 @@ def _applelib_compatVersionFromSoVersion(source, target, env, for_signature): return "-Wl,-compatibility_version,%s" % version_string +def _applelib_soname(target, source, env, for_signature): + """ + Override default _soname() function from SCons.Tools.linkCommon.SharedLibrary. + Apple's file naming for versioned shared libraries puts the version string before + the shared library suffix (.dylib), instead of after. + """ + if "SONAME" in env: + # Now verify that SOVERSION is not also set as that is not allowed + if "SOVERSION" in env: + raise UserError( + "Ambiguous library .so naming, both SONAME: %s and SOVERSION: %s are defined. " + "Only one can be defined for a target library." + % (env["SONAME"], env["SOVERSION"]) + ) + return "$SONAME" + else: + return "$SHLIBPREFIX$_get_shlib_stem$_SHLIBSOVERSION${SHLIBSUFFIX}" + def generate(env): """Add Builders and construction variables for applelink to an @@ -178,6 +196,8 @@ def generate(env): env['__LDMODULEVERSIONFLAGS'] = '${__lib_either_version_flag(__env__,' \ '"LDMODULEVERSION","_APPLELINK_CURRENT_VERSION", "_LDMODULEVERSIONFLAGS")}' + env["_SHLIBSONAME"] = _applelib_soname + def exists(env): return env['PLATFORM'] == 'darwin' diff --git a/SCons/Tool/linkCommon/SharedLibrary.py b/SCons/Tool/linkCommon/SharedLibrary.py index 2a079bf..6a12dd4 100644 --- a/SCons/Tool/linkCommon/SharedLibrary.py +++ b/SCons/Tool/linkCommon/SharedLibrary.py @@ -166,8 +166,12 @@ def _get_shlib_dir(target, source, env, for_signature: bool) -> str: Returns: the directory the library will be in (empty string if '.') """ + verbose = False + if target.dir and str(target.dir) != ".": - print("target.dir:%s" % target.dir) + if verbose: + print("_get_shlib_dir: target.dir:%s" % target.dir) + return "%s/" % str(target.dir) else: return "" diff --git a/test/LINK/SHLIBVERSIONFLAGS.py b/test/LINK/SHLIBVERSIONFLAGS.py index 7832862..158e82a 100644 --- a/test/LINK/SHLIBVERSIONFLAGS.py +++ b/test/LINK/SHLIBVERSIONFLAGS.py @@ -47,9 +47,9 @@ elif 'sunlink' in tool_list: soname = 'libfoo.so.4' sonameVersionFlags = r".+ -h %s( .+)+" % soname elif 'applelink' in tool_list: - versionflags = r" 'libfoo.1.dylib'->'libfoo.1.2.3.dylib'" + versionflags = r".+ -Wl,-current_version,1.2.3( .+)+" soname = 'libfoo.4.dylib' - sonameVersionFlags = r" '%s'->'libfoo.1.2.3.dylib'(.+)+" % soname + sonameVersionFlags = r".+ -Wl,-compatibility_version,1.2.0(.+)+" else: test.skip_test('No testable linkers found, skipping the test\n') -- cgit v0.12 From 6df6df2570b2371d8508475ff427976972f889b5 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Mon, 3 May 2021 14:59:08 -0600 Subject: Some code modernizatoion Remove obsolete __getslice__ and __setslice_ definitions add Node.fs.scandir to call new (Py3.5) os.scandir Node.fs.makedirs now passes the exist_ok flag Cachedir creation now uses this fs.makedirs with exist_ok=True Signed-off-by: Mats Wichmann --- CHANGES.txt | 3 +++ SCons/CacheDir.py | 15 +++++---------- SCons/Executor.py | 4 ---- SCons/Node/FS.py | 10 ++++++---- SCons/Subst.py | 4 ---- SCons/Util.py | 6 ------ 6 files changed, 14 insertions(+), 28 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 3d29ec3..59c20ea 100755 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -81,6 +81,9 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER - Simplified Mkdir(), the internal mkdir_func no longer needs to handle existing directories, it can now pass exist_ok=True to os.makedirs(). - Avoid WhereIs exception if user set a tool name to empty (from issue 1742) + - Maintenance: remove obsolete __getslice__ definitions (Py3 never calls); + add Node.fs.scandir to call new (Py3.5) os.scandir; Node.fs.makedirs + now passes the exist_ok flag; Cachedir creation now uses this flag. From Dillan Mills: - Add support for the (TARGET,SOURCE,TARGETS,SOURCES,CHANGED_TARGETS,CHANGED_SOURCES}.relpath property. diff --git a/SCons/CacheDir.py b/SCons/CacheDir.py index 90c70e5..f021751 100644 --- a/SCons/CacheDir.py +++ b/SCons/CacheDir.py @@ -106,16 +106,11 @@ def CachePushFunc(target, source, env): tempfile = "%s.tmp%s"%(cachefile,cache_tmp_uuid) errfmt = "Unable to copy %s to cache. Cache file is %s" - if not fs.isdir(cachedir): - try: - fs.makedirs(cachedir) - except EnvironmentError: - # We may have received an exception because another process - # has beaten us creating the directory. - if not fs.isdir(cachedir): - msg = errfmt % (str(target), cachefile) - raise SCons.Errors.SConsEnvironmentError(msg) - + try: + fs.makedirs(cachedir, exist_ok=True) + except OSError: + msg = errfmt % (str(target), cachefile) + raise SCons.Errors.SConsEnvironmentError(msg) try: if fs.islink(t.get_internal_path()): fs.symlink(fs.readlink(t.get_internal_path()), tempfile) diff --git a/SCons/Executor.py b/SCons/Executor.py index 005906f..ee52151 100644 --- a/SCons/Executor.py +++ b/SCons/Executor.py @@ -63,10 +63,6 @@ class TSList(collections.UserList): def __getitem__(self, i): nl = self.func() return nl[i] - def __getslice__(self, i, j): - nl = self.func() - i, j = max(i, 0), max(j, 0) - return nl[i:j] def __str__(self): nl = self.func() return str(nl) diff --git a/SCons/Node/FS.py b/SCons/Node/FS.py index fd2f719..383a4a5 100644 --- a/SCons/Node/FS.py +++ b/SCons/Node/FS.py @@ -1140,10 +1140,12 @@ class LocalFS: return os.lstat(path) def listdir(self, path): return os.listdir(path) - def makedirs(self, path): - return os.makedirs(path) - def mkdir(self, path): - return os.mkdir(path) + def scandir(self, path): + return os.scandir(path) + def makedirs(self, path, mode=0o777, exist_ok=False): + return os.makedirs(path, mode=mode, exist_ok=exist_ok) + def mkdir(self, path, mode=0o777): + return os.mkdir(path, mode=mode) def rename(self, old, new): return os.rename(old, new) def stat(self, path): diff --git a/SCons/Subst.py b/SCons/Subst.py index f23b2d0..4d732c3 100644 --- a/SCons/Subst.py +++ b/SCons/Subst.py @@ -217,10 +217,6 @@ class Targets_or_Sources(collections.UserList): def __getitem__(self, i): nl = self.nl._create_nodelist() return nl[i] - def __getslice__(self, i, j): - nl = self.nl._create_nodelist() - i = max(i, 0); j = max(j, 0) - return nl[i:j] def __str__(self): nl = self.nl._create_nodelist() return str(nl) diff --git a/SCons/Util.py b/SCons/Util.py index af43220..4e575d5 100644 --- a/SCons/Util.py +++ b/SCons/Util.py @@ -1345,12 +1345,6 @@ class UniqueList(UserList): def __setitem__(self, i, item): UserList.__setitem__(self, i, item) self.unique = False - def __getslice__(self, i, j): - self.__make_unique() - return UserList.__getslice__(self, i, j) - def __setslice__(self, i, j, other): - UserList.__setslice__(self, i, j, other) - self.unique = False def __add__(self, other): result = UserList.__add__(self, other) result.unique = False -- cgit v0.12 From 2ea622bf4b2d5e6ffff66fabdb234720404b4d82 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Mon, 3 May 2021 16:25:20 -0600 Subject: Reformat LocalFS to quiet sider complaints Signed-off-by: Mats Wichmann --- SCons/Node/FS.py | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/SCons/Node/FS.py b/SCons/Node/FS.py index 383a4a5..909e5b6 100644 --- a/SCons/Node/FS.py +++ b/SCons/Node/FS.py @@ -1116,58 +1116,81 @@ class LocalFS: needs to use os.chdir() directly to avoid recursion. Will we really need this one? """ - #def chdir(self, path): - # return os.chdir(path) + def chmod(self, path, mode): return os.chmod(path, mode) + def copy(self, src, dst): return shutil.copy(src, dst) + def copy2(self, src, dst): return shutil.copy2(src, dst) + def exists(self, path): return os.path.exists(path) + def getmtime(self, path): return os.path.getmtime(path) + def getsize(self, path): return os.path.getsize(path) + def isdir(self, path): return os.path.isdir(path) + def isfile(self, path): return os.path.isfile(path) + def link(self, src, dst): return os.link(src, dst) + def lstat(self, path): return os.lstat(path) + def listdir(self, path): return os.listdir(path) + def scandir(self, path): return os.scandir(path) + def makedirs(self, path, mode=0o777, exist_ok=False): return os.makedirs(path, mode=mode, exist_ok=exist_ok) + def mkdir(self, path, mode=0o777): return os.mkdir(path, mode=mode) + def rename(self, old, new): return os.rename(old, new) + def stat(self, path): return os.stat(path) + def symlink(self, src, dst): return os.symlink(src, dst) + def open(self, path): return open(path) + def unlink(self, path): return os.unlink(path) if hasattr(os, 'symlink'): + def islink(self, path): return os.path.islink(path) + else: + def islink(self, path): - return 0 # no symlinks + return False # no symlinks if hasattr(os, 'readlink'): + def readlink(self, file): return os.readlink(file) + else: + def readlink(self, file): return '' -- cgit v0.12 From 147267b81c75e20cb780957bcf94a2416a0bade5 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Mon, 3 May 2021 18:25:08 -0600 Subject: Create lgtm.yml This is an attempt to configure scons for the automatically-run scans at lgtm.com. We can toss this if it doesn't work out. --- lgtm.yml | 135 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 lgtm.yml diff --git a/lgtm.yml b/lgtm.yml new file mode 100644 index 0000000..952122d --- /dev/null +++ b/lgtm.yml @@ -0,0 +1,135 @@ +########################################################################################## +# Customize file classifications. # +# Results from files under any classifier will be excluded from LGTM # +# statistics. # +########################################################################################## + +########################################################################################## +# Use the `path_classifiers` block to define changes to the default classification of # +# files. # +########################################################################################## + +path_classifiers: + docs: + - doc + - bin + test: + # Override LGTM's default classification of test files by excluding all files. + - exclude: / + # Classify all files in the top-level directories test/ and testing/ as test code. + - test + - testing + # Classify all files with suffix `.Test.py` as test code. + - "**/*.Test.py" + # and the test runner + - runtest.py + # The default behavior is to tag all files created during the + # build as `generated`. Results are hidden for generated code. You can tag + # further files as being generated by adding them to the `generated` section. + generated: + - build + # By default, all files not checked into the repository are considered to be + # 'generated'. + # The default behavior is to tag library code as `library`. Results are hidden + # for library code. You can tag further files as being library code by adding them + # to the `library` section. + library: + - exclude: path/to/libary/code/**/*.c + # The default behavior is to tag template files as `template`. Results are hidden + # for template files. You can tag further files as being template files by adding + # them to the `template` section. + template: + - template + # Define your own category, for example: 'some_custom_category'. + bench: + - bench + - timings + +######################################################################################### +# Define changes to the default code extraction process. # +# Each block configures the extraction of a single language, and modifies actions in a # +# named step. Every named step includes automatic default actions, # +# except for the 'prepare' step. The steps are performed in the following sequence: # +# prepare # +# after_prepare # +# configure (C/C++ only) # +# python_setup (Python only) # +# before_index # +# index # +########################################################################################## + +######################################################################################### +# Environment variables available to the steps: # +######################################################################################### + +# LGTM_SRC +# The root of the source tree. +# LGTM_WORKSPACE +# An existing (initially empty) folder outside the source tree. +# Used for temporary download and setup commands. + +######################################################################################### +# Use the extraction block to define changes to the default code extraction process # +# for one or more languages. The settings for each language are defined in a child # +# block, with one or more steps. # +######################################################################################### + +extraction: + javascript: + # The `prepare` step exists for customization on LGTM.com only. + # prepare: + # packages: + # - example_package + # Add an `after-prepare` step if you need to run commands after the prepare step. + # Each command should be listed on a separate line. + after_prepare: + - export PATH=$LGTM_WORKSPACE/tools:$PATH + # The `index` step extracts information from the files in the codebase. + index: + # Specify a list of files and folders to extract. + # Default: The project root directory. + include: + - src/js + # Specify a list of files and folders to exclude from extraction. + exclude: + - SCons/Tool/docbook/docbook-xsl-1.76.1 + + # Define settings for Python analysis + ###################################### + python: + # The `prepare` step exists for customization on LGTM.com only. + # prepare: + # # The `packages` section is valid for LGTM.com only. It names packages to + # # be installed. + # packages: libpng-dev + # This step is useful for Python analysis where you want to prepare the + # environment for the `python_setup` step without changing the default behavior + # for that step. + after_prepare: + - export PATH=$LGTM_WORKSPACE/tools:$PATH + # This sets up the Python interpreter and virtual environment, ready for the + # `index` step to extract the codebase. + python_setup: + # Specify packages that should NOT be installed despite being mentioned in the + # requirements.txt file. + # Default: no package marked for exclusion. + exclude_requirements: + - pywin32 + - readme-renderer + - sphinx<3.5.0 + - sphinx_rtd_theme + - lxml==4.6.3 + - rst2pdf + # Specify a list of pip packages to install. + # If any of these packages cannot be installed, the extraction will fail. + requirements: + #- Pillow + # Specify a list of requirements text files to use to set up the environment, + # or false for none. Default: any requirements.txt, test-requirements.txt, + # and similarly named files identified in the codebase are used. + requirements_files: + - required-packages.txt + # Specify a setup.py file to use to set up the environment, or false for none. + # Default: any setup.py files identified in the codebase are used in preference + # to any requirements text files. + #setup_py: new-setup.py -- cgit v0.12 From d7b1df36e2faf84c2b1789658300ceef90605997 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Wed, 5 May 2021 08:37:22 -0600 Subject: Fix some imports and other checker warnings * Removed a number of imports reported as unused. * Reorganize imports in a few places. * Checker reported warnings problems ("Instantiating an exception, but not raising it, has no effect"): serveral tool modules instantiated a warning class thinking (?) it would issue the warning; changed these to the standard use - calling the warn() function with the warnclass as an arg. * Tool modules that were touched had the copyright header munging applied. * Removed irritating "####" lines from gettext and msgfmt tools. Signed-off-by: Mats Wichmann --- CHANGES.txt | 3 ++ SCons/Action.py | 1 - SCons/Builder.py | 4 +- SCons/BuilderTests.py | 1 - SCons/Defaults.py | 1 - SCons/DefaultsTests.py | 4 -- SCons/ErrorsTests.py | 1 - SCons/Executor.py | 6 +-- SCons/Node/FSTests.py | 1 - SCons/Node/__init__.py | 20 +++------ SCons/PathListTests.py | 2 - SCons/Platform/darwin.py | 2 +- SCons/Platform/posix.py | 3 -- SCons/SConf.py | 6 ++- SCons/SConfTests.py | 2 - SCons/SConsignTests.py | 2 - SCons/Script/Main.py | 1 - SCons/Script/MainTests.py | 3 -- SCons/Script/SConscriptTests.py | 2 - SCons/Script/__init__.py | 2 +- SCons/Tool/GettextCommon.py | 92 ++++++++++++---------------------------- SCons/Tool/clang.py | 9 +--- SCons/Tool/clangxx.py | 24 ++++------- SCons/Tool/f03.py | 25 ++++------- SCons/Tool/f08.py | 25 ++++------- SCons/Tool/f77.py | 25 ++++------- SCons/Tool/f90.py | 25 ++++------- SCons/Tool/f95.py | 25 ++++------- SCons/Tool/fortran.py | 25 +++-------- SCons/Tool/gettext_tool.py | 50 ++++++++++++---------- SCons/Tool/install.py | 23 +++++----- SCons/Tool/intelc.py | 58 +++++++++++++------------ SCons/Tool/jar.py | 40 +++++++++-------- SCons/Tool/lex.py | 28 ++++++------ SCons/Tool/msgfmt.py | 42 +++++++++--------- SCons/Tool/msginit.py | 54 ++++++++++------------- SCons/Tool/msgmerge.py | 41 ++++++++---------- SCons/Tool/msvs.py | 26 +++++------- SCons/Tool/packaging/__init__.py | 17 ++++---- SCons/Tool/qt.py | 23 ++++------ SCons/Tool/swig.py | 26 ++++++------ SCons/Tool/tex.py | 27 ++++++------ SCons/Tool/xgettext.py | 43 ++++--------------- SCons/Tool/yacc.py | 27 ++++++------ SCons/cpp.py | 4 -- site_scons/site_init.py | 6 +-- 46 files changed, 348 insertions(+), 529 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index e7d555d..d7765d6 100755 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -89,6 +89,9 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER - Maintenance: remove obsolete __getslice__ definitions (Py3 never calls); add Node.fs.scandir to call new (Py3.5) os.scandir; Node.fs.makedirs now passes the exist_ok flag; Cachedir creation now uses this flag. + - Maintenance: remove unneeded imports and reorganize some. Fix uses + of warnings in some tools which instantiated the class but did nothing + with them, need to instead call SCons.Warnings.warn with the warn class. From Dillan Mills: - Add support for the (TARGET,SOURCE,TARGETS,SOURCES,CHANGED_TARGETS,CHANGED_SOURCES}.relpath property. diff --git a/SCons/Action.py b/SCons/Action.py index c5d3ea9..67eeb1d 100644 --- a/SCons/Action.py +++ b/SCons/Action.py @@ -106,7 +106,6 @@ import re import sys import subprocess from subprocess import DEVNULL -import itertools import inspect from collections import OrderedDict diff --git a/SCons/Builder.py b/SCons/Builder.py index 34bd330..38eadf8 100644 --- a/SCons/Builder.py +++ b/SCons/Builder.py @@ -103,12 +103,12 @@ from collections import UserDict, UserList import SCons.Action import SCons.Debug -from SCons.Debug import logInstanceCreation -from SCons.Errors import InternalError, UserError import SCons.Executor import SCons.Memoize import SCons.Util import SCons.Warnings +from SCons.Debug import logInstanceCreation +from SCons.Errors import InternalError, UserError class _Null: pass diff --git a/SCons/BuilderTests.py b/SCons/BuilderTests.py index 9828ef7..29b1cf0 100644 --- a/SCons/BuilderTests.py +++ b/SCons/BuilderTests.py @@ -38,7 +38,6 @@ import sys import unittest import TestCmd -import TestUnit import SCons.Action import SCons.Builder diff --git a/SCons/Defaults.py b/SCons/Defaults.py index 50c30c6..ba42a26 100644 --- a/SCons/Defaults.py +++ b/SCons/Defaults.py @@ -31,7 +31,6 @@ The code that reads the registry to find MSVC components was borrowed from distutils.msvccompiler. """ -import errno import os import shutil import stat diff --git a/SCons/DefaultsTests.py b/SCons/DefaultsTests.py index 1e1ebdd..6a7ce9c 100644 --- a/SCons/DefaultsTests.py +++ b/SCons/DefaultsTests.py @@ -21,15 +21,11 @@ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -import SCons.compat - import os import unittest import TestCmd -import SCons.Errors - from SCons.Defaults import mkdir_func class DefaultsTestCase(unittest.TestCase): diff --git a/SCons/ErrorsTests.py b/SCons/ErrorsTests.py index cc63d9b..9f2f1a2 100644 --- a/SCons/ErrorsTests.py +++ b/SCons/ErrorsTests.py @@ -21,7 +21,6 @@ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -import errno import unittest import SCons.Errors diff --git a/SCons/Executor.py b/SCons/Executor.py index ee52151..492ebe3 100644 --- a/SCons/Executor.py +++ b/SCons/Executor.py @@ -25,12 +25,12 @@ import collections -import SCons.Debug -from SCons.Debug import logInstanceCreation import SCons.Errors import SCons.Memoize import SCons.Util from SCons.compat import NoSlotsPyPy +import SCons.Debug +from SCons.Debug import logInstanceCreation class Batch: """Remembers exact association between targets @@ -270,10 +270,8 @@ class Executor(object, metaclass=NoSlotsPyPy): return self.get_lvars()[targets_string] def set_action_list(self, action): - import SCons.Util if not SCons.Util.is_List(action): if not action: - import SCons.Errors raise SCons.Errors.UserError("Executor must have an action.") action = [action] self.action_list = action diff --git a/SCons/Node/FSTests.py b/SCons/Node/FSTests.py index d2a1ebe..d78940e 100644 --- a/SCons/Node/FSTests.py +++ b/SCons/Node/FSTests.py @@ -31,7 +31,6 @@ import shutil import stat from TestCmd import TestCmd, IS_WINDOWS -import TestUnit import SCons.Errors import SCons.Node.FS diff --git a/SCons/Node/__init__.py b/SCons/Node/__init__.py index ad177a7..b55d9e7 100644 --- a/SCons/Node/__init__.py +++ b/SCons/Node/__init__.py @@ -44,17 +44,11 @@ import collections import copy from itertools import chain, zip_longest -import SCons.Debug import SCons.Executor import SCons.Memoize -import SCons.Util -from SCons.Util import hash_signature - -from SCons.Debug import Trace - from SCons.compat import NoSlotsPyPy -from SCons.Debug import logInstanceCreation, Trace -from SCons.Util import MD5signature +from SCons.Debug import track_instances, logInstanceCreation, Trace +from SCons.Util import hash_signature, is_List, UniqueList, render_tree print_duplicate = 0 @@ -1278,7 +1272,7 @@ class Node(object, metaclass=NoSlotsPyPy): self._add_child(self.depends, self.depends_set, depend) except TypeError as e: e = e.args[0] - if SCons.Util.is_List(e): + if is_List(e): s = list(map(str, e)) else: s = str(e) @@ -1287,7 +1281,7 @@ class Node(object, metaclass=NoSlotsPyPy): def add_prerequisite(self, prerequisite): """Adds prerequisites""" if self.prerequisites is None: - self.prerequisites = SCons.Util.UniqueList() + self.prerequisites = UniqueList() self.prerequisites.extend(prerequisite) self._children_reset() @@ -1297,7 +1291,7 @@ class Node(object, metaclass=NoSlotsPyPy): self._add_child(self.ignore, self.ignore_set, depend) except TypeError as e: e = e.args[0] - if SCons.Util.is_List(e): + if is_List(e): s = list(map(str, e)) else: s = str(e) @@ -1311,7 +1305,7 @@ class Node(object, metaclass=NoSlotsPyPy): self._add_child(self.sources, self.sources_set, source) except TypeError as e: e = e.args[0] - if SCons.Util.is_List(e): + if is_List(e): s = list(map(str, e)) else: s = str(e) @@ -1555,7 +1549,7 @@ class Node(object, metaclass=NoSlotsPyPy): path = None def f(node, env=env, scanner=scanner, path=path): return node.get_found_includes(env, scanner, path) - return SCons.Util.render_tree(s, f, 1) + return render_tree(s, f, 1) else: return None diff --git a/SCons/PathListTests.py b/SCons/PathListTests.py index ea7cecd..e62baad 100644 --- a/SCons/PathListTests.py +++ b/SCons/PathListTests.py @@ -23,8 +23,6 @@ import unittest -import TestUnit - import SCons.PathList diff --git a/SCons/Platform/darwin.py b/SCons/Platform/darwin.py index 68cb7df..d9d7f2d 100644 --- a/SCons/Platform/darwin.py +++ b/SCons/Platform/darwin.py @@ -44,7 +44,7 @@ def generate(env): # make sure this works on Macs with Tiger or earlier try: dirlist = os.listdir('/etc/paths.d') - except: + except FileNotFoundError: dirlist = [] for file in dirlist: diff --git a/SCons/Platform/posix.py b/SCons/Platform/posix.py index 4c9f8f9..dc98408 100644 --- a/SCons/Platform/posix.py +++ b/SCons/Platform/posix.py @@ -28,11 +28,8 @@ will usually be imported through the generic SCons.Platform.Platform() selection method. """ -import errno import subprocess -import select -import SCons.Util from SCons.Platform import TempFileMunge from SCons.Platform.virtualenv import ImportVirtualenv from SCons.Platform.virtualenv import ignore_virtualenv, enable_virtualenv diff --git a/SCons/SConf.py b/SCons/SConf.py index d024600..68e890a 100644 --- a/SCons/SConf.py +++ b/SCons/SConf.py @@ -234,8 +234,10 @@ class SConfBuildTask(SCons.Taskmaster.AlwaysTask): bi. """ if not isinstance(bi, SConfBuildInfo): - SCons.Warnings.warn(SConfWarning, - "The stored build information has an unexpected class: %s" % bi.__class__) + SCons.Warnings.warn( + SConfWarning, + "The stored build information has an unexpected class: %s" % bi.__class__ + ) else: self.display("The original builder output was:\n" + (" |" + str(bi.string)).replace("\n", "\n |")) diff --git a/SCons/SConfTests.py b/SCons/SConfTests.py index a6fe508..008dfc2 100644 --- a/SCons/SConfTests.py +++ b/SCons/SConfTests.py @@ -21,8 +21,6 @@ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -import SCons.compat - import io import os import re diff --git a/SCons/SConsignTests.py b/SCons/SConsignTests.py index fdce588..d4f4418 100644 --- a/SCons/SConsignTests.py +++ b/SCons/SConsignTests.py @@ -25,10 +25,8 @@ import os import unittest import TestCmd -import TestUnit import SCons.dblite - import SCons.SConsign class BuildInfo: diff --git a/SCons/Script/Main.py b/SCons/Script/Main.py index 15f7ece..b674692 100644 --- a/SCons/Script/Main.py +++ b/SCons/Script/Main.py @@ -44,7 +44,6 @@ import re import sys import time import traceback -import sysconfig import platform import threading diff --git a/SCons/Script/MainTests.py b/SCons/Script/MainTests.py index 232a8a2..f7e3263 100644 --- a/SCons/Script/MainTests.py +++ b/SCons/Script/MainTests.py @@ -23,9 +23,6 @@ import unittest -import SCons.Errors -import SCons.Script.Main - # Unit tests of various classes within SCons.Script.Main.py. # # Most of the tests of this functionality are actually end-to-end scripts diff --git a/SCons/Script/SConscriptTests.py b/SCons/Script/SConscriptTests.py index bb88dfa..e6a8be5 100644 --- a/SCons/Script/SConscriptTests.py +++ b/SCons/Script/SConscriptTests.py @@ -21,8 +21,6 @@ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -import SCons.Script.SConscript - # all of the SConscript.py tests are in test/SConscript.py # Local Variables: diff --git a/SCons/Script/__init__.py b/SCons/Script/__init__.py index dff1567..5f58d99 100644 --- a/SCons/Script/__init__.py +++ b/SCons/Script/__init__.py @@ -255,7 +255,7 @@ def HelpFunction(text, append=False): if help_text is None: if append: s = StringIO() - PrintHelp(s) + PrintHelp(s) help_text = s.getvalue() s.close() else: diff --git a/SCons/Tool/GettextCommon.py b/SCons/Tool/GettextCommon.py index 5da4517..16900e0 100644 --- a/SCons/Tool/GettextCommon.py +++ b/SCons/Tool/GettextCommon.py @@ -1,9 +1,6 @@ -"""SCons.Tool.GettextCommon module - -Used by several tools of `gettext` toolset. -""" - -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -24,38 +21,49 @@ Used by several tools of `gettext` toolset. # 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__" +"""Common routines for gettext tools -import SCons.Warnings +Used by several tools of `gettext` toolset. +""" + +import os import re +import SCons.Util +import SCons.Warnings -############################################################################# -class XgettextToolWarning(SCons.Warnings.SConsWarning): pass +class XgettextToolWarning(SCons.Warnings.SConsWarning): + pass -class XgettextNotFound(XgettextToolWarning): pass +class XgettextNotFound(XgettextToolWarning): + pass -class MsginitToolWarning(SCons.Warnings.SConsWarning): pass +class MsginitToolWarning(SCons.Warnings.SConsWarning): + pass -class MsginitNotFound(MsginitToolWarning): pass +class MsginitNotFound(MsginitToolWarning): + pass -class MsgmergeToolWarning(SCons.Warnings.SConsWarning): pass +class MsgmergeToolWarning(SCons.Warnings.SConsWarning): + pass -class MsgmergeNotFound(MsgmergeToolWarning): pass +class MsgmergeNotFound(MsgmergeToolWarning): + pass -class MsgfmtToolWarning(SCons.Warnings.SConsWarning): pass +class MsgfmtToolWarning(SCons.Warnings.SConsWarning): + pass -class MsgfmtNotFound(MsgfmtToolWarning): pass +class MsgfmtNotFound(MsgfmtToolWarning): + pass -############################################################################# SCons.Warnings.enableWarningClass(XgettextToolWarning) SCons.Warnings.enableWarningClass(XgettextNotFound) SCons.Warnings.enableWarningClass(MsginitToolWarning) @@ -66,9 +74,6 @@ SCons.Warnings.enableWarningClass(MsgfmtToolWarning) SCons.Warnings.enableWarningClass(MsgfmtNotFound) -############################################################################# - -############################################################################# class _POTargetFactory: """ A factory of `PO` target files. @@ -101,7 +106,6 @@ class _POTargetFactory: def _create_node(self, name, factory, directory=None, create=1): """ Create node, and set it up to factory settings. """ - import SCons.Util node = factory(name, directory, create) node.set_noclean(self.noclean) node.set_precious(self.precious) @@ -120,18 +124,12 @@ class _POTargetFactory: return self._create_node(name, self.env.fs.File, directory, create) -############################################################################# - -############################################################################# _re_comment = re.compile(r'(#[^\n\r]+)$', re.M) _re_lang = re.compile(r'([a-zA-Z0-9_]+)', re.M) -############################################################################# def _read_linguas_from_files(env, linguas_files=None): """ Parse `LINGUAS` file and return list of extracted languages """ - import SCons.Util - import SCons.Environment global _re_comment global _re_lang if not SCons.Util.is_List(linguas_files) \ @@ -151,13 +149,9 @@ def _read_linguas_from_files(env, linguas_files=None): return linguas -############################################################################# - -############################################################################# from SCons.Builder import BuilderBase -############################################################################# class _POFileBuilder(BuilderBase): """ `PO` file builder. @@ -222,7 +216,6 @@ class _POFileBuilder(BuilderBase): The arguments and return value are same as for `SCons.Builder.BuilderBase._execute()`. """ - import SCons.Util import SCons.Node linguas_files = None if 'LINGUAS_FILE' in env and env['LINGUAS_FILE']: @@ -252,12 +245,6 @@ class _POFileBuilder(BuilderBase): return SCons.Node.NodeList(result) -############################################################################# - -import SCons.Environment - - -############################################################################# def _translate(env, target=None, source=SCons.Environment._null, *args, **kw): """ Function for `Translate()` pseudo-builder """ if target is None: target = [] @@ -266,9 +253,6 @@ def _translate(env, target=None, source=SCons.Environment._null, *args, **kw): return po -############################################################################# - -############################################################################# class RPaths: """ Callable object, which returns pathnames relative to SCons current working directory. @@ -342,7 +326,6 @@ class RPaths: - Tuple of strings, which represent paths relative to current working directory (for given environment). """ - import os import SCons.Node.FS rpaths = () cwd = self.env.fs.getcwd().get_abspath() @@ -356,9 +339,6 @@ class RPaths: return rpaths -############################################################################# - -############################################################################# def _init_po_files(target, source, env): """ Action function for `POInit` builder. """ nop = lambda target, source, env: 0 @@ -383,9 +363,6 @@ def _init_po_files(target, source, env): return 0 -############################################################################# - -############################################################################# def _detect_xgettext(env): """ Detects *xgettext(1)* binary """ if 'XGETTEXT' in env: @@ -397,14 +374,10 @@ def _detect_xgettext(env): return None -############################################################################# def _xgettext_exists(env): return _detect_xgettext(env) -############################################################################# - -############################################################################# def _detect_msginit(env): """ Detects *msginit(1)* program. """ if 'MSGINIT' in env: @@ -416,14 +389,10 @@ def _detect_msginit(env): return None -############################################################################# def _msginit_exists(env): return _detect_msginit(env) -############################################################################# - -############################################################################# def _detect_msgmerge(env): """ Detects *msgmerge(1)* program. """ if 'MSGMERGE' in env: @@ -435,14 +404,10 @@ def _detect_msgmerge(env): return None -############################################################################# def _msgmerge_exists(env): return _detect_msgmerge(env) -############################################################################# - -############################################################################# def _detect_msgfmt(env): """ Detects *msgmfmt(1)* program. """ if 'MSGFMT' in env: @@ -454,16 +419,11 @@ def _detect_msgfmt(env): return None -############################################################################# def _msgfmt_exists(env): return _detect_msgfmt(env) -############################################################################# - -############################################################################# def tool_list(platform, env): """ List tools that shall be generated by top-level `gettext` tool """ return ['xgettext', 'msginit', 'msgmerge', 'msgfmt'] -############################################################################# diff --git a/SCons/Tool/clang.py b/SCons/Tool/clang.py index e033cfa..6c9227c 100644 --- a/SCons/Tool/clang.py +++ b/SCons/Tool/clang.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8; -*- -# # MIT License # # Copyright The SCons Foundation @@ -22,25 +20,20 @@ # 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. -# -"""SCons.Tool.clang -Tool-specific initialization for 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. - """ - # 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 diff --git a/SCons/Tool/clangxx.py b/SCons/Tool/clangxx.py index 736d455..4443b39 100644 --- a/SCons/Tool/clangxx.py +++ b/SCons/Tool/clangxx.py @@ -1,17 +1,6 @@ -# -*- coding: 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. - -""" - +# MIT License # -# __COPYRIGHT__ +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -31,9 +20,13 @@ selection method. # 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__" +"""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. +""" # Based on SCons/Tool/g++.py by Paweł Tomulik 2014 as a separate tool. # Brought into the SCons mainline by Russel Winder 2017. @@ -41,7 +34,6 @@ selection method. import os.path import re import subprocess -import sys import SCons.Tool import SCons.Util diff --git a/SCons/Tool/f03.py b/SCons/Tool/f03.py index 41d9c43..142c127 100644 --- a/SCons/Tool/f03.py +++ b/SCons/Tool/f03.py @@ -1,15 +1,6 @@ -"""SCons.Tool.f03 - -Tool-specific initialization for the generic Posix f03 Fortran compiler. - -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. - -""" - +# MIT License # -# __COPYRIGHT__ +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -29,14 +20,14 @@ selection method. # 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__" +"""Tool-specific initialization for the generic Posix f03 Fortran compiler. + +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. +""" -import SCons.Defaults -import SCons.Tool -import SCons.Util -from . import fortran from SCons.Tool.FortranCommon import add_all_to_env, add_f03_to_env compilers = ['f03'] diff --git a/SCons/Tool/f08.py b/SCons/Tool/f08.py index 3d1bce2..eb367c5 100644 --- a/SCons/Tool/f08.py +++ b/SCons/Tool/f08.py @@ -1,15 +1,6 @@ -"""SCons.Tool.f08 - -Tool-specific initialization for the generic Posix f08 Fortran compiler. - -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. - -""" - +# MIT License # -# __COPYRIGHT__ +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -29,14 +20,14 @@ selection method. # 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__" +"""Tool-specific initialization for the generic Posix f08 Fortran compiler. + +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. +""" -import SCons.Defaults -import SCons.Tool -import SCons.Util -from . import fortran from SCons.Tool.FortranCommon import add_all_to_env, add_f08_to_env compilers = ['f08'] diff --git a/SCons/Tool/f77.py b/SCons/Tool/f77.py index b936acd..5ff15ae 100644 --- a/SCons/Tool/f77.py +++ b/SCons/Tool/f77.py @@ -1,15 +1,6 @@ -"""SCons.Tool.f77 - -Tool-specific initialization for the generic Posix f77 Fortran compiler. - -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. - -""" - +# MIT License # -# __COPYRIGHT__ +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -29,14 +20,14 @@ selection method. # 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__" +"""Tool-specific initialization for the generic Posix f77 Fortran compiler. + +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. +""" -import SCons.Defaults -import SCons.Scanner.Fortran -import SCons.Tool -import SCons.Util from SCons.Tool.FortranCommon import add_all_to_env, add_f77_to_env compilers = ['f77'] diff --git a/SCons/Tool/f90.py b/SCons/Tool/f90.py index ef7d93d..cbf3947 100644 --- a/SCons/Tool/f90.py +++ b/SCons/Tool/f90.py @@ -1,15 +1,6 @@ -"""SCons.Tool.f90 - -Tool-specific initialization for the generic Posix f90 Fortran compiler. - -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. - -""" - +# MIT License # -# __COPYRIGHT__ +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -29,14 +20,14 @@ selection method. # 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__" +"""Tool-specific initialization for the generic Posix f90 Fortran compiler. + +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. +""" -import SCons.Defaults -import SCons.Scanner.Fortran -import SCons.Tool -import SCons.Util from SCons.Tool.FortranCommon import add_all_to_env, add_f90_to_env compilers = ['f90'] diff --git a/SCons/Tool/f95.py b/SCons/Tool/f95.py index 7b56d4e..4830ee0 100644 --- a/SCons/Tool/f95.py +++ b/SCons/Tool/f95.py @@ -1,15 +1,6 @@ -"""SCons.Tool.f95 - -Tool-specific initialization for the generic Posix f95 Fortran compiler. - -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. - -""" - +# MIT License # -# __COPYRIGHT__ +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -29,14 +20,14 @@ selection method. # 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__" +"""Tool-specific initialization for the generic Posix f95 Fortran compiler. + +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. +""" -import SCons.Defaults -import SCons.Tool -import SCons.Util -from . import fortran from SCons.Tool.FortranCommon import add_all_to_env, add_f95_to_env compilers = ['f95'] diff --git a/SCons/Tool/fortran.py b/SCons/Tool/fortran.py index 0a68df6..9a095ae 100644 --- a/SCons/Tool/fortran.py +++ b/SCons/Tool/fortran.py @@ -1,15 +1,6 @@ -"""SCons.Tool.fortran - -Tool-specific initialization for a generic Posix f77/f90 Fortran compiler. - -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. - -""" - +# MIT License # -# __COPYRIGHT__ +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -29,16 +20,14 @@ selection method. # 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__" +"""Tool-specific initialization for a generic Posix f77/f90 Fortran compiler. +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. +""" -import SCons.Action -import SCons.Defaults -import SCons.Scanner.Fortran -import SCons.Tool -import SCons.Util from SCons.Tool.FortranCommon import add_all_to_env, add_fortran_to_env compilers = ['f95', 'f90', 'f77'] diff --git a/SCons/Tool/gettext_tool.py b/SCons/Tool/gettext_tool.py index 43ca494..8e66a56 100644 --- a/SCons/Tool/gettext_tool.py +++ b/SCons/Tool/gettext_tool.py @@ -1,9 +1,7 @@ -"""gettext tool -""" - - -# __COPYRIGHT__ -# +# MIT License +# +# Copyright The SCons Foundation +# # 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 @@ -11,10 +9,10 @@ # 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 @@ -23,13 +21,13 @@ # 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__" +"""gettext tool""" -############################################################################# def generate(env,**kw): import sys import os import SCons.Tool + import SCons.Warnings from SCons.Platform.mingw import MINGW_DEFAULT_PATHS from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS @@ -42,19 +40,27 @@ def generate(env,**kw): tool_bin_dir = os.path.dirname(tool) env.AppendENVPath('PATH', tool_bin_dir) else: - SCons.Warnings.SConsWarning(t + ' tool requested, but binary not found in ENV PATH') + SCons.Warnings.warn( + SCons.Warnings.SConsWarning, + t + ' tool requested, but binary not found in ENV PATH' + ) env.Tool(t) env.AddMethod(_translate, 'Translate') -############################################################################# -############################################################################# def exists(env): - from SCons.Tool.GettextCommon \ - import _xgettext_exists, _msginit_exists, \ - _msgmerge_exists, _msgfmt_exists - try: - return _xgettext_exists(env) and _msginit_exists(env) \ - and _msgmerge_exists(env) and _msgfmt_exists(env) - except: - return False -############################################################################# + from SCons.Tool.GettextCommon import ( + _xgettext_exists, + _msginit_exists, + _msgmerge_exists, + _msgfmt_exists, + ) + + try: + return ( + _xgettext_exists(env) + and _msginit_exists(env) + and _msgmerge_exists(env) + and _msgfmt_exists(env) + ) + except: + return False diff --git a/SCons/Tool/install.py b/SCons/Tool/install.py index 9910264..59b4a52 100644 --- a/SCons/Tool/install.py +++ b/SCons/Tool/install.py @@ -1,14 +1,6 @@ -"""SCons.Tool.install - -Tool-specific initialization for the install tool. - -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. -""" - +# MIT License # -# __COPYRIGHT__ +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -28,11 +20,17 @@ selection method. # 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. -# + +""" Tool-specific initialization for the install tool. + +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. +""" import os import stat -from shutil import copy2, copymode, copystat +from shutil import copy2, copystat import SCons.Action import SCons.Tool @@ -44,7 +42,6 @@ from SCons.Tool.linkCommon import ( EmitLibSymlinks, ) -# # We keep track of *all* installed files. _INSTALLED_FILES = [] _UNIQUE_INSTALLED_FILES = None diff --git a/SCons/Tool/intelc.py b/SCons/Tool/intelc.py index 5025719..50011b1 100644 --- a/SCons/Tool/intelc.py +++ b/SCons/Tool/intelc.py @@ -1,16 +1,6 @@ -"""SCons.Tool.icl - -Tool-specific initialization for the Intel C/C++ compiler. -Supports Linux and Windows compilers, v7 and up. - -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. - -""" - +# MIT License # -# __COPYRIGHT__ +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -30,7 +20,15 @@ selection method. # 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__" + +"""Tool-specific initialization for the Intel C/C++ compiler. + +Supports Linux and Windows compilers, v7 and up. + +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. +""" import glob import math @@ -454,20 +452,25 @@ def generate(env, version=None, abi=None, topdir=None, verbose=0): # on $PATH and the user is importing their env. class ICLTopDirWarning(SCons.Warnings.SConsWarning): pass - if (is_mac or is_linux) and not env.Detect('icc') or \ - is_windows and not env.Detect('icl'): + + if (is_mac or is_linux) and not env.Detect('icc') \ + or is_windows and not env.Detect('icl'): SCons.Warnings.enableWarningClass(ICLTopDirWarning) - SCons.Warnings.warn(ICLTopDirWarning, - "Failed to find Intel compiler for version='%s', abi='%s'"% - (str(version), str(abi))) + SCons.Warnings.warn( + ICLTopDirWarning, + "Failed to find Intel compiler for version='%s', abi='%s'" + % (str(version), str(abi)), + ) else: # should be cleaned up to say what this other version is # since in this case we have some other Intel compiler installed SCons.Warnings.enableWarningClass(ICLTopDirWarning) - SCons.Warnings.warn(ICLTopDirWarning, - "Can't find Intel compiler top dir for version='%s', abi='%s'"% - (str(version), str(abi))) + SCons.Warnings.warn( + ICLTopDirWarning, + "Can't find Intel compiler top dir for version='%s', abi='%s'" + % (str(version), str(abi)), + ) if topdir: archdir={'x86_64': 'intel64', @@ -576,11 +579,14 @@ def generate(env, version=None, abi=None, topdir=None, verbose=0): class ICLLicenseDirWarning(SCons.Warnings.SConsWarning): pass SCons.Warnings.enableWarningClass(ICLLicenseDirWarning) - SCons.Warnings.warn(ICLLicenseDirWarning, - "Intel license dir was not found." - " Tried using the INTEL_LICENSE_FILE environment variable (%s), the registry (%s) and the default path (%s)." - " Using the default path as a last resort." - % (envlicdir, reglicdir, defaultlicdir)) + SCons.Warnings.warn( + ICLLicenseDirWarning, + "Intel license dir was not found. " + "Tried using the INTEL_LICENSE_FILE environment variable " + "(%s), the registry (%s) and the default path (%s). " + "Using the default path as a last resort." + % (envlicdir, reglicdir, defaultlicdir) + ) env['ENV']['INTEL_LICENSE_FILE'] = licdir def exists(env): diff --git a/SCons/Tool/jar.py b/SCons/Tool/jar.py index fa29987..a19c40a 100644 --- a/SCons/Tool/jar.py +++ b/SCons/Tool/jar.py @@ -1,15 +1,6 @@ -"""SCons.Tool.jar - -Tool-specific initialization for jar. - -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. - -""" - +# MIT License # -# __COPYRIGHT__ +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -29,13 +20,19 @@ selection method. # 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__" +"""Tool-specific initialization for jar. + +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. +""" + import os import SCons.Subst import SCons.Util +import SCons.Warnings from SCons.Node.FS import _my_normcase from SCons.Tool.JavaCommon import get_java_install_dirs @@ -101,8 +98,10 @@ def Jar(env, target = None, source = [], *args, **kw): # no target and want implicit target to be made and the arg # was actaully the list of sources if SCons.Util.is_List(target) and source == []: - SCons.Warnings.SConsWarning("Making implicit target jar file, " + - "and treating the list as sources") + SCons.Warnings.warn( + SCons.Warnings.SConsWarning, + "Making implicit target jar file, and treating the list as sources" + ) source = target target = None @@ -123,7 +122,10 @@ def Jar(env, target = None, source = [], *args, **kw): target = os.path.splitext(str(source[0]))[0] + env.subst('$JARSUFFIX') except: # something strange is happening but attempt anyways - SCons.Warnings.SConsWarning("Could not make implicit target from sources, using directory") + SCons.Warnings.warn( + SCons.Warnings.SConsWarning, + "Could not make implicit target from sources, using directory" + ) target = os.path.basename(str(env.Dir('.'))) + env.subst('$JARSUFFIX') # make lists out of our target and sources @@ -192,7 +194,11 @@ def Jar(env, target = None, source = [], *args, **kw): except: pass - SCons.Warnings.SConsWarning("File: " + str(s) + " could not be identified as File or Directory, skipping.") + SCons.Warnings.warn( + SCons.Warnings.SConsWarning, + ("File: " + str(s) + + " could not be identified as File or Directory, skipping.") + ) # at this point all our sources have been converted to classes or directories of class # so pass it to the Jar builder diff --git a/SCons/Tool/lex.py b/SCons/Tool/lex.py index a9f7a8a..d8d8de4 100644 --- a/SCons/Tool/lex.py +++ b/SCons/Tool/lex.py @@ -1,15 +1,6 @@ -"""SCons.Tool.lex - -Tool-specific initialization for lex. - -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. - -""" - +# MIT License # -# __COPYRIGHT__ +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -29,9 +20,13 @@ selection method. # 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__" +"""Tool-specific initialization for lex. + +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. +""" import os.path import sys @@ -39,6 +34,7 @@ import sys import SCons.Action import SCons.Tool import SCons.Util +import SCons.Warnings from SCons.Platform.mingw import MINGW_DEFAULT_PATHS from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS from SCons.Platform.win32 import CHOCO_DEFAULT_PATH @@ -93,7 +89,11 @@ def get_lex_path(env, append_paths=False): if append_paths: env.AppendENVPath('PATH', os.path.dirname(bin_path)) return bin_path - SCons.Warnings.SConsWarning('lex tool requested, but lex or flex binary not found in ENV PATH') + + SCons.Warnings.warn( + SCons.Warnings.SConsWarning, + 'lex tool requested, but lex or flex binary not found in ENV PATH' + ) def generate(env): diff --git a/SCons/Tool/msgfmt.py b/SCons/Tool/msgfmt.py index 3a77fc6..873e66b 100644 --- a/SCons/Tool/msgfmt.py +++ b/SCons/Tool/msgfmt.py @@ -1,7 +1,7 @@ -""" msgfmt tool """ - -# __COPYRIGHT__ -# +# MIT License +# +# Copyright The SCons Foundation +# # 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 @@ -9,10 +9,10 @@ # 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 @@ -21,14 +21,14 @@ # 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__" +""" msgfmt tool """ from SCons.Builder import BuilderBase -############################################################################# + class _MOFileBuilder(BuilderBase): """ The builder class for `MO` files. - - The reason for this builder to exists and its purpose is quite simillar + + The reason for this builder to exists and its purpose is quite simillar as for `_POFileBuilder`. This time, we extend list of sources, not targets, and call `BuilderBase._execute()` only once (as we assume single-target here). @@ -43,7 +43,7 @@ class _MOFileBuilder(BuilderBase): linguas_files = None if 'LINGUAS_FILE' in env and env['LINGUAS_FILE'] is not None: linguas_files = env['LINGUAS_FILE'] - # This should prevent from endless recursion. + # This should prevent from endless recursion. env['LINGUAS_FILE'] = None # We read only languages. Suffixes shall be added automatically. linguas = _read_linguas_from_files(env, linguas_files) @@ -57,9 +57,8 @@ class _MOFileBuilder(BuilderBase): if linguas_files is not None: env['LINGUAS_FILE'] = linguas_files return result -############################################################################# -############################################################################# + def _create_mo_file_builder(env, **kw): """ Create builder object for `MOFiles` builder """ import SCons.Action @@ -68,17 +67,17 @@ def _create_mo_file_builder(env, **kw): kw['suffix'] = '$MOSUFFIX' kw['src_suffix'] = '$POSUFFIX' kw['src_builder'] = '_POUpdateBuilder' - kw['single_source'] = True + kw['single_source'] = True return _MOFileBuilder(**kw) -############################################################################# -############################################################################# + def generate(env,**kw): """ Generate `msgfmt` tool """ import sys import os - import SCons.Util import SCons.Tool + import SCons.Util + import SCons.Warnings from SCons.Tool.GettextCommon import _detect_msgfmt from SCons.Platform.mingw import MINGW_DEFAULT_PATHS from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS @@ -89,7 +88,10 @@ def generate(env,**kw): msgfmt_bin_dir = os.path.dirname(msgfmt) env.AppendENVPath('PATH', msgfmt_bin_dir) else: - SCons.Warnings.SConsWarning('msgfmt tool requested, but binary not found in ENV PATH') + SCons.Warnings.warn( + SCons.Warnings.SConsWarning, + 'msgfmt tool requested, but binary not found in ENV PATH' + ) try: env['MSGFMT'] = _detect_msgfmt(env) @@ -103,9 +105,8 @@ def generate(env,**kw): POSUFFIX = ['.po'] ) env.Append( BUILDERS = { 'MOFiles' : _create_mo_file_builder(env) } ) -############################################################################# -############################################################################# + def exists(env): """ Check if the tool exists """ from SCons.Tool.GettextCommon import _msgfmt_exists @@ -113,7 +114,6 @@ def exists(env): return _msgfmt_exists(env) except: return False -############################################################################# # Local Variables: # tab-width:4 diff --git a/SCons/Tool/msginit.py b/SCons/Tool/msginit.py index 4b72c30..b099686 100644 --- a/SCons/Tool/msginit.py +++ b/SCons/Tool/msginit.py @@ -1,10 +1,7 @@ -""" msginit tool - -Tool specific initialization of msginit tool. -""" - -# __COPYRIGHT__ -# +# MIT License +# +# Copyright The SCons Foundation +# # 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 @@ -12,10 +9,10 @@ Tool specific initialization of msginit tool. # 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 @@ -24,16 +21,16 @@ Tool specific initialization of msginit tool. # 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__" +"""Tool specific initialization of msginit tool.""" +import SCons.Action +import SCons.Util import SCons.Warnings -import SCons.Builder +from SCons.Environment import _null -############################################################################# def _optional_no_translator_flag(env): """ Return '--no-translator' flag if we run *msginit(1)* in non-interactive mode.""" - import SCons.Util if 'POAUTOINIT' in env: autoinit = env['POAUTOINIT'] else: @@ -42,25 +39,20 @@ def _optional_no_translator_flag(env): return [SCons.Util.CLVar('--no-translator')] else: return [SCons.Util.CLVar('')] -############################################################################# -############################################################################# + def _POInitBuilder(env, **kw): """ Create builder object for `POInit` builder. """ - import SCons.Action from SCons.Tool.GettextCommon import _init_po_files, _POFileBuilder action = SCons.Action.Action(_init_po_files, None) return _POFileBuilder(env, action=action, target_alias='$POCREATE_ALIAS') -############################################################################# - -############################################################################# -from SCons.Environment import _null -############################################################################# + + def _POInitBuilderWrapper(env, target=None, source=_null, **kw): """ Wrapper for _POFileBuilder. We use it to make user's life easier. - + This wrapper checks for `$POTDOMAIN` construction variable (or override in - `**kw`) and treats it appropriatelly. + `**kw`) and treats it appropriatelly. """ if source is _null: if 'POTDOMAIN' in kw: @@ -69,17 +61,16 @@ def _POInitBuilderWrapper(env, target=None, source=_null, **kw): domain = env['POTDOMAIN'] else: domain = 'messages' - source = [ domain ] # NOTE: Suffix shall be appended automatically + source = [ domain ] # NOTE: Suffix shall be appended automatically return env._POInitBuilder(target, source, **kw) -############################################################################# -############################################################################# + def generate(env,**kw): """ Generate the `msginit` tool """ import sys import os - import SCons.Util import SCons.Tool + import SCons.Warnings from SCons.Tool.GettextCommon import _detect_msginit from SCons.Platform.mingw import MINGW_DEFAULT_PATHS from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS @@ -90,7 +81,10 @@ def generate(env,**kw): msginit_bin_dir = os.path.dirname(msginit) env.AppendENVPath('PATH', msginit_bin_dir) else: - SCons.Warnings.SConsWarning('msginit tool requested, but binary not found in ENV PATH') + SCons.Warnings.warn( + SCons.Warnings.SConsWarning, + 'msginit tool requested, but binary not found in ENV PATH' + ) try: env['MSGINIT'] = _detect_msginit(env) @@ -114,9 +108,8 @@ def generate(env,**kw): env.Append( BUILDERS = { '_POInitBuilder' : _POInitBuilder(env) } ) env.AddMethod(_POInitBuilderWrapper, 'POInit') env.AlwaysBuild(env.Alias('$POCREATE_ALIAS')) -############################################################################# -############################################################################# + def exists(env): """ Check if the tool exists """ from SCons.Tool.GettextCommon import _msginit_exists @@ -124,7 +117,6 @@ def exists(env): return _msginit_exists(env) except: return False -############################################################################# # Local Variables: # tab-width:4 diff --git a/SCons/Tool/msgmerge.py b/SCons/Tool/msgmerge.py index 4551235..f30b27d 100644 --- a/SCons/Tool/msgmerge.py +++ b/SCons/Tool/msgmerge.py @@ -1,10 +1,7 @@ -""" msgmerget tool - -Tool specific initialization for `msgmerge` tool. -""" - -# __COPYRIGHT__ -# +# MIT License +# +# Copyright The SCons Foundation +# # 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 @@ -12,10 +9,10 @@ Tool specific initialization for `msgmerge` tool. # 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 @@ -24,9 +21,8 @@ Tool specific initialization for `msgmerge` tool. # 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__" +"""Tool specific initialization for `msgmerge` tool.""" -############################################################################# def _update_or_init_po_files(target, source, env): """ Action function for `POUpdate` builder """ import SCons.Action @@ -39,20 +35,18 @@ def _update_or_init_po_files(target, source, env): status = action([tgt], source, env) if status : return status return 0 -############################################################################# -############################################################################# + def _POUpdateBuilder(env, **kw): """ Create an object of `POUpdate` builder """ import SCons.Action from SCons.Tool.GettextCommon import _POFileBuilder action = SCons.Action.Action(_update_or_init_po_files, None) return _POFileBuilder(env, action=action, target_alias='$POUPDATE_ALIAS') -############################################################################# -############################################################################# + from SCons.Environment import _null -############################################################################# + def _POUpdateBuilderWrapper(env, target=None, source=_null, **kw): """ Wrapper for `POUpdate` builder - make user's life easier """ if source is _null: @@ -62,16 +56,16 @@ def _POUpdateBuilderWrapper(env, target=None, source=_null, **kw): domain = env['POTDOMAIN'] else: domain = 'messages' - source = [ domain ] # NOTE: Suffix shall be appended automatically + source = [ domain ] # NOTE: Suffix shall be appended automatically return env._POUpdateBuilder(target, source, **kw) -############################################################################# -############################################################################# + def generate(env,**kw): """ Generate the `msgmerge` tool """ import sys import os import SCons.Tool + import SCons.Warnings from SCons.Tool.GettextCommon import _detect_msgmerge from SCons.Platform.mingw import MINGW_DEFAULT_PATHS from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS @@ -82,7 +76,10 @@ def generate(env,**kw): msgmerge_bin_dir = os.path.dirname(msgmerge) env.AppendENVPath('PATH', msgmerge_bin_dir) else: - SCons.Warnings.SConsWarning('msgmerge tool requested, but binary not found in ENV PATH') + SCons.Warnings.warn( + SCons.Warnings.SConsWarning, + 'msgmerge tool requested, but binary not found in ENV PATH' + ) try: env['MSGMERGE'] = _detect_msgmerge(env) except: @@ -98,9 +95,8 @@ def generate(env,**kw): env.Append(BUILDERS = { '_POUpdateBuilder':_POUpdateBuilder(env) }) env.AddMethod(_POUpdateBuilderWrapper, 'POUpdate') env.AlwaysBuild(env.Alias('$POUPDATE_ALIAS')) -############################################################################# -############################################################################# + def exists(env): """ Check if the tool exists """ from SCons.Tool.GettextCommon import _msgmerge_exists @@ -108,7 +104,6 @@ def exists(env): return _msgmerge_exists(env) except: return False -############################################################################# # Local Variables: # tab-width:4 diff --git a/SCons/Tool/msvs.py b/SCons/Tool/msvs.py index c398365..9fdee65 100644 --- a/SCons/Tool/msvs.py +++ b/SCons/Tool/msvs.py @@ -1,15 +1,6 @@ -"""SCons.Tool.msvs - -Tool-specific initialization for Microsoft Visual Studio project files. - -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. - -""" - +# MIT License # -# __COPYRIGHT__ +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -29,9 +20,13 @@ selection method. # 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 SCons.compat +""" Tool-specific initialization for Microsoft Visual Studio project files. + +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. +""" import base64 import uuid @@ -48,10 +43,9 @@ import SCons.Script.SConscript import SCons.PathList import SCons.Util import SCons.Warnings - -from .MSCommon import msvc_exists, msvc_setup_env_once from SCons.Defaults import processDefines from SCons.compat import PICKLE_PROTOCOL +from .MSCommon import msvc_exists, msvc_setup_env_once ############################################################################## # Below here are the classes and functions for generation of @@ -782,7 +776,7 @@ class _GenerateV6DSP(_DSPGenerator): data = pickle.loads(datas) except KeyboardInterrupt: raise - except: + except Exception: return # unable to unpickle any data for some reason self.configs.update(data) diff --git a/SCons/Tool/packaging/__init__.py b/SCons/Tool/packaging/__init__.py index c378909..68cedeb 100644 --- a/SCons/Tool/packaging/__init__.py +++ b/SCons/Tool/packaging/__init__.py @@ -1,5 +1,6 @@ +# MIT License # -# __COPYRIGHT__ +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,12 +21,7 @@ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -"""SCons.Tool.Packaging - -SCons Packaging Tool. -""" - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" +"""SCons Packaging Tool.""" import importlib from inspect import getfullargspec @@ -306,8 +302,11 @@ def stripinstallbuilder(target, source, env): and file.builder.name in ["InstallBuilder", "InstallAsBuilder"]) if len([src for src in source if has_no_install_location(src)]): - warn(SConsWarning, "there are files to package which have no\ - InstallBuilder attached, this might lead to irreproducible packages") + warn( + SConsWarning, + "there are files to package which have no InstallBuilder " + "attached, this might lead to irreproducible packages" + ) n_source = [] for s in source: diff --git a/SCons/Tool/qt.py b/SCons/Tool/qt.py index d8a51b2..2fd7294 100644 --- a/SCons/Tool/qt.py +++ b/SCons/Tool/qt.py @@ -1,16 +1,6 @@ - -"""SCons.Tool.qt - -Tool-specific initialization for Qt. - -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. - -""" - +# MIT License # -# __COPYRIGHT__ +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -30,8 +20,13 @@ selection method. # 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__" + +"""Tool-specific initialization for Qt. + +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. +""" import os.path import re diff --git a/SCons/Tool/swig.py b/SCons/Tool/swig.py index 48d65d4..fa9d93b 100644 --- a/SCons/Tool/swig.py +++ b/SCons/Tool/swig.py @@ -1,14 +1,6 @@ -"""SCons.Tool.swig - -Tool-specific initialization for swig. - -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. - -""" +# MIT License # -# __COPYRIGHT__ +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -28,9 +20,13 @@ selection method. # 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__" +"""Tool-specific initialization for swig. + +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. +""" import os.path import sys @@ -42,6 +38,7 @@ import SCons.Defaults import SCons.Tool import SCons.Util import SCons.Node +import SCons.Warnings verbose = False @@ -190,7 +187,10 @@ def generate(env): swig_bin_dir = os.path.dirname(swig) env.AppendENVPath('PATH', swig_bin_dir) else: - SCons.Warnings.SConsWarning('swig tool requested, but binary not found in ENV PATH') + SCons.Warnings.warn( + SCons.Warnings.SConsWarning, + 'swig tool requested, but binary not found in ENV PATH' + ) if 'SWIG' not in env: env['SWIG'] = env.Detect(swigs) or swigs[0] diff --git a/SCons/Tool/tex.py b/SCons/Tool/tex.py index 0ca7e2d..3a133b8 100644 --- a/SCons/Tool/tex.py +++ b/SCons/Tool/tex.py @@ -1,16 +1,6 @@ -"""SCons.Tool.tex - -Tool-specific initialization for TeX. -Generates .dvi files from .tex files - -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. - -""" - +# MIT License # -# __COPYRIGHT__ +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -30,8 +20,15 @@ selection method. # 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__" + +""" Tool-specific initialization for TeX. + +Generates .dvi files from .tex files + +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. +""" import os.path import re @@ -867,7 +864,7 @@ def generate_darwin(env): if platform.system() == 'Darwin': try: ospath = env['ENV']['PATHOSX'] - except: + except KeyError: ospath = None if ospath: env.AppendENVPath('PATH', ospath) diff --git a/SCons/Tool/xgettext.py b/SCons/Tool/xgettext.py index ae40555..2fbebf3 100644 --- a/SCons/Tool/xgettext.py +++ b/SCons/Tool/xgettext.py @@ -1,9 +1,6 @@ -""" xgettext tool - -Tool specific initialization of `xgettext` tool. -""" - -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -24,7 +21,7 @@ Tool specific initialization of `xgettext` tool. # 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__" +"""Tool specific initialization of `xgettext` tool.""" import os import re @@ -35,6 +32,7 @@ import SCons.Action import SCons.Node.FS import SCons.Tool import SCons.Util +import SCons.Warnings from SCons.Builder import BuilderBase from SCons.Environment import _null from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS @@ -44,7 +42,6 @@ from SCons.Tool.GettextCommon import RPaths, _detect_xgettext from SCons.Tool.GettextCommon import _xgettext_exists -############################################################################# class _CmdRunner: """ Callable object, which runs shell command storing its stdout and stderr to variables. It also provides `strfunction()` method, which shall be used by @@ -81,9 +78,6 @@ class _CmdRunner: return s -############################################################################# - -############################################################################# def _update_pot_file(target, source, env): """ Action function for `POTUpdate` builder """ nop = lambda target, source, env: 0 @@ -160,9 +154,6 @@ def _update_pot_file(target, source, env): return 0 -############################################################################# - -############################################################################# class _POTBuilder(BuilderBase): def _execute(self, env, target, source, *args): if not target: @@ -174,9 +165,6 @@ class _POTBuilder(BuilderBase): return BuilderBase._execute(self, env, target, source, *args) -############################################################################# - -############################################################################# def _scan_xgettext_from_files(target, source, env, files=None, path=None): """ Parses `POTFILES.in`-like file and returns list of extracted file names. """ @@ -226,9 +214,6 @@ def _scan_xgettext_from_files(target, source, env, files=None, path=None): return 0 -############################################################################# - -############################################################################# def _pot_update_emitter(target, source, env): """ Emitter function for `POTUpdate` builder """ if 'XGETTEXTFROM' in env: @@ -255,16 +240,10 @@ def _pot_update_emitter(target, source, env): return target, source -############################################################################# - -############################################################################# def _POTUpdateBuilderWrapper(env, target=None, source=_null, **kw): return env._POTUpdateBuilder(target, source, **kw) -############################################################################# - -############################################################################# def _POTUpdateBuilder(env, **kw): """ Creates `POTUpdate` builder object """ kw['action'] = SCons.Action.Action(_update_pot_file, None) @@ -274,9 +253,6 @@ def _POTUpdateBuilder(env, **kw): return _POTBuilder(**kw) -############################################################################# - -############################################################################# def generate(env, **kw): """ Generate `xgettext` tool """ @@ -286,7 +262,10 @@ def generate(env, **kw): xgettext_bin_dir = os.path.dirname(xgettext) env.AppendENVPath('PATH', xgettext_bin_dir) else: - SCons.Warnings.SConsWarning('xgettext tool requested, but binary not found in ENV PATH') + SCons.Warnings.warn( + SCons.Warnings.SConsWarning, + 'xgettext tool requested, but binary not found in ENV PATH' + ) try: env['XGETTEXT'] = _detect_xgettext(env) except: @@ -338,9 +317,6 @@ def generate(env, **kw): env.AlwaysBuild(env.Alias('$POTUPDATE_ALIAS')) -############################################################################# - -############################################################################# def exists(env): """ Check, whether the tool exists """ try: @@ -348,7 +324,6 @@ def exists(env): except: return False -############################################################################# # Local Variables: # tab-width:4 diff --git a/SCons/Tool/yacc.py b/SCons/Tool/yacc.py index ab019b2..61ad61a 100644 --- a/SCons/Tool/yacc.py +++ b/SCons/Tool/yacc.py @@ -1,15 +1,6 @@ -"""SCons.Tool.yacc - -Tool-specific initialization for yacc. - -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. - -""" - +# MIT License # -# __COPYRIGHT__ +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -29,9 +20,13 @@ selection method. # 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__" +"""Tool-specific initialization for yacc. + +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. +""" import os.path import sys @@ -39,6 +34,7 @@ import sys import SCons.Defaults import SCons.Tool import SCons.Util +import SCons.Warnings from SCons.Platform.mingw import MINGW_DEFAULT_PATHS from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS from SCons.Platform.win32 import CHOCO_DEFAULT_PATH @@ -125,7 +121,10 @@ def get_yacc_path(env, append_paths=False): if append_paths: env.AppendENVPath('PATH', os.path.dirname(bin_path)) return bin_path - SCons.Warnings.SConsWarning('yacc tool requested, but yacc or bison binary not found in ENV PATH') + SCons.Warnings.warn( + SCons.Warnings.SConsWarning, + 'yacc tool requested, but yacc or bison binary not found in ENV PATH' + ) def generate(env): diff --git a/SCons/cpp.py b/SCons/cpp.py index 65358b3..4c6b437 100644 --- a/SCons/cpp.py +++ b/SCons/cpp.py @@ -23,18 +23,14 @@ """SCons C Pre-Processor module""" -import SCons.compat - import os import re -# # First "subsystem" of regular expressions that we set up: # # Stuff to turn the C preprocessor directives in a file's contents into # a list of tuples that we can process easily. # - # A table of regular expressions that fetch the arguments from the rest of # a C preprocessor line. Different directives have different arguments # that we want to fetch, using the regular expressions to which the lists diff --git a/site_scons/site_init.py b/site_scons/site_init.py index 336cad6..faaa010 100644 --- a/site_scons/site_init.py +++ b/site_scons/site_init.py @@ -7,12 +7,12 @@ from Utilities import is_windows, whereis, platform, deb_date from soe_utils import soelim, soscan, soelimbuilder # from epydoc import epydoc_cli, epydoc_commands from BuildCommandLine import BuildCommandLine -from scons_local_package import install_local_package_files, create_local_packages -from update_build_info import update_init_file +#from scons_local_package import install_local_package_files, create_local_packages +# from update_build_info import update_init_file gzip = whereis('gzip') git = os.path.exists('.git') and whereis('git') unzip = whereis('unzip') zip_path = whereis('zip') -BuildCommandLine.git = git \ No newline at end of file +BuildCommandLine.git = git -- cgit v0.12 From 5a683d8293fb0f02ad8a0bf91bacc15442c3bf9a Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Wed, 5 May 2021 11:52:25 -0600 Subject: Fix several sider complaints Unfortunately, this made for more reformatting - sider complains in some of these about indent not being a multiple of four because one line of a block was touched, to eliminate had to reindent the whole block, including all the lines not touched by the original commit. Used a tool... Signed-off-by: Mats Wichmann --- SCons/Node/__init__.py | 3 +- SCons/Tool/gettext_tool.py | 46 ++++++------ SCons/Tool/intelc.py | 8 ++- SCons/Tool/msgfmt.py | 169 +++++++++++++++++++++++---------------------- SCons/Tool/msginit.py | 164 ++++++++++++++++++++++--------------------- SCons/Tool/msgmerge.py | 145 ++++++++++++++++++++------------------ site_scons/site_init.py | 4 +- 7 files changed, 281 insertions(+), 258 deletions(-) diff --git a/SCons/Node/__init__.py b/SCons/Node/__init__.py index b55d9e7..a449082 100644 --- a/SCons/Node/__init__.py +++ b/SCons/Node/__init__.py @@ -44,10 +44,11 @@ import collections import copy from itertools import chain, zip_longest +import SCons.Debug import SCons.Executor import SCons.Memoize from SCons.compat import NoSlotsPyPy -from SCons.Debug import track_instances, logInstanceCreation, Trace +from SCons.Debug import logInstanceCreation, Trace from SCons.Util import hash_signature, is_List, UniqueList, render_tree print_duplicate = 0 diff --git a/SCons/Tool/gettext_tool.py b/SCons/Tool/gettext_tool.py index 8e66a56..36a942d 100644 --- a/SCons/Tool/gettext_tool.py +++ b/SCons/Tool/gettext_tool.py @@ -23,29 +23,31 @@ """gettext tool""" -def generate(env,**kw): - import sys - import os - import SCons.Tool - import SCons.Warnings - from SCons.Platform.mingw import MINGW_DEFAULT_PATHS - from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS +def generate(env, **kw): + import sys + import os + import SCons.Tool + import SCons.Warnings + from SCons.Platform.mingw import MINGW_DEFAULT_PATHS + from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS - from SCons.Tool.GettextCommon \ - import _translate, tool_list - for t in tool_list(env['PLATFORM'], env): - if sys.platform == 'win32': - tool = SCons.Tool.find_program_path(env, t, default_paths=MINGW_DEFAULT_PATHS + CYGWIN_DEFAULT_PATHS ) - if tool: - tool_bin_dir = os.path.dirname(tool) - env.AppendENVPath('PATH', tool_bin_dir) - else: - SCons.Warnings.warn( - SCons.Warnings.SConsWarning, - t + ' tool requested, but binary not found in ENV PATH' + from SCons.Tool.GettextCommon import _translate, tool_list + + for t in tool_list(env['PLATFORM'], env): + if sys.platform == 'win32': + tool = SCons.Tool.find_program_path( + env, t, default_paths=MINGW_DEFAULT_PATHS + CYGWIN_DEFAULT_PATHS ) - env.Tool(t) - env.AddMethod(_translate, 'Translate') + if tool: + tool_bin_dir = os.path.dirname(tool) + env.AppendENVPath('PATH', tool_bin_dir) + else: + SCons.Warnings.warn( + SCons.Warnings.SConsWarning, + t + ' tool requested, but binary not found in ENV PATH', + ) + env.Tool(t) + env.AddMethod(_translate, 'Translate') def exists(env): from SCons.Tool.GettextCommon import ( @@ -62,5 +64,5 @@ def exists(env): and _msgmerge_exists(env) and _msgfmt_exists(env) ) - except: + except SCons.Errors.XgettextNotFound: return False diff --git a/SCons/Tool/intelc.py b/SCons/Tool/intelc.py index 50011b1..533f8fa 100644 --- a/SCons/Tool/intelc.py +++ b/SCons/Tool/intelc.py @@ -447,15 +447,17 @@ def generate(env, version=None, abi=None, topdir=None, verbose=0): except (SCons.Util.RegError, IntelCError): topdir = None +if not topdir: if not topdir: # Normally this is an error, but it might not be if the compiler is # on $PATH and the user is importing their env. class ICLTopDirWarning(SCons.Warnings.SConsWarning): pass - if (is_mac or is_linux) and not env.Detect('icc') \ - or is_windows and not env.Detect('icl'): - + if ( + ((is_mac or is_linux) and not env.Detect('icc')) + (or is_windows and not env.Detect('icl')) + ): SCons.Warnings.enableWarningClass(ICLTopDirWarning) SCons.Warnings.warn( ICLTopDirWarning, diff --git a/SCons/Tool/msgfmt.py b/SCons/Tool/msgfmt.py index 873e66b..8c558d5 100644 --- a/SCons/Tool/msgfmt.py +++ b/SCons/Tool/msgfmt.py @@ -26,94 +26,99 @@ from SCons.Builder import BuilderBase class _MOFileBuilder(BuilderBase): - """ The builder class for `MO` files. - - The reason for this builder to exists and its purpose is quite simillar - as for `_POFileBuilder`. This time, we extend list of sources, not targets, - and call `BuilderBase._execute()` only once (as we assume single-target - here). - """ - - def _execute(self, env, target, source, *args, **kw): - # Here we add support for 'LINGUAS_FILE' keyword. Emitter is not suitable - # in this case, as it is called too late (after multiple sources - # are handled single_source builder. - import SCons.Util - from SCons.Tool.GettextCommon import _read_linguas_from_files - linguas_files = None - if 'LINGUAS_FILE' in env and env['LINGUAS_FILE'] is not None: - linguas_files = env['LINGUAS_FILE'] - # This should prevent from endless recursion. - env['LINGUAS_FILE'] = None - # We read only languages. Suffixes shall be added automatically. - linguas = _read_linguas_from_files(env, linguas_files) - if SCons.Util.is_List(source): - source.extend(linguas) - elif source is not None: - source = [source] + linguas - else: - source = linguas - result = BuilderBase._execute(self,env,target,source,*args, **kw) - if linguas_files is not None: - env['LINGUAS_FILE'] = linguas_files - return result + """The builder class for `MO` files. + + The reason for this builder to exists and its purpose is quite simillar + as for `_POFileBuilder`. This time, we extend list of sources, not targets, + and call `BuilderBase._execute()` only once (as we assume single-target + here). + """ + + def _execute(self, env, target, source, *args, **kw): + # Here we add support for 'LINGUAS_FILE' keyword. Emitter is not suitable + # in this case, as it is called too late (after multiple sources + # are handled single_source builder. + import SCons.Util + from SCons.Tool.GettextCommon import _read_linguas_from_files + + linguas_files = None + if 'LINGUAS_FILE' in env and env['LINGUAS_FILE'] is not None: + linguas_files = env['LINGUAS_FILE'] + # This should prevent from endless recursion. + env['LINGUAS_FILE'] = None + # We read only languages. Suffixes shall be added automatically. + linguas = _read_linguas_from_files(env, linguas_files) + if SCons.Util.is_List(source): + source.extend(linguas) + elif source is not None: + source = [source] + linguas + else: + source = linguas + result = BuilderBase._execute(self, env, target, source, *args, **kw) + if linguas_files is not None: + env['LINGUAS_FILE'] = linguas_files + return result def _create_mo_file_builder(env, **kw): - """ Create builder object for `MOFiles` builder """ - import SCons.Action - # FIXME: What factory use for source? Ours or their? - kw['action'] = SCons.Action.Action('$MSGFMTCOM','$MSGFMTCOMSTR') - kw['suffix'] = '$MOSUFFIX' - kw['src_suffix'] = '$POSUFFIX' - kw['src_builder'] = '_POUpdateBuilder' - kw['single_source'] = True - return _MOFileBuilder(**kw) - - -def generate(env,**kw): - """ Generate `msgfmt` tool """ - import sys - import os - import SCons.Tool - import SCons.Util - import SCons.Warnings - from SCons.Tool.GettextCommon import _detect_msgfmt - from SCons.Platform.mingw import MINGW_DEFAULT_PATHS - from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS - - if sys.platform == 'win32': - msgfmt = SCons.Tool.find_program_path(env, 'msgfmt', default_paths=MINGW_DEFAULT_PATHS + CYGWIN_DEFAULT_PATHS ) - if msgfmt: - msgfmt_bin_dir = os.path.dirname(msgfmt) - env.AppendENVPath('PATH', msgfmt_bin_dir) - else: - SCons.Warnings.warn( - SCons.Warnings.SConsWarning, - 'msgfmt tool requested, but binary not found in ENV PATH' - ) - - try: - env['MSGFMT'] = _detect_msgfmt(env) - except: - env['MSGFMT'] = 'msgfmt' - env.SetDefault( - MSGFMTFLAGS = [ SCons.Util.CLVar('-c') ], - MSGFMTCOM = '$MSGFMT $MSGFMTFLAGS -o $TARGET $SOURCE', - MSGFMTCOMSTR = '', - MOSUFFIX = ['.mo'], - POSUFFIX = ['.po'] - ) - env.Append( BUILDERS = { 'MOFiles' : _create_mo_file_builder(env) } ) + """ Create builder object for `MOFiles` builder """ + import SCons.Action + + # FIXME: What factory use for source? Ours or their? + kw['action'] = SCons.Action.Action('$MSGFMTCOM', '$MSGFMTCOMSTR') + kw['suffix'] = '$MOSUFFIX' + kw['src_suffix'] = '$POSUFFIX' + kw['src_builder'] = '_POUpdateBuilder' + kw['single_source'] = True + return _MOFileBuilder(**kw) + + +def generate(env, **kw): + """ Generate `msgfmt` tool """ + import sys + import os + import SCons.Tool + import SCons.Util + import SCons.Warnings + from SCons.Tool.GettextCommon import _detect_msgfmt + from SCons.Platform.mingw import MINGW_DEFAULT_PATHS + from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS + + if sys.platform == 'win32': + msgfmt = SCons.Tool.find_program_path( + env, 'msgfmt', default_paths=MINGW_DEFAULT_PATHS + CYGWIN_DEFAULT_PATHS + ) + if msgfmt: + msgfmt_bin_dir = os.path.dirname(msgfmt) + env.AppendENVPath('PATH', msgfmt_bin_dir) + else: + SCons.Warnings.warn( + SCons.Warnings.SConsWarning, + 'msgfmt tool requested, but binary not found in ENV PATH', + ) + + try: + env['MSGFMT'] = _detect_msgfmt(env) + except: + env['MSGFMT'] = 'msgfmt' + env.SetDefault( + MSGFMTFLAGS=[SCons.Util.CLVar('-c')], + MSGFMTCOM='$MSGFMT $MSGFMTFLAGS -o $TARGET $SOURCE', + MSGFMTCOMSTR='', + MOSUFFIX=['.mo'], + POSUFFIX=['.po'], + ) + env.Append(BUILDERS={'MOFiles': _create_mo_file_builder(env)}) def exists(env): - """ Check if the tool exists """ - from SCons.Tool.GettextCommon import _msgfmt_exists - try: - return _msgfmt_exists(env) - except: - return False + """ Check if the tool exists """ + from SCons.Tool.GettextCommon import _msgfmt_exists + + try: + return _msgfmt_exists(env) + except: + return False # Local Variables: # tab-width:4 diff --git a/SCons/Tool/msginit.py b/SCons/Tool/msginit.py index b099686..e07373d 100644 --- a/SCons/Tool/msginit.py +++ b/SCons/Tool/msginit.py @@ -28,95 +28,101 @@ import SCons.Util import SCons.Warnings from SCons.Environment import _null + def _optional_no_translator_flag(env): - """ Return '--no-translator' flag if we run *msginit(1)* in non-interactive - mode.""" - if 'POAUTOINIT' in env: - autoinit = env['POAUTOINIT'] - else: - autoinit = False - if autoinit: - return [SCons.Util.CLVar('--no-translator')] - else: - return [SCons.Util.CLVar('')] + """Return '--no-translator' flag if we run *msginit(1)* in non-interactive + mode.""" + if 'POAUTOINIT' in env: + autoinit = env['POAUTOINIT'] + else: + autoinit = False + if autoinit: + return [SCons.Util.CLVar('--no-translator')] + else: + return [SCons.Util.CLVar('')] def _POInitBuilder(env, **kw): - """ Create builder object for `POInit` builder. """ - from SCons.Tool.GettextCommon import _init_po_files, _POFileBuilder - action = SCons.Action.Action(_init_po_files, None) - return _POFileBuilder(env, action=action, target_alias='$POCREATE_ALIAS') + """ Create builder object for `POInit` builder. """ + from SCons.Tool.GettextCommon import _init_po_files, _POFileBuilder + + action = SCons.Action.Action(_init_po_files, None) + return _POFileBuilder(env, action=action, target_alias='$POCREATE_ALIAS') def _POInitBuilderWrapper(env, target=None, source=_null, **kw): - """ Wrapper for _POFileBuilder. We use it to make user's life easier. - - This wrapper checks for `$POTDOMAIN` construction variable (or override in - `**kw`) and treats it appropriatelly. - """ - if source is _null: - if 'POTDOMAIN' in kw: - domain = kw['POTDOMAIN'] - elif 'POTDOMAIN' in env: - domain = env['POTDOMAIN'] - else: - domain = 'messages' - source = [ domain ] # NOTE: Suffix shall be appended automatically - return env._POInitBuilder(target, source, **kw) - - -def generate(env,**kw): - """ Generate the `msginit` tool """ - import sys - import os - import SCons.Tool - import SCons.Warnings - from SCons.Tool.GettextCommon import _detect_msginit - from SCons.Platform.mingw import MINGW_DEFAULT_PATHS - from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS - - if sys.platform == 'win32': - msginit = SCons.Tool.find_program_path(env, 'msginit', default_paths=MINGW_DEFAULT_PATHS + CYGWIN_DEFAULT_PATHS ) - if msginit: - msginit_bin_dir = os.path.dirname(msginit) - env.AppendENVPath('PATH', msginit_bin_dir) - else: - SCons.Warnings.warn( - SCons.Warnings.SConsWarning, - 'msginit tool requested, but binary not found in ENV PATH' - ) - - try: - env['MSGINIT'] = _detect_msginit(env) - except: - env['MSGINIT'] = 'msginit' - msginitcom = '$MSGINIT ${_MSGNoTranslator(__env__)} -l ${_MSGINITLOCALE}' \ - + ' $MSGINITFLAGS -i $SOURCE -o $TARGET' - # NOTE: We set POTSUFFIX here, in case the 'xgettext' is not loaded - # (sometimes we really don't need it) - env.SetDefault( - POSUFFIX = ['.po'], - POTSUFFIX = ['.pot'], - _MSGINITLOCALE = '${TARGET.filebase}', - _MSGNoTranslator = _optional_no_translator_flag, - MSGINITCOM = msginitcom, - MSGINITCOMSTR = '', - MSGINITFLAGS = [ ], - POAUTOINIT = False, - POCREATE_ALIAS = 'po-create' - ) - env.Append( BUILDERS = { '_POInitBuilder' : _POInitBuilder(env) } ) - env.AddMethod(_POInitBuilderWrapper, 'POInit') - env.AlwaysBuild(env.Alias('$POCREATE_ALIAS')) + """Wrapper for _POFileBuilder. We use it to make user's life easier. + + This wrapper checks for `$POTDOMAIN` construction variable (or override in + `**kw`) and treats it appropriatelly. + """ + if source is _null: + if 'POTDOMAIN' in kw: + domain = kw['POTDOMAIN'] + elif 'POTDOMAIN' in env: + domain = env['POTDOMAIN'] + else: + domain = 'messages' + source = [domain] # NOTE: Suffix shall be appended automatically + return env._POInitBuilder(target, source, **kw) + +def generate(env, **kw): + """ Generate the `msginit` tool """ + import sys + import os + import SCons.Tool + import SCons.Warnings + from SCons.Tool.GettextCommon import _detect_msginit + from SCons.Platform.mingw import MINGW_DEFAULT_PATHS + from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS + + if sys.platform == 'win32': + msginit = SCons.Tool.find_program_path( + env, 'msginit', default_paths=MINGW_DEFAULT_PATHS + CYGWIN_DEFAULT_PATHS + ) + if msginit: + msginit_bin_dir = os.path.dirname(msginit) + env.AppendENVPath('PATH', msginit_bin_dir) + else: + SCons.Warnings.warn( + SCons.Warnings.SConsWarning, + 'msginit tool requested, but binary not found in ENV PATH', + ) + + try: + env['MSGINIT'] = _detect_msginit(env) + except: + env['MSGINIT'] = 'msginit' + msginitcom = ( + '$MSGINIT ${_MSGNoTranslator(__env__)} -l ${_MSGINITLOCALE}' + + ' $MSGINITFLAGS -i $SOURCE -o $TARGET' + ) + # NOTE: We set POTSUFFIX here, in case the 'xgettext' is not loaded + # (sometimes we really don't need it) + env.SetDefault( + POSUFFIX=['.po'], + POTSUFFIX=['.pot'], + _MSGINITLOCALE='${TARGET.filebase}', + _MSGNoTranslator=_optional_no_translator_flag, + MSGINITCOM=msginitcom, + MSGINITCOMSTR='', + MSGINITFLAGS=[], + POAUTOINIT=False, + POCREATE_ALIAS='po-create', + ) + env.Append(BUILDERS={'_POInitBuilder': _POInitBuilder(env)}) + env.AddMethod(_POInitBuilderWrapper, 'POInit') + env.AlwaysBuild(env.Alias('$POCREATE_ALIAS')) def exists(env): - """ Check if the tool exists """ - from SCons.Tool.GettextCommon import _msginit_exists - try: - return _msginit_exists(env) - except: - return False + """ Check if the tool exists """ + from SCons.Tool.GettextCommon import _msginit_exists + + try: + return _msginit_exists(env) + except: + return False # Local Variables: # tab-width:4 diff --git a/SCons/Tool/msgmerge.py b/SCons/Tool/msgmerge.py index f30b27d..913726d 100644 --- a/SCons/Tool/msgmerge.py +++ b/SCons/Tool/msgmerge.py @@ -24,86 +24,93 @@ """Tool specific initialization for `msgmerge` tool.""" def _update_or_init_po_files(target, source, env): - """ Action function for `POUpdate` builder """ - import SCons.Action - from SCons.Tool.GettextCommon import _init_po_files - for tgt in target: - if tgt.rexists(): - action = SCons.Action.Action('$MSGMERGECOM', '$MSGMERGECOMSTR') - else: - action = _init_po_files - status = action([tgt], source, env) - if status : return status - return 0 + """ Action function for `POUpdate` builder """ + import SCons.Action + from SCons.Tool.GettextCommon import _init_po_files + + for tgt in target: + if tgt.rexists(): + action = SCons.Action.Action('$MSGMERGECOM', '$MSGMERGECOMSTR') + else: + action = _init_po_files + status = action([tgt], source, env) + if status: + return status + return 0 def _POUpdateBuilder(env, **kw): - """ Create an object of `POUpdate` builder """ - import SCons.Action - from SCons.Tool.GettextCommon import _POFileBuilder - action = SCons.Action.Action(_update_or_init_po_files, None) - return _POFileBuilder(env, action=action, target_alias='$POUPDATE_ALIAS') + """ Create an object of `POUpdate` builder """ + import SCons.Action + from SCons.Tool.GettextCommon import _POFileBuilder + + action = SCons.Action.Action(_update_or_init_po_files, None) + return _POFileBuilder(env, action=action, target_alias='$POUPDATE_ALIAS') from SCons.Environment import _null + def _POUpdateBuilderWrapper(env, target=None, source=_null, **kw): - """ Wrapper for `POUpdate` builder - make user's life easier """ - if source is _null: - if 'POTDOMAIN' in kw: - domain = kw['POTDOMAIN'] - elif 'POTDOMAIN' in env and env['POTDOMAIN']: - domain = env['POTDOMAIN'] - else: - domain = 'messages' - source = [ domain ] # NOTE: Suffix shall be appended automatically - return env._POUpdateBuilder(target, source, **kw) - - -def generate(env,**kw): - """ Generate the `msgmerge` tool """ - import sys - import os - import SCons.Tool - import SCons.Warnings - from SCons.Tool.GettextCommon import _detect_msgmerge - from SCons.Platform.mingw import MINGW_DEFAULT_PATHS - from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS - - if sys.platform == 'win32': - msgmerge = SCons.Tool.find_program_path(env, 'msgmerge', default_paths=MINGW_DEFAULT_PATHS + CYGWIN_DEFAULT_PATHS ) - if msgmerge: - msgmerge_bin_dir = os.path.dirname(msgmerge) - env.AppendENVPath('PATH', msgmerge_bin_dir) - else: - SCons.Warnings.warn( - SCons.Warnings.SConsWarning, - 'msgmerge tool requested, but binary not found in ENV PATH' - ) - try: - env['MSGMERGE'] = _detect_msgmerge(env) - except: - env['MSGMERGE'] = 'msgmerge' - env.SetDefault( - POTSUFFIX = ['.pot'], - POSUFFIX = ['.po'], - MSGMERGECOM = '$MSGMERGE $MSGMERGEFLAGS --update $TARGET $SOURCE', - MSGMERGECOMSTR = '', - MSGMERGEFLAGS = [ ], - POUPDATE_ALIAS = 'po-update' - ) - env.Append(BUILDERS = { '_POUpdateBuilder':_POUpdateBuilder(env) }) - env.AddMethod(_POUpdateBuilderWrapper, 'POUpdate') - env.AlwaysBuild(env.Alias('$POUPDATE_ALIAS')) + """ Wrapper for `POUpdate` builder - make user's life easier """ + if source is _null: + if 'POTDOMAIN' in kw: + domain = kw['POTDOMAIN'] + elif 'POTDOMAIN' in env and env['POTDOMAIN']: + domain = env['POTDOMAIN'] + else: + domain = 'messages' + source = [domain] # NOTE: Suffix shall be appended automatically + return env._POUpdateBuilder(target, source, **kw) + + +def generate(env, **kw): + """ Generate the `msgmerge` tool """ + import sys + import os + import SCons.Tool + import SCons.Warnings + from SCons.Tool.GettextCommon import _detect_msgmerge + from SCons.Platform.mingw import MINGW_DEFAULT_PATHS + from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS + + if sys.platform == 'win32': + msgmerge = SCons.Tool.find_program_path( + env, 'msgmerge', default_paths=MINGW_DEFAULT_PATHS + CYGWIN_DEFAULT_PATHS + ) + if msgmerge: + msgmerge_bin_dir = os.path.dirname(msgmerge) + env.AppendENVPath('PATH', msgmerge_bin_dir) + else: + SCons.Warnings.warn( + SCons.Warnings.SConsWarning, + 'msgmerge tool requested, but binary not found in ENV PATH', + ) + try: + env['MSGMERGE'] = _detect_msgmerge(env) + except: + env['MSGMERGE'] = 'msgmerge' + env.SetDefault( + POTSUFFIX=['.pot'], + POSUFFIX=['.po'], + MSGMERGECOM='$MSGMERGE $MSGMERGEFLAGS --update $TARGET $SOURCE', + MSGMERGECOMSTR='', + MSGMERGEFLAGS=[], + POUPDATE_ALIAS='po-update', + ) + env.Append(BUILDERS={'_POUpdateBuilder': _POUpdateBuilder(env)}) + env.AddMethod(_POUpdateBuilderWrapper, 'POUpdate') + env.AlwaysBuild(env.Alias('$POUPDATE_ALIAS')) def exists(env): - """ Check if the tool exists """ - from SCons.Tool.GettextCommon import _msgmerge_exists - try: - return _msgmerge_exists(env) - except: - return False + """ Check if the tool exists """ + from SCons.Tool.GettextCommon import _msgmerge_exists + + try: + return _msgmerge_exists(env) + except: + return False # Local Variables: # tab-width:4 diff --git a/site_scons/site_init.py b/site_scons/site_init.py index faaa010..7d51fda 100644 --- a/site_scons/site_init.py +++ b/site_scons/site_init.py @@ -7,8 +7,8 @@ from Utilities import is_windows, whereis, platform, deb_date from soe_utils import soelim, soscan, soelimbuilder # from epydoc import epydoc_cli, epydoc_commands from BuildCommandLine import BuildCommandLine -#from scons_local_package import install_local_package_files, create_local_packages -# from update_build_info import update_init_file +from scons_local_package import install_local_package_files, create_local_packages +from update_build_info import update_init_file gzip = whereis('gzip') git = os.path.exists('.git') and whereis('git') -- cgit v0.12 From 48927790d55d1bc7cda811591f704d737e1041b0 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Wed, 5 May 2021 12:01:00 -0600 Subject: Even more sider complaints fixed Got rid of bare exceptions - complained about because the code had been reformatted and thus "touched". Others were a missing import and a syntax mistake. Signed-off-by: Mats Wichmann --- SCons/Tool/gettext_tool.py | 1 + SCons/Tool/intelc.py | 2 +- SCons/Tool/msgfmt.py | 6 ++++-- SCons/Tool/msginit.py | 6 ++++-- SCons/Tool/msgmerge.py | 6 ++++-- 5 files changed, 14 insertions(+), 7 deletions(-) diff --git a/SCons/Tool/gettext_tool.py b/SCons/Tool/gettext_tool.py index 36a942d..66505fc 100644 --- a/SCons/Tool/gettext_tool.py +++ b/SCons/Tool/gettext_tool.py @@ -56,6 +56,7 @@ def exists(env): _msgmerge_exists, _msgfmt_exists, ) + import SCons.Errors try: return ( diff --git a/SCons/Tool/intelc.py b/SCons/Tool/intelc.py index 533f8fa..bc27cef 100644 --- a/SCons/Tool/intelc.py +++ b/SCons/Tool/intelc.py @@ -456,7 +456,7 @@ if not topdir: if ( ((is_mac or is_linux) and not env.Detect('icc')) - (or is_windows and not env.Detect('icl')) + or (is_windows and not env.Detect('icl')) ): SCons.Warnings.enableWarningClass(ICLTopDirWarning) SCons.Warnings.warn( diff --git a/SCons/Tool/msgfmt.py b/SCons/Tool/msgfmt.py index 8c558d5..676b1b1 100644 --- a/SCons/Tool/msgfmt.py +++ b/SCons/Tool/msgfmt.py @@ -77,6 +77,7 @@ def generate(env, **kw): """ Generate `msgfmt` tool """ import sys import os + import SCons.Errors import SCons.Tool import SCons.Util import SCons.Warnings @@ -99,7 +100,7 @@ def generate(env, **kw): try: env['MSGFMT'] = _detect_msgfmt(env) - except: + except MsgfmtNotFound: env['MSGFMT'] = 'msgfmt' env.SetDefault( MSGFMTFLAGS=[SCons.Util.CLVar('-c')], @@ -113,11 +114,12 @@ def generate(env, **kw): def exists(env): """ Check if the tool exists """ + import SCons.Errors from SCons.Tool.GettextCommon import _msgfmt_exists try: return _msgfmt_exists(env) - except: + except MsgfmtNotFound: return False # Local Variables: diff --git a/SCons/Tool/msginit.py b/SCons/Tool/msginit.py index e07373d..e3ef7ba 100644 --- a/SCons/Tool/msginit.py +++ b/SCons/Tool/msginit.py @@ -70,6 +70,7 @@ def generate(env, **kw): """ Generate the `msginit` tool """ import sys import os + import SCons.Errors import SCons.Tool import SCons.Warnings from SCons.Tool.GettextCommon import _detect_msginit @@ -91,7 +92,7 @@ def generate(env, **kw): try: env['MSGINIT'] = _detect_msginit(env) - except: + except MsginitNotFound: env['MSGINIT'] = 'msginit' msginitcom = ( '$MSGINIT ${_MSGNoTranslator(__env__)} -l ${_MSGINITLOCALE}' @@ -117,11 +118,12 @@ def generate(env, **kw): def exists(env): """ Check if the tool exists """ + import SCons.Errors from SCons.Tool.GettextCommon import _msginit_exists try: return _msginit_exists(env) - except: + except MsginitNotFound: return False # Local Variables: diff --git a/SCons/Tool/msgmerge.py b/SCons/Tool/msgmerge.py index 913726d..846c0c1 100644 --- a/SCons/Tool/msgmerge.py +++ b/SCons/Tool/msgmerge.py @@ -68,6 +68,7 @@ def generate(env, **kw): """ Generate the `msgmerge` tool """ import sys import os + import SCons.Errors import SCons.Tool import SCons.Warnings from SCons.Tool.GettextCommon import _detect_msgmerge @@ -88,7 +89,7 @@ def generate(env, **kw): ) try: env['MSGMERGE'] = _detect_msgmerge(env) - except: + except MsgmergeNotFound: env['MSGMERGE'] = 'msgmerge' env.SetDefault( POTSUFFIX=['.pot'], @@ -105,11 +106,12 @@ def generate(env, **kw): def exists(env): """ Check if the tool exists """ + import SCons.Errors from SCons.Tool.GettextCommon import _msgmerge_exists try: return _msgmerge_exists(env) - except: + except MsgmergeNotFound: return False # Local Variables: -- cgit v0.12 From bc3b1423f987e9d577f1a275589aae1c88f8ae64 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Wed, 5 May 2021 12:07:27 -0600 Subject: Redo botched changes for sider complaints Signed-off-by: Mats Wichmann --- SCons/Tool/intelc.py | 1 - SCons/Tool/msgfmt.py | 6 ++---- SCons/Tool/msginit.py | 6 ++---- SCons/Tool/msgmerge.py | 6 ++---- 4 files changed, 6 insertions(+), 13 deletions(-) diff --git a/SCons/Tool/intelc.py b/SCons/Tool/intelc.py index bc27cef..2542f81 100644 --- a/SCons/Tool/intelc.py +++ b/SCons/Tool/intelc.py @@ -447,7 +447,6 @@ def generate(env, version=None, abi=None, topdir=None, verbose=0): except (SCons.Util.RegError, IntelCError): topdir = None -if not topdir: if not topdir: # Normally this is an error, but it might not be if the compiler is # on $PATH and the user is importing their env. diff --git a/SCons/Tool/msgfmt.py b/SCons/Tool/msgfmt.py index 676b1b1..efa5ce4 100644 --- a/SCons/Tool/msgfmt.py +++ b/SCons/Tool/msgfmt.py @@ -77,11 +77,10 @@ def generate(env, **kw): """ Generate `msgfmt` tool """ import sys import os - import SCons.Errors import SCons.Tool import SCons.Util import SCons.Warnings - from SCons.Tool.GettextCommon import _detect_msgfmt + from SCons.Tool.GettextCommon import _detect_msgfmt, MsgfmtNotFound from SCons.Platform.mingw import MINGW_DEFAULT_PATHS from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS @@ -114,8 +113,7 @@ def generate(env, **kw): def exists(env): """ Check if the tool exists """ - import SCons.Errors - from SCons.Tool.GettextCommon import _msgfmt_exists + from SCons.Tool.GettextCommon import _msgfmt_exists, MsgfmtNotFound try: return _msgfmt_exists(env) diff --git a/SCons/Tool/msginit.py b/SCons/Tool/msginit.py index e3ef7ba..8a30092 100644 --- a/SCons/Tool/msginit.py +++ b/SCons/Tool/msginit.py @@ -70,10 +70,9 @@ def generate(env, **kw): """ Generate the `msginit` tool """ import sys import os - import SCons.Errors import SCons.Tool import SCons.Warnings - from SCons.Tool.GettextCommon import _detect_msginit + from SCons.Tool.GettextCommon import _detect_msginit, MsginitNotFound from SCons.Platform.mingw import MINGW_DEFAULT_PATHS from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS @@ -118,8 +117,7 @@ def generate(env, **kw): def exists(env): """ Check if the tool exists """ - import SCons.Errors - from SCons.Tool.GettextCommon import _msginit_exists + from SCons.Tool.GettextCommon import _msginit_exists, MsginitNotFound try: return _msginit_exists(env) diff --git a/SCons/Tool/msgmerge.py b/SCons/Tool/msgmerge.py index 846c0c1..e4688e0 100644 --- a/SCons/Tool/msgmerge.py +++ b/SCons/Tool/msgmerge.py @@ -68,10 +68,9 @@ def generate(env, **kw): """ Generate the `msgmerge` tool """ import sys import os - import SCons.Errors import SCons.Tool import SCons.Warnings - from SCons.Tool.GettextCommon import _detect_msgmerge + from SCons.Tool.GettextCommon import _detect_msgmerge, MsgmergeNotFound from SCons.Platform.mingw import MINGW_DEFAULT_PATHS from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS @@ -106,8 +105,7 @@ def generate(env, **kw): def exists(env): """ Check if the tool exists """ - import SCons.Errors - from SCons.Tool.GettextCommon import _msgmerge_exists + from SCons.Tool.GettextCommon import _msgmerge_exists, MsgmergeNotFound try: return _msgmerge_exists(env) -- cgit v0.12 From 2324eec4bddba512c144f967db2d15adb3cd4429 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Wed, 5 May 2021 12:35:28 -0600 Subject: One more fix to the warnings changes Signed-off-by: Mats Wichmann --- SCons/Tool/gettext_tool.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SCons/Tool/gettext_tool.py b/SCons/Tool/gettext_tool.py index 66505fc..055939c 100644 --- a/SCons/Tool/gettext_tool.py +++ b/SCons/Tool/gettext_tool.py @@ -56,7 +56,7 @@ def exists(env): _msgmerge_exists, _msgfmt_exists, ) - import SCons.Errors + from SCons.Tool.GettextCommon import XgettextNotFound try: return ( @@ -65,5 +65,5 @@ def exists(env): and _msgmerge_exists(env) and _msgfmt_exists(env) ) - except SCons.Errors.XgettextNotFound: + except XgettextNotFound: return False -- cgit v0.12 From 0dacb1fb2de5d85094e6c4eed32352caf01c0a84 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Wed, 5 May 2021 17:32:18 -0600 Subject: Fiddle the gettext tool family imports/warnings more Previous few rounds of PR #3942 all seemed to fall in some hole. If it works right when the tool is found, it doens't work when the tool is not found (with the main complainer being the test/import.py test, which tries to import *everything* in the tools dir). This change should let the tests pass on both Posix and Windows hosts. Signed-off-by: Mats Wichmann --- SCons/Tool/gettext_tool.py | 34 +++++++++++++++++----------------- SCons/Tool/intelc.py | 4 ++-- SCons/Tool/msgfmt.py | 33 +++++++++++++++++++-------------- SCons/Tool/msginit.py | 28 +++++++++++++++++----------- SCons/Tool/msgmerge.py | 34 ++++++++++++++++++++-------------- SCons/Tool/xgettext.py | 11 ++++++++--- 6 files changed, 83 insertions(+), 61 deletions(-) diff --git a/SCons/Tool/gettext_tool.py b/SCons/Tool/gettext_tool.py index 055939c..a1407b3 100644 --- a/SCons/Tool/gettext_tool.py +++ b/SCons/Tool/gettext_tool.py @@ -23,16 +23,24 @@ """gettext tool""" -def generate(env, **kw): - import sys - import os - import SCons.Tool - import SCons.Warnings - from SCons.Platform.mingw import MINGW_DEFAULT_PATHS - from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS +import sys +import os - from SCons.Tool.GettextCommon import _translate, tool_list +import SCons.Tool +import SCons.Warnings +from SCons.Errors import StopError +from SCons.Platform.mingw import MINGW_DEFAULT_PATHS +from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS +from SCons.Tool.GettextCommon import ( + _msgfmt_exists, + _msginit_exists, + _msgmerge_exists, + tool_list, + _translate, + _xgettext_exists, +) +def generate(env, **kw): for t in tool_list(env['PLATFORM'], env): if sys.platform == 'win32': tool = SCons.Tool.find_program_path( @@ -50,14 +58,6 @@ def generate(env, **kw): env.AddMethod(_translate, 'Translate') def exists(env): - from SCons.Tool.GettextCommon import ( - _xgettext_exists, - _msginit_exists, - _msgmerge_exists, - _msgfmt_exists, - ) - from SCons.Tool.GettextCommon import XgettextNotFound - try: return ( _xgettext_exists(env) @@ -65,5 +65,5 @@ def exists(env): and _msgmerge_exists(env) and _msgfmt_exists(env) ) - except XgettextNotFound: + except StopError: return False diff --git a/SCons/Tool/intelc.py b/SCons/Tool/intelc.py index 2542f81..0d07c72 100644 --- a/SCons/Tool/intelc.py +++ b/SCons/Tool/intelc.py @@ -582,9 +582,9 @@ def generate(env, version=None, abi=None, topdir=None, verbose=0): SCons.Warnings.enableWarningClass(ICLLicenseDirWarning) SCons.Warnings.warn( ICLLicenseDirWarning, - "Intel license dir was not found. " + "Intel license dir was not found. " "Tried using the INTEL_LICENSE_FILE environment variable " - "(%s), the registry (%s) and the default path (%s). " + "(%s), the registry (%s) and the default path (%s). " "Using the default path as a last resort." % (envlicdir, reglicdir, defaultlicdir) ) diff --git a/SCons/Tool/msgfmt.py b/SCons/Tool/msgfmt.py index efa5ce4..a15c1dc 100644 --- a/SCons/Tool/msgfmt.py +++ b/SCons/Tool/msgfmt.py @@ -23,7 +23,23 @@ """ msgfmt tool """ +import sys +import os + +import SCons.Action +import SCons.Tool +import SCons.Util +import SCons.Warnings from SCons.Builder import BuilderBase +from SCons.Errors import StopError +from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS +from SCons.Platform.mingw import MINGW_DEFAULT_PATHS +from SCons.Tool.GettextCommon import ( + _detect_msgfmt, + _msgfmt_exists, + # MsgfmtToolWarning, + _read_linguas_from_files, +) class _MOFileBuilder(BuilderBase): """The builder class for `MO` files. @@ -38,8 +54,6 @@ class _MOFileBuilder(BuilderBase): # Here we add support for 'LINGUAS_FILE' keyword. Emitter is not suitable # in this case, as it is called too late (after multiple sources # are handled single_source builder. - import SCons.Util - from SCons.Tool.GettextCommon import _read_linguas_from_files linguas_files = None if 'LINGUAS_FILE' in env and env['LINGUAS_FILE'] is not None: @@ -62,7 +76,6 @@ class _MOFileBuilder(BuilderBase): def _create_mo_file_builder(env, **kw): """ Create builder object for `MOFiles` builder """ - import SCons.Action # FIXME: What factory use for source? Ours or their? kw['action'] = SCons.Action.Action('$MSGFMTCOM', '$MSGFMTCOMSTR') @@ -75,14 +88,6 @@ def _create_mo_file_builder(env, **kw): def generate(env, **kw): """ Generate `msgfmt` tool """ - import sys - import os - import SCons.Tool - import SCons.Util - import SCons.Warnings - from SCons.Tool.GettextCommon import _detect_msgfmt, MsgfmtNotFound - from SCons.Platform.mingw import MINGW_DEFAULT_PATHS - from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS if sys.platform == 'win32': msgfmt = SCons.Tool.find_program_path( @@ -93,13 +98,14 @@ def generate(env, **kw): env.AppendENVPath('PATH', msgfmt_bin_dir) else: SCons.Warnings.warn( + # MsgfmtToolWarning, # using this breaks test, so keep: SCons.Warnings.SConsWarning, 'msgfmt tool requested, but binary not found in ENV PATH', ) try: env['MSGFMT'] = _detect_msgfmt(env) - except MsgfmtNotFound: + except StopError: env['MSGFMT'] = 'msgfmt' env.SetDefault( MSGFMTFLAGS=[SCons.Util.CLVar('-c')], @@ -113,11 +119,10 @@ def generate(env, **kw): def exists(env): """ Check if the tool exists """ - from SCons.Tool.GettextCommon import _msgfmt_exists, MsgfmtNotFound try: return _msgfmt_exists(env) - except MsgfmtNotFound: + except StopError: return False # Local Variables: diff --git a/SCons/Tool/msginit.py b/SCons/Tool/msginit.py index 8a30092..9635f57 100644 --- a/SCons/Tool/msginit.py +++ b/SCons/Tool/msginit.py @@ -23,10 +23,24 @@ """Tool specific initialization of msginit tool.""" +import sys +import os + import SCons.Action +import SCons.Tool import SCons.Util import SCons.Warnings from SCons.Environment import _null +from SCons.Errors import StopError +from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS +from SCons.Platform.mingw import MINGW_DEFAULT_PATHS +from SCons.Tool.GettextCommon import ( + _detect_msginit, + _init_po_files, + _msginit_exists, + # MsginitToolWarning, + _POFileBuilder, +) def _optional_no_translator_flag(env): @@ -44,7 +58,6 @@ def _optional_no_translator_flag(env): def _POInitBuilder(env, **kw): """ Create builder object for `POInit` builder. """ - from SCons.Tool.GettextCommon import _init_po_files, _POFileBuilder action = SCons.Action.Action(_init_po_files, None) return _POFileBuilder(env, action=action, target_alias='$POCREATE_ALIAS') @@ -68,13 +81,6 @@ def _POInitBuilderWrapper(env, target=None, source=_null, **kw): def generate(env, **kw): """ Generate the `msginit` tool """ - import sys - import os - import SCons.Tool - import SCons.Warnings - from SCons.Tool.GettextCommon import _detect_msginit, MsginitNotFound - from SCons.Platform.mingw import MINGW_DEFAULT_PATHS - from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS if sys.platform == 'win32': msginit = SCons.Tool.find_program_path( @@ -85,13 +91,14 @@ def generate(env, **kw): env.AppendENVPath('PATH', msginit_bin_dir) else: SCons.Warnings.warn( + # MsginitToolWarning, # using this breaks test, so keep: SCons.Warnings.SConsWarning, 'msginit tool requested, but binary not found in ENV PATH', ) try: env['MSGINIT'] = _detect_msginit(env) - except MsginitNotFound: + except StopError: env['MSGINIT'] = 'msginit' msginitcom = ( '$MSGINIT ${_MSGNoTranslator(__env__)} -l ${_MSGINITLOCALE}' @@ -117,11 +124,10 @@ def generate(env, **kw): def exists(env): """ Check if the tool exists """ - from SCons.Tool.GettextCommon import _msginit_exists, MsginitNotFound try: return _msginit_exists(env) - except MsginitNotFound: + except StopError: return False # Local Variables: diff --git a/SCons/Tool/msgmerge.py b/SCons/Tool/msgmerge.py index e4688e0..69508eb 100644 --- a/SCons/Tool/msgmerge.py +++ b/SCons/Tool/msgmerge.py @@ -23,10 +23,25 @@ """Tool specific initialization for `msgmerge` tool.""" +import sys +import os + +import SCons.Action +import SCons.Tool +import SCons.Warnings +from SCons.Errors import StopError +from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS +from SCons.Platform.mingw import MINGW_DEFAULT_PATHS +from SCons.Tool.GettextCommon import ( + _detect_msgmerge, + _init_po_files, + _msgmerge_exists, + # MsgmergeToolWarning, + _POFileBuilder, +) + def _update_or_init_po_files(target, source, env): """ Action function for `POUpdate` builder """ - import SCons.Action - from SCons.Tool.GettextCommon import _init_po_files for tgt in target: if tgt.rexists(): @@ -41,8 +56,6 @@ def _update_or_init_po_files(target, source, env): def _POUpdateBuilder(env, **kw): """ Create an object of `POUpdate` builder """ - import SCons.Action - from SCons.Tool.GettextCommon import _POFileBuilder action = SCons.Action.Action(_update_or_init_po_files, None) return _POFileBuilder(env, action=action, target_alias='$POUPDATE_ALIAS') @@ -66,13 +79,6 @@ def _POUpdateBuilderWrapper(env, target=None, source=_null, **kw): def generate(env, **kw): """ Generate the `msgmerge` tool """ - import sys - import os - import SCons.Tool - import SCons.Warnings - from SCons.Tool.GettextCommon import _detect_msgmerge, MsgmergeNotFound - from SCons.Platform.mingw import MINGW_DEFAULT_PATHS - from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS if sys.platform == 'win32': msgmerge = SCons.Tool.find_program_path( @@ -83,12 +89,13 @@ def generate(env, **kw): env.AppendENVPath('PATH', msgmerge_bin_dir) else: SCons.Warnings.warn( + # MsgmergeToolWarning, # using this breaks test, so keep: SCons.Warnings.SConsWarning, 'msgmerge tool requested, but binary not found in ENV PATH', ) try: env['MSGMERGE'] = _detect_msgmerge(env) - except MsgmergeNotFound: + except StopError: env['MSGMERGE'] = 'msgmerge' env.SetDefault( POTSUFFIX=['.pot'], @@ -105,11 +112,10 @@ def generate(env, **kw): def exists(env): """ Check if the tool exists """ - from SCons.Tool.GettextCommon import _msgmerge_exists, MsgmergeNotFound try: return _msgmerge_exists(env) - except MsgmergeNotFound: + except StopError: return False # Local Variables: diff --git a/SCons/Tool/xgettext.py b/SCons/Tool/xgettext.py index 2fbebf3..ed76e25 100644 --- a/SCons/Tool/xgettext.py +++ b/SCons/Tool/xgettext.py @@ -37,9 +37,13 @@ from SCons.Builder import BuilderBase from SCons.Environment import _null from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS from SCons.Platform.mingw import MINGW_DEFAULT_PATHS -from SCons.Tool.GettextCommon import _POTargetFactory -from SCons.Tool.GettextCommon import RPaths, _detect_xgettext -from SCons.Tool.GettextCommon import _xgettext_exists +from SCons.Tool.GettextCommon import ( + _detect_xgettext, + _POTargetFactory, + RPaths, + _xgettext_exists, + # XgettextToolWarning, +) class _CmdRunner: @@ -263,6 +267,7 @@ def generate(env, **kw): env.AppendENVPath('PATH', xgettext_bin_dir) else: SCons.Warnings.warn( + # XgettextToolWarning, # using this breaks test, so keep: SCons.Warnings.SConsWarning, 'xgettext tool requested, but binary not found in ENV PATH' ) -- cgit v0.12 From 690b51aee3f62bdf8f55b7da2f35d93729c981a3 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Thu, 6 May 2021 08:57:41 -0600 Subject: Drop overridden changed_since_last_build method in Value class Value defined this method, but the __init__ methos also does "self.changed_since_last_build = 6" to set an index into the decider map, meaning no instance of Value will ever see that function. The map index will cause picking the "real" function, changed_since_last_build_python(), which has identical impl to the now removed method. Signed-off-by: Mats Wichmann --- CHANGES.txt | 1 + SCons/Node/Python.py | 7 ------- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index e7d555d..2f64355 100755 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -89,6 +89,7 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER - Maintenance: remove obsolete __getslice__ definitions (Py3 never calls); add Node.fs.scandir to call new (Py3.5) os.scandir; Node.fs.makedirs now passes the exist_ok flag; Cachedir creation now uses this flag. + - Drop overridden changed_since_last_build method in Value class. From Dillan Mills: - Add support for the (TARGET,SOURCE,TARGETS,SOURCES,CHANGED_TARGETS,CHANGED_SOURCES}.relpath property. diff --git a/SCons/Node/Python.py b/SCons/Node/Python.py index 738682c..c6850ab 100644 --- a/SCons/Node/Python.py +++ b/SCons/Node/Python.py @@ -146,13 +146,6 @@ class Value(SCons.Node.Node): """Get contents for signature calculations.""" return self.get_text_contents().encode() - def changed_since_last_build(self, target, prev_ni): - cur_csig = self.get_csig() - try: - return cur_csig != prev_ni.csig - except AttributeError: - return True - def get_csig(self, calc=None): """Because we're a Python value node and don't have a real timestamp, we get to ignore the calculator and just use the -- cgit v0.12 From 1801220fb3d89da579c037208f058becf96125d8 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Thu, 6 May 2021 09:31:54 -0600 Subject: Fix (and simplify) starting tests in debugger [ci skip] A mis-indented break statement caused the "-d" option to runtest.py to start a test in the debugger to be inoperative. It's not necessary to search for the path to the debugger module, so this can be simplified to just supply "-m pdb". Signed-off-by: Mats Wichmann --- runtest.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/runtest.py b/runtest.py index 9e7cb2c..69b3a61 100755 --- a/runtest.py +++ b/runtest.py @@ -199,11 +199,8 @@ if args.short_progress: suppress_output = catch_output = True if args.debug: - for d in sys.path: - pdb = os.path.join(d, 'pdb.py') - if os.path.exists(pdb): - debug = pdb - break + # TODO: add a way to pass a specific debugger + debug = "pdb" if args.exec: scons = args.exec @@ -710,7 +707,7 @@ def run_test(t, io_lock=None, run_async=True): t.headline = "" command_args = [] if debug: - command_args.append(debug) + command_args.extend(['-m', debug]) if args.devmode and sys.version_info >= (3, 7, 0): command_args.append('-X dev') command_args.append(t.path) -- cgit v0.12 From d2838ef49fa002afc9d44fe90a29870a34472005 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Sun, 2 May 2021 07:00:40 -0600 Subject: Tweak intro section of manpage [skip appveyor] [skip travis] Signed-off-by: Mats Wichmann --- doc/man/scons.xml | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/doc/man/scons.xml b/doc/man/scons.xml index c34e7b1..0fba467 100644 --- a/doc/man/scons.xml +++ b/doc/man/scons.xml @@ -105,6 +105,7 @@ component pieces must be built or rebuilt and invoking the necessary commands to build them. &SCons; offers many features to improve developer productivity such as parallel builds, caching of build artifacts, +automatic dependency scanning, and a database of information about previous builds so details do not have to be recalculated each run. @@ -123,7 +124,7 @@ build system by writing a script that describes things to build (targets), and, if necessary, the rules to build those files (actions). &SCons; comes with a collection of Builder methods -which apply premade rules for building many common software components +which apply premade actions for building many common software components such as executable programs, object files and libraries, so that for many software projects, only the targets and input files (sources) @@ -131,7 +132,7 @@ need be specified in a call to a builder. &scons; thus can operate at a level of abstraction above that of pure files. For example if you specify a library target named "foo", &scons; keeps track of the actual operating system dependent filename -(for example libfoo.so on a GNU/Linux system), +(such as libfoo.so on a GNU/Linux system), and how to refer to that library in later construction steps that want to use it, so you don't have to specify that precise information yourself. @@ -146,7 +147,7 @@ looks for a file named &SConstruct; in the current directory and reads the build configuration from that file -(other names are possible, +(other names are allowed, see for more information). The &SConstruct; file may specify subsidiary @@ -158,7 +159,7 @@ these subsidiary files are named although any name may be used. As a result of this naming convention, the term SConscript files -is often used to refer +is used to refer generically to the complete set of configuration files for a project (including the &SConstruct; file), @@ -292,14 +293,14 @@ integration setups. &scons; -can scan known input files automatically for dependency +can scan known input file types automatically for dependency information (for example, #include preprocessor directives in C or C++ files) and will rebuild dependent files appropriately whenever any "included" input file changes. &scons; supports the -ability to define new scanners for unknown input file types. +ability to define new scanners to support additional input file types. &scons; is normally executed in a top-level directory containing an @@ -309,9 +310,7 @@ the command line (including the contents of the &SCONSFLAGS; environment variable, if set) is processed. Command-line options (see ) are consumed. -Any variable argument assignments -(see ) -are collected, and +Any variable argument assignments are collected, and remaining arguments are taken as targets to build. Values of variables to be passed to the SConscript files @@ -341,6 +340,11 @@ if necessary. Each &ARGLIST; entry is a tuple containing (argname, argvalue). + +See +for more information. + + &scons; can maintain a cache of target (derived) files that can be shared between multiple builds. When derived-file caching is enabled in an @@ -429,7 +433,7 @@ and are made available in the -If there are no targets from the previous steps, +If no targets are selected by the previous steps, &scons; selects the current directory for scanning, unless command-line options which affect the target scan are detected -- cgit v0.12 From 576f2cdf248efce2f7e16c51dbe08801811ab99b Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Fri, 7 May 2021 10:11:00 -0600 Subject: Make sure SetOption list is up to date Signed-off-by: Mats Wichmann --- SCons/Script/Main.xml | 62 +++++++++++++++++++++++++++++++++++++++----- SCons/Script/SConsOptions.py | 21 ++++++++------- doc/man/scons.xml | 3 ++- 3 files changed, 69 insertions(+), 17 deletions(-) diff --git a/SCons/Script/Main.xml b/SCons/Script/Main.xml index 4935f88..74bb40a 100644 --- a/SCons/Script/Main.xml +++ b/SCons/Script/Main.xml @@ -787,9 +787,9 @@ The settable variables with their associated command-line options are: - + -VariableCommand-line options +VariableCommand-line optionsNotes @@ -797,19 +797,19 @@ The settable variables with their associated command-line options are: , , + diskcheck - + duplicate - experimental @@ -817,30 +817,74 @@ The settable variables with their associated command-line options are: + + since 4.2 + + +hash_chunksize + + + +since 4.2 + + + +hash_format + + + +since 4.2 + help , + implicit_cache + + since 4.2 + +implicit_deps_changed + + + +Also sets +implicit_cache +(since 4.2) + + + +implicit_deps_unchanged + + + +Also sets +implicit_cache +(since 4.2) + + + max_drift + md5_chunksize + no_exec @@ -848,35 +892,41 @@ The settable variables with their associated command-line options are: , , + no_progress + num_jobs , + random + silent -. + + stack_size + warn -. + diff --git a/SCons/Script/SConsOptions.py b/SCons/Script/SConsOptions.py index 0233703..cb4cf1d 100644 --- a/SCons/Script/SConsOptions.py +++ b/SCons/Script/SConsOptions.py @@ -129,28 +129,31 @@ class SConsValues(optparse.Values): 'clean', 'diskcheck', 'duplicate', + 'experimental', + 'hash_chunksize', 'hash_format', 'help', 'implicit_cache', 'max_drift', 'md5_chunksize', 'no_exec', + 'no_progress', 'num_jobs', 'random', + 'silent', 'stack_size', 'warn', - 'silent', - 'no_progress', - 'experimental', ] def set_option(self, name, value): - """ - Sets an option from an SConscript file. - """ + """Sets an option from an SConscript file.""" + if name not in self.settable: - raise SCons.Errors.UserError("This option is not settable from a SConscript file: %s"%name) + raise SCons.Errors.UserError( + "This option is not settable from a SConscript file: %s" % name + ) + # the following are for options that need some extra processing if name == 'num_jobs': try: value = int(value) @@ -188,7 +191,7 @@ class SConsValues(optparse.Values): value = int(value) except ValueError: raise SCons.Errors.UserError("An integer is required: %s"%repr(value)) - elif name == 'md5_chunksize': + elif name in ('md5_chunksize', 'hash_chunksize'): try: value = int(value) except ValueError: @@ -205,8 +208,6 @@ class SConsValues(optparse.Values): value = [value] value = self.__SConscript_settings__.get(name, []) + value - - self.__SConscript_settings__[name] = value diff --git a/doc/man/scons.xml b/doc/man/scons.xml index 0fba467..165d906 100644 --- a/doc/man/scons.xml +++ b/doc/man/scons.xml @@ -1124,7 +1124,7 @@ the mechanisms in the specified order. - + , @@ -1132,6 +1132,7 @@ the mechanisms in the specified order. Enable experimental features and/or tools. No Support offered for any features or tools enabled by this flag The default setting is none. + Available since &scons; 4.2. -- cgit v0.12 From 17536127a3978b0ae816e3a1a17208aeaf7e8361 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Sat, 8 May 2021 08:14:01 -0600 Subject: Enable SetOption for implicit_deps* The SetOption table in the docs is reformatted for easier editing. Signed-off-by: Mats Wichmann --- CHANGES.txt | 4 + SCons/Script/Main.xml | 282 +++++++++++++++++++++---------------------- SCons/Script/SConsOptions.py | 30 +++-- 3 files changed, 163 insertions(+), 153 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index ff4ae28..7f6f7cb 100755 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -93,6 +93,10 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER of warnings in some tools which instantiated the class but did nothing with them, need to instead call SCons.Warnings.warn with the warn class. - Drop overridden changed_since_last_build method in Value class. + - Resync the SetOption implementation and the manpage, making sure new + options are available and adding a notes column for misc information. + SetOption equivalents to --hash-chunksize, --implicit-deps-unchanged + and --implicit-deps-changed are enabled. From Dillan Mills: - Add support for the (TARGET,SOURCE,TARGETS,SOURCES,CHANGED_TARGETS,CHANGED_SOURCES}.relpath property. diff --git a/SCons/Script/Main.xml b/SCons/Script/Main.xml index 74bb40a..ce21ee1 100644 --- a/SCons/Script/Main.xml +++ b/SCons/Script/Main.xml @@ -768,15 +768,21 @@ Multiple targets can be passed in to a single call to Sets &scons; option variable name to value. These options are all also settable via -&scons; command-line options but the variable name -may differ from the command-line option name (see table). +command-line options but the variable name +may differ from the command-line option name - +see the table for correspondences. A value set via command-line option will take precedence over one set with &f-SetOption;, which allows setting a project default in the scripts and temporarily overriding it via command line. +Project-wide +&f-SetOption; calls can also be placed in the +site_init.py file. + + Options which affect the reading and processing of SConscript files -are not settable this way, since those files must -be read in order to find the &f-SetOption; call. +are not settable using &f-SetOption; since those files must +be read in order to find the &f-SetOption; call in the first place. @@ -789,145 +795,127 @@ The settable variables with their associated command-line options are: -VariableCommand-line optionsNotes + + Variable + Command-line options + Notes + + - -clean - -, , - - - -diskcheck - - - - - -duplicate - - - - - - - experimental - - - - - - since 4.2 - - - - -hash_chunksize - - - -since 4.2 - - - -hash_format - - - -since 4.2 - - - -help - -, - - - -implicit_cache - - - - since 4.2 - - - - -implicit_deps_changed - - - -Also sets -implicit_cache -(since 4.2) - - - -implicit_deps_unchanged - - - -Also sets -implicit_cache -(since 4.2) - - - -max_drift - - - - - -md5_chunksize - - - - - -no_exec - -, , -, , - - - - -no_progress - - - - - -num_jobs - -, - - - -random - - - - - -silent - - - - - -stack_size - - - - - -warn - - - + + clean + + , + , + + + + + + diskcheck + + + + + duplicate + + + + + experimental + + since 4.2 + + + + hash_chunksize + + since 4.2 + + + + hash_format + + since 4.2 + + + + help + , + + + + implicit_cache + + since 4.2 + + + + implicit_deps_changed + + Also sets implicit_cache + (since 4.2) + + + + implicit_deps_unchanged + + Also sets implicit_cache + (since 4.2) + + + + max_drift + + + + + md5_chunksize + + + + + no_exec + + , + , + , + , + + + + + + no_progress + + + + + num_jobs + , + + + + random + + + + + silent + + + + + stack_size + + + + + warn + + + @@ -935,15 +923,19 @@ Also sets See the documentation in the manpage for the corresponding command line option for information about each specific option. -Option values which are boolean in nature (that is, they are -either on or off) should be set to a true value (True, -1) or a false value (False, +The value parameter is mandatory, +for option values which are boolean in nature +(that is, the command line option does not take an argument) +use a value +which evaluates to true (e.g. True, +1) or false (e.g. False, 0). If no_progress is set via &f-SetOption; +in an SConscript file, there will still be initial progress output as &SCons; has to start reading SConscript files before it can see the &f-SetOption; in an SConscript file: @@ -956,7 +948,7 @@ Example: -SetOption('max_drift', True) +SetOption('max_drift', 0) diff --git a/SCons/Script/SConsOptions.py b/SCons/Script/SConsOptions.py index cb4cf1d..4988a8d 100644 --- a/SCons/Script/SConsOptions.py +++ b/SCons/Script/SConsOptions.py @@ -134,6 +134,8 @@ class SConsValues(optparse.Values): 'hash_format', 'help', 'implicit_cache', + 'implicit_deps_changed', + 'implicit_deps_unchanged', 'max_drift', 'md5_chunksize', 'no_exec', @@ -146,7 +148,11 @@ class SConsValues(optparse.Values): ] def set_option(self, name, value): - """Sets an option from an SConscript file.""" + """Sets an option from an SConscript file. + + Raises: + UserError: invalid or malformed option ("error in your script") + """ if name not in self.settable: raise SCons.Errors.UserError( @@ -160,19 +166,23 @@ class SConsValues(optparse.Values): if value < 1: raise ValueError except ValueError: - raise SCons.Errors.UserError("A positive integer is required: %s"%repr(value)) + raise SCons.Errors.UserError( + "A positive integer is required: %s" % repr(value) + ) elif name == 'max_drift': try: value = int(value) except ValueError: - raise SCons.Errors.UserError("An integer is required: %s"%repr(value)) + raise SCons.Errors.UserError("An integer is required: %s" % repr(value)) elif name == 'duplicate': try: value = str(value) except ValueError: - raise SCons.Errors.UserError("A string is required: %s"%repr(value)) + raise SCons.Errors.UserError("A string is required: %s" % repr(value)) if value not in SCons.Node.FS.Valid_Duplicates: - raise SCons.Errors.UserError("Not a valid duplication style: %s" % value) + raise SCons.Errors.UserError( + "Not a valid duplication style: %s" % value + ) # Set the duplicate style right away so it can affect linking # of SConscript files. SCons.Node.FS.set_duplicate(value) @@ -180,7 +190,7 @@ class SConsValues(optparse.Values): try: value = diskcheck_convert(value) except ValueError as v: - raise SCons.Errors.UserError("Not a valid diskcheck value: %s"%v) + raise SCons.Errors.UserError("Not a valid diskcheck value: %s" % v) if 'diskcheck' not in self.__dict__: # No --diskcheck= option was specified on the command line. # Set this right away so it can affect the rest of the @@ -190,12 +200,13 @@ class SConsValues(optparse.Values): try: value = int(value) except ValueError: - raise SCons.Errors.UserError("An integer is required: %s"%repr(value)) + raise SCons.Errors.UserError("An integer is required: %s" % repr(value)) elif name in ('md5_chunksize', 'hash_chunksize'): try: value = int(value) except ValueError: - raise SCons.Errors.UserError("An integer is required: %s"%repr(value)) + raise SCons.Errors.UserError("An integer is required: %s" % repr(value)) + name = 'md5_chunksize' # for now, the old name is used elif name == 'warn': if SCons.Util.is_String(value): value = [value] @@ -207,6 +218,9 @@ class SConsValues(optparse.Values): if SCons.Util.is_String(value): value = [value] value = self.__SConscript_settings__.get(name, []) + value + elif name in ('implicit_deps_changed', 'implicit_deps_unchanged'): + if value: + self.__SConscript_settings__['implicit_cache'] = True self.__SConscript_settings__[name] = value -- cgit v0.12 From 29e5392ee9c7d99a01855ec47c492923d532c190 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Mon, 10 May 2021 10:19:21 -0600 Subject: Add tests for SetOption failing on illegal options and values Signed-off-by: Mats Wichmann --- CHANGES.txt | 1 + test/GetOption/BadSetOption.py | 65 ++++++++++++++++++++++++++++++++++++++++++ test/GetOption/GetSetOption.py | 58 +++++++++++++++++++++++++++++++++++++ test/GetOption/help.py | 7 ++--- test/GetSetOption.py | 59 -------------------------------------- 5 files changed, 127 insertions(+), 63 deletions(-) create mode 100644 test/GetOption/BadSetOption.py create mode 100644 test/GetOption/GetSetOption.py delete mode 100644 test/GetSetOption.py diff --git a/CHANGES.txt b/CHANGES.txt index 7f6f7cb..6e2bf94 100755 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -97,6 +97,7 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER options are available and adding a notes column for misc information. SetOption equivalents to --hash-chunksize, --implicit-deps-unchanged and --implicit-deps-changed are enabled. + - Add tests for SetOption failing on disallowed options and value types. From Dillan Mills: - Add support for the (TARGET,SOURCE,TARGETS,SOURCES,CHANGED_TARGETS,CHANGED_SOURCES}.relpath property. diff --git a/test/GetOption/BadSetOption.py b/test/GetOption/BadSetOption.py new file mode 100644 index 0000000..997ff15 --- /dev/null +++ b/test/GetOption/BadSetOption.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python +# +# MIT License +# +# Copyright The SCons Foundation +# +# 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. + +""" +Test that invalid SetOption calls generate expected errors. +""" + +import TestSCons +from TestSCons import file_expr + +test = TestSCons.TestSCons() + +badopts = ( + ("no_such_var", True, "This option is not settable from a SConscript file: no_such_var"), + ("num_jobs", -22, "A positive integer is required: -22"), + ("max_drift", "'Foo'", "An integer is required: 'Foo'"), + ("duplicate", "'cookie'", "Not a valid duplication style: cookie"), + ("diskcheck", "'off'", "Not a valid diskcheck value: off"), + ("md5_chunksize", "'big'", "An integer is required: 'big'"), + ("hash_chunksize", "'small'", "An integer is required: 'small'"), +) + +for opt, value, expect in badopts: + SConstruct = "SC-" + opt + test.write( + SConstruct, + """\ +DefaultEnvironment(tools=[]) +SetOption("%(opt)s", %(value)s) +""" + % locals(), + ) + expect = r"scons: *** %s" % expect + test.run(arguments='-Q -f %s .' % SConstruct, stderr=None, status=2) + test.must_contain_all(test.stderr(), expect) + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/GetOption/GetSetOption.py b/test/GetOption/GetSetOption.py new file mode 100644 index 0000000..e773ec6 --- /dev/null +++ b/test/GetOption/GetSetOption.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python +# +# MIT License +# +# Copyright The SCons Foundation +# +# 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. + +""" +Test getting and setting options through global functions +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.write('SConstruct', """ +env = Environment() +option_list = ['clean', 'implicit_cache', 'max_drift', 'num_jobs'] +val = 1 +for option in option_list: + SetOption(option, val) + o = env.GetOption(option) + assert o == val, "%s %s != %s" % (option, o, val) + val = val + 1 +for option in option_list: + env.SetOption(option, val) + o = GetOption(option) + assert o == val, "%s %s != %s" % (option, o, val) + val = val + 1 +""") + +test.run(arguments = '.') + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/GetOption/help.py b/test/GetOption/help.py index f83dc54..ebca99f 100644 --- a/test/GetOption/help.py +++ b/test/GetOption/help.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # 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 use of GetOption('help') to short-circuit work. diff --git a/test/GetSetOption.py b/test/GetSetOption.py deleted file mode 100644 index 929f8d0..0000000 --- a/test/GetSetOption.py +++ /dev/null @@ -1,59 +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__" - -""" -Test getting and setting options through global functions -""" - -import TestSCons - -test = TestSCons.TestSCons() - -test.write('SConstruct', """ -env = Environment() -option_list = ['clean', 'implicit_cache', 'max_drift', 'num_jobs'] -val = 1 -for option in option_list: - SetOption(option, val) - o = env.GetOption(option) - assert o == val, "%s %s != %s" % (option, o, val) - val = val + 1 -for option in option_list: - env.SetOption(option, val) - o = GetOption(option) - assert o == val, "%s %s != %s" % (option, o, val) - val = val + 1 -""") - -test.run(arguments = '.') - -test.pass_test() - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: -- cgit v0.12 From a3bb2b9f4235072e5e39e73e7568ab2633368040 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Mon, 10 May 2021 10:25:08 -0600 Subject: Fix sider complain about unused import Left a symbol import from an interim version, and sider decided to complain! Signed-off-by: Mats Wichmann --- test/GetOption/BadSetOption.py | 1 - 1 file changed, 1 deletion(-) diff --git a/test/GetOption/BadSetOption.py b/test/GetOption/BadSetOption.py index 997ff15..7b0a33d 100644 --- a/test/GetOption/BadSetOption.py +++ b/test/GetOption/BadSetOption.py @@ -28,7 +28,6 @@ Test that invalid SetOption calls generate expected errors. """ import TestSCons -from TestSCons import file_expr test = TestSCons.TestSCons() -- cgit v0.12 From 91d46fc9be159ad0455b03eb00916bee3d2c3ee6 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Tue, 11 May 2021 11:11:29 -0600 Subject: Update the documentation for GetOption Since working on Get/SetOption anyway via tests, update the documentation as well. GetOption now has a table (instead of a spread out list) to match SetOption, and the available vars are all listed, as well as a note on AddOption'd vars. Signed-off-by: Mats Wichmann --- SCons/Script/Main.xml | 562 ++++++++++++++++++++--------------------- test/GetOption/GetSetOption.py | 3 +- test/GetOption/help.py | 6 +- 3 files changed, 282 insertions(+), 289 deletions(-) diff --git a/SCons/Script/Main.xml b/SCons/Script/Main.xml index ce21ee1..f4f4705 100644 --- a/SCons/Script/Main.xml +++ b/SCons/Script/Main.xml @@ -317,261 +317,242 @@ atexit.register(print_build_failures) This function provides a way to query the value of -SCons options set on scons command line -(or set using the -&f-link-SetOption; -function). -The options supported are: +options which can be set via the command line or using the +&f-link-SetOption; function. - - - - -cache_debug - - -which corresponds to ; - - - - -cache_disable - - -which corresponds to ; - - - - -cache_force - - -which corresponds to ; - - - - -cache_show - - -which corresponds to ; - - - - -clean - - -which corresponds to , -and ; - - - - -config - - -which corresponds to ; - - - - -directory - - -which corresponds to and ; - - - - -diskcheck - - -which corresponds to ; - - - - -duplicate - - -which corresponds to ; - - - - -file - - -which corresponds to , , and ; - - - - -help - - -which corresponds to and ; - - - - -ignore_errors - - -which corresponds to ; - - - - -implicit_cache - - -which corresponds to ; - - - - -implicit_deps_changed - - -which corresponds to ; - - - - -implicit_deps_unchanged - - -which corresponds to ; - - - - -interactive - - -which corresponds to and ; - - - - -keep_going - - -which corresponds to and ; - - - - -max_drift - - -which corresponds to ; - - - - -no_exec - - -which corresponds to , -, , - and ; - - - - -no_site_dir - - -which corresponds to ; - - - - -num_jobs - - -which corresponds to and ; - - - - -profile_file - - -which corresponds to ; - - - - -question - -which corresponds to and ; - - - - -random - - -which corresponds to ; - - - - -repository - - -which corresponds to , and ; - - - - -silent - - -which corresponds to , and ; - - - - -site_dir - - -which corresponds to ; - - - - -stack_size - - -which corresponds to ; - - - - -taskmastertrace_file - - -which corresponds to ; and - - - - -warn - - -which corresponds to and . - - - - +name can be an entry from the following table, +which shows the corresponding command line arguments +that could affect the value. +name can be also be the destination +variable name from a project-specific option added using the +&f-link-AddOption; function, as long as the addition +happens prior to the &f-GetOption; call in the SConscript files. + + + + + Query name + Command-line options + Notes + + + + + + cache_debug + + + + cache_disable + + , + + + + + cache_force + + , + + + + + cache_readonly + + + + cache_show + + + + clean + + , + , + + + + + climb_up + + + + + + + + + + config + + + + debug + + + + directory + , + + + diskcheck + + + + duplicate + + + + enable_virtualenv + + + + experimental + + since 4.2 + + + file + + , + , + , + + + + + hash_format + + since 4.2 + + + help + , + + + ignore_errors + , + + + ignore_virtualenv + + + + implicit_cache + + + + implicit_deps_changed + + + + implicit_deps_unchanged + + + + include_dir + , + + + install_sandbox + + Available only if the &t-link-install; tool has been called + + + keep_going + , + + + max_drift + + + + md5_chunksize + + , + + + since 4.2 + + + no_exec + + , + , + , + , + + + + + no_progress + + + + num_jobs + , + + + package_type + + Available only if the &t-link-packaging; tool has been called + + + profile_file + + + + question + , + + + random + + + + repository + + , + , + + + + + silent + + , + , + + + + + site_dir + , + + + stack_size + + + + taskmastertrace_file + + + + tree_printers + + + + warn + , + + + + + + See the documentation for the corresponding command line option for information about each specific @@ -775,10 +756,22 @@ A value set via command-line option will take precedence over one set with &f-SetOption;, which allows setting a project default in the scripts and temporarily overriding it via command line. -Project-wide &f-SetOption; calls can also be placed in the site_init.py file. + + +See the documentation in the manpage for the +corresponding command line option for information about each specific option. +The value parameter is mandatory, +for option values which are boolean in nature +(that is, the command line option does not take an argument) +use a value +which evaluates to true (e.g. True, +1) or false (e.g. False, +0). + + Options which affect the reading and processing of SConscript files are not settable using &f-SetOption; since those files must @@ -796,9 +789,9 @@ The settable variables with their associated command-line options are: - Variable - Command-line options - Notes + Settable name + Command-line options + Notes @@ -831,7 +824,10 @@ The settable variables with their associated command-line options are: hash_chunksize - since 4.2 + + Actually sets md5_chunksize. + since 4.2 + @@ -848,21 +844,24 @@ The settable variables with their associated command-line options are: implicit_cache - since 4.2 implicit_deps_changed - Also sets implicit_cache - (since 4.2) + + Also sets implicit_cache. + (settable since 4.2) + implicit_deps_unchanged - Also sets implicit_cache - (since 4.2) + + Also sets implicit_cache. + (settable since 4.2) + @@ -889,6 +888,18 @@ The settable variables with their associated command-line options are: no_progress + See + + If no_progress is set via &f-SetOption; + in an SConscript file + (but not if set in a site_init.py file) + there will still be an initial status message about + reading SConscript files since &SCons; has + to start reading them before it can see the + &f-SetOption;. + + + @@ -903,7 +914,11 @@ The settable variables with their associated command-line options are: silent - + + , + , + + @@ -921,29 +936,6 @@ The settable variables with their associated command-line options are: -See the documentation in the manpage for the -corresponding command line option for information about each specific option. -The value parameter is mandatory, -for option values which are boolean in nature -(that is, the command line option does not take an argument) -use a value -which evaluates to true (e.g. True, -1) or false (e.g. False, -0). - - - - -If no_progress is set via &f-SetOption; -in an SConscript file, -there will still be initial progress output as &SCons; has -to start reading SConscript files before it can see the -&f-SetOption; in an SConscript file: -scons: Reading SConscript files ... - - - - Example: diff --git a/test/GetOption/GetSetOption.py b/test/GetOption/GetSetOption.py index e773ec6..3ab3e7b 100644 --- a/test/GetOption/GetSetOption.py +++ b/test/GetOption/GetSetOption.py @@ -32,7 +32,8 @@ import TestSCons test = TestSCons.TestSCons() test.write('SConstruct', """ -env = Environment() +DefaultEnvironment(tools=[]) +env = Environment(tools=[]) option_list = ['clean', 'implicit_cache', 'max_drift', 'num_jobs'] val = 1 for option in option_list: diff --git a/test/GetOption/help.py b/test/GetOption/help.py index ebca99f..4db4bc8 100644 --- a/test/GetOption/help.py +++ b/test/GetOption/help.py @@ -39,14 +39,14 @@ else: print("no help for you") """) -test.run(arguments = '-q -Q', stdout = "no help for you\n") +test.run(arguments='-q -Q', stdout="no help for you\n") expect = "GetOption('help') set" -test.run(arguments = '-q -Q -h') +test.run(arguments='-q -Q -h') test.fail_test(test.stdout().split('\n')[0] != expect) -test.run(arguments = '-q -Q --help') +test.run(arguments='-q -Q --help') test.fail_test(test.stdout().split('\n')[0] != expect) test.pass_test() -- cgit v0.12 From 2909e28730ab72930f923b55f860d554f3b5e216 Mon Sep 17 00:00:00 2001 From: Andrew Morrow Date: Thu, 13 May 2021 13:22:51 -0400 Subject: 3790 - Add a test which fails --- test/CPPDEFINES/basic.py | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/test/CPPDEFINES/basic.py b/test/CPPDEFINES/basic.py index d0019a1..176f543 100644 --- a/test/CPPDEFINES/basic.py +++ b/test/CPPDEFINES/basic.py @@ -39,13 +39,24 @@ test_list = [ ['x', ['y', 123], 'z', ('int', '$INTEGER')], { 'c' : 3, 'b': None, 'a' : 1 }, "${TESTDEFS}", + "${GEN}", ] + +def generator(target, source, env, for_signature): + if target and source: + return '_'.join([str(target[0]), 'GENERATED', str(source[0])]) + return 'TARGET_AND_SOURCE_ARE_MISSING' + for i in test_list: - env = Environment(CPPDEFPREFIX='-D', CPPDEFSUFFIX='', INTEGER=0, TESTDEFS=["FOO", "BAR=1"]) - print(env.Clone(CPPDEFINES=i).subst('$_CPPDEFFLAGS')) + env = Environment(CPPDEFPREFIX='-D', CPPDEFSUFFIX='', INTEGER=0, TESTDEFS=["FOO", "BAR=1"], GEN=generator) + ttt = env.Entry('#ttt') + sss = env.Entry('#sss') + print(env.Clone(CPPDEFINES=i).subst('$_CPPDEFFLAGS', target=[ttt], source=[sss])) for i in test_list: - env = Environment(CPPDEFPREFIX='|', CPPDEFSUFFIX='|', INTEGER=1, TESTDEFS=["FOO", "BAR=1"]) - print(env.Clone(CPPDEFINES=i).subst('$_CPPDEFFLAGS')) + env = Environment(CPPDEFPREFIX='|', CPPDEFSUFFIX='|', INTEGER=1, TESTDEFS=["FOO", "BAR=1"], GEN=generator) + ttt = env.Entry('#ttt') + sss = env.Entry('#sss') + print(env.Clone(CPPDEFINES=i).subst('$_CPPDEFFLAGS', target=[ttt], source=[sss])) """) expect = test.wrap_stdout(build_str="scons: `.' is up to date.\n", @@ -55,11 +66,13 @@ expect = test.wrap_stdout(build_str="scons: `.' is up to date.\n", -Dx -Dy=123 -Dz -Dint=0 -Da=1 -Db -Dc=3 -DFOO -DBAR=1 +-Dttt_GENERATED_sss |xyz| |x| |y| |z| |x| |y=123| |z| |int=1| |a=1| |b| |c=3| |FOO| |BAR=1| +|ttt_GENERATED_sss| """) test.run(arguments = '.', stdout=expect) -- cgit v0.12 From 3467ea5877718f0e31d1718c35fddb108a410d64 Mon Sep 17 00:00:00 2001 From: Andrew Morrow Date: Thu, 13 May 2021 13:23:07 -0400 Subject: 3790 - Fix the failing test --- SCons/Defaults.py | 6 +++--- test/CPPDEFINES/basic.py | 0 2 files changed, 3 insertions(+), 3 deletions(-) mode change 100644 => 100755 test/CPPDEFINES/basic.py diff --git a/SCons/Defaults.py b/SCons/Defaults.py index ba42a26..95a2e52 100644 --- a/SCons/Defaults.py +++ b/SCons/Defaults.py @@ -498,12 +498,12 @@ def processDefines(defs): return l -def _defines(prefix, defs, suffix, env, c=_concat_ixes): +def _defines(prefix, defs, suffix, env, target, source, c=_concat_ixes): """A wrapper around _concat_ixes that turns a list or string into a list of C preprocessor command-line definitions. """ - return c(prefix, env.subst_list(processDefines(defs)), suffix, env) + return c(prefix, env.subst_list(processDefines(defs), target=target, source=source), suffix, env) class NullCmdGenerator: @@ -608,7 +608,7 @@ ConstructionEnvironment = { '_LIBFLAGS': '${_concat(LIBLINKPREFIX, LIBS, LIBLINKSUFFIX, __env__)}', '_LIBDIRFLAGS': '$( ${_concat(LIBDIRPREFIX, LIBPATH, LIBDIRSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)', '_CPPINCFLAGS': '$( ${_concat(INCPREFIX, CPPPATH, INCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)', - '_CPPDEFFLAGS': '${_defines(CPPDEFPREFIX, CPPDEFINES, CPPDEFSUFFIX, __env__)}', + '_CPPDEFFLAGS': '${_defines(CPPDEFPREFIX, CPPDEFINES, CPPDEFSUFFIX, __env__, TARGET, SOURCE)}', '__libversionflags': __libversionflags, '__SHLIBVERSIONFLAGS': '${__libversionflags(__env__,"SHLIBVERSION","_SHLIBVERSIONFLAGS")}', diff --git a/test/CPPDEFINES/basic.py b/test/CPPDEFINES/basic.py old mode 100644 new mode 100755 -- cgit v0.12 From d4caa2cf6939fcae4094ccc2201e57aa662f9790 Mon Sep 17 00:00:00 2001 From: Andrew Morrow Date: Thu, 13 May 2021 17:40:28 -0400 Subject: update changes and release --- CHANGES.txt | 4 ++++ RELEASE.txt | 2 ++ 2 files changed, 6 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index ff4ae28..89a1dac 100755 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -99,6 +99,10 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER This will provide a path relative to the top of the build tree (where the SConstruct is located) Fixes #396 + From Andrew Morrow: + - Fix issue #3790: Generators in CPPDEFINES now have access to populated source + and target lists + RELEASE 4.1.0 - Tues, 19 Jan 2021 15:04:42 -0700 From James Benton: diff --git a/RELEASE.txt b/RELEASE.txt index db64ee8..f5c1af3 100755 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -62,6 +62,8 @@ FIXES - The Install builder will now set the writable mode on the file(s) it copies. This restores the (previously undocumented) SCons behavior that regressed as of 4.0.0. + - Fix issue #3790: Generators in CPPDEFINES now have access to populated source + and target lists IMPROVEMENTS -- cgit v0.12