SCons.Taskmaster package#

Submodules#

SCons.Taskmaster.Job module#

Serial and Parallel classes to execute build tasks.

The Jobs class provides a higher level interface to start, stop, and wait on jobs.

class SCons.Taskmaster.Job.InterruptState[source]#

Bases: object

set()[source]#
class SCons.Taskmaster.Job.Jobs(num, taskmaster)[source]#

Bases: object

An instance of this class initializes N jobs, and provides methods for starting, stopping, and waiting on all N jobs.

_reset_sig_handler()[source]#

Restore the signal handlers to their previous state (before the call to _setup_sig_handler().

_setup_sig_handler()[source]#

Setup an interrupt handler so that SCons can shutdown cleanly in various conditions:

  1. SIGINT: Keyboard interrupt

  2. SIGTERM: kill or system shutdown

  3. SIGHUP: Controlling shell exiting

We handle all of these cases by stopping the taskmaster. It turns out that it’s very difficult to stop the build process by throwing asynchronously an exception such as KeyboardInterrupt. For example, the python Condition variables (threading.Condition) and queues do not seem to be asynchronous-exception-safe. It would require adding a whole bunch of try/finally block and except KeyboardInterrupt all over the place.

Note also that we have to be careful to handle the case when SCons forks before executing another process. In that case, we want the child to exit immediately.

run(postfunc=<function Jobs.<lambda>>)[source]#

Run the jobs.

postfunc() will be invoked after the jobs has run. It will be invoked even if the jobs are interrupted by a keyboard interrupt (well, in fact by a signal such as either SIGINT, SIGTERM or SIGHUP). The execution of postfunc() is protected against keyboard interrupts and is guaranteed to run to completion.

were_interrupted()[source]#

Returns whether the jobs were interrupted by a signal.

class SCons.Taskmaster.Job.LegacyParallel(taskmaster, num, stack_size)[source]#

Bases: object

This class is used to execute tasks in parallel, and is somewhat less efficient than Serial, but is appropriate for parallel builds.

This class is thread safe.

start()[source]#

Start the job. This will begin pulling tasks from the taskmaster and executing them, and return when there are no more tasks. If a task fails to execute (i.e. execute() raises an exception), then the job will stop.

class SCons.Taskmaster.Job.NewParallel(taskmaster, num, stack_size)[source]#

Bases: object

class State(value)[source]#

Bases: enum.Enum

An enumeration.

COMPLETED = 3#
READY = 0#
SEARCHING = 1#
STALLED = 2#
class Worker(owner)[source]#

Bases: threading.Thread

_bootstrap()#
_bootstrap_inner()#
_delete()#

Remove current thread from the dict of currently running threads.

_initialized = False#
_reset_internal_locks(is_alive)#
_set_ident()#
_set_native_id()#
_set_tstate_lock()#

Set a lock object which will be released by the interpreter when the underlying thread state (see pystate.h) gets deleted.

_stop()#
_wait_for_tstate_lock(block=True, timeout=- 1)#
property daemon#

A boolean value indicating whether this thread is a daemon thread.

This must be set before start() is called, otherwise RuntimeError is raised. Its initial value is inherited from the creating thread; the main thread is not a daemon thread and therefore all threads created in the main thread default to daemon = False.

The entire Python program exits when only daemon threads are left.

getName()#

Return a string used for identification purposes only.

This method is deprecated, use the name attribute instead.

property ident#

Thread identifier of this thread or None if it has not been started.

This is a nonzero integer. See the get_ident() function. Thread identifiers may be recycled when a thread exits and another thread is created. The identifier is available even after the thread has exited.

isDaemon()#

Return whether this thread is a daemon.

This method is deprecated, use the daemon attribute instead.

is_alive()#

Return whether the thread is alive.

This method returns True just before the run() method starts until just after the run() method terminates. See also the module function enumerate().

join(timeout=None)#

Wait until the thread terminates.

This blocks the calling thread until the thread whose join() method is called terminates – either normally or through an unhandled exception or until the optional timeout occurs.

When the timeout argument is present and not None, it should be a floating point number specifying a timeout for the operation in seconds (or fractions thereof). As join() always returns None, you must call is_alive() after join() to decide whether a timeout happened – if the thread is still alive, the join() call timed out.

When the timeout argument is not present or None, the operation will block until the thread terminates.

A thread can be join()ed many times.

join() raises a RuntimeError if an attempt is made to join the current thread as that would cause a deadlock. It is also an error to join() a thread before it has been started and attempts to do so raises the same exception.

property name#

A string used for identification purposes only.

It has no semantics. Multiple threads may be given the same name. The initial name is set by the constructor.

property native_id#

Native integral thread ID of this thread, or None if it has not been started.

This is a non-negative integer. See the get_native_id() function. This represents the Thread ID as reported by the kernel.

run()[source]#

Method representing the thread’s activity.

You may override this method in a subclass. The standard run() method invokes the callable object passed to the object’s constructor as the target argument, if any, with sequential and keyword arguments taken from the args and kwargs arguments, respectively.

setDaemon(daemonic)#

Set whether this thread is a daemon.

This method is deprecated, use the .daemon property instead.

setName(name)#

Set the name string for this thread.

This method is deprecated, use the name attribute instead.

start()#

Start the thread’s activity.

It must be called at most once per thread object. It arranges for the object’s run() method to be invoked in a separate thread of control.

This method will raise a RuntimeError if called more than once on the same thread object.

_adjust_stack_size()[source]#
_restore_stack_size(prev_size)[source]#
_setup_logging()[source]#
_start_workers()[source]#
_work()[source]#
start()[source]#
trace_message(message)[source]#
class SCons.Taskmaster.Job.Serial(taskmaster)[source]#

Bases: object

This class is used to execute tasks in series, and is more efficient than Parallel, but is only appropriate for non-parallel builds. Only one instance of this class should be in existence at a time.

This class is not thread safe.

start()[source]#

Start the job. This will begin pulling tasks from the taskmaster and executing them, and return when there are no more tasks. If a task fails to execute (i.e. execute() raises an exception), then the job will stop.

class SCons.Taskmaster.Job.ThreadPool(num, stack_size, interrupted)[source]#

Bases: object

This class is responsible for spawning and managing worker threads.

cleanup()[source]#

Shuts down the thread pool, giving each worker thread a chance to shut down gracefully.

get()[source]#

Remove and return a result tuple from the results queue.

preparation_failed(task)[source]#
put(task)[source]#

Put task into request queue.

class SCons.Taskmaster.Job.Worker(requestQueue, resultsQueue, interrupted)[source]#

Bases: threading.Thread

A worker thread waits on a task to be posted to its request queue, dequeues the task, executes it, and posts a tuple including the task and a boolean indicating whether the task executed successfully.

_bootstrap()#
_bootstrap_inner()#
_delete()#

Remove current thread from the dict of currently running threads.

_initialized = False#
_reset_internal_locks(is_alive)#
_set_ident()#
_set_native_id()#
_set_tstate_lock()#

Set a lock object which will be released by the interpreter when the underlying thread state (see pystate.h) gets deleted.

_stop()#
_wait_for_tstate_lock(block=True, timeout=- 1)#
property daemon#

A boolean value indicating whether this thread is a daemon thread.

This must be set before start() is called, otherwise RuntimeError is raised. Its initial value is inherited from the creating thread; the main thread is not a daemon thread and therefore all threads created in the main thread default to daemon = False.

The entire Python program exits when only daemon threads are left.

getName()#

Return a string used for identification purposes only.

This method is deprecated, use the name attribute instead.

property ident#

Thread identifier of this thread or None if it has not been started.

This is a nonzero integer. See the get_ident() function. Thread identifiers may be recycled when a thread exits and another thread is created. The identifier is available even after the thread has exited.

isDaemon()#

Return whether this thread is a daemon.

This method is deprecated, use the daemon attribute instead.

is_alive()#

Return whether the thread is alive.

This method returns True just before the run() method starts until just after the run() method terminates. See also the module function enumerate().

join(timeout=None)#

Wait until the thread terminates.

This blocks the calling thread until the thread whose join() method is called terminates – either normally or through an unhandled exception or until the optional timeout occurs.

When the timeout argument is present and not None, it should be a floating point number specifying a timeout for the operation in seconds (or fractions thereof). As join() always returns None, you must call is_alive() after join() to decide whether a timeout happened – if the thread is still alive, the join() call timed out.

When the timeout argument is not present or None, the operation will block until the thread terminates.

A thread can be join()ed many times.

join() raises a RuntimeError if an attempt is made to join the current thread as that would cause a deadlock. It is also an error to join() a thread before it has been started and attempts to do so raises the same exception.

property name#

A string used for identification purposes only.

It has no semantics. Multiple threads may be given the same name. The initial name is set by the constructor.

property native_id#

Native integral thread ID of this thread, or None if it has not been started.

This is a non-negative integer. See the get_native_id() function. This represents the Thread ID as reported by the kernel.

run()[source]#

Method representing the thread’s activity.

You may override this method in a subclass. The standard run() method invokes the callable object passed to the object’s constructor as the target argument, if any, with sequential and keyword arguments taken from the args and kwargs arguments, respectively.

setDaemon(daemonic)#

Set whether this thread is a daemon.

This method is deprecated, use the .daemon property instead.

setName(name)#

Set the name string for this thread.

This method is deprecated, use the name attribute instead.

start()#

Start the thread’s activity.

It must be called at most once per thread object. It arranges for the object’s run() method to be invoked in a separate thread of control.

This method will raise a RuntimeError if called more than once on the same thread object.

Module contents#

Generic Taskmaster module for the SCons build engine.

This module contains the primary interface(s) between a wrapping user interface and the SCons build engine. There are two key classes here:

Taskmaster

This is the main engine for walking the dependency graph and calling things to decide what does or doesn’t need to be built.

Task

This is the base class for allowing a wrapping interface to decide what does or doesn’t actually need to be done. The intention is for a wrapping interface to subclass this as appropriate for different types of behavior it may need.

The canonical example is the SCons native Python interface, which has Task subclasses that handle its specific behavior, like printing “‘foo’ is up to date” when a top-level target doesn’t need to be built, and handling the -c option by removing targets as its “build” action. There is also a separate subclass for suppressing this output when the -q option is used.

The Taskmaster instantiates a Task object for each (set of) target(s) that it decides need to be evaluated and/or built.

class SCons.Taskmaster.AlwaysTask(tm, targets, top, node)[source]#

Bases: SCons.Taskmaster.Task

LOGGER = None#
_abc_impl = <_abc._abc_data object>#
_exception_raise()#

Raises a pending exception that was recorded while getting a Task ready for execution.

_no_exception_to_raise()#
display(message)#

Hook to allow the calling interface to display a message.

This hook gets called as part of preparing a task for execution (that is, a Node to be built). As part of figuring out what Node should be built next, the actual target list may be altered, along with a message describing the alteration. The calling interface can subclass Task and provide a concrete implementation of this method to see those messages.

exc_clear()#

Clears any recorded exception.

This also changes the “exception_raise” attribute to point to the appropriate do-nothing method.

exc_info()#

Returns info about a recorded exception.

exception_set(exception=None)#

Records an exception to be raised at the appropriate time.

This also changes the “exception_raise” attribute to point to the method that will, in fact

execute()#

Called to execute the task.

This method is called from multiple threads in a parallel build, so only do thread safe stuff here. Do thread unsafe stuff in prepare(), executed() or failed().

executed()#

Called when the task has been successfully executed and the Taskmaster instance wants to call the Node’s callback methods.

This may have been a do-nothing operation (to preserve build order), so we must check the node’s state before deciding whether it was “built”, in which case we call the appropriate Node method. In any event, we always call “visited()”, which will handle any post-visit actions that must take place regardless of whether or not the target was an actual built target or a source Node.

executed_with_callbacks()#

Called when the task has been successfully executed and the Taskmaster instance wants to call the Node’s callback methods.

This may have been a do-nothing operation (to preserve build order), so we must check the node’s state before deciding whether it was “built”, in which case we call the appropriate Node method. In any event, we always call “visited()”, which will handle any post-visit actions that must take place regardless of whether or not the target was an actual built target or a source Node.

executed_without_callbacks()#

Called when the task has been successfully executed and the Taskmaster instance doesn’t want to call the Node’s callback methods.

fail_continue()#

Explicit continue-the-build failure.

This sets failure status on the target nodes and all of their dependent parent nodes.

Note: Although this function is normally invoked on nodes in the executing state, it might also be invoked on up-to-date nodes when using Configure().

fail_stop()#

Explicit stop-the-build failure.

This sets failure status on the target nodes and all of their dependent parent nodes.

Note: Although this function is normally invoked on nodes in the executing state, it might also be invoked on up-to-date nodes when using Configure().

failed()#

Default action when a task fails: stop the build.

Note: Although this function is normally invoked on nodes in the executing state, it might also be invoked on up-to-date nodes when using Configure().

get_target()#

Fetch the target being built or updated by this task.

make_ready()#

Marks all targets in a task ready for execution if any target is not current.

This is the default behavior for building only what’s necessary.

make_ready_all()#

Marks all targets in a task ready for execution.

This is used when the interface needs every target Node to be visited–the canonical example being the “scons -c” option.

make_ready_current()#

Marks all targets in a task ready for execution if any target is not current.

This is the default behavior for building only what’s necessary.

needs_execute()[source]#

Always returns True (indicating this Task should always be executed).

Subclasses that need this behavior (as opposed to the default of only executing Nodes that are out of date w.r.t. their dependencies) can use this as follows:

class MyTaskSubclass(SCons.Taskmaster.Task):

needs_execute = SCons.Taskmaster.AlwaysTask.needs_execute

postprocess()#

Post-processes a task after it’s been executed.

This examines all the targets just built (or not, we don’t care if the build was successful, or even if there was no build because everything was up-to-date) to see if they have any waiting parent Nodes, or Nodes waiting on a common side effect, that can be put back on the candidates list.

prepare()#

Called just before the task is executed.

This is mainly intended to give the target Nodes a chance to unlink underlying files and make all necessary directories before the Action is actually called to build the targets.

trace_message(node, description='node')#
class SCons.Taskmaster.OutOfDateTask(tm, targets, top, node)[source]#

Bases: SCons.Taskmaster.Task

LOGGER = None#
_abc_impl = <_abc._abc_data object>#
_exception_raise()#

Raises a pending exception that was recorded while getting a Task ready for execution.

_no_exception_to_raise()#
display(message)#

Hook to allow the calling interface to display a message.

This hook gets called as part of preparing a task for execution (that is, a Node to be built). As part of figuring out what Node should be built next, the actual target list may be altered, along with a message describing the alteration. The calling interface can subclass Task and provide a concrete implementation of this method to see those messages.

exc_clear()#

Clears any recorded exception.

This also changes the “exception_raise” attribute to point to the appropriate do-nothing method.

exc_info()#

Returns info about a recorded exception.

exception_set(exception=None)#

Records an exception to be raised at the appropriate time.

This also changes the “exception_raise” attribute to point to the method that will, in fact

execute()#

Called to execute the task.

This method is called from multiple threads in a parallel build, so only do thread safe stuff here. Do thread unsafe stuff in prepare(), executed() or failed().

executed()#

Called when the task has been successfully executed and the Taskmaster instance wants to call the Node’s callback methods.

This may have been a do-nothing operation (to preserve build order), so we must check the node’s state before deciding whether it was “built”, in which case we call the appropriate Node method. In any event, we always call “visited()”, which will handle any post-visit actions that must take place regardless of whether or not the target was an actual built target or a source Node.

executed_with_callbacks()#

Called when the task has been successfully executed and the Taskmaster instance wants to call the Node’s callback methods.

This may have been a do-nothing operation (to preserve build order), so we must check the node’s state before deciding whether it was “built”, in which case we call the appropriate Node method. In any event, we always call “visited()”, which will handle any post-visit actions that must take place regardless of whether or not the target was an actual built target or a source Node.

executed_without_callbacks()#

Called when the task has been successfully executed and the Taskmaster instance doesn’t want to call the Node’s callback methods.

fail_continue()#

Explicit continue-the-build failure.

This sets failure status on the target nodes and all of their dependent parent nodes.

Note: Although this function is normally invoked on nodes in the executing state, it might also be invoked on up-to-date nodes when using Configure().

fail_stop()#

Explicit stop-the-build failure.

This sets failure status on the target nodes and all of their dependent parent nodes.

Note: Although this function is normally invoked on nodes in the executing state, it might also be invoked on up-to-date nodes when using Configure().

failed()#

Default action when a task fails: stop the build.

Note: Although this function is normally invoked on nodes in the executing state, it might also be invoked on up-to-date nodes when using Configure().

get_target()#

Fetch the target being built or updated by this task.

make_ready()#

Marks all targets in a task ready for execution if any target is not current.

This is the default behavior for building only what’s necessary.

make_ready_all()#

Marks all targets in a task ready for execution.

This is used when the interface needs every target Node to be visited–the canonical example being the “scons -c” option.

make_ready_current()#

Marks all targets in a task ready for execution if any target is not current.

This is the default behavior for building only what’s necessary.

needs_execute()[source]#

Returns True (indicating this Task should be executed) if this Task’s target state indicates it needs executing, which has already been determined by an earlier up-to-date check.

postprocess()#

Post-processes a task after it’s been executed.

This examines all the targets just built (or not, we don’t care if the build was successful, or even if there was no build because everything was up-to-date) to see if they have any waiting parent Nodes, or Nodes waiting on a common side effect, that can be put back on the candidates list.

prepare()#

Called just before the task is executed.

This is mainly intended to give the target Nodes a chance to unlink underlying files and make all necessary directories before the Action is actually called to build the targets.

trace_message(node, description='node')#
class SCons.Taskmaster.Stats[source]#

Bases: object

A simple class for holding statistics about the disposition of a Node by the Taskmaster. If we’re collecting statistics, each Node processed by the Taskmaster gets one of these attached, in which case the Taskmaster records its decision each time it processes the Node. (Ideally, that’s just once per Node.)

class SCons.Taskmaster.Task(tm, targets, top, node)[source]#

Bases: abc.ABC

SCons build engine abstract task class.

This controls the interaction of the actual building of node and the rest of the engine.

This is expected to handle all of the normally-customizable aspects of controlling a build, so any given application should be able to do what it wants by sub-classing this class and overriding methods as appropriate. If an application needs to customize something by sub-classing Taskmaster (or some other build engine class), we should first try to migrate that functionality into this class.

Note that it’s generally a good idea for sub-classes to call these methods explicitly to update state, etc., rather than roll their own interaction with Taskmaster from scratch.

LOGGER = None#
_abc_impl = <_abc._abc_data object>#
_exception_raise()[source]#

Raises a pending exception that was recorded while getting a Task ready for execution.

_no_exception_to_raise()[source]#
display(message)[source]#

Hook to allow the calling interface to display a message.

This hook gets called as part of preparing a task for execution (that is, a Node to be built). As part of figuring out what Node should be built next, the actual target list may be altered, along with a message describing the alteration. The calling interface can subclass Task and provide a concrete implementation of this method to see those messages.

exc_clear()[source]#

Clears any recorded exception.

This also changes the “exception_raise” attribute to point to the appropriate do-nothing method.

exc_info()[source]#

Returns info about a recorded exception.

exception_set(exception=None)[source]#

Records an exception to be raised at the appropriate time.

This also changes the “exception_raise” attribute to point to the method that will, in fact

execute()[source]#

Called to execute the task.

This method is called from multiple threads in a parallel build, so only do thread safe stuff here. Do thread unsafe stuff in prepare(), executed() or failed().

executed()#

Called when the task has been successfully executed and the Taskmaster instance wants to call the Node’s callback methods.

This may have been a do-nothing operation (to preserve build order), so we must check the node’s state before deciding whether it was “built”, in which case we call the appropriate Node method. In any event, we always call “visited()”, which will handle any post-visit actions that must take place regardless of whether or not the target was an actual built target or a source Node.

executed_with_callbacks()[source]#

Called when the task has been successfully executed and the Taskmaster instance wants to call the Node’s callback methods.

This may have been a do-nothing operation (to preserve build order), so we must check the node’s state before deciding whether it was “built”, in which case we call the appropriate Node method. In any event, we always call “visited()”, which will handle any post-visit actions that must take place regardless of whether or not the target was an actual built target or a source Node.

executed_without_callbacks()[source]#

Called when the task has been successfully executed and the Taskmaster instance doesn’t want to call the Node’s callback methods.

fail_continue()[source]#

Explicit continue-the-build failure.

This sets failure status on the target nodes and all of their dependent parent nodes.

Note: Although this function is normally invoked on nodes in the executing state, it might also be invoked on up-to-date nodes when using Configure().

fail_stop()[source]#

Explicit stop-the-build failure.

This sets failure status on the target nodes and all of their dependent parent nodes.

Note: Although this function is normally invoked on nodes in the executing state, it might also be invoked on up-to-date nodes when using Configure().

failed()[source]#

Default action when a task fails: stop the build.

Note: Although this function is normally invoked on nodes in the executing state, it might also be invoked on up-to-date nodes when using Configure().

get_target()[source]#

Fetch the target being built or updated by this task.

make_ready()#

Marks all targets in a task ready for execution if any target is not current.

This is the default behavior for building only what’s necessary.

make_ready_all()[source]#

Marks all targets in a task ready for execution.

This is used when the interface needs every target Node to be visited–the canonical example being the “scons -c” option.

make_ready_current()[source]#

Marks all targets in a task ready for execution if any target is not current.

This is the default behavior for building only what’s necessary.

abstract needs_execute()[source]#
postprocess()[source]#

Post-processes a task after it’s been executed.

This examines all the targets just built (or not, we don’t care if the build was successful, or even if there was no build because everything was up-to-date) to see if they have any waiting parent Nodes, or Nodes waiting on a common side effect, that can be put back on the candidates list.

prepare()[source]#

Called just before the task is executed.

This is mainly intended to give the target Nodes a chance to unlink underlying files and make all necessary directories before the Action is actually called to build the targets.

trace_message(node, description='node')[source]#
class SCons.Taskmaster.Taskmaster(targets=[], tasker=None, order=None, trace=None)[source]#

Bases: object

The Taskmaster for walking the dependency DAG.

_find_next_ready_node()[source]#

Finds the next node that is ready to be built.

This is the main guts of the DAG walk. We loop through the list of candidates, looking for something that has no un-built children (i.e., that is a leaf Node or has dependencies that are all leaf Nodes or up-to-date). Candidate Nodes are re-scanned (both the target Node itself and its sources, which are always scanned in the context of a given target) to discover implicit dependencies. A Node that must wait for some children to be built will be put back on the candidates list after the children have finished building. A Node that has been put back on the candidates list in this way may have itself (or its sources) re-scanned, in order to handle generated header files (e.g.) and the implicit dependencies therein.

Note that this method does not do any signature calculation or up-to-date check itself. All of that is handled by the Task class. This is purely concerned with the dependency graph walk.

_validate_pending_children()[source]#

Validate the content of the pending_children set. Assert if an internal error is found.

This function is used strictly for debugging the taskmaster by checking that no invariants are violated. It is not used in normal operation.

The pending_children set is used to detect cycles in the dependency graph. We call a “pending child” a child that is found in the “pending” state when checking the dependencies of its parent node.

A pending child can occur when the Taskmaster completes a loop through a cycle. For example, let’s imagine a graph made of three nodes (A, B and C) making a cycle. The evaluation starts at node A. The Taskmaster first considers whether node A’s child B is up-to-date. Then, recursively, node B needs to check whether node C is up-to-date. This leaves us with a dependency graph looking like:

                      Next candidate                                                                       Node A (Pending) --> Node B(Pending) --> Node C (NoState)
^                                     |
|                                     |
+-------------------------------------+

Now, when the Taskmaster examines the Node C’s child Node A, it finds that Node A is in the “pending” state. Therefore, Node A is a pending child of node C.

Pending children indicate that the Taskmaster has potentially loop back through a cycle. We say potentially because it could also occur when a DAG is evaluated in parallel. For example, consider the following graph:

Node A (Pending) --> Node B(Pending) --> Node C (Pending) --> ...
        |                                     ^
        |                                     |
        +----------> Node D (NoState) --------+
                          /
          Next candidate /

The Taskmaster first evaluates the nodes A, B, and C and starts building some children of node C. Assuming, that the maximum parallel level has not been reached, the Taskmaster will examine Node D. It will find that Node C is a pending child of Node D.

In summary, evaluating a graph with a cycle will always involve a pending child at one point. A pending child might indicate either a cycle or a diamond-shaped DAG. Only a fraction of the nodes ends-up being a “pending child” of another node. This keeps the pending_children set small in practice.

We can differentiate between the two cases if we wait until the end of the build. At this point, all the pending children nodes due to a diamond-shaped DAG will have been properly built (or will have failed to build). But, the pending children involved in a cycle will still be in the pending state.

The taskmaster removes nodes from the pending_children set as soon as a pending_children node moves out of the pending state. This also helps to keep the pending_children set small.

cleanup()[source]#

Check for dependency cycles.

configure_trace(trace=None)[source]#

This handles the command line option –taskmastertrace= It can be: - : output to stdout <filename> : output to a file False/None : Do not trace

find_next_candidate()[source]#

Returns the next candidate Node for (potential) evaluation.

The candidate list (really a stack) initially consists of all of the top-level (command line) targets provided when the Taskmaster was initialized. While we walk the DAG, visiting Nodes, all the children that haven’t finished processing get pushed on to the candidate list. Each child can then be popped and examined in turn for whether their children are all up-to-date, in which case a Task will be created for their actual evaluation and potential building.

Here is where we also allow candidate Nodes to alter the list of Nodes that should be examined. This is used, for example, when invoking SCons in a source directory. A source directory Node can return its corresponding build directory Node, essentially saying, “Hey, you really need to build this thing over here instead.”

next_task()[source]#

Returns the next task to be executed.

This simply asks for the next Node to be evaluated, and then wraps it in the specific Task subclass with which we were initialized.

no_next_candidate()[source]#

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.

stop()[source]#

Stops the current build completely.

tm_trace_node(node)[source]#
will_not_build(nodes, node_func=<function Taskmaster.<lambda>>)[source]#

Perform clean-up about nodes that will never be built. Invokes a user defined function on all of these nodes (including all of their parents).

SCons.Taskmaster.dump_stats()[source]#
SCons.Taskmaster.find_cycle(stack, visited)[source]#