2
0
mirror of https://gitlab.com/ita1024/waf.git synced 2024-11-22 01:46:15 +01:00
This commit is contained in:
Thomas Nagy 2015-10-03 11:54:22 +02:00
parent a6b467d73e
commit b970bfcb2d
No known key found for this signature in database
GPG Key ID: 67A565EDFDF90E64
5 changed files with 92 additions and 15 deletions

View File

@ -214,11 +214,11 @@ The _WAFLOCK_ environment variable is used to control the configuration lock and
// advbuild_waflock
[source,python]
---------------
def configure(conf):
def configure(ctx):
pass
def build(bld):
bld(rule='touch ${TGT}', target='foo.txt')
def build(ctx):
ctx(rule='touch ${TGT}', target='foo.txt')
---------------
We will change the _WAFLOCK_ variable in the execution:

View File

@ -5,7 +5,7 @@ Transformations may be performed automatically based on the file name or on the
==== Refactoring repeated rule-based task generators into implicit rules
The explicit rules described in the previous chapter become limited for processing several files of the same kind. The following code may lead to unmaintainable scripts and to slow builds (for loop):
The explicit rules described in the previous chapter become a limitation for processing several files of the same extension. The following code may lead to unmaintainable scripts and to slow builds (large amount of objects):
[source, python]
----------------
@ -16,7 +16,7 @@ def build(bld):
bld.install_files('${LUADIR}', x)
----------------
Rather, the rule should be removed from the user script, like this:
It is desirable to extract the rule from the user scripts in the following manner:
[source,python]
---------------
@ -24,7 +24,7 @@ def build(bld):
bld(source='a.lua b.lua c.lua')
---------------
The equivalent logic may then be provided by using the following code. It may be located in either the same 'wscript', or in a waf tool:
The following piece of code will enable this functionality. It may be inserted in a waf tool or in the same `wscript` file:
[source,python]
---------------
@ -41,11 +41,11 @@ TaskGen.declare_chain(
---------------
<1> The name for the corresponding task class to use
<2> The rule is the same as for any rule-based task generator
<2> The rule is the same as for any rule-based task generator. It is passed to the `run_str` attribute of a task class.
<3> Input file, processed by extension
<4> Output files extensions separated by spaces. In this case there is only one output file
<5> The reentrant attribute is used to add the output files as source again, for processing by another implicit rule
<6> String representing the installation path for the output files, similar to the destination path from 'bld.install_files'. To disable installation, set it to False.
<6> String representing the installation path for the output files, similar to the destination path from 'bld.install_files'. To disable installation, set it to `False` or `None`.
==== Chaining more than one command

View File

@ -0,0 +1,32 @@
#! /usr/bin/env python
# encoding: utf-8
def configure(ctx):
pass
def build(ctx):
import os
from waflib import Utils, Task
def chmod_fun(task):
for x in task.outputs:
os.chmod(x.abspath(), Utils.O755)
def remove_fun(task):
for x in task.outputs:
try:
os.remove(x.abspath())
except OSError:
if os.path.exists(x.abspath()):
raise ValueError('Cannot remove %r' % x)
class complex_copy(Task.Task):
run_str = (remove_fun, "${CP} ${SRC} ${TGT}", chmod_fun)
ctx.env.CP = '/bin/cp'
tsk = complex_copy(env=ctx.env.derive())
tsk.set_inputs(ctx.path.find_resource('wscript'))
tsk.set_outputs(ctx.path.find_or_declare('wscript.out'))
ctx.add_to_group(tsk)

View File

@ -96,7 +96,7 @@ $ waf distclean configure build --zones=task_gen <1>
Waf: Entering directory `/tmp/simpleproject/build'
23:03:44 task_gen posting objects (normal)
23:03:44 task_gen posting >task_gen '' of type task_gen defined in dir:///tmp/simpleproject> 139657958706768 <2>
23:03:44 task_gen -> exec_rule (139657958706768) <3>
23:03:44 task_gen -> process_rule (139657958706768) <3>
23:03:44 task_gen -> process_source (139657958706768) <4>
23:03:44 task_gen -> methodName (139657958706768) <5>
Hello, world!
@ -108,8 +108,8 @@ Waf: Leaving directory `/tmp/simpleproject/build'
<1> The debugging zone 'task_gen' is used to display the task generator methods being executed
<2> Display which task generator is being executed
<3> The method 'exec_rule' is used to process the 'rule'. It is always executed.
<4> The method 'process_source' is used to process the 'source' attribute. It is always executed exept if the method 'exec_rule' processes a 'rule' attribute
<3> The method 'process_rule' is used to process the 'rule'. It is always executed.
<4> The method 'process_source' is used to process the 'source' attribute. It is always executed exept if the method 'process_rule' processes a 'rule' attribute
<5> Our task generator method is executed, and prints 'Hello, world!'
<6> The task generator methods have been executed, the task generator is marked as done (posted)
@ -150,13 +150,13 @@ $ waf distclean configure build --zones=task_gen
Waf: Entering directory `/tmp/simpleproject/build'
16:22:07 task_gen posting objects (normal)
16:22:07 task_gen posting <task_gen '' of type task_gen defined in dir:///tmp/simpleproject> 140631018237584
16:22:07 task_gen -> exec_rule (140631018237584)
16:22:07 task_gen -> process_rule (140631018237584)
16:22:07 task_gen -> process_source (140631018237584)
16:22:07 task_gen -> ping (140631018237584)
ping
16:22:07 task_gen posted
16:22:07 task_gen posting <task_gen '' of type task_gen defined in dir:///tmp/simpleproject> 140631018237776
16:22:07 task_gen -> exec_rule (140631018237776)
16:22:07 task_gen -> process_rule (140631018237776)
16:22:07 task_gen -> process_source (140631018237776)
16:22:07 task_gen -> pong (140631018237776)
pong
@ -188,7 +188,7 @@ def build(bld):
from waflib import TaskGen
@TaskGen.feature('*')
@TaskGen.before('process_source', 'exec_rule')
@TaskGen.before('process_source', 'process_rule')
def method1(self):
print('method 1 %r' % getattr(self, 'myattr', None))
@ -211,7 +211,7 @@ Waf: Entering directory `/tmp/simpleproject/build'
15:54:02 task_gen posting <task_gen of type task_gen defined in dir:///tmp/simpleproject> 139808568487632
15:54:02 task_gen -> method1 (139808568487632)
method 1 'Hello, world!'
15:54:02 task_gen -> exec_rule (139808568487632)
15:54:02 task_gen -> process_rule (139808568487632)
15:54:02 task_gen -> method2 (139808568487632)
method 2 'Hello, world!'
15:54:02 task_gen -> process_source (139808568487632)

View File

@ -514,6 +514,51 @@ ${CPPPATH_ST:INCPATHS} <4>
<3> Print the task unique identifier
<4> Perform a map replacement equivalent to _[env.CPPPATH_ST % x for x in env.INCPATHS]_
==== Command chains
In order to improve script portability 'run_str' can also be a list of command strings or functions. All sub-commands must complete for the task to succeed.
The following example shows how to chain three commands to copy `wscript` to `wscript.out`. The output file will be removed first if it already exists.
The copy is then performed. When successful, the output file permissions are changed to turn it into an executable.
// tasks_chains
[source,python]
---------------
def build(ctx):
import os
from waflib import Utils, Task
def chmod_fun(task): <1>
for x in task.outputs:
os.chmod(x.abspath(), Utils.O755)
return 0
def remove_fun(task):
for x in task.outputs:
try:
os.remove(x.abspath())
except OSError:
if os.path.exists(x.abspath()):
raise ValueError('Cannot remove %r' % x) <2>
return 0
class complex_copy(Task.Task):
run_str = (remove_fun, "${CP} ${SRC} ${TGT}", chmod_fun) <3>
ctx.env.CP = '/bin/cp' <4>
tsk = complex_copy(env=ctx.env.derive())
tsk.set_inputs(ctx.path.find_resource('wscript'))
tsk.set_outputs(ctx.path.find_or_declare('wscript.out'))
ctx.add_to_group(tsk)
---------------
<1> The function arguments is the same as that of 'run' methods. Function commands return 0 or None in case of success.
<2> Function commands can raise exceptions such as OSError, ValueError or WafError
<3> Several functions or strings can be chained together; the build will run the commands in the order specified
<4> Rebuilds will occur when variables used in command strings are modified, and when command strings or function definitions change
NOTE: Chaining is also possible through subclassing.
==== Direct class modifications
===== Always execute