CMake add_custom_command() POST_BUILD 生成器表达式扩展不起作用

sth*_*m58 0 cmake cmake-language

我想在构建后运行 POST_BUILD 操作(但仅在调试配置中)。

在阅读了add_custom_command 文档可能的解决方案后,我明白我可以将我的命令“包装”到$<CONFIG:Debug>生成器表达式中(以确保它在发布模式下为“空”)。

我尝试了以下方法:

cmake_minimum_required(VERSION 3.18)

project(post-build CXX)
file(WRITE main.cxx "int main() {}")
add_executable(foo main.cxx)

add_custom_command(
  TARGET foo POST_BUILD
  COMMAND $<$<CONFIG:Debug>:${CMAKE_COMMAND} -E echo "hi there from debug build">
)
Run Code Online (Sandbox Code Playgroud)

但这给了我 CMake 配置时警告和构建时的硬故障(使用 Ninja 生成器):

(...) && "$<1:C:\Program Files\CMake\bin\cmake.exe" -E echo "hi there from debug build" >""
[build] The system cannot find the path specified.
[build] ninja: build stopped: subcommand failed.
[build] Build finished with exit code 1
Run Code Online (Sandbox Code Playgroud)

我尝试了许多可能的引号组合(包括转义引号):
COMMAND $<$<CONFIG:Debug>:"${CMAKE_COMMAND} -E echo \"hi there from debug build\"">
等等
COMMAND "$<$<CONFIG:Debug>:${CMAKE_COMMAND} -E echo \"hi there from debug build\">"

但即使它删除了配置时警告,它仍然会在构建时产生硬错误。

问题:实现我想要的目标的正确方法是什么?是否有可能像这样或者这里有 CMake 限制?

(注意:如果可能的话,我希望将整个命令保留在一个地方执行。我还知道其他可能的解决方法)

sth*_*m58 5

以下是 Ben Boeckel 的回答:

\n
\n

Genex 内部的空间通常是\xe2\x80\x99t 格式良好的。您\xe2\x80\x99将需要替换空格以;使其正确解析(这就是为什么您\xe2\x80\x99在构建命令中看到半展开的残余部分)。

\n
\n

CMake 邮件列表(此处)中的一些讨论最终对我有用的是:

\n
add_custom_command(\n  TARGET foo POST_BUILD\n  COMMAND "$<$<CONFIG:Debug>:${CMAKE_COMMAND};-E;echo;\\"hi there from debug build\\">"\n  COMMAND_EXPAND_LISTS\n)\n
Run Code Online (Sandbox Code Playgroud)\n

(注意整个genex周围的引号,用分号分隔,对字符串进行反引号,以及COMMAND_EXPAND_LISTS以消除输出中的分号——总而言之,绝对不是读起来最令人愉快的事情)

\n

编辑:\n这也有效:

\n
set(HELLO_FROM_DEBUG ${CMAKE_COMMAND} -E echo "hi there")\n\nadd_custom_command(\n  TARGET foo POST_BUILD\n  COMMAND "$<$<CONFIG:Debug>:${HELLO_FROM_DEBUG}>"\n  COMMAND_EXPAND_LISTS\n)\n
Run Code Online (Sandbox Code Playgroud)\n