cmake - install()命令的生成器表达式

标签 cmake

CMake 3.2.2的文档指出,可以将生成器表达式用于install(<FILES|PROGRAMS> ...)签名。我试图在install()的其他签名中使用生成器表达式,但是显然不能正常工作。我想做这样的事情:

install(TARGETS foo EXPORT fooConfig
        RUNTIME DESTINATION "Bin/$<CONFIG>"
        LIBRARY DESTINATION "Lib/$<CONFIG>"
        ARCHIVE DESTINATION "Lib/$<CONFIG>"

我还尝试过多次调用install(),如下所示:
install(TARGETS foo EXPORT fooConfig
        RUNTIME DESTINATION "Bin/Debug" CONFIGURATIONS Debug
        LIBRARY DESTINATION "Lib/Debug" CONFIGURATIONS Debug
        ARCHIVE DESTINATION "Lib/Debug" CONFIGURATIONS Debug
install(TARGETS foo EXPORT fooConfig
        RUNTIME DESTINATION "Bin/Release" CONFIGURATIONS Release
        LIBRARY DESTINATION "Lib/Release" CONFIGURATIONS Release
        ARCHIVE DESTINATION "Lib/Release" CONFIGURATIONS Release
install(TARGETS foo EXPORT fooConfig
        RUNTIME DESTINATION "Bin/MinSizeRel" CONFIGURATIONS MinSizeRel
        LIBRARY DESTINATION "Lib/MinSizeRel" CONFIGURATIONS MinSizeRel
        ARCHIVE DESTINATION "Lib/MinSizeRel" CONFIGURATIONS MinSizeRel
install(TARGETS foo EXPORT fooConfig
        RUNTIME DESTINATION "Bin/RelWithDebInfo" CONFIGURATIONS RelWithDebInfo
        LIBRARY DESTINATION "Lib/RelWithDebInfo" CONFIGURATIONS RelWithDebInfo
        ARCHIVE DESTINATION "Lib/RelWithDebInfo" CONFIGURATIONS RelWithDebInfo

这将导致CMake沿在“fooConfig”中多次导出的目标“foo”发出错误。

我不能在这里使用CMAKE_BUILD_TYPE而不更新CMake缓存并重新运行构建。相反,我想使用Visual Studio批处理构建功能,该功能可以为我构建多个配置。

我也尝试过一点技巧。我注意到CMake生成的INSTALL项目只是使用参数${CMAKE_BINARY_DIR}/cmake_install.cmake调用CMake脚本-DBUILD_TYPE=$(Configuration)。所以我尝试了以下方法:
install(TARGETS foo EXPORT fooConfig
        RUNTIME DESTINATION "Bin/\${BUILD_TYPE}"
        LIBRARY DESTINATION "Lib/\${BUILD_TYPE}"
        ARCHIVE DESTINATION "Lib/\${BUILD_TYPE}"

这对于安装实际上效果很好。但是,已安装的导出脚本(即install(EXPORT fooConfig DESTINATION .)的输出)现在也尝试使用${BUILD_TYPE},在用户包括该脚本时未设置......

如果有人知道实现我目标的另一种方法,请告诉我。

最佳答案

不幸的是,install命令仅支持生成器表达式用于要安装的文件列表,但不支持目标目录。

我建议坚持使用您的小技巧,但请使用CMAKE_INSTALL_CONFIG_NAME而不是CMAKE_BUILD_TYPE,即:

install(TARGETS foo EXPORT fooConfig
        RUNTIME DESTINATION "Bin/\${CMAKE_INSTALL_CONFIG_NAME}"
        LIBRARY DESTINATION "Lib/\${CMAKE_INSTALL_CONFIG_NAME}"
        ARCHIVE DESTINATION "Lib/\${CMAKE_INSTALL_CONFIG_NAME}"
CMAKE_INSTALL_CONFIG_NAME设置为用于在生成的cmake_install.cmake脚本中进行安装的实际构建配置。

通过将补丁脚本添加到安装过程中,可以自动修复生成的导出脚本(例如fooConfig-debug.cmake)。在源目录中生成具有以下内容的文件patch_export_files.cmake:
file(GLOB_RECURSE _configFiles "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/fooConfig-*.cmake")
foreach(_configFile ${_configFiles})
    file (READ "${_configFile}" _contents)
    string (REGEX MATCH "configuration \"[A-Za-z]+\"" _configName "${_contents}")
    if (_configName MATCHES "\"([A-Za-z]+)\"")
        message(STATUS "Patching: ${_configFile}")
        string (REPLACE "\${CMAKE_INSTALL_CONFIG_NAME}" "${CMAKE_MATCH_1}" _patchedContents "${_contents}")
        file (WRITE "${_configFile}" "${_patchedContents}")
    endif()
endforeach()

修补程序脚本需要在安装时通过在install(SCRIPT ...之后添加install(EXPORT ...调用来运行:
install(EXPORT fooConfig DESTINATION .)
...
install(SCRIPT patch_export_files.cmake)

修补程序脚本首先从其标题注释中解析所生成的导出脚本对其有效的配置,然后将每次对${CMAKE_INSTALL_CONFIG_NAME}的使用替换为配置名称。

关于cmake - install()命令的生成器表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29971026/

相关文章:

c - 在Linux上编译OpenCL ICD加载器时出错

c++ - CMake 设置默认资源/ Assets 目录

cmake - 在自定义命令中调用找到的可执行文件的正确方法?

c++ - CMake:C 编译器无法编译简单的测试程序。令人惊讶的是,C 编译器标识未知,但 CXX 是 GNU 4.9.2

makefile - 调用 cmake 文件中现有的 make 命令

c++ - 将 Boost 与 CMake 链接时出错

build - 如何使CMake使用环境变量LD_LIBRARY_PATH和C_INCLUDE_DIRS

配置 CLion 以处理 gtk_builder 信号

c++ - 无法在 Visual Studio 2015 Update 1 CMake 中将工具集设置为新的 v140_clang_3_7

c++ - 如何在应该失败的CMake中实现编译测试?