c++ - CMake 如何确定目标依赖项的回退构建配置?

标签 c++ visual-studio dll cmake

背景

在 Windows 上,我使用 CMake (3.2.3) 和 Visual Studio 2015(社区)构建一个名为 Foo 的 C++ 项目。 Foo 由一个名为 foo 的共享库组成。我在调试和发布配置中构建和安装 Foo。我将 CMAKE_DEBUG_POSTFIX 设置为 _d 以便 Foo 的安装同时包含 foo.dllfoo_d.dll,因为以及 CMake 配置文件 FooConfig.cmakeFooTargets.cmakeFooTargets-debug.cmakeFooTargets-release.cmake.

现在,我开始构建一个单独的 CMake 项目 Bar,它由一个可执行文件“bar”组成,并且依赖于库 foo。但是我在 RelWithDebInfo 配置中构建了 bar。当我尝试从 Visual Studio 运行 bar 时,它查找 foo_d.dll 而不是 foo.dll

也就是说,如果在 RelWithDebInfo 配置下不存在依赖项,则 RelWithDebInfo 配置会回退到 Debug 配置。

这是 Foo 的 CMakeLists.txt:

project(Foo)
cmake_minimum_required(VERSION 3.2.3)
add_library(foo SHARED foo.h foo.cpp)
install(TARGETS foo EXPORT FooTargets DESTINATION
    RUNTIME DESTINATION bin LIBRARY DESTINATION lib
    ARCHIVE DESTINATION lib)
configure_package_config_file(FooConfig.cmake.in
    "${CMAKE_BINARY_DIR}/FooConfigToInstall.cmake"
    INSTALL_DESTINATION cmake)
install(FILES ${CMAKE_BINARY_DIR}/FooConfigToInstall.cmake"
        DESTINATION cmake RENAME FooConfig.cmake)
install(EXPORT FooTargets DESTINATION cmake)

这是 Bar 的 CMakeLists.txt:

project(Bar)
cmake_minimum_required(VERSION 3.2.3)
find_package(Foo)
add_executable(bar bar.cpp)
target_link_libraries(bar foo)

问题

如果依赖项所需的配置不可用,CMake 如何确定依赖项的配置?

跟进:是否可以控制这种回退?理想情况下,不会有回退。我希望 CMake 给出一个错误,如“无法在 RelWithDebInfo 配置中构建栏,因为依赖项 foo 在该配置中不可用(可用配置:调试、发布)。

最佳答案

使用Foo包生成的

脚本FooConfig.cmake提供IMPORTED库目标foo,用于通过 Bar 链接。

CMake 有一个关于“从项目配置映射到导入的目标配置”的概念,它由属性 MAP_IMPORTED_CONFIG_<CONFIG> 决定。 :

Set this to the list of configurations of an imported target that may be used for the current project’s configuration. Targets imported from another project may not provide the same set of configuration names available in the current project. Setting this property tells CMake what imported configurations are suitable for use when building the <CONFIG> configuration. The first configuration in the list found to be provided by the imported target is selected. If this property is set and no matching configurations are available, then the imported target is considered to be not found.

您可以在脚本 FooConfig.cmake.in 的末尾添加类似

set_target_property(foo PROPERTIES MAP_IMPORTED_CONFIG_RELWITHDEBINFO "prohibited")

因此将无法在 RelWithDebInfo 配置中与 foo 链接(因为 foo 目标不提供名为“prohibited”的配置) .

关于c++ - CMake 如何确定目标依赖项的回退构建配置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40029551/

相关文章:

c++ - 运算符重载 : ok MSVS but fails in g++

C++ "<<"运算符重载

.net - 有没有办法以编程方式提取接口(interface)?

c# - 通过直接读取 PE 来确定一个 dll 是否为 .valid CLR dll(64 位问题)

c# - 调试底层 C++ DLL 中的问题

c++ - 模板父类(super class)的静态成员定义

C++ 标准委员会 "reflector"邮件列表

c# - 找不到部分路径 ... bin\roslyn\csc.exe

visual-studio - 在 Visual Studio 2010 中显示多于(或少于)六个最近的项目

c# - 从 C# 设置非托管 C dll 的公共(public)字段