首页 > 解决方案 > cmake 生成器表达式在 IDE 和命令行中的行为不同

问题描述

我正在尝试根据构建配置使用不同的目标属性。有一个名为 libmongocxx 的导入目标,它有 3 个用于不同配置的属性:

因此,要将必要的依赖项复制到构建目录,我尝试使用以下代码:

add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
    "$<TARGET_PROPERTY:libmongocxx,$<$<CONFIG:Debug>:IMPORTED_LOCATION_DEBUG>$<$<CONFIG:Release>:IMPORTED_LOCATION_RELEASE>$<$<CONFIG:RelWithDebInfo>:IMPORTED_LOCATION_RELWITHDEBINFO>>"
    $<TARGET_FILE_DIR:${PROJECT_NAME}>)

问题是:当我从 IDE 运行配置时(我尝试了 CLion 和 VS2017),这很有效,但是CMakeLists.txt当我从命令行运行 cmake 时,同样无法配置。错误cmake显示:

CMake Error at CMakeLists.txt:93 (add_custom_command):
  Error evaluating generator expression:

    $<TARGET_PROPERTY:libmongocxx,$<$<CONFIG:Debug>:IMPORTED_LOCATION_DEBUG>$<$<CONFIG:Release>:IMPORTED_LOCATION_RELEASE>$<$<CONFIG:RelWithDebInfo>:IMPORTED_LOCATION_RELWITHDEBINFO>>

  $<TARGET_PROPERTY:...> expression requires a non-empty property name.

顺便说一句,我已经发现使用TARGET_FILE生成器表达式可以更轻松地解决相同的任务,但是,为什么 IDE 和命令行中的行为不同?我在 CMake 版本 3.12.3 上发现了这一点,但后来在 3.14.4(仅限 cmd 行)上进行了测试,但仍然失败。

更新

这是重现该问题的最小示例。不需要依赖项。test.cpp 是空文件。配置从 VS2017 成功完成,但从 cmd 行失败。

CMakeLists.txt:

project(test LANGUAGES CXX)
cmake_minimum_required(VERSION 3.8.0)

add_executable(${PROJECT_NAME} test.cpp)

set_target_properties(${PROJECT_NAME} PROPERTIES
  IMPORTED_LOCATION_DEBUG "libd.dll"
  IMPORTED_LOCATION_RELEASE "lib.dll"
  IMPORTED_LOCATION_RELWITHDEBINFO "libi.dll"
)

add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E copy_if_different
    "$<TARGET_PROPERTY:${PROJECT_NAME},$<$<CONFIG:Debug>:IMPORTED_LOCATION_DEBUG>$<$<CONFIG:Release>:IMPORTED_LOCATION_RELEASE>$<$<CONFIG:RelWithDebInfo>:IMPORTED_LOCATION_RELWITHDEBINFO>>"
    $<TARGET_FILE_DIR:${PROJECT_NAME}>
)

命令行:

cmake -G "Visual Studio 15 2017 Win64" ..

更新2

不能同意这个问题是重复的。另一个问题是关于 Visual Studio 构建的正确配置。这个问题是关于 cmake 生成器表达式的使用以及关于从命令行使用 cmake 的。

标签: cmake

解决方案


Visual Studio IDE CMake 插件仅使用 RelWithDebInfo 和 Debug 配置(至少对我而言)。通过命令行调用时,默认为所有四种标准配置:Debug;Release;MinSizeRel;RelWithDebInfo.

您的 CMakeLists.txt 不完整,因为MinSizeRel未定义或未使用,因此没有MinSizeRel配置信息。

顺便说一句,CMAKE_BUILD_TYPE对于多配置生成器,将被忽略。CMAKE_CONFIGURATION_TYPES定义在生成期间应考虑哪些构建类型。

因此,要么添加缺失值,要么更改CMAKE_CONFIGURATION_TYPES.


推荐阅读