cmake - cmake 生成器表达式在 IDE 和命令行中的行为不同
问题描述
我正在尝试根据构建配置使用不同的目标属性。有一个名为 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),这很有效,但是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 的。
解决方案
Visual Studio IDE CMake 插件仅使用 RelWithDebInfo 和 Debug 配置(至少对我而言)。通过命令行调用时,默认为所有四种标准配置:Debug;Release;MinSizeRel;RelWithDebInfo
.
您的 CMakeLists.txt 不完整,因为MinSizeRel
未定义或未使用,因此没有MinSizeRel
配置信息。
顺便说一句,CMAKE_BUILD_TYPE
对于多配置生成器,将被忽略。CMAKE_CONFIGURATION_TYPES
定义在生成期间应考虑哪些构建类型。
因此,要么添加缺失值,要么更改CMAKE_CONFIGURATION_TYPES
.
推荐阅读
- java - 如何在 gradle 中以编程方式从 src/java 中排除顶级包?
- sql - 基于 FOR LOOP 在 SQL Query 中使用 PLSQL 变量
- azure - 如何在 Azure Cosmos DB 中设置时区?
- laravel - SQLSTATE [42S02] 工匠修补程序的问题
- stream - 如何使用 exceljs 流读取 excel 文件
- python - Python curve_fit 创建奇角
- laravel - Laravel Backpack 管理员登录 419 页面已过期
- javascript - 如何解决 JEST 错误重复键值违反唯一约束“users_pkey”
- r - RShiny Code 在运行时会执行多次
- node.js - 用于监控电子应用的工具