8

我正在尝试为 CMake 设置一个构建后命令,我使用 CMake 文档中所述的 ADD_CUSTOM_COMMAND 指令完成了该命令。不过,我想要做的是,只有在创建可执行文件的发布版本时才运行后期构建。

如何做到这一点?

4

3 回答 3

9

我遇到了类似的情况,想将 DLL 文件复制到目标目录,但仅用于发布版本。经过大量撕裂的头发后,我设法使用一些生成器表达式(the $<...>thingies)让它工作。七年后我把它放在这里不是为了解决你的问题(虽然我很佩服你的针对性水平),而是为了拯救下一个人遇到同样问题并在谷歌上找到这个问题的颅毛:

set(no_copy $<NOT:$<CONFIG:Release>>) # An abbreviation to make the example easier to read.
add_custom_command(TARGET myDLL POST_BUILD
    COMMAND "${CMAKE_COMMAND}" -E
    # do nothing for non-Release build
    $<${no_copy}:echo>
    # output text to make clear that the copy command is not actually issued
    $<${no_copy}:"copy omitted for non-release build, command would have been ">
    # the actual copy command, which is overridden by the "echo" above
    # in the case of a non-release build
    copy_if_different $<TARGET_FILE:myDLL> ${DIR_FOR_DLL})

诀窍是echo在本来会发出的命令前面写一个。这样,即使输出了一点噪音,命令也不会执行。可以将命令行的其余部分包含在多个生成器表达式中,以缩短输出,但会牺牲一个完全不可读的 cmake 文件。另一方面,似乎没有办法在不产生任何输出的情况下便携地抑制复制。最后,如果你认为有一个简单的方法,你可以写if($<CONFIG:Release>) ... endif(),我建议你不要让自己失望。

于 2017-09-27T04:49:17.550 回答
2

对于基于 Makefile 的生成器,您可以检查CMAKE_BUILD_TYPE变量并根据其值进行操作:

if(CMAKE_BUILD_TYPE STREQUAL Debug)
    message(STATUS "Do debug stuff")
elseif(CMAKE_BUILD_TYPE STREQUAL Release)
    message(STATUS "Do release stuff")
elseif(CMAKE_BUILD_TYPE STREQUAL RelWithDebInfo)
    message(STATUS "Do release with debug info stuff")
elseif(CMAKE_BUILD_TYPE STREQUAL MinSizeRel)
    message(STATUS "Do minimal size release stuff")
endif()

对于基于 Visual Studio 的构建,这个 SO question似乎表明它CMAKE_BUILD_TYPE也适用于 VS 2005+。

于 2009-10-25T15:50:24.720 回答
1

在 Visual Studio中检查配置的另一种方法是使用它的宏:

if(MSVC)
    add_custom_command(TARGET myDLL POST_BUILD
        COMMAND cmd.exe /c if "$(Configuration)" == "Release" "${CMAKE_COMMAND}" -E copy_if_different "$<TARGET_FILE:myDLL>" "${DIR_FOR_DLL}")
endif()
于 2020-12-26T12:15:04.613 回答