Task

Tasks represent atomic operations such as processes.

waflib.Task.NOT_RUN = 0

The task was not executed yet

waflib.Task.MISSING = 1

The task has been executed but the files have not been created

waflib.Task.CRASHED = 2

The task execution returned a non-zero exit status

waflib.Task.EXCEPTION = 3

An exception occurred in the task execution

waflib.Task.CANCELED = 4

A dependency for the task is missing so it was cancelled

waflib.Task.SKIPPED = 8

The task did not have to be executed

waflib.Task.SUCCESS = 9

The task was successfully executed

waflib.Task.ASK_LATER = -1

The task is not ready to be executed

waflib.Task.SKIP_ME = -2

The task does not need to be executed

waflib.Task.RUN_ME = -3

The task must be executed

waflib.Task.CANCEL_ME = -4

The task cannot be executed because of a dependency problem

waflib.Task.classes = {'JTask': <class 'waflib.Tools.javaw.JTask'>, 'asm': <class 'waflib.Tools.asm.asm'>, 'asmprogram': <class 'waflib.Tools.asm.asmprogram'>, 'asmshlib': <class 'waflib.Tools.asm.asmshlib'>, 'asmstlib': <class 'waflib.Tools.asm.asmstlib'>, 'bison': <class 'waflib.Tools.bison.bison'>, 'c': <class 'waflib.Tools.c.c'>, 'cfgtask': <class 'waflib.Tools.c_config.cfgtask'>, 'cprogram': <class 'waflib.Tools.c.cprogram'>, 'cshlib': <class 'waflib.Tools.c.cshlib'>, 'cstlib': <class 'waflib.Tools.c.cstlib'>, 'cxx': <class 'waflib.Tools.cxx.cxx'>, 'cxxprogram': <class 'waflib.Tools.cxx.cxxprogram'>, 'cxxshlib': <class 'waflib.Tools.cxx.cxxshlib'>, 'cxxstlib': <class 'waflib.Tools.cxx.cxxstlib'>, 'd': <class 'waflib.Tools.d.d'>, 'd_header': <class 'waflib.Tools.d.d_header'>, 'd_with_header': <class 'waflib.Tools.d.d_with_header'>, 'dbus_binding_tool': <class 'waflib.Tools.dbus.dbus_binding_tool'>, 'dprogram': <class 'waflib.Tools.d.dprogram'>, 'dshlib': <class 'waflib.Tools.d.dshlib'>, 'dstlib': <class 'waflib.Tools.d.dstlib'>, 'dvipdf': <class 'waflib.Tools.tex.dvipdf'>, 'dvips': <class 'waflib.Tools.tex.dvips'>, 'fake_csshlib': <class 'waflib.Tools.cs.fake_csshlib'>, 'fake_o': <class 'waflib.Tools.ccroot.fake_o'>, 'fake_shlib': <class 'waflib.Tools.ccroot.fake_shlib'>, 'fake_stlib': <class 'waflib.Tools.ccroot.fake_stlib'>, 'fc': <class 'waflib.Tools.fc.fc'>, 'fcprogram': <class 'waflib.Tools.fc.fcprogram'>, 'fcprogram_test': <class 'waflib.Tools.fc.fcprogram_test'>, 'fcshlib': <class 'waflib.Tools.fc.fcshlib'>, 'fcstlib': <class 'waflib.Tools.fc.fcstlib'>, 'flex': <class 'waflib.Task.flex'>, 'glib_genmarshal': <class 'waflib.Tools.glib2.glib_genmarshal'>, 'glib_gresource_base': <class 'waflib.Tools.glib2.glib_gresource_base'>, 'glib_gresource_bundle': <class 'waflib.Tools.glib2.glib_gresource_bundle'>, 'glib_gresource_source': <class 'waflib.Tools.glib2.glib_gresource_source'>, 'glib_mkenums': <class 'waflib.Tools.glib2.glib_mkenums'>, 'glib_validate_schema': <class 'waflib.Tools.glib2.glib_validate_schema'>, 'grep_for_endianness': <class 'waflib.Tools.c_tests.grep_for_endianness'>, 'inst': <class 'waflib.Build.inst'>, 'intltool': <class 'waflib.Tools.intltool.intltool'>, 'jar_create': <class 'waflib.Tools.javaw.jar_create'>, 'javac': <class 'waflib.Tools.javaw.javac'>, 'javadoc': <class 'waflib.Tools.javaw.javadoc'>, 'latex': <class 'waflib.Tools.tex.latex'>, 'link_task': <class 'waflib.Tools.ccroot.link_task'>, 'luac': <class 'waflib.Tools.lua.luac'>, 'macapp': <class 'waflib.Tools.c_osx.macapp'>, 'macplist': <class 'waflib.Tools.c_osx.macplist'>, 'mcs': <class 'waflib.Tools.cs.mcs'>, 'moc': <class 'waflib.Tools.qt5.moc'>, 'pdf2ps': <class 'waflib.Tools.tex.pdf2ps'>, 'pdflatex': <class 'waflib.Tools.tex.pdflatex'>, 'po': <class 'waflib.Tools.intltool.po'>, 'pyc': <class 'waflib.Tools.python.pyc'>, 'pyo': <class 'waflib.Tools.python.pyo'>, 'qm2rcc': <class 'waflib.Tools.qt5.qm2rcc'>, 'qxx': <class 'waflib.Tools.qt5.qxx'>, 'rcc': <class 'waflib.Tools.qt5.rcc'>, 'run_ruby': <class 'waflib.Tools.ruby.run_ruby'>, 'stlink_task': <class 'waflib.Tools.ccroot.stlink_task'>, 'subst': <class 'waflib.TaskGen.subst'>, 'subst_pc': <class 'waflib.TaskGen.subst_pc'>, 'test_exec': <class 'waflib.Tools.c_config.test_exec'>, 'tex': <class 'waflib.Tools.tex.tex'>, 'trans_update': <class 'waflib.Tools.qt5.trans_update'>, 'ts2qm': <class 'waflib.Tools.qt5.ts2qm'>, 'ui5': <class 'waflib.Tools.qt5.ui5'>, 'utest': <class 'waflib.Tools.waf_unit_test.utest'>, 'valac': <class 'waflib.Tools.vala.valac'>, 'vnum': <class 'waflib.Tools.ccroot.vnum'>, 'winrc': <class 'waflib.Tools.winres.winrc'>, 'xelatex': <class 'waflib.Tools.tex.xelatex'>, 'xsubpp': <class 'waflib.Tools.perl.xsubpp'>}

The metaclass waflib.Task.store_task_type stores all class tasks created by user scripts or Waf tools to this dict. It maps class names to class objects.

class waflib.Task.store_task_type(name, bases, dict)[source]

Metaclass: store the task classes into the dict pointed by the class attribute ‘register’ which defaults to waflib.Task.classes,

The attribute ‘run_str’ is compiled into a method ‘run’ bound to the task class.

__annotations__ = {}
class waflib.Task.evil

Base class provided to avoid writing a metaclass, so the code can run in python 2.6 and 3.x unmodified

__annotations__ = {}
class waflib.Task.Task(*k, **kw)[source]

Task objects represents actions to perform such as commands to execute by calling the run method.

Detecting when to execute a task occurs in the method waflib.Task.Task.runnable_status().

Detecting which tasks to execute is performed through a hash value returned by waflib.Task.Task.signature(). The task signature is persistent from build to build.

vars = []

ConfigSet variables that should trigger a rebuild (class attribute used for waflib.Task.Task.sig_vars())

always_run = False

Specify whether task instances must always be executed or not (class attribute)

shell = False

Execute the command with the shell (class attribute)

color = 'GREEN'

Color for the console display, see waflib.Logs.colors_lst

ext_in = []

File extensions that objects of this task class may use

ext_out = []

File extensions that objects of this task class may create

before = []

The instances of this class are executed before the instances of classes whose names are in this list

after = []

The instances of this class are executed after the instances of classes whose names are in this list

hcode = b'SIG_NIL_SIG_NIL_'

String representing an additional hash for the class representation

keep_last_cmd = False

Whether to keep the last command executed on the instance after execution. This may be useful for certain extensions but it can a lot of memory.

weight = 0

Optional weight to tune the priority for task instances. The higher, the earlier. The weight only applies to single task objects.

tree_weight = 0

Optional weight to tune the priority of task instances and whole subtrees. The higher, the earlier.

prio_order = 0

Priority order set by the scheduler on instances during the build phase. You most likely do not need to set it.

__slots__ = ('hasrun', 'generator', 'env', 'inputs', 'outputs', 'dep_nodes', 'run_after')
hasrun
generator
env

waflib.ConfigSet.ConfigSet object (make sure to provide one)

inputs

List of input nodes, which represent the files used by the task instance

outputs

List of output nodes, which represent the files created by the task instance

dep_nodes

List of additional nodes to depend on

run_after

Set of tasks that must be executed before this one

get_cwd()[source]
Returns

current working directory

Return type

waflib.Node.Node

quote_flag(x)[source]

Surround a process argument by quotes so that a list of arguments can be written to a file

Parameters

x (string) – flag

Returns

quoted flag

Return type

string

priority()[source]

Priority of execution; the higher, the earlier

Returns

the priority value

Return type

a tuple of numeric values

split_argfile(cmd)[source]

Splits a list of process commands into the executable part and its list of arguments

Returns

a tuple containing the executable first and then the rest of arguments

Return type

tuple

exec_command(cmd, **kw)[source]

Wrapper for waflib.Context.Context.exec_command(). This version set the current working directory (build.variant_dir), applies PATH settings (if self.env.PATH is provided), and can run long commands through a temporary @argfile.

Parameters

cmd (list of string (best) or string (process will use a shell)) – process command to execute

Returns

the return code

Return type

int

Optional parameters:

  1. cwd: current working directory (Node or string)

  2. stdout: set to None to prevent waf from capturing the process standard output

  3. stderr: set to None to prevent waf from capturing the process standard error

  4. timeout: timeout value (Python 3)

log_display(bld)[source]

Writes the execution status on the context logger

display()[source]

Returns an execution status for the console, the progress bar, or the IDE output.

Return type

string

hash_constraints()[source]

Identifies a task type for all the constraints relevant for the scheduler: precedence, file production

Returns

a hash value

Return type

string

format_error()[source]

Returns an error message to display the build failure reasons

Return type

string

colon(var1, var2)[source]

Enable scriptlet expressions of the form ${FOO_ST:FOO} If the first variable (FOO_ST) is empty, then an empty list is returned

The results will be slightly different if FOO_ST is a list, for example:

env.FOO    = ['p1', 'p2']
env.FOO_ST = '-I%s'
# ${FOO_ST:FOO} returns
['-Ip1', '-Ip2']

env.FOO_ST = ['-a', '-b']
# ${FOO_ST:FOO} returns
['-a', '-b', 'p1', '-a', '-b', 'p2']
__str__()[source]

string to display to the user

keyword()[source]

Display keyword used to prettify the console outputs

__repr__()[source]

for debugging purposes

uid()[source]

Returns an identifier used to determine if tasks are up-to-date. Since the identifier will be stored between executions, it must be:

  • unique for a task: no two tasks return the same value (for a given build context)

  • the same for a given task instance

By default, the node paths, the class name, and the function are used as inputs to compute a hash.

The pointer to the object (python built-in ‘id’) will change between build executions, and must be avoided in such hashes.

Returns

hash value

Return type

string

set_inputs(inp)[source]

Appends the nodes to the inputs list

Parameters

inp (node or list of nodes) – input nodes

set_outputs(out)[source]

Appends the nodes to the outputs list

Parameters

out (node or list of nodes) – output nodes

set_run_after(task)[source]

Run this task only after the given task.

Calling this method from waflib.Task.Task.runnable_status() may cause build deadlocks; see waflib.Tools.fc.fc.runnable_status() for details.

Parameters

task (waflib.Task.Task) – task

signature()[source]

Task signatures are stored between build executions, they are use to track the changes made to the input nodes (not to the outputs!). The signature hashes data from various sources:

If the signature is expected to give a different result, clear the cache kept in self.cache_sig:

from waflib import Task
class cls(Task.Task):
        def signature(self):
                sig = super(Task.Task, self).signature()
                delattr(self, 'cache_sig')
                return super(Task.Task, self).signature()
Returns

the signature value

Return type

string or bytes

runnable_status()[source]

Returns the Task status

Returns

a task state in waflib.Task.RUN_ME, waflib.Task.SKIP_ME, waflib.Task.CANCEL_ME or waflib.Task.ASK_LATER.

Return type

int

post_run()[source]

Update the cache files (executed by threads). Override in subclasses.

sig_explicit_deps()[source]

Used by waflib.Task.Task.signature(); it hashes waflib.Task.Task.inputs and waflib.Task.Task.dep_nodes signatures.

sig_deep_inputs()[source]

Enable rebuilds on input files task signatures. Not used by default.

Example: hashes of output programs can be unchanged after being re-linked, despite the libraries being different. This method can thus prevent stale unit test results (waf_unit_test.py).

Hashing input file timestamps is another possibility for the implementation. This may cause unnecessary rebuilds when input tasks are frequently executed. Here is an implementation example:

lst = []
for node in self.inputs + self.dep_nodes:
        st = os.stat(node.abspath())
        lst.append(st.st_mtime)
        lst.append(st.st_size)
self.m.update(Utils.h_list(lst))

The downside of the implementation is that it absolutely requires all build directory files to be declared within the current build.

sig_vars()[source]

Used by waflib.Task.Task.signature(); it hashes waflib.Task.Task.env variables/values When overriding this method, and if scriptlet expressions are used, make sure to follow the code in waflib.Task.Task.compile_sig_vars() to enable dependencies on scriptlet results.

This method may be replaced on subclasses by the metaclass to force dependencies on scriptlet code.

scan = None

This method, when provided, returns a tuple containing:

  • a list of nodes corresponding to real files

  • a list of names for files not found in path_lst

For example:

from waflib.Task import Task
class mytask(Task):
        def scan(self, node):
                return ([], [])

The first and second lists in the tuple are stored in waflib.Build.BuildContext.node_deps and waflib.Build.BuildContext.raw_deps respectively.

sig_implicit_deps()[source]

Used by waflib.Task.Task.signature(); it hashes node signatures obtained by scanning for dependencies (waflib.Task.Task.scan()).

The exception waflib.Errors.TaskRescan is thrown when a file has changed. In this case, the method waflib.Task.Task.signature() is called once again, and return here to call waflib.Task.Task.scan() and searching for dependencies.

__annotations__ = {}
compute_sig_implicit_deps()[source]

Used by waflib.Task.Task.sig_implicit_deps() for computing the actual hash of the waflib.Node.Node returned by the scanner.

Returns

a hash value for the implicit dependencies

Return type

string or bytes

are_implicit_nodes_ready()[source]

For each node returned by the scanner, see if there is a task that creates it, and infer the build order

This has a low performance impact on null builds (1.86s->1.66s) thanks to caching (28s->1.86s)

waflib.Task.uid(self)[source]

Returns an identifier used to determine if tasks are up-to-date. Since the identifier will be stored between executions, it must be:

  • unique for a task: no two tasks return the same value (for a given build context)

  • the same for a given task instance

By default, the node paths, the class name, and the function are used as inputs to compute a hash.

The pointer to the object (python built-in ‘id’) will change between build executions, and must be avoided in such hashes.

Returns

hash value

Return type

string

waflib.Task.is_before(t1, t2)[source]

Returns a non-zero value if task t1 is to be executed before task t2:

t1.ext_out = '.h'
t2.ext_in = '.h'
t2.after = ['t1']
t1.before = ['t2']
waflib.Task.is_before(t1, t2) # True
Parameters
waflib.Task.set_file_constraints(tasks)[source]

Updates the run_after attribute of all tasks based on the task inputs and outputs

Parameters

tasks (list of waflib.Task.Task) – tasks

class waflib.Task.TaskGroup(prev, next)[source]

Wrap nxm task order constraints into a single object to prevent the creation of large list/set objects

This is an optimization

waflib.Task.set_precedence_constraints(tasks)[source]

Updates the run_after attribute of all tasks based on the after/before/ext_out/ext_in attributes

Parameters

tasks (list of waflib.Task.Task) – tasks

waflib.Task.funex(c)[source]

Compiles a scriptlet expression into a Python function

Parameters

c (string) – function to compile

Returns

the function ‘f’ declared in the input string

Return type

function

waflib.Task.compile_fun_shell(line)[source]

Creates a compiled function to execute a process through a sub-shell

waflib.Task.compile_fun_noshell(line)[source]

Creates a compiled function to execute a process without a sub-shell

waflib.Task.compile_fun(line, shell=False)[source]

Parses a string expression such as ‘${CC} ${SRC} -o ${TGT}’ and returns a pair containing:

  • The function created (compiled) for use as waflib.Task.Task.run()

  • The list of variables that must cause rebuilds when env data is modified

for example:

from waflib.Task import compile_fun
compile_fun('cxx', '${CXX} -o ${TGT[0]} ${SRC} -I ${SRC[0].parent.bldpath()}')

def build(bld):
        bld(source='wscript', rule='echo "foo\${SRC[0].name}\bar"')

The env variables (CXX, ..) on the task must not hold dicts so as to preserve a consistent order. The reserved keywords TGT and SRC represent the task input and output nodes

waflib.Task.compile_sig_vars(vars)[source]

This method produces a sig_vars method suitable for subclasses that provide scriptlet code in their run_str code. If no such method can be created, this method returns None.

The purpose of the sig_vars method returned is to ensures that rebuilds occur whenever the contents of the expression changes. This is the case B below:

import time
# case A: regular variables
tg = bld(rule='echo ${FOO}')
tg.env.FOO = '%s' % time.time()
# case B
bld(rule='echo ${gen.foo}', foo='%s' % time.time())
Parameters

vars (list of string) – env variables such as CXXFLAGS or gen.foo

Returns

A sig_vars method relevant for dependencies if adequate, else None

Return type

A function, or None in most cases

waflib.Task.task_factory(name, func=None, vars=None, color='GREEN', ext_in=[], ext_out=[], before=[], after=[], shell=False, scan=None)[source]

Returns a new task subclass with the function run compiled from the line given.

Parameters
  • func (string or function) – method run

  • vars (list of string) – list of variables to hash

  • color (string) – color to use

  • shell (bool) – when func is a string, enable/disable the use of the shell

  • scan (function) – method scan

Return type

waflib.Task.Task

waflib.Task.deep_inputs(cls)[source]

Task class decorator to enable rebuilds on input files task signatures

waflib.Task.TaskBase

Provided for compatibility reasons, TaskBase should not be used

class waflib.Task.TaskSemaphore(num)[source]

Task semaphores provide a simple and efficient way of throttling the amount of a particular task to run concurrently. The throttling value is capped by the amount of maximum jobs, so for example, a TaskSemaphore(10) has no effect in a -j2 build.

Task semaphores are typically specified on the task class level:

class compile(waflib.Task.Task):
        semaphore = waflib.Task.TaskSemaphore(2)
        run_str = 'touch ${TGT}'

Task semaphores are meant to be used by the build scheduler in the main thread, so there are no guarantees of thread safety.

__init__(num)[source]
Parameters

num (int) – maximum value of concurrent tasks

is_locked()[source]

Returns True if this semaphore cannot be acquired by more tasks

acquire(tsk)[source]

Mark the semaphore as used by the given task (not re-entrant).

Parameters

tsk (waflib.Task.Task) – task object

Raises

IndexError in case the resource is already acquired

release(tsk)[source]

Mark the semaphore as unused by the given task.

Parameters

tsk (waflib.Task.Task) – task object

Raises

KeyError in case the resource is not acquired by the task