如何在Windows上使add_custom_command配置特定?

Jon*_*vis 9 cmake

为了在我的一个项目中运行单元测试,我有一个自定义命令,它将可执行文件,库和其他相关文件复制到其他地方,以便它们可以使用特定的设置运行,而不是在它们所在的位置运行它们建成.在Linux上,这非常简单.但是在Windows上,由于cmake将配置名称附加到输出目录(我一般都喜欢它,但它搞砸了我在这种情况下正在做的事情),因此我遇到了一些麻烦.这使得很难确定生成的库或可执行文件的路径.例如,如果我有一个自定义命令,它只是将可执行文件复制到另一个目录

set(EXE_PATH "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/exeName${CMAKE_EXECUTABLE_SUFFIX}")
set(NEW_EXE_PATH "${RUN_UNITTESTS_DIR}/exeName${CMAKE_EXECUTABLE_SUFFIX}")

add_custom_command(TARGET unitTests POST_BUILD
                   COMMAND ${CMAKE_COMMAND} ARGS -E copy "${EXE_PATH}" "${NEW_EXE_PATH}")
Run Code Online (Sandbox Code Playgroud)

它会在Windows上窒息,因为可执行文件实际上并不存在CMAKE_RUNTIME_OUTPUT_DIRECTORY.根据配置类型,它位于${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Release或中${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Debug.在Linux上,通过使用CMAKE_BUILD_TYPE并将其添加到路径可以轻松修复,但这不适用于Windows,因为在Windows上,cmake生成多个配置而不是一个.所以,我希望能够做的就是这样

add_custom_command(TARGET unitTests POST_BUILD
                   debug
                   COMMAND ${CMAKE_COMMAND} ARGS -E copy "${DEBUG_EXE_PATH}" "${DEBUG_NEW_EXE}")

add_custom_command(TARGET unitTests POST_BUILD
                   release
                   COMMAND ${CMAKE_COMMAND} ARGS -E copy "${RELEASE_EXE_PATH}" "${RELEASE_NEW_EXE}")
Run Code Online (Sandbox Code Playgroud)

并且一些cmake命令看到能够做到这一点(例如target_link_libraries),但据我所知,add_custom_target并没有提供这种能力.那么,问题是我将如何做到这一点?如何在Windows上将自定义命令设置为特定于配置?

小智 12

它可以在下一个"生成器表达式"(CMake 2.8.10)的帮助下解决:

  • $<0:...> =空字符串(忽略"...")
  • $<1:...> ="......"的内容
  • $<CONFIG:cfg> 如果config是"cfg",则='1',否则为'0'

您可以将它们组合起来以达到您需要的行为(伪代码):

if debug then ${DEBUG_EXE_PATH} elseif release then ${RELEASE_EXE_PATH}

转换为:

$<$<CONFIG:debug>:${DEBUG_EXE_PATH}>$<$<CONFIG:release>:${RELEASE_EXE_PATH}>

所以你的字符串看起来像:

add_custom_command(TARGET unitTests POST_BUILD
                       COMMAND ${CMAKE_COMMAND} ARGS -E copy "$<$<CONFIG:debug>:${DEBUG_EXE_PATH}>$<$<CONFIG:release>:${RELEASE_EXE_PATH}>" "$<$<CONFIG:debug>:${DEBUG_NEW_EXE}>$<$<CONFIG:release>:${RELEASE_NEW_EXE}>")
Run Code Online (Sandbox Code Playgroud)

详细信息:CMake:add_custom_command

  • 你应该*几乎永远*不需要使用这种方法。除非你的构建正在做一些真正奇特的事情,否则使用 `$&lt;TARGET_FILE&gt;` 会好得多。 (2认同)

Fra*_*ser 7

这是提供用于的生成器表达式的情况add_custom_command.

在您的情况下,您需要编译的exe的完整路径,以及它的文件名附加到目标目录.这些是$<TARGET_FILE:unitTests>$<TARGET_FILE_NAME:unitTests>.

你的完整命令是:

add_custom_command(TARGET unitTests POST_BUILD
                   COMMAND ${CMAKE_COMMAND} -E
                       copy $<TARGET_FILE:unitTests>
                            ${RUN_UNITTESTS_DIR}/$<TARGET_FILE_NAME:unitTests>)
Run Code Online (Sandbox Code Playgroud)