【问题标题】:How to declare WAF dependency of test script on built program?如何在构建的程序上声明测试脚本的 WAF 依赖关系?
【发布时间】:2025-11-28 14:25:02
【问题描述】:

我正在努力寻找正确的方法来定义测试脚本的依赖关系 在 waf 在同一构建过程中构建的二进制程序上。 这是wscript 的最小示例:

from waflib.Tools import waf_unit_test

def options(opt):
    opt.load("compiler_cxx python waf_unit_test")

def configure(cnf):
    cnf.load("compiler_cxx python waf_unit_test")


def build(bld):
    bld.add_post_fun(waf_unit_test.summary)
    bld.options.clear_failed_tests= True

    bld(features= "cxx cxxprogram",
        target= "foo",
        source= "foo.cpp")

    tg= bld(features= "test_scripts",
        test_scripts_source= "fooTest.py",
        test_scripts_template= "${PYTHON} ${SRC}")
    tg.post()
    tg.tasks[0].inputs.append(bld.path.find_or_declare("foo"))

我想表达的是,waf 将构建程序foo。 然后,如果程序 foo 自上次构建运行以来发生了变化,则脚本 fooTest.py 将检查该程序的执行情况。上面的wscript 有效:

Waf: Entering directory `/home/x/tmp/exe_depend/build'
[1/3] Compiling foo.cpp
[2/3] Linking build/foo
[3/3] Processing utest: fooTest.py build/foo
Waf: Leaving directory `/home/x/tmp/exe_depend/build'
execution summary 
  tests that pass 1/1 
    /home/x/tmp/exe_depend/fooTest.py 
  tests that fail 0/1 
'build' finished successfully (0.054s)

原则上,上面的wscript 满足了我的需求,但它看起来很难看,而且摆弄任务生成器tg 似乎是错误的。有没有人知道一个顺利的解决方案?

【问题讨论】:

    标签: build dependencies waf


    【解决方案1】:

    好吧,waf_unit_test.py 中没有很多钩子。最好的方法是通过制作自己的工具并将两行代码放入其中来扩展它。类似的东西:

    # in file my_unit_test.py
    
    def options(opt):
        opt.load("waf_unit_test") # we extend it, no need to recode
    
    def configure(conf):
        conf.load("waf_unit_test") # we extend it, no need to recode
    
    @feature('test_scripts')
    @after_method('make_interpreted_test') # we execute after task creation
    def process_test_scripts_dependencies(self):
        try:
            self.test_scripts_deps
        except AttributeError:
            return
    
        for task in self.tasks: # there can be many scripts
            task.set_inputs(self.to_nodes(self.test_scripts_deps))
    

    使用它:

    def options(opt):
        opt.load("compiler_cxx python my_unit_test")
    
    def configure(cnf):
        cnf.load("compiler_cxx python my_unit_test")
    
    
    def build(bld):
        bld.add_post_fun(waf_unit_test.summary)
        bld.options.clear_failed_tests= True
    
        myprogram = "foo"
    
        bld(
            features = "cxx cxxprogram",
            target = myprogram,
            source = "foo.cpp",
        )
    
        bld(
            features = "test_scripts",
            test_scripts_deps = myprogram,
            test_scripts_source = "fooTest.py",
            test_scripts_template = "${PYTHON} ${SRC}",
        )
    

    当然,你可以走得更远,重写一些适合你需要的东西:)

    【讨论】:

      最近更新 更多