生成器表达式cmake:复制在调试但不是释放模式下工作

时间:2016-04-29 09:28:16

标签: c++ cmake

我试图弄清楚如何根据cmake中的配置复制一些lib。

我试过了:

add_custom_command(TARGET Myapp
  POST_BUILD
  COMMAND ${CMAKE_COMMAND} -E copy_if_different
  $<$<CONFIG:Debug>:${_LIBS_DEBUG}> 
  $<$<CONFIG:Release>:${_LIBS_RELEASE}> 
  $<TARGET_FILE_DIR:MyApp>)

它在Debug中复制libs但不在release中复制:

  1. 这应该是合法的,应该有用吗?
  2. 如果不合法(我没有收到错误),我怎样才能达到同样的效果?

2 个答案:

答案 0 :(得分:2)

将我的评论转化为答案

我通常做的调试这种情况的方法是在有问题的实际行之前添加另一个COMMAND,它只是回显命令行。在你的情况下:

COMMAND ${CMAKE_COMMAND} -E echo 
    $<$<CONFIG:Debug>:${_LIBS_DEBUG}>
    $<$<CONFIG:Release>:${_LIBS_RELEASE}> 

我已经运行了一些测试,您会看到$<1:...>$<0:...>表达式未被评估。

所以看到这个我正在搜索CMake的bug跟踪器数据库,这是一个已知问题,但是(对于CMake 3.5.2)尚未解决:0009974: CMake should support custom commands that can vary by configuration.

此故障单中提出了几种与现有版本的CMake一起使用的方法。

在你的情况下 - 直到这个问题得到解决,并且如果你想让它独立于shell - 我会用“旧方式”并调用CMake脚本:

<强> CopyLibsByConfig.cmake.in

if (_CONFIG STREQUAL "Debug")
    file(COPY @_LIBS_DEBUG@ DESTINATION "${_DEST_PATH}")
else()
    file(COPY @_LIBS_RELEASE@ DESTINATION "${_DEST_PATH}")
endif()

<强>的CMakeLists.txt

...
configure_file(CopyLibsByConfig.cmake.in CopyLibsByConfig.cmake @ONLY)
add_custom_command(TARGET MyApp
  POST_BUILD
  COMMAND ${CMAKE_COMMAND} 
    -D _CONFIG=$<CONFIG> 
    -D _DEST_PATH="$<TARGET_FILE_DIR:MyApp>"
    -P "${CMAKE_CURRENT_BINARY_DIR}/CopyLibsByConfig.cmake"
)

但是解决方案很大程度上取决于您要复制到二进制输出文件夹的文件。并且有很多方法可以实现,例如使用install()

install(FILES ${_LIBS_DEBUG} CONFIGURATIONS Debug DESTINATION $<TARGET_FILE_DIR:MyApp>)
install(FILES ${_LIBS_RELEASE} CONFIGURATIONS Release DESTINATION $<TARGET_FILE_DIR:MyApp>)

set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1)

显然,这不是install()的使用方式,因此请考虑正确使用INSTALLPACKAGE目标来分发您的应用及其所有依赖项。

如果我们谈论Visual Studio运行时DLL,您很可能想看看InstallRequiredSystemLibraries CMake模块。

答案 1 :(得分:0)

其他解决方案是使用generator expression

例如,我有cppzmq(共享库)和cppzmq-static(具有静态依赖项的静态库)。我想拥有更快的调试版本,因此在调试版本和(其他)版本中使用cppzmq。释放我想要一位大胖子。

target_link_libraries(CommunicationCommonLib PUBLIC
    $<IF:$<CONFIG:Debug>,cppzmq,cppzmq-static>
    Dexode::EventBus
    gcpp
    protobuf::libprotobuf
    )