Build context instances

Executing tasks, accessing the file system and consulting the results of a previous build are very different concerns which have to be encapsulated properly. The core class representing a build is a build context.

Build context and persistence

The build context holds all the information necessary for a build. To accelerate the start-up, a part of the information is stored and loaded between the runs. The persistent attributes are the following:

Table 12.2. Build context persistence

AttributeInformation
rootNode representing the root of the file system
srcnodeNode representing the source directory
bldnodeNode representing the build directory
node_sigsFile hashes (dict mapping Node ids to hashes)
node_depsImplicit dependencies (dict mapping Node ids)
raw_depsImplicit file dependencies which could not be resolved (dict mapping Node ids to lists of strings)
task_sigsSignature of the tasks previously run (dict mapping a Task id to a hash)
id_nodesSequence for generating unique node instance ids (id of the last Node created)


Build context access

In previous Waf releases, the build context was supposed to be a unique object (one build active at a time). To enable the use of Waf as a library, the dependency on the singleton Build.bld was removed. This implies that each object should be able to obtain its build context from its attributes. Here are a few examples:

Table 12.3. Build context access

Object typeBuild context access
Nodeself.__class__.bld
task_genself.bld
Taskself.generator.bld


Parallelization concerns

Build contexts perform an os.chdir call before starting to execute the tasks. When running build contexts within build contexts (tasks), the current working directory may cause various problems. To work around them, it may be necessary to change the compilation rules (compile from the file system root) and to inject code (replace bld.compile).

Direct Node instances are not used anywhere in the Waf code. Instead, each build context creates a new Node subclass (bld.node_class), on which the build context instance is attached as a class attribute.

Threading concerns

Nearly all the code is executed in the main thread. The other threads are merely waiting for new tasks, and executing the methods run from the task instances. Such methods should contain as little code as possible, and access the BuildContext in a read-only manner.

If the run methods have to modify the build context, it is recommended to overload the method get_out of the scheduler and to execute methods in an event-like manner (data is attached to the task, and the method get_out executes the code). Adding more tasks from a running task is demonstrated the section called “A compiler producing source files with names unknown in advance”.