在其他 waf Task 中使用 waf Task 的输出
Use output of waf Task in other waf Task
我想将一个 waf 任务的 target 用作另一个 waf 任务中的 source,但这并没有像预期的那样工作。
一个简单但完整的例子:
我添加了两个任务(t_1
、t_2
)我想添加为功能并通过 before
和 after
添加了它们的约束。
在任务 t_1
中,我使用 src=link_task.outputs[0]
作为 src
和 link_task.outputs[0].change_ext('.txt')
作为 tgt
作为任务。
但是在t_2
中我想使用t_1
的output/target作为输入。我以为我可以通过引用 self.t_1.ouputs
来获取它,但这似乎是错误的。为什么这对 t_1
中的 apply_link
任务有效,但对 t_1
无效?
MWE: wscript
from waflib import Context, Options
from waflib import Task, TaskGen
from waflib.Tools.compiler_c import c_compiler
def options(opt):
opt.load('compiler_c')
def configure(cnf):
cnf.load('compiler_c')
def build(bld):
bld.program(features=['t_1', 't_2'], source='main.c', target="abc")
class t_1(Task.Task):
always_run = True
run_str = 'echo ${SRC} && echo hello t_1 > ${TGT}'
color = 'RED'
@TaskGen.feature('t_1')
@TaskGen.after('apply_link')
@TaskGen.before('t_2')
def add_t_1_task(self):
try:
link_task = self.link_task
except AttributeError as err:
print err
return
self.create_task('t_1', src=link_task.outputs[0], tgt=link_task.outputs[0].change_ext('.txt'))
class t_2(Task.Task):
always_run = True
run_str = 'echo ${SRC}'
color = 'RED'
@TaskGen.feature('t_2')
@TaskGen.after('apply_link', 't_1')
def add_t_2_task(self):
try:
t_1 = self.t_1
except AttributeError as err:
print err
return
self.create_task('t_2', src=t_1.outputs[0])
运行 python waf configure build
导致:
user@laptop /cygdrive/c/work
$ python waf-1.9.13 configure clean build
Setting top to : /cygdrive/c/work
Setting out to : /cygdrive/c/work/build
Checking for 'gcc' (C compiler) : /usr/bin/gcc
'configure' finished successfully (0.150s)
'clean' finished successfully (0.010s)
Waf: Entering directory `/cygdrive/c/work/build'
'task_gen' object has no attribute 't_1' <===================== How to get this working
[1/3] Compiling main.c
[2/3] Linking build/abc.exe
[3/3] Compiling build/abc.exe
abc.exe
Waf: Leaving directory `/cygdrive/c/work/build'
'build' finished successfully (0.270s)
before
和 after
装饰器适用于任务生成器 方法 ,而不是 任务 。你应该有:
@TaskGen.feature('t_1')
@TaskGen.after('apply_link')
# correction: no need to use @TaskGen.before('add_t_2_task')
def add_t_1_task(self):
# correction: you have to define self.t_1
self.t_1 = self.create_task(
't_1',
self.link_task.outputs[0],
self.link_task.outputs[0].change_ext('.txt')
)
@TaskGen.feature('t_2')
@TaskGen.after('apply_link', 'add_t_1_task') # correction: use method name
def add_t_2_task(self):
# add_t-2_task is executed after add_t_1_task, so using self.t_1 is ok
print "t_1", self.t_1
顺便说一下,不要使用 always_run=True
,因为它破坏了 waf 的主要功能之一,即只构建你需要构建的东西:)
我想将一个 waf 任务的 target 用作另一个 waf 任务中的 source,但这并没有像预期的那样工作。
一个简单但完整的例子:
我添加了两个任务(t_1
、t_2
)我想添加为功能并通过 before
和 after
添加了它们的约束。
在任务
t_1
中,我使用src=link_task.outputs[0]
作为src
和link_task.outputs[0].change_ext('.txt')
作为tgt
作为任务。但是在
t_2
中我想使用t_1
的output/target作为输入。我以为我可以通过引用self.t_1.ouputs
来获取它,但这似乎是错误的。为什么这对t_1
中的apply_link
任务有效,但对t_1
无效?
MWE: wscript
from waflib import Context, Options from waflib import Task, TaskGen from waflib.Tools.compiler_c import c_compiler def options(opt): opt.load('compiler_c') def configure(cnf): cnf.load('compiler_c') def build(bld): bld.program(features=['t_1', 't_2'], source='main.c', target="abc") class t_1(Task.Task): always_run = True run_str = 'echo ${SRC} && echo hello t_1 > ${TGT}' color = 'RED' @TaskGen.feature('t_1') @TaskGen.after('apply_link') @TaskGen.before('t_2') def add_t_1_task(self): try: link_task = self.link_task except AttributeError as err: print err return self.create_task('t_1', src=link_task.outputs[0], tgt=link_task.outputs[0].change_ext('.txt')) class t_2(Task.Task): always_run = True run_str = 'echo ${SRC}' color = 'RED' @TaskGen.feature('t_2') @TaskGen.after('apply_link', 't_1') def add_t_2_task(self): try: t_1 = self.t_1 except AttributeError as err: print err return self.create_task('t_2', src=t_1.outputs[0])
运行
python waf configure build
导致:user@laptop /cygdrive/c/work $ python waf-1.9.13 configure clean build Setting top to : /cygdrive/c/work Setting out to : /cygdrive/c/work/build Checking for 'gcc' (C compiler) : /usr/bin/gcc 'configure' finished successfully (0.150s) 'clean' finished successfully (0.010s) Waf: Entering directory `/cygdrive/c/work/build' 'task_gen' object has no attribute 't_1' <===================== How to get this working [1/3] Compiling main.c [2/3] Linking build/abc.exe [3/3] Compiling build/abc.exe abc.exe Waf: Leaving directory `/cygdrive/c/work/build' 'build' finished successfully (0.270s)
before
和 after
装饰器适用于任务生成器 方法 ,而不是 任务 。你应该有:
@TaskGen.feature('t_1')
@TaskGen.after('apply_link')
# correction: no need to use @TaskGen.before('add_t_2_task')
def add_t_1_task(self):
# correction: you have to define self.t_1
self.t_1 = self.create_task(
't_1',
self.link_task.outputs[0],
self.link_task.outputs[0].change_ext('.txt')
)
@TaskGen.feature('t_2')
@TaskGen.after('apply_link', 'add_t_1_task') # correction: use method name
def add_t_2_task(self):
# add_t-2_task is executed after add_t_1_task, so using self.t_1 is ok
print "t_1", self.t_1
顺便说一下,不要使用 always_run=True
,因为它破坏了 waf 的主要功能之一,即只构建你需要构建的东西:)