add_custom_command: 失败时删除重定向输出
add_custom_command: Remove redirected output on failure
考虑以下自定义命令(最新的 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 的结果代码,因此自定义命令不会像它应该的那样失败在后续构建中。
您快完成了,只需在 rm
后添加一个命令,这将return 一个错误代码。例如。这样:
${Python3_EXECUTABLE} script.py ${INPUT} > ${OUTPUT} || (rm -f ${OUTPUT} && /bin/false)
使用这样的命令 VERBATIM
选项 add_custom_command
不应该使用:使用该选项 CMake 引用方括号((
和 )
),这样可以防止 shell 为分组目的解释它们。
I would expect the build system to automatically delete ${OUTPUT} when the command fails
请注意,CMake 本身不是构建系统,它只是为构建系统生成代码。
例如,当 CMake 生成 Makefile 时,它 ,因此 make
实用程序实际上会在失败时删除输出文件。
Ninja 好像没有Make 那样的功能。或者 CMake 在为 Ninja 生成代码时不使用此功能。
考虑以下自定义命令(最新的 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 的结果代码,因此自定义命令不会像它应该的那样失败在后续构建中。
您快完成了,只需在 rm
后添加一个命令,这将return 一个错误代码。例如。这样:
${Python3_EXECUTABLE} script.py ${INPUT} > ${OUTPUT} || (rm -f ${OUTPUT} && /bin/false)
使用这样的命令 VERBATIM
选项 add_custom_command
不应该使用:使用该选项 CMake 引用方括号((
和 )
),这样可以防止 shell 为分组目的解释它们。
I would expect the build system to automatically delete ${OUTPUT} when the command fails
请注意,CMake 本身不是构建系统,它只是为构建系统生成代码。
例如,当 CMake 生成 Makefile 时,它 make
实用程序实际上会在失败时删除输出文件。
Ninja 好像没有Make 那样的功能。或者 CMake 在为 Ninja 生成代码时不使用此功能。