【问题标题】:SCONS: Run target always, not only if updatedSCONS:始终运行目标,不仅在更新时
【发布时间】:2021-05-05 08:58:33
【问题描述】:

基于SCONS run target,我创建了一个基本的 SCONS 脚本来构建并运行我的单元测试:

test = env.Program(
    target='artifacts/unittest',
    source= sources + tests
)

Alias(
    'test',
    test,
    test[0].abspath
)

修改代码后,效果很好:

> scons test
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
g++ [...]
[Lots of compiler output]
unittest.exe
===============================================================================
All tests passed (22 assertions in 4 test cases)

如果我现在再次运行 scons test 而不更改代码,它认为不需要再次构建,这是正确的,但也不会再次运行测试:

> scons test
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
scons: `test' is up to date.
scons: done building targets.

但是,很明显,我希望即使没有重建测试也能运行:

> scons test
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
scons: `test' is up to date.
scons: done building targets.
unittest.exe
===============================================================================
All tests passed (22 assertions in 4 test cases)

得到这个结果的最简单方法是什么?

【问题讨论】:

  • 只是旁白,但是“但是,很明显,我希望即使没有重建测试也能运行” ...真的不是 明显。除非代码改变,否则为什么结果会改变?
  • 至少对我来说这是一个明显的用例,对不起,如果我认为这也适用于其他情况,但事实并非如此。两个示例,对我有效: - 测试不仅依赖于代码,还依赖于由测试可执行文件读取的外部文件,例如.csv。在 CI 期间,这个文件来自版本控制,并且被认为是一致的,但是在本地开发期间,我可能会在不更改代码的情况下更改它。 - 我简单地关闭了我的终端窗口,并想在再次打开它以重新检查结果后重新运行测试。
  • 你仍然有单元测试可执行文件,所以在第二种情况下总是可以直接运行它。希望这并不常见,以至于我宁愿手动做一些事情,也不愿无缘无故地让所有单元测试每次都运行。另一种情况,如果数据文件是一个依赖,你应该告诉你的构建系统,然后它才能正常工作。

标签: c++ scons


【解决方案1】:

试试

env.Pseudo('test')

这应该将目标标记为不生成任何文件,并且可能对您有用。

【讨论】:

  • 谢谢,这将我引向了pseudobuilders,我很想听听您对我的解决方案的意见。
  • Pseudo() 与伪构建器无关。它将目标标记为“错误”目标,因此 scons 不会期望/关心正在创建的目标文件。您是否尝试过以上方法?
【解决方案2】:

还看到AlwaysBuild 用于触发单元测试执行。 “见过”并不一定是最佳实践(@bdbaddog 是这里的专家!)。

【讨论】:

    【解决方案3】:

    现在通过使用 AddMethod 创建 PseudoBuilder 以连接 Builder 和命令来修复它:

    env.AddMethod(
        lambda env, target, source:
            [
                env.Program(
                    target=target,
                    source=source
                )[0],
                env.Command(
                    target,
                    source,
                    '.\\$TARGET'
                )[0]
            ]
        ,
        'BuildAndRun'
    )
    
    env.Alias(
        'test',
        env.BuildAndRun(
            target='artifacts/unittest',
            source= sources + tests
        )
    )
    

    到目前为止按预期工作:

    > scons test
    scons: Reading SConscript files ...
    scons: done reading SConscript files.
    scons: Building targets ...
    g++ [...]
    [Lots of compiler output]
    .\artifacts\unittest
    ===============================================================================
    All tests passed (22 assertions in 4 test cases)
    > scons test
    scons: Reading SConscript files ...
    scons: done reading SConscript files.
    scons: Building targets ...
    .\artifacts\unittest
    ===============================================================================
    All tests passed (22 assertions in 4 test cases)
    

    唯一的缺点:命令中的反斜杠使我依赖于 Windows。

    有什么意见吗?

    【讨论】:

    • 您根本不需要 Lambda。您可以在别名中列出这两项。您的解决方案看起来过于复杂。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-15
    • 1970-01-01
    相关资源
    最近更新 更多