diff --git a/CHANGES.txt b/CHANGES.txt index d907867c13..f8e612169f 100755 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -25,6 +25,14 @@ 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 Adam Gross: + - Fix an issue causing scanners to receive incorrect paths when the + environment contains a Directory node that is a subdirectory of the + source root directory, the environment variable used by the scanner + (e.g. env['LIBPATH']) references a subdirectory of that directory node, + and a SConscript file is being run that is not in the source root + directory. + 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']) @@ -145,7 +153,6 @@ RELEASE 4.1.0 - Tues, 19 Jan 2021 15:04:42 -0700 - Fix python3 crash when Value node get_text_content when child content does not have decode() NOTE: If you depend on Value node's get_text_content returning concatenated contents of it's children. This may break your code. It now concatenates the csig() of all children. ->>>>>>> master From Joachim Kuebart: - Suppress missing SConscript deprecation warning if `must_exist=False` diff --git a/SCons/PathList.py b/SCons/PathList.py index a7e666dfa6..955a3fd6f1 100644 --- a/SCons/PathList.py +++ b/SCons/PathList.py @@ -20,6 +20,7 @@ # 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. +# """Handle lists of directory paths. @@ -43,6 +44,7 @@ TYPE_STRING_SUBST = 1 # string containing '$' TYPE_OBJECT = 2 # other object + def node_conv(obj): """ This is the "string conversion" routine that we have our substitutions @@ -63,6 +65,7 @@ def node_conv(obj): result = get() return result + class _PathList: """ An actual PathList object. @@ -123,15 +126,20 @@ def subst_path(self, env, target, source): PathList for a specific target and source. """ result = [] - for type, value in self.pathlist: - if type == TYPE_STRING_SUBST: - value = env.subst(value, target=target, source=source, - conv=node_conv) + for pathlist_type, value in self.pathlist: + if pathlist_type == TYPE_STRING_SUBST: + # We override conv below to use absolute paths when possible. + # This avoids problems with relative paths when the target's + # working directory is different than the FS object's working + # directory. + value = env.subst( + value, target=target, source=source, + conv=lambda x: x.abspath if hasattr(x, 'abspath') else x) if SCons.Util.is_Sequence(value): result.extend(SCons.Util.flatten(value)) elif value: result.append(value) - elif type == TYPE_OBJECT: + elif pathlist_type == TYPE_OBJECT: value = node_conv(value) if value: result.append(value) diff --git a/test/ScannerAbsPathCheck/fixture/SConstruct b/test/ScannerAbsPathCheck/fixture/SConstruct new file mode 100644 index 0000000000..95473cdd6a --- /dev/null +++ b/test/ScannerAbsPathCheck/fixture/SConstruct @@ -0,0 +1,43 @@ +import os +import sys +import SCons.Scanner + +sdk_root = None + +def verify_paths(node, env, scanpaths, arg): + """Verifies that the paths provided are as expected.""" + global sdk_root + sdk_root_subdir = os.path.join(sdk_root, 'sdk_subdir') + if len(scanpaths) != 2: + raise Exception('Expected two entries in scanpaths') + if scanpaths[0].abspath != sdk_root: + raise Exception('Expected first scanpath=%s, got %s.' % + (sdk_root, scanpaths[0].abspath)) + if scanpaths[1].abspath != sdk_root_subdir: + raise Exception('Expected second scanpath=%s, got %s.' % + (sdk_root_subdir, scanpaths[1].abspath)) + return [] + + +# Create a scanner that generates a path using the variables in env['PYPATH']. +pyscan = Scanner(name='pythonfile', + function=verify_paths, + argument=None, + path_function=SCons.Scanner.FindPathDirs('PYPATH'), + skeys=['.py']) + +# Create a builder that uses that scanner. +b = Builder(action='$PYTHON $SOURCE', source_scanner=pyscan) + +env = Environment(BUILDERS={'DummyPythonBuilder': b}) + +# Now set some variables that are needed by the scanner and/or the SConscript. +env.Replace( + PYTHON=sys.executable, + PYPATH=['$SDKROOT', '$SDKROOT/sdk_subdir'], + SDKROOT=env.Dir('sdk'), +) +sdk_root = env['SDKROOT'].abspath + +Export('env') +SConscript('subdir/SConscript', exports='env') diff --git a/test/ScannerAbsPathCheck/fixture/subdir/SConscript b/test/ScannerAbsPathCheck/fixture/subdir/SConscript new file mode 100644 index 0000000000..16f3513238 --- /dev/null +++ b/test/ScannerAbsPathCheck/fixture/subdir/SConscript @@ -0,0 +1,2 @@ +Import('env') +env.DummyPythonBuilder(target=['foo'], source=['empty.py']) diff --git a/test/ScannerAbsPathCheck/fixture/subdir/empty.py b/test/ScannerAbsPathCheck/fixture/subdir/empty.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/ScannerAbsPathCheck/fixture/subdir/sconstest.skip b/test/ScannerAbsPathCheck/fixture/subdir/sconstest.skip new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/ScannerAbsPathCheck/test.py b/test/ScannerAbsPathCheck/test.py new file mode 100644 index 0000000000..41f199f16d --- /dev/null +++ b/test/ScannerAbsPathCheck/test.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python +# +# 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. +# + +""" +This test verifies that a scanner retrieves the correct paths when +path_function is set to SCons.Scanner.FindPathDirs(some_var) and env[some_var] +contains paths relative to the SConstruct root. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.dir_fixture('fixture') +test.run() + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: