TaskGen
Task generators
The class waflib.TaskGen.task_gen encapsulates the creation of task objects (low-level code)
The instances can have various parameters, but the creation of task nodes (Task.py)
is always postponed. To achieve this, various methods are called from the method “apply”
-
waflib.TaskGen.feats = defaultdict(<type 'set'>, {'py': set(['feature_py']), 'pyembed': set(['init_pyembed']), 'seq': set(['sequence_order']), 'cxx': set(['set_macosx_deployment_target', 'process_use', 'apply_incpaths', 'apply_link', 'apply_flags_msvc', 'propagate_uselib_vars']), 'winphoneapp': set(['make_winphone_app']), 'cxxshlib': set(['apply_implib', 'apply_vnum', 'apply_manifest', 'apply_bundle']), 'javadoc': set(['create_javadoc']), 'fcstlib': set(['dummy']), 'tex': set(['apply_tex']), 'cs': set(['use_cs', 'propagate_uselib_vars', 'debug_cs', 'apply_cs']), 'link_main_routines_func': set(['link_main_routines_tg_method']), 'vnum': set(['apply_vnum']), 'grep_for_endianness': set(['grep_for_endianness_fun']), 'use': set(['process_use']), 'javac': set(['apply_java', 'propagate_uselib_vars', 'use_javac_files', 'set_classpath']), 'uselib': set(['propagate_uselib_vars']), '*': set(['process_rule', 'process_source']), 'jar': set(['jar_files', 'use_jar_files']), 'fcprogram': set(['dummy']), 'subst': set(['process_subst']), 'fake_lib': set(['process_lib']), 'cxxprogram': set(['set_full_paths_hpux', 'create_task_macapp', 'create_task_macplist', 'apply_manifest']), 'test': set(['make_test']), 'intltool_in': set(['apply_intltool_in_f']), 'cshlib': set(['apply_implib', 'apply_vnum', 'apply_manifest', 'apply_bundle']), 'qt4': set(['apply_qt4']), 'qt5': set(['apply_qt5']), 'intltool_po': set(['apply_intltool_po']), 'msgfmt': set(['apply_msgfmt']), 'cprogram': set(['set_full_paths_hpux', 'create_task_macapp', 'create_task_macplist', 'apply_manifest']), 'rubyext': set(['init_rubyext', 'apply_ruby_so_name']), 'includes': set(['apply_incpaths']), 'winapp': set(['make_windows_app']), 'fc': set(['process_use', 'apply_incpaths', 'propagate_uselib_vars', 'apply_link']), 'gresource': set(['process_gresource_bundle']), 'pyext': set(['set_lib_pat', 'set_bundle', 'init_pyext']), 'fcshlib': set(['apply_implib', 'dummy', 'apply_vnum']), 'perlext': set(['init_perlext']), 'asm': set(['apply_incpaths', 'propagate_uselib_vars', 'apply_nasm_vars', 'apply_link']), 'test_exec': set(['test_exec_fun']), 'c': set(['set_macosx_deployment_target', 'process_use', 'apply_incpaths', 'apply_link', 'apply_flags_msvc', 'propagate_uselib_vars']), 'd': set(['process_use', 'apply_incpaths', 'propagate_uselib_vars', 'process_header', 'apply_link']), 'link_lib_test': set(['link_lib_test_fun']), 'dshlib': set(['apply_vnum']), 'glib2': set(['process_settings']), 'fcprogram_test': set(['dummy']), 'fake_obj': set(['process_objs'])})
remember the methods declaring features
-
class waflib.TaskGen.task_gen(*k, **kw)[source]
Bases: object
Instances of this class create waflib.Task.TaskBase when
calling the method waflib.TaskGen.task_gen.post() from the main thread.
A few notes:
- The methods to call (self.meths) can be specified dynamically (removing, adding, ..)
- The ‘features’ are used to add methods to self.meths and then execute them
- The attribute ‘path’ is a node representing the location of the task generator
- The tasks created are added to the attribute tasks
- The attribute ‘idx’ is a counter of task generators in the same path
-
__init__(*k, **kw)[source]
The task generator objects predefine various attributes (source, target) for possible
processing by process_rule (make-like rules) or process_source (extensions, misc methods)
The tasks are stored on the attribute ‘tasks’. They are created by calling methods
listed in self.meths or referenced in the attribute features
A topological sort is performed to ease the method re-use.
The extra key/value elements passed in kw are set as attributes
-
meths = None
List of method names to execute (it is usually a good idea to avoid touching this)
-
prec = defaultdict(<type 'list'>, {'make_test': ['apply_link'], 'apply_lib_vars': ['init_rubyext'], 'make_winphone_app': ['propagate_uselib_vars', 'process_use'], 'apply_incpaths': ['propagate_uselib_vars', 'process_source', 'process_use', 'init_rubyext', 'init_perlext'], 'use_cs': ['apply_cs'], 'use_jar_files': ['jar_files'], 'use_javac_files': ['apply_java'], 'apply_bundle': ['init_rubyext', 'set_bundle'], 'process_use': ['apply_link', 'process_source'], 'apply_qt5': ['apply_link'], 'create_javadoc': ['process_rule'], 'set_full_paths_hpux': ['apply_link', 'process_use'], 'debug_cs': ['apply_cs', 'use_cs'], 'process_source': ['process_rule', 'process_subst', 'link_lib_test_fun', 'process_objs', 'process_marshal', 'process_enums', 'feature_py', 'apply_java', 'jar_files', 'apply_cs', 'link_main_routines_tg_method', 'apply_intltool_in_f', 'apply_tex'], 'apply_link': ['apply_bundle', 'process_source', 'init_rubyext', 'apply_ruby_so_name', 'init_pyext', 'set_bundle', 'init_perlext', 'set_lib_pat'], 'init_pyext': ['apply_bundle'], 'apply_core': ['process_dbus'], 'apply_vnum': ['apply_link', 'propagate_uselib_vars'], 'create_task_macplist': ['apply_link'], 'make_windows_app': ['propagate_uselib_vars', 'process_use'], 'grep_for_endianness_fun': ['process_source'], 'propagate_uselib': ['apply_ruby_so_name'], 'test_exec_fun': ['apply_link'], 'jar_files': ['apply_java', 'use_javac_files'], 'apply_manifest': ['apply_link'], 'process_rule': ['process_subst'], 'set_classpath': ['apply_java', 'propagate_uselib_vars', 'use_javac_files'], 'create_task_macapp': ['apply_link'], 'apply_implib': ['apply_link'], 'apply_qt4': ['apply_link'], 'apply_flags_msvc': ['apply_link'], 'propagate_uselib_vars': ['apply_bundle', 'process_use', 'init_pyext', 'init_pyembed', 'init_perlext', 'set_lib_pat']})
Precedence table for sorting the methods in self.meths
-
mappings = OrderedDict([('.pc.in', <function add_pcfile at 0x7f40a9145578>), ('.o', <function add_those_o_files at 0x7f40a8e7c0c8>), ('.obj', <function add_those_o_files at 0x7f40a8e7c0c8>), ('.d', <function d_hook at 0x7f40a8e826e0>), ('.di', <function d_hook at 0x7f40a8e826e0>), ('.D', <function d_hook at 0x7f40a8e826e0>), ('.rb', <function process at 0x7f40a8e82e60>), ('.s', <function asm_hook at 0x7f40a8e860c8>), ('.S', <function asm_hook at 0x7f40a8e860c8>), ('.asm', <function asm_hook at 0x7f40a8e860c8>), ('.ASM', <function asm_hook at 0x7f40a8e860c8>), ('.spp', <function asm_hook at 0x7f40a8e860c8>), ('.SPP', <function asm_hook at 0x7f40a8e860c8>), ('.vala', <function vala_file at 0x7f40a8e869b0>), ('.gs', <function vala_file at 0x7f40a8e869b0>), ('.rc', <function rc_file at 0x7f40a8f06140>), ('.gresource.xml', <function process_gresource_source at 0x7f40a8eee230>), ('.py', <function process_py at 0x7f40a8eeef50>), ('.l', <function x_file at 0x7f40a8f53410>), ('.xs', <function xsubpp_file at 0x7f40a8f53758>), ('.c', <function c_hook at 0x7f40a8f6d8c0>), ('.cpp', <function cxx_hook at 0x7f40a8f24500>), ('.cc', <function cxx_hook at 0x7f40a8f24500>), ('.cxx', <function cxx_hook at 0x7f40a8f24500>), ('.C', <function cxx_hook at 0x7f40a8f24500>), ('.c++', <function cxx_hook at 0x7f40a8f6da28>), ('.qrc', <function create_rcc_task at 0x7f40a8f24398>), ('.ui', <function create_uic_task at 0x7f40a8f24410>), ('.ts', <function add_lang at 0x7f40a8f24488>), ('.y', <function big_bison at 0x7f40a8dbade8>), ('.yc', <function big_bison at 0x7f40a8dbade8>), ('.yy', <function big_bison at 0x7f40a8dbade8>), ('.lua', <function add_lua at 0x7f40a8f0d848>), ('.f', <function fc_hook at 0x7f40a8f3cc08>), ('.f90', <function fc_hook at 0x7f40a8f3cc08>), ('.F', <function fc_hook at 0x7f40a8f3cc08>), ('.F90', <function fc_hook at 0x7f40a8f3cc08>), ('.for', <function fc_hook at 0x7f40a8f3cc08>), ('.FOR', <function fc_hook at 0x7f40a8f3cc08>)])
List of mappings {extension -> function} for processing files by extension
This is very rarely used, so we do not use an ordered dict here
-
features = None
List of feature names for bringing new methods in
-
tasks = None
List of tasks created.
-
__str__()[source]
for debugging purposes
-
__repr__()[source]
for debugging purposes
-
get_name()[source]
If not set, the name is computed from the target name:
def build(bld):
x = bld(name='foo')
x.get_name() # foo
y = bld(target='bar')
y.get_name() # bar
Return type: | string |
Returns: | name of this task generator |
-
name
If not set, the name is computed from the target name:
def build(bld):
x = bld(name='foo')
x.get_name() # foo
y = bld(target='bar')
y.get_name() # bar
Return type: | string |
Returns: | name of this task generator |
-
to_list(val)[source]
Ensure that a parameter is a list
Parameters: | val (string or list of string) – input to return as a list |
Return type: | list |
-
post()[source]
Create task objects. The following operations are performed:
- The body of this method is called only once and sets the attribute posted
- The attribute features is used to add more methods in self.meths
- The methods are sorted by the precedence table self.prec or :waflib:attr:waflib.TaskGen.task_gen.prec
- The methods are then executed in order
- The tasks created are added to waflib.TaskGen.task_gen.tasks
-
get_hook(node)[source]
Parameters: | node (waflib.Tools.Node.Node) – Input file to process |
Returns: | A method able to process the input node by looking at the extension |
Return type: | function |
-
create_task(name, src=None, tgt=None, **kw)[source]
Wrapper for creating task instances. The classes are retrieved from the
context class if possible, then from the global dict Task.classes.
Parameters: |
- name (string) – task class name
- src (list of waflib.Tools.Node.Node) – input nodes
- tgt (list of waflib.Tools.Node.Node) – output nodes
|
Returns: | A task object
|
Return type: | waflib.Task.TaskBase
|
-
clone(env)[source]
Make a copy of a task generator. Once the copy is made, it is necessary to ensure that the
it does not create the same output files as the original, or the same files may
be compiled several times.
-
__doc__ = "\n\tInstances of this class create :py:class:`waflib.Task.TaskBase` when\n\tcalling the method :py:meth:`waflib.TaskGen.task_gen.post` from the main thread.\n\tA few notes:\n\n\t* The methods to call (*self.meths*) can be specified dynamically (removing, adding, ..)\n\t* The 'features' are used to add methods to self.meths and then execute them\n\t* The attribute 'path' is a node representing the location of the task generator\n\t* The tasks created are added to the attribute *tasks*\n\t* The attribute 'idx' is a counter of task generators in the same path\n\t"
-
__module__ = 'waflib.TaskGen'
-
process_dbus()
Process the dbus files stored in the attribute dbus_lst to create waflib.Tools.dbus.dbus_binding_tool instances.
-
process_enums()
Process the enum files stored in the attribute enum_list to create waflib.Tools.glib2.glib_mkenums instances.
-
process_marshal()
Process the marshal files stored in the attribute marshal_list to create waflib.Tools.glib2.glib_genmarshal instances.
Add the c file created to the list of source to process.
-
waflib.TaskGen.declare_chain(name='', rule=None, reentrant=None, color='BLUE', ext_in=[], ext_out=[], before=[], after=[], decider=None, scan=None, install_path=None, shell=False)[source]
Create a new mapping and a task class for processing files by extension.
See Tools/flex.py for an example.
Parameters: |
- name (string) – name for the task class
- rule (string or function) – function to execute or string to be compiled in a function
- reentrant (int) – re-inject the output file in the process (done automatically, set to 0 to disable)
- color (string) – color for the task output
- ext_in (list of string) – execute the task only after the files of such extensions are created
- ext_out (list of string) – execute the task only before files of such extensions are processed
- before (list of string) – execute instances of this task before classes of the given names
- after (list of string) – execute instances of this task after classes of the given names
- decider (function) – if present, use it to create the output nodes for the task
- scan (function) – scanner function for the task
- install_path (string) – installation path for the output nodes
|
-
waflib.TaskGen.taskgen_method(func)[source]
Decorator: register a method as a task generator method.
The function must accept a task generator as first parameter:
from waflib.TaskGen import taskgen_method
@taskgen_method
def mymethod(self):
pass
Parameters: | func (function) – task generator method to add |
Return type: | function |
-
waflib.TaskGen.feature(*k)[source]
Decorator: register a task generator method that will be executed when the
object attribute ‘feature’ contains the corresponding key(s):
from waflib.Task import feature
@feature('myfeature')
def myfunction(self):
print('that is my feature!')
def build(bld):
bld(features='myfeature')
Parameters: | k (list of string) – feature names |
-
waflib.TaskGen.before_method(*k)[source]
Decorator: register a task generator method which will be executed
before the functions of given name(s):
from waflib.TaskGen import feature, before
@feature('myfeature')
@before_method('fun2')
def fun1(self):
print('feature 1!')
@feature('myfeature')
def fun2(self):
print('feature 2!')
def build(bld):
bld(features='myfeature')
Parameters: | k (list of string) – method names |
-
waflib.TaskGen.before(*k)
Decorator: register a task generator method which will be executed
before the functions of given name(s):
from waflib.TaskGen import feature, before
@feature('myfeature')
@before_method('fun2')
def fun1(self):
print('feature 1!')
@feature('myfeature')
def fun2(self):
print('feature 2!')
def build(bld):
bld(features='myfeature')
Parameters: | k (list of string) – method names |
-
waflib.TaskGen.after_method(*k)[source]
Decorator: register a task generator method which will be executed
after the functions of given name(s):
from waflib.TaskGen import feature, after
@feature('myfeature')
@after_method('fun2')
def fun1(self):
print('feature 1!')
@feature('myfeature')
def fun2(self):
print('feature 2!')
def build(bld):
bld(features='myfeature')
Parameters: | k (list of string) – method names |
-
waflib.TaskGen.after(*k)
Decorator: register a task generator method which will be executed
after the functions of given name(s):
from waflib.TaskGen import feature, after
@feature('myfeature')
@after_method('fun2')
def fun1(self):
print('feature 1!')
@feature('myfeature')
def fun2(self):
print('feature 2!')
def build(bld):
bld(features='myfeature')
Parameters: | k (list of string) – method names |
-
waflib.TaskGen.extension(*k)[source]
Decorator: register a task generator method which will be invoked during
the processing of source files for the extension given:
from waflib import Task
class mytask(Task):
run_str = 'cp ${SRC} ${TGT}'
@extension('.moo')
def create_maa_file(self, node):
self.create_task('mytask', node, node.change_ext('.maa'))
def build(bld):
bld(source='foo.moo')
-
waflib.TaskGen.to_nodes(self, lst, path=None)[source]
Task generator method
Convert the input list into a list of nodes.
It is used by waflib.TaskGen.process_source() and waflib.TaskGen.process_rule().
It is designed for source files, for folders, see waflib.Tools.ccroot.to_incnodes():
Parameters: |
- lst (list of string and nodes) – input list
- path (waflib.Tools.Node.Node) – path from which to search the nodes (by default, waflib.TaskGen.task_gen.path)
|
Return type: | list of waflib.Tools.Node.Node
|
-
waflib.TaskGen.process_source(self)[source]
Task generator method
Process each element in the attribute source by extension.
- The source list is converted through waflib.TaskGen.to_nodes() to a list of waflib.Node.Node first.
- File extensions are mapped to methods having the signature: def meth(self, node) by waflib.TaskGen.extension()
- The method is retrieved through waflib.TaskGen.task_gen.get_hook()
- When called, the methods may modify self.source to append more source to process
- The mappings can map an extension or a filename (see the code below)
-
waflib.TaskGen.process_rule(self)[source]
Task generator method
Process the attribute rule. When present, waflib.TaskGen.process_source() is disabled:
def build(bld):
bld(rule='cp ${SRC} ${TGT}', source='wscript', target='bar.txt')
-
waflib.TaskGen.sequence_order(self)[source]
Task generator method
Add a strict sequential constraint between the tasks generated by task generators.
It works because task generators are posted in order.
It will not post objects which belong to other folders.
Example:
bld(features='javac seq')
bld(features='jar seq')
To start a new sequence, set the attribute seq_start, for example:
obj = bld(features='seq')
obj.seq_start = True
Note that the method is executed in last position. This is more an
example than a widely-used solution.
-
class waflib.TaskGen.subst_pc(*k, **kw)[source]
Bases: waflib.Task.Task
Create .pc files from .pc.in. The task is executed whenever an input variable used
in the substitution changes.
-
__doc__ = '\n\tCreate *.pc* files from *.pc.in*. The task is executed whenever an input variable used\n\tin the substitution changes.\n\t'
-
__module__ = 'waflib.TaskGen'
-
hcode = '\tdef run(self):\n\t\t"Substitutes variables in a .in file"\n\n\t\tif getattr(self.generator, \'is_copy\', None):\n\t\t\tself.outputs[0].write(self.inputs[0].read(\'rb\'), \'wb\')\n\t\t\tif getattr(self.generator, \'chmod\', None):\n\t\t\t\tos.chmod(self.outputs[0].abspath(), self.generator.chmod)\n\t\t\treturn None\n\n\t\tif getattr(self.generator, \'fun\', None):\n\t\t\treturn self.generator.fun(self)\n\n\t\tcode = self.inputs[0].read(encoding=getattr(self.generator, \'encoding\', \'ISO8859-1\'))\n\t\tif getattr(self.generator, \'subst_fun\', None):\n\t\t\tcode = self.generator.subst_fun(self, code)\n\t\t\tif code is not None:\n\t\t\t\tself.outputs[0].write(code, encoding=getattr(self.generator, \'encoding\', \'ISO8859-1\'))\n\t\t\treturn\n\n\t\t# replace all % by %% to prevent errors by % signs\n\t\tcode = code.replace(\'%\', \'%%\')\n\n\t\t# extract the vars foo into lst and replace @foo@ by %(foo)s\n\t\tlst = []\n\t\tdef repl(match):\n\t\t\tg = match.group\n\t\t\tif g(1):\n\t\t\t\tlst.append(g(1))\n\t\t\t\treturn "%%(%s)s" % g(1)\n\t\t\treturn \'\'\n\t\tglobal re_m4\n\t\tcode = getattr(self.generator, \'re_m4\', re_m4).sub(repl, code)\n\n\t\ttry:\n\t\t\td = self.generator.dct\n\t\texcept AttributeError:\n\t\t\td = {}\n\t\t\tfor x in lst:\n\t\t\t\ttmp = getattr(self.generator, x, \'\') or self.env[x] or self.env[x.upper()]\n\t\t\t\ttry:\n\t\t\t\t\ttmp = \'\'.join(tmp)\n\t\t\t\texcept TypeError:\n\t\t\t\t\ttmp = str(tmp)\n\t\t\t\td[x] = tmp\n\n\t\tcode = code % d\n\t\tself.outputs[0].write(code, encoding=getattr(self.generator, \'encoding\', \'ISO8859-1\'))\n\t\tself.generator.bld.raw_deps[self.uid()] = self.dep_vars = lst\n\n\t\t# make sure the signature is updated\n\t\ttry: delattr(self, \'cache_sig\')\n\t\texcept AttributeError: pass\n\n\t\tif getattr(self.generator, \'chmod\', None):\n\t\t\tos.chmod(self.outputs[0].abspath(), self.generator.chmod)\n'
-
run()[source]
Substitutes variables in a .in file
-
sig_vars()[source]
Compute a hash (signature) of the variables used in the substitution
-
waflib.TaskGen.add_pcfile(self, node)[source]
Process .pc.in files to .pc. Install the results to ${PREFIX}/lib/pkgconfig/
- def build(bld):
- bld(source=’foo.pc.in’, install_path=’${LIBDIR}/pkgconfig/’)
-
waflib.TaskGen.process_subst(self)[source]
Task generator method
Define a transformation that substitutes the contents of source files to target files:
def build(bld):
bld(
features='subst',
source='foo.c.in',
target='foo.c',
install_path='${LIBDIR}/pkgconfig',
VAR = 'val'
)
The input files are supposed to contain macros of the form @VAR@, where VAR is an argument
of the task generator object.
This method overrides the processing by waflib.TaskGen.process_source().