VS16 不扩展 CMake 生成器表达式



我使用CMake生成跨平台构建配置。对于项目的工作,我需要复制额外的预编译库到二进制目录。因此,我使用这样的脚本来构建这个项目:

cmake_minimum_required(VERSION 3.17)
project(foo)
add_executable(bar foobar.cpp)
# Doing some logic to find library files... 
list(APPEND DBG_LIBRARIES_LIST "lib1" "lib2")
list(APPEND REL_LIBRARIES_LIST "lib1" "lib2")
# Joining all libraries with " " character to be parsed as different program arguments
list(JOIN DBG_LIBRARIES_LIST " " DEBUG_LIBRARIES)
list(JOIN REL_LIBRARIES_LIST " " RELEASE_LIBRARIES)
add_custom_command(TARGET bar POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
$<IF:$<CONFIG:Debug>,${DEBUG_LIBRARIES},${RELEASE_LIBRARIES}>
$<TARGET_FILE_DIR:estareng>
)

在我使用VS16在Windows上生成这样的项目后,我的构建后事件包含这样的行:

cmake -E copy_if_different "lib1 lib2" someprojdir

如果我尝试使用$<JOIN:$<IF:$<CONFIG:Debug>,${DEBUG_LIBRARIES_LIST},${RELEASE_LIBRARIES_LIST}>," ">加入列表,我只是在构建后事件中获得原始生成器表达式。

注意:在GNU/Linux上,使用makefiles或Ninja都可以正常工作

这应该可以工作:

cmake_minimum_required(VERSION 3.18)
project(test)
add_executable(bar foobar.cpp)
list(APPEND DBG_LIBRARIES "lib1" "lib2")
list(APPEND REL_LIBRARIES "lib1" "lib2")
add_custom_command(
TARGET bar POST_BUILD
COMMAND "${CMAKE_COMMAND}" -E copy_if_different
"$<IF:$<CONFIG:Debug>,${DBG_LIBRARIES},${REL_LIBRARIES}>"
"$<TARGET_FILE_DIR:bar>"
COMMAND_EXPAND_LISTS
VERBATIM
)

设置VERBATIM后,COMMAND的每个参数都被认为是一个单个命令行参数,即使里面有空格或分号。如果没有这个选项,对COMMAND的参数的解释是平台特定的。正如你所注意到的,这有时意味着在空格上分词,而其他时候则不是。

教训1:您应该始终使用VERBATIM选项与add_custom_command

但是,不要忘记在此发生之前CMake自己的参数拆分运行。因此,如果没有$<IF:...>周围的双引号,DBG_LIBRARIESREL_LIBRARIES中的分号将把它分割成add_custom_command的许多参数,其中没有一个是完整的生成器表达式。这就是为什么你会看到&;raw&;命令行上的生成器表达式。

2课:总是将单个参数与变量展开括在双引号中。

最后,我们传递COMMAND_EXPAND_LISTS,这样在生成器表达式处理之后,任何包含;的参数都会在;上被分割成多个参数。

相关内容

  • 没有找到相关文章