【问题标题】:cmake generator expressions behave differently in IDE and from command linecmake 生成器表达式在 IDE 和命令行中的行为不同
【发布时间】:2019-05-22 12:05:03
【问题描述】:

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

  • IMPORTED_LOCATION_DEBUG
  • IMPORTED_LOCATION_RELEASE
  • IMPORTED_LOCATION_RELWITHDEBINFO

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

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),但是当我从命令行运行 cmake 时,相同的 CMakeLists.txt 配置失败。 错误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。

【问题讨论】:

  • CMakeLists.txtFindlibmongocxx.cmake 脚本都可以区分命令行 CMake 和 IDE。例如,通过检查生成器。您没有向我们展示这些脚本,因此我们只能猜测为什么在不同的用例中结果会有所不同。请准备好minimal reproducible example 来证明您的问题。
  • 哪个生成器导致问题?或者您是说在命令行中使用 CMake 时 Visual Studio 生成器失败,但在使用 Visual Studio CMake 插件时没有?
  • 好吧,当命令行发布时,它解释了问题。请参阅有关 Visual Studio 的正确设置构建类型的重复问题。
  • @Tsyvarev 我不同意这是重复的。这与更改构建类型无关。这是关于生成器表达式并且必须考虑CMAKE_CONFIGURATION_TYPES 中的所有构建类型。即使CMAKE_BUILD_TYPE 不在命令行上,您也会注意到同样的错误。它的使用只是分散实际问题的注意力。
  • "这个问题是关于 cmake 生成器表达式的使用以及关于从命令行使用 cmake。" - 副本是关于您尝试在命令行中为 Visual Studio 设置 CMAKE_BUILD_TYPE 的方式。但我同意@Fred 的观点,如果没有这种尝试,你的问题肯定会有所不同。请从帖子中删除该尝试(或仅删除 -DCMAKE_BUILD_TYPE=Debug 部分,因为它没有效果),我很乐意重新提出问题。

标签: cmake


【解决方案1】:

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

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

顺便说一句,CMAKE_BUILD_TYPE 被多配置生成器忽略。 CMAKE_CONFIGURATION_TYPES 定义了在生成过程中应该考虑哪些构建类型。

所以要么添加缺失值,要么更改CMAKE_CONFIGURATION_TYPES

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-01-23
    • 2019-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多