0

考虑以下自定义命令(最新的 CMake + ninja):

add_custom_command(
        OUTPUT
            ${OUTPUT}
        COMMAND
            ${Python3_EXECUTABLE} script.py ${INPUT} > ${OUTPUT}
        DEPENDS
            ${INPUT}
        VERBATIM
        COMMAND_EXPAND_LISTS
    )

script.py运行没有错误时,它工作正常。

但是,当script.py失败并出现错误时,${OUTPUT}仍然会创建。
因此,当前构建按预期失败,但下一个构建${OUTPUT}比预期更新,${INPUT}并且不会尝试再次运行自定义命令。

我希望构建系统${OUTPUT}在命令失败时自动删除,以防止这种情况,但显然这不会发生。

  • 有没有办法在自定义命令“失败”时执行操作?
    如果有,我可以${OUTPUT}在那里删除。
  • 或者,除非命令成功,否则防止输出创建的最简单方法是什么?

我天真地尝试过做类似的事情:

${Python3_EXECUTABLE} script.py ${INPUT} > ${OUTPUT} || rm -f ${OUTPUT}

但这不起作用,因为命令结果代码实际上是rm结果代码而不是 Python 的结果代码,因此自定义命令不会像在后续构建中那样失败。

4

1 回答 1

2

你快到了,只需在命令 rm添加,这将返回一个错误代码。比如这样:

${Python3_EXECUTABLE} script.py ${INPUT} > ${OUTPUT} || (rm -f ${OUTPUT} && /bin/false)

不应该使用这样的命令VERBATIM选项:使用该选项,CMake 会引用方括号 (和),这会阻止 shell 解释它们以用于分组目的。add_custom_command()


我希望构建系统在命令失败时自动删除 ${OUTPUT}

请注意,CMake 本身不是构建系统,它只是为构建系统生成代码。

例如,当 CMake 生成 Makefile 时,它​​会添加 .DELETE_ON_ERROR 目标,因此make实用程序实际上会在失败时删除输出文件。

看起来,Ninja 没有 Make 那样的功能。或者 CMake 在为 Ninja 生成代码时不使用此功能。

于 2021-03-27T11:48:13.123 回答