diff --git a/CHANGES.txt b/CHANGES.txt index 31407fb1fa..58950d7e53 100755 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -14,6 +14,11 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER those specified by SCons itself, or by AddOption() in SConstruct/SConscript. It should not be called until all AddOption() calls are completed. Resolves Issue #4187 + From Daniel Moody: + - Fix for github issue #2908, this updates taskmaster to queue up srcnodes of nodes which + are in a variantdir if the srcnode has a builder. For the executors prepare, it also + checks the srcnode if the node has a srcnode. + From Dan Mezhiborsky: - Add newline to end of compilation db (compile_commands.json). diff --git a/RELEASE.txt b/RELEASE.txt index 3eff8adbae..92472bb9ed 100755 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -33,9 +33,10 @@ CHANGED/ENHANCED EXISTING FUNCTIONALITY FIXES ----- -- List fixes of outright bugs - -- Added missing newline to generated compilation database (compile_commands.json) +- Fix for github issue #2908, this updates taskmaster to queue up srcnodes of nodes which + are in a variantdir if the srcnode has a builder. For the executors prepare, it also + checks the srcnode if the node has a srcnode. + IMPROVEMENTS ------------ diff --git a/SCons/Node/FS.py b/SCons/Node/FS.py index b4de337cec..4703da1f98 100644 --- a/SCons/Node/FS.py +++ b/SCons/Node/FS.py @@ -3012,6 +3012,8 @@ def retrieve_from_cache(self): if self.nocache: return None if not self.is_derived(): + if self.srcnode().is_derived(): + return self.get_build_env().get_CacheDir().retrieve(self.srcnode()) return None return self.get_build_env().get_CacheDir().retrieve(self) diff --git a/SCons/Node/__init__.py b/SCons/Node/__init__.py index ec742a686b..e56b326169 100644 --- a/SCons/Node/__init__.py +++ b/SCons/Node/__init__.py @@ -1264,7 +1264,11 @@ def get_contents(self): return _get_contents_map[self._func_get_contents](self) def missing(self): - return not self.is_derived() and \ + # nodes in variant dirs may have a srcnode which is also derived + # so check if that is the case. + return not (self.is_derived() or \ + (hasattr(self, 'srcnode') + and self.srcnode().is_derived())) and \ not self.linked and \ not self.rexists() diff --git a/SCons/Taskmaster.py b/SCons/Taskmaster.py index d57179545b..9c0cf00a2e 100644 --- a/SCons/Taskmaster.py +++ b/SCons/Taskmaster.py @@ -181,6 +181,8 @@ def prepare(self): # or implicit dependencies exists, and also initialize the # .sconsign info. executor = self.targets[0].get_executor() + if executor is None and hasattr(self.targets[0], 'srcnode'): + executor = self.targets[0].srcnode().get_executor() if executor is None: return executor.prepare() @@ -232,7 +234,12 @@ def execute(self): t.fs.unlink(t.get_internal_path()) except (IOError, OSError): pass - self.targets[0].build() + if self.targets[0].has_builder(): + self.targets[0].build() + elif hasattr(self.targets[0], 'srcnode'): + self.targets[0].srcnode().build() + else: + self.targets[0].build() else: for t in cached_targets: t.cached = 1 @@ -387,7 +394,7 @@ def make_ready_current(self): for t in self.targets: try: t.disambiguate().make_ready() - is_up_to_date = not t.has_builder() or \ + is_up_to_date = not (t.has_builder() or (hasattr(t, 'srcnode') and t.srcnode().has_builder())) or \ (not t.always_build and t.is_up_to_date()) except EnvironmentError as e: raise SCons.Errors.BuildError(node=t, errstr=e.strerror, filename=e.filename) @@ -946,11 +953,12 @@ def next_task(self): it in the specific Task subclass with which we were initialized. """ node = self._find_next_ready_node() - if node is None: return None executor = node.get_executor() + if executor is None and hasattr(node, 'srcnode'): + executor = node.srcnode().get_executor() if executor is None: return None diff --git a/test/VariantDir/derived_srcnode-fixture/SConstruct b/test/VariantDir/derived_srcnode-fixture/SConstruct new file mode 100644 index 0000000000..38f57c2438 --- /dev/null +++ b/test/VariantDir/derived_srcnode-fixture/SConstruct @@ -0,0 +1,3 @@ +VariantDir('bin', 'src', duplicate=False) +Command('src/file.cc', 'src/file.in', Copy('$TARGET', '$SOURCE')) +Program('bin/program', ['bin/main.cc', 'bin/file.cc']) diff --git a/test/VariantDir/derived_srcnode-fixture/src/file.in b/test/VariantDir/derived_srcnode-fixture/src/file.in new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/VariantDir/derived_srcnode-fixture/src/main.cc b/test/VariantDir/derived_srcnode-fixture/src/main.cc new file mode 100644 index 0000000000..6a86477b67 --- /dev/null +++ b/test/VariantDir/derived_srcnode-fixture/src/main.cc @@ -0,0 +1 @@ +int main(){return 0;} \ No newline at end of file diff --git a/test/VariantDir/derived_srcnode.py b/test/VariantDir/derived_srcnode.py new file mode 100644 index 0000000000..e637cfeef7 --- /dev/null +++ b/test/VariantDir/derived_srcnode.py @@ -0,0 +1,51 @@ +#!/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 reproducing issue https://github.com/SCons/scons/issues/2908 +The test makes sure that if the srcnode of a variant dir is +a derived file, that it is built correctly. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +obj_suffix = TestSCons._obj + +test.dir_fixture('derived_srcnode-fixture') + +test.run(arguments='.') + +test.must_exist(test.workpath('src/file.cc')) +test.must_exist(test.workpath('bin/file' + obj_suffix)) + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: