diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/CHANGES.txt | 24 | ||||
-rw-r--r-- | src/engine/MANIFEST.in | 7 | ||||
-rw-r--r-- | src/engine/SCons/Executor.py | 8 | ||||
-rw-r--r-- | src/engine/SCons/Job.py | 38 | ||||
-rw-r--r-- | src/engine/SCons/Node/FS.py | 14 | ||||
-rw-r--r-- | src/engine/SCons/Options/BoolOption.py | 35 | ||||
-rw-r--r-- | src/engine/SCons/Options/EnumOption.py | 35 | ||||
-rw-r--r-- | src/engine/SCons/Options/ListOption.py | 35 | ||||
-rw-r--r-- | src/engine/SCons/Options/PackageOption.py | 35 | ||||
-rw-r--r-- | src/engine/SCons/Options/PathOption.py | 35 | ||||
-rw-r--r-- | src/engine/SCons/Options/__init__.py (renamed from src/engine/SCons/Options.py) | 12 | ||||
-rw-r--r-- | src/engine/SCons/Taskmaster.py | 120 | ||||
-rw-r--r-- | src/engine/SCons/TaskmasterTests.py | 25 | ||||
-rw-r--r-- | src/engine/SCons/Tool/FortranCommon.py | 2 | ||||
-rw-r--r-- | src/engine/SCons/Tool/c++.py | 2 | ||||
-rw-r--r-- | src/engine/SCons/Tool/g++.py | 14 | ||||
-rw-r--r-- | src/setup.py | 1 |
17 files changed, 337 insertions, 105 deletions
diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 37422bc..8a3515f 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -8,6 +8,30 @@ +RELEASE XXX - XXX + + From Greg Noel: + + - Fix use of $CXXFLAGS when building C++ shared object files. + + From Steven Knight: + + - Fix a regression when a Builder's source_scanner doesn't select + a more specific scanner for the suffix of a specified source file. + + - Fix the Options object backwards compatibility so people can still + "import SCons.Options.{Bool,Enum,List,Package,Path}Option" submodules. + + - Fix searching for implicit dependencies when an Entry Node shows up + in the search path list. + + From Stefano: + + - Fix expansion of $FORTRANMODDIR in the default Fortran command line(s) + when it's set to something like ${TARGET.dir}. + + + RELEASE 0.98.2 - Sun, 20 Apr 2008 23:38:56 -0700 From Steven Knight: diff --git a/src/engine/MANIFEST.in b/src/engine/MANIFEST.in index 4c8b7a7..f220946 100644 --- a/src/engine/MANIFEST.in +++ b/src/engine/MANIFEST.in @@ -28,7 +28,12 @@ SCons/Node/__init__.py SCons/Node/Alias.py SCons/Node/FS.py SCons/Node/Python.py -SCons/Options.py +SCons/Options/__init__.py +SCons/Options/BoolOption.py +SCons/Options/EnumOption.py +SCons/Options/ListOption.py +SCons/Options/PackageOption.py +SCons/Options/PathOption.py SCons/PathList.py SCons/Platform/__init__.py SCons/Platform/aix.py diff --git a/src/engine/SCons/Executor.py b/src/engine/SCons/Executor.py index a9417bc..435b54c 100644 --- a/src/engine/SCons/Executor.py +++ b/src/engine/SCons/Executor.py @@ -237,11 +237,11 @@ class Executor: if scanner: for node in node_list: node.disambiguate() - scanner = scanner.select(node) - if not scanner: + s = scanner.select(node) + if not s: continue - path = self.get_build_scanner_path(scanner) - deps.extend(node.get_implicit_deps(env, scanner, path)) + path = self.get_build_scanner_path(s) + deps.extend(node.get_implicit_deps(env, s, path)) else: kw = self.get_kw() for node in node_list: diff --git a/src/engine/SCons/Job.py b/src/engine/SCons/Job.py index d93952c..545df98 100644 --- a/src/engine/SCons/Job.py +++ b/src/engine/SCons/Job.py @@ -49,6 +49,18 @@ default_stack_size = 256 interrupt_msg = 'Build interrupted.' + +class InterruptState: + def __init__(self): + self.interrupted = False + + def set(self): + self.interrupted = True + + def __call__(self): + return self.interrupted + + class Jobs: """An instance of this class initializes N jobs, and provides methods for starting, stopping, and waiting on all N jobs. @@ -84,8 +96,6 @@ class Jobs: self.job = Serial(taskmaster) self.num_jobs = 1 - self.job.interrupted = False - def run(self, postfunc=lambda: None): """Run the jobs. @@ -104,7 +114,7 @@ class Jobs: def were_interrupted(self): """Returns whether the jobs were interrupted by a signal.""" - return self.job.interrupted + return self.job.interrupted() def _setup_sig_handler(self): """Setup an interrupt handler so that SCons can shutdown cleanly in @@ -127,10 +137,10 @@ class Jobs: SCons forks before executing another process. In that case, we want the child to exit immediately. """ - def handler(signum, stack, parentpid=os.getpid()): + def handler(signum, stack, self=self, parentpid=os.getpid()): if os.getpid() == parentpid: self.job.taskmaster.stop() - self.job.interrupted = True + self.job.interrupted.set() else: os._exit(2) @@ -170,6 +180,7 @@ class Serial: execute (e.g. execute() raised an exception).""" self.taskmaster = taskmaster + self.interrupted = InterruptState() def start(self): """Start the job. This will begin pulling tasks from the taskmaster @@ -188,7 +199,7 @@ class Serial: if task.needs_execute(): task.execute() except: - if self.interrupted: + if self.interrupted(): try: raise SCons.Errors.BuildError( task.targets[0], errstr=interrupt_msg) @@ -221,11 +232,12 @@ else: dequeues the task, executes it, and posts a tuple including the task and a boolean indicating whether the task executed successfully. """ - def __init__(self, requestQueue, resultsQueue): + def __init__(self, requestQueue, resultsQueue, interrupted): threading.Thread.__init__(self) self.setDaemon(1) self.requestQueue = requestQueue self.resultsQueue = resultsQueue + self.interrupted = interrupted self.start() def run(self): @@ -239,6 +251,9 @@ else: break try: + if self.interrupted(): + raise SCons.Errors.BuildError( + task.targets[0], errstr=interrupt_msg) task.execute() except: task.exception_set() @@ -251,7 +266,7 @@ else: class ThreadPool: """This class is responsible for spawning and managing worker threads.""" - def __init__(self, num, stack_size): + def __init__(self, num, stack_size, interrupted): """Create the request and reply queues, and 'num' worker threads. One must specify the stack size of the worker threads. The @@ -277,7 +292,7 @@ else: # Create worker threads self.workers = [] for _ in range(num): - worker = Worker(self.requestQueue, self.resultsQueue) + worker = Worker(self.requestQueue, self.resultsQueue, interrupted) self.workers.append(worker) # Once we drop Python 1.5 we can change the following to: @@ -348,7 +363,8 @@ else: multiple tasks simultaneously. """ self.taskmaster = taskmaster - self.tp = ThreadPool(num, stack_size) + self.interrupted = InterruptState() + self.tp = ThreadPool(num, stack_size, self.interrupted) self.maxjobs = num @@ -395,7 +411,7 @@ else: if ok: task.executed() else: - if self.interrupted: + if self.interrupted(): try: raise SCons.Errors.BuildError( task.targets[0], errstr=interrupt_msg) diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py index 6ff3833..bd8b564 100644 --- a/src/engine/SCons/Node/FS.py +++ b/src/engine/SCons/Node/FS.py @@ -2873,9 +2873,10 @@ class FileFinder: node = p.entries[norm_name] except KeyError: return p.dir_on_disk(name) - # Once we move to Python 2.2 we can do: - #if isinstance(node, (Dir, Entry)): - if isinstance(node, Dir) or isinstance(node, Entry): + if isinstance(node, Dir): + return node + if isinstance(node, Entry): + node.must_be_same(Dir) return node return None @@ -2944,8 +2945,11 @@ class FileFinder: # node = p.entries[norm_name] # except KeyError: # return p.dir_on_disk(name) - # # Once we move to Python 2.2 we can do: - # #if isinstance(node, (Dir, Entry)): + # if isinstance(node, Dir): + # return node + # if isinstance(node, Entry): + # node.must_be_same(Dir) + # return node # if isinstance(node, Dir) or isinstance(node, Entry): # return node # return None diff --git a/src/engine/SCons/Options/BoolOption.py b/src/engine/SCons/Options/BoolOption.py new file mode 100644 index 0000000..c3b50b3 --- /dev/null +++ b/src/engine/SCons/Options/BoolOption.py @@ -0,0 +1,35 @@ +# +# __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__" + +__doc__ = """Place-holder for the old SCons.Options module hierarchy + +This is for backwards compatibility. The new equivalent is the Variables/ +class hierarchy. These will have deprecation warnings added (some day), +and will then be removed entirely (some day). +""" + +import SCons.Variables + +BoolOption = SCons.Variables.BoolVariable diff --git a/src/engine/SCons/Options/EnumOption.py b/src/engine/SCons/Options/EnumOption.py new file mode 100644 index 0000000..24ccf28 --- /dev/null +++ b/src/engine/SCons/Options/EnumOption.py @@ -0,0 +1,35 @@ +# +# __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__" + +__doc__ = """Place-holder for the old SCons.Options module hierarchy + +This is for backwards compatibility. The new equivalent is the Variables/ +class hierarchy. These will have deprecation warnings added (some day), +and will then be removed entirely (some day). +""" + +import SCons.Variables + +EnumOption = SCons.Variables.EnumVariable diff --git a/src/engine/SCons/Options/ListOption.py b/src/engine/SCons/Options/ListOption.py new file mode 100644 index 0000000..1a56806 --- /dev/null +++ b/src/engine/SCons/Options/ListOption.py @@ -0,0 +1,35 @@ +# +# __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__" + +__doc__ = """Place-holder for the old SCons.Options module hierarchy + +This is for backwards compatibility. The new equivalent is the Variables/ +class hierarchy. These will have deprecation warnings added (some day), +and will then be removed entirely (some day). +""" + +import SCons.Variables + +ListOption = SCons.Variables.ListVariable diff --git a/src/engine/SCons/Options/PackageOption.py b/src/engine/SCons/Options/PackageOption.py new file mode 100644 index 0000000..479a8a2 --- /dev/null +++ b/src/engine/SCons/Options/PackageOption.py @@ -0,0 +1,35 @@ +# +# __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__" + +__doc__ = """Place-holder for the old SCons.Options module hierarchy + +This is for backwards compatibility. The new equivalent is the Variables/ +class hierarchy. These will have deprecation warnings added (some day), +and will then be removed entirely (some day). +""" + +import SCons.Variables + +PackageOption = SCons.Variables.PackageVariable diff --git a/src/engine/SCons/Options/PathOption.py b/src/engine/SCons/Options/PathOption.py new file mode 100644 index 0000000..e694127 --- /dev/null +++ b/src/engine/SCons/Options/PathOption.py @@ -0,0 +1,35 @@ +# +# __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__" + +__doc__ = """Place-holder for the old SCons.Options module hierarchy + +This is for backwards compatibility. The new equivalent is the Variables/ +class hierarchy. These will have deprecation warnings added (some day), +and will then be removed entirely (some day). +""" + +import SCons.Variables + +PathOption = SCons.Variables.PathVariable diff --git a/src/engine/SCons/Options.py b/src/engine/SCons/Options/__init__.py index 0f2fde1..5cc09a7 100644 --- a/src/engine/SCons/Options.py +++ b/src/engine/SCons/Options/__init__.py @@ -32,6 +32,12 @@ and will then be removed entirely (some day). import SCons.Variables +from BoolOption import BoolOption # okay +from EnumOption import EnumOption # okay +from ListOption import ListOption # naja +from PackageOption import PackageOption # naja +from PathOption import PathOption # okay + class Options(SCons.Variables.Variables): def AddOptions(self, *args, **kw): @@ -48,9 +54,3 @@ class Options(SCons.Variables.Variables): return apply(SCons.Variables.Variables.FormatVariableHelpText, (self,) + args, kw) - -BoolOption = SCons.Variables.BoolVariable -EnumOption = SCons.Variables.EnumVariable -ListOption = SCons.Variables.ListVariable -PackageOption = SCons.Variables.PackageVariable -PathOption = SCons.Variables.PathVariable diff --git a/src/engine/SCons/Taskmaster.py b/src/engine/SCons/Taskmaster.py index 8a0fcf7..6f93ca7 100644 --- a/src/engine/SCons/Taskmaster.py +++ b/src/engine/SCons/Taskmaster.py @@ -277,9 +277,9 @@ class Task: Explicit stop-the-build failure. """ - # Invoke fail_continue() to clean-up the pending children + # Invoke will_not_build() to clean-up the pending children # list. - self.fail_continue() + self.tm.will_not_build(self.targets) # Tell the taskmaster to not start any new tasks self.tm.stop() @@ -297,44 +297,8 @@ class Task: This sets failure status on the target nodes and all of their dependent parent nodes. """ + self.tm.will_not_build(self.targets) - pending_children = self.tm.pending_children - - to_visit = set() - for t in self.targets: - # Set failure state on all of the parents that were dependent - # on this failed build. - if t.state != NODE_FAILED: - t.state = NODE_FAILED - parents = t.waiting_parents - to_visit = to_visit | parents - pending_children = pending_children - parents - - try: - while 1: - try: - node = to_visit.pop() - except AttributeError: - # Python 1.5.2 - if len(to_visit): - node = to_visit[0] - to_visit.remove(node) - else: - break - if node.state != NODE_FAILED: - node.state = NODE_FAILED - parents = node.waiting_parents - to_visit = to_visit | parents - pending_children = pending_children - parents - except KeyError: - # The container to_visit has been emptied. - pass - - # We have the stick back the pending_children list into the - # task master because the python 1.5.2 compatibility does not - # allow us to use in-place updates - self.tm.pending_children = pending_children - def make_ready_all(self): """ Marks all targets in a task ready for execution. @@ -557,7 +521,15 @@ class Taskmaster: def no_next_candidate(self): """ Stops Taskmaster processing by not returning a next candidate. - """ + + Note that we have to clean-up the Taskmaster candidate list + because the cycle detection depends on the fact all nodes have + been processed somehow. + """ + while self.candidates: + candidates = self.candidates + self.candidates = [] + self.will_not_build(candidates) return None def _find_next_ready_node(self): @@ -604,9 +576,9 @@ class Taskmaster: S.considered = S.considered + 1 else: S = None - - if T: T.write('Taskmaster: Considering node <%-10s %s> and its children:\n' % - (StateString[node.get_state()], repr(str(node)))) + + if T: T.write('Taskmaster: Considering node <%-10s %-3s %s> and its children:\n' % + (StateString[node.get_state()], node.ref_count, repr(str(node)))) if state == NODE_NO_STATE: # Mark this node as being on the execution stack: @@ -643,8 +615,8 @@ class Taskmaster: for child in chain(children,node.prerequisites): childstate = child.get_state() - if T: T.write('Taskmaster: <%-10s %s>\n' % - (StateString[childstate], repr(str(child)))) + if T: T.write('Taskmaster: <%-10s %-3s %s>\n' % + (StateString[childstate], child.ref_count, repr(str(child)))) if childstate == NODE_NO_STATE: children_not_visited.append(child) @@ -685,8 +657,8 @@ class Taskmaster: node.set_state(NODE_FAILED) if S: S.child_failed = S.child_failed + 1 - if T: T.write('Taskmaster:****** <%-10s %s>\n' % - (StateString[node.get_state()], repr(str(node)))) + if T: T.write('Taskmaster:****** <%-10s %-3s %s>\n' % + (StateString[node.get_state()], node.ref_count, repr(str(node)))) continue if children_not_ready: @@ -700,6 +672,8 @@ class Taskmaster: # count so we can be put back on the list for # re-evaluation when they've all finished. node.ref_count = node.ref_count + child.add_to_waiting_parents(node) + if T: T.write('Taskmaster: adjusting ref count: <%-10s %-3s %s>\n' % + (StateString[node.get_state()], node.ref_count, repr(str(node)))) self.pending_children = self.pending_children | children_pending @@ -720,8 +694,8 @@ class Taskmaster: # The default when we've gotten through all of the checks above: # this node is ready to be built. if S: S.build = S.build + 1 - if T: T.write('Taskmaster: Evaluating <%-10s %s>\n' % - (StateString[node.get_state()], repr(str(node)))) + if T: T.write('Taskmaster: Evaluating <%-10s %-3s %s>\n' % + (StateString[node.get_state()], node.ref_count, repr(str(node)))) return node return None @@ -757,6 +731,48 @@ class Taskmaster: return task + def will_not_build(self, nodes): + """ + Perform clean-up about nodes that will never be built. + """ + + pending_children = self.pending_children + + to_visit = set() + for node in nodes: + # Set failure state on all of the parents that were dependent + # on this failed build. + if node.state != NODE_FAILED: + node.state = NODE_FAILED + parents = node.waiting_parents + to_visit = to_visit | parents + pending_children = pending_children - parents + + try: + while 1: + try: + node = to_visit.pop() + except AttributeError: + # Python 1.5.2 + if len(to_visit): + node = to_visit[0] + to_visit.remove(node) + else: + break + if node.state != NODE_FAILED: + node.state = NODE_FAILED + parents = node.waiting_parents + to_visit = to_visit | parents + pending_children = pending_children - parents + except KeyError: + # The container to_visit has been emptied. + pass + + # We have the stick back the pending_children list into the + # task master because the python 1.5.2 compatibility does not + # allow us to use in-place updates + self.pending_children = pending_children + def stop(self): """ Stops the current build completely. @@ -774,6 +790,8 @@ class Taskmaster: if cycle: desc = desc + " " + string.join(map(str, cycle), " -> ") + "\n" else: - desc = desc + " Internal Error: no cycle found for node %s (%s)\n" % \ - (node, repr(node)) + desc = desc + \ + " Internal Error: no cycle found for node %s (%s) in state %s\n" % \ + (node, repr(node), StateString[node.get_state()]) + raise SCons.Errors.UserError, desc diff --git a/src/engine/SCons/TaskmasterTests.py b/src/engine/SCons/TaskmasterTests.py index 88d3078..9324581 100644 --- a/src/engine/SCons/TaskmasterTests.py +++ b/src/engine/SCons/TaskmasterTests.py @@ -1053,23 +1053,24 @@ class TaskmasterTestCase(unittest.TestCase): expect = """\ Taskmaster: Looking for a node to evaluate -Taskmaster: Considering node <no_state 'n1'> and its children: -Taskmaster: Evaluating <pending 'n1'> +Taskmaster: Considering node <no_state 0 'n1'> and its children: +Taskmaster: Evaluating <pending 0 'n1'> Taskmaster: Looking for a node to evaluate -Taskmaster: Considering node <executed 'n1'> and its children: +Taskmaster: Considering node <executed 0 'n1'> and its children: Taskmaster: already handled (executed) -Taskmaster: Considering node <no_state 'n3'> and its children: -Taskmaster: <executed 'n1'> -Taskmaster: <no_state 'n2'> -Taskmaster: Considering node <no_state 'n2'> and its children: -Taskmaster: Evaluating <pending 'n2'> +Taskmaster: Considering node <no_state 0 'n3'> and its children: +Taskmaster: <executed 0 'n1'> +Taskmaster: <no_state 0 'n2'> +Taskmaster: adjusting ref count: <pending 1 'n3'> +Taskmaster: Considering node <no_state 0 'n2'> and its children: +Taskmaster: Evaluating <pending 0 'n2'> Taskmaster: Looking for a node to evaluate -Taskmaster: Considering node <pending 'n3'> and its children: -Taskmaster: <executed 'n1'> -Taskmaster: <executed 'n2'> -Taskmaster: Evaluating <pending 'n3'> +Taskmaster: Considering node <pending 0 'n3'> and its children: +Taskmaster: <executed 0 'n1'> +Taskmaster: <executed 0 'n2'> +Taskmaster: Evaluating <pending 0 'n3'> Taskmaster: Looking for a node to evaluate Taskmaster: No candidate anymore. diff --git a/src/engine/SCons/Tool/FortranCommon.py b/src/engine/SCons/Tool/FortranCommon.py index 82a5a6c..825cbe5 100644 --- a/src/engine/SCons/Tool/FortranCommon.py +++ b/src/engine/SCons/Tool/FortranCommon.py @@ -183,7 +183,7 @@ def add_fortran_to_env(env): env['FORTRANMODDIR'] = '' # where the compiler should place .mod files env['FORTRANMODDIRPREFIX'] = '' # some prefix to $FORTRANMODDIR - similar to $INCPREFIX env['FORTRANMODDIRSUFFIX'] = '' # some suffix to $FORTRANMODDIR - similar to $INCSUFFIX - env['_FORTRANMODFLAG'] = '$( ${_concat(FORTRANMODDIRPREFIX, FORTRANMODDIR, FORTRANMODDIRSUFFIX, __env__, RDirs)} $)' + env['_FORTRANMODFLAG'] = '$( ${_concat(FORTRANMODDIRPREFIX, FORTRANMODDIR, FORTRANMODDIRSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)' def add_f77_to_env(env): """Add Builders and construction variables for f77 to an Environment.""" diff --git a/src/engine/SCons/Tool/c++.py b/src/engine/SCons/Tool/c++.py index a4375c0..f360ed8 100644 --- a/src/engine/SCons/Tool/c++.py +++ b/src/engine/SCons/Tool/c++.py @@ -76,7 +76,7 @@ def generate(env): env['CXXFLAGS'] = SCons.Util.CLVar('') env['CXXCOM'] = '$CXX -o $TARGET -c $CXXFLAGS $CCFLAGS $_CCCOMCOM $SOURCES' env['SHCXX'] = '$CXX' - env['SHCXXFLAGS'] = SCons.Util.CLVar('') + env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS') env['SHCXXCOM'] = '$SHCXX -o $TARGET -c $SHCXXFLAGS $SHCCFLAGS $_CCCOMCOM $SOURCES' env['CPPDEFPREFIX'] = '-D' diff --git a/src/engine/SCons/Tool/g++.py b/src/engine/SCons/Tool/g++.py index 9c7e477..917229f 100644 --- a/src/engine/SCons/Tool/g++.py +++ b/src/engine/SCons/Tool/g++.py @@ -53,26 +53,14 @@ def generate(env): env['CXX'] = env.Detect(compilers) # platform specific settings - if env['PLATFORM'] == 'cygwin': - env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS') - elif env['PLATFORM'] == 'aix': - # Original line from Christian Engel added -DPIC: - #env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS -DPIC -mminimal-toc') + if env['PLATFORM'] == 'aix': env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS -mminimal-toc') env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1 env['SHOBJSUFFIX'] = '$OBJSUFFIX' elif env['PLATFORM'] == 'hpux': - # Original line from Christian Engel added -DPIC: - #env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS -DPIC') env['SHOBJSUFFIX'] = '.pic.o' elif env['PLATFORM'] == 'sunos': - # Original line from Christian Engel added -DPIC: - #env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS -DPIC') env['SHOBJSUFFIX'] = '.pic.o' - else: - # Original line from Christian Engel added -DPIC: - #env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS -DPIC') - pass # determine compiler version if env['CXX']: line = os.popen(env['CXX'] + ' --version').readline() diff --git a/src/setup.py b/src/setup.py index 281a69c..5b2212c 100644 --- a/src/setup.py +++ b/src/setup.py @@ -376,6 +376,7 @@ arguments = { 'packages' : ["SCons", "SCons.compat", "SCons.Node", + "SCons.Options", "SCons.Platform", "SCons.Scanner", "SCons.Script", |