如何在PRE_BUILD的add_custom_command中捕获$<CONFIG>到变量?
在CMake中捕获$值并用于路径拼接的解决方案
为什么直接set存$会失败?
$<CONFIG>是生成器表达式,仅在CMake生成构建系统(如Ninja/Makefile)之后、实际构建阶段才会被解析替换为Debug/Release等具体值。而set(currentBuildType $<CONFIG>)是在CMake配置阶段执行的,此时CMake还未确定最终构建配置,变量中存储的是字面字符串$<CONFIG>,而非实际配置值——这就是你在自定义命令的echo中能正确输出,但变量始终保持初始值的原因。
正确的解决方案
针对你拼接路径链接无*Config.cmake导入库的核心需求,分场景处理:
1. 在自定义命令/目标中直接使用生成器表达式
如果是在add_custom_command或add_custom_target里需要拼接路径,无需将$<CONFIG>存入变量,直接在命令或路径中嵌入生成器表达式即可,构建时会自动替换:
add_custom_command( OUTPUT my_output.bin COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_SOURCE_DIR}/libs/$<CONFIG>/mylib.a" $<TARGET_FILE_DIR:my_target> DEPENDS my_target )
2. 为导入库设置多配置路径
针对无*Config.cmake的第三方库,用生成器表达式或多配置属性设置导入库路径,CMake会自动匹配当前构建配置:
方式一:为每个配置单独设置属性(兼容性好)
add_library(thirdparty_lib STATIC IMPORTED GLOBAL) # 设置头文件包含目录 target_include_directories(thirdparty_lib INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/include") # 为每个构建配置指定对应的库路径 set_target_properties(thirdparty_lib PROPERTIES IMPORTED_LOCATION_DEBUG "${CMAKE_CURRENT_SOURCE_DIR}/lib/Debug/thirdparty.lib" IMPORTED_LOCATION_RELEASE "${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/thirdparty.lib" IMPORTED_LOCATION_RELWITHDEBINFO "${CMAKE_CURRENT_SOURCE_DIR}/lib/RelWithDebInfo/thirdparty.lib" ) # 链接到你的项目目标 add_executable(my_app main.cpp) target_link_libraries(my_app PRIVATE thirdparty_lib)
方式二:用生成器表达式统一设置(更简洁)
如果所有配置的路径遵循lib/<CONFIG>/xxx的统一格式,可直接用$<CONFIG>生成器表达式批量设置:
add_library(thirdparty_lib STATIC IMPORTED GLOBAL) target_include_directories(thirdparty_lib INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/include") set_target_properties(thirdparty_lib PROPERTIES IMPORTED_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/lib/$<CONFIG>/thirdparty.lib" ) add_executable(my_app main.cpp) target_link_libraries(my_app PRIVATE thirdparty_lib)
单配置与多配置生成器的差异
- 单配置生成器(Ninja、Unix Makefiles):配置阶段通过
CMAKE_BUILD_TYPE确定构建配置,可直接用${CMAKE_BUILD_TYPE}拼接路径,比如set(lib_path "${CMAKE_SOURCE_DIR}/lib/${CMAKE_BUILD_TYPE}/mylib.a"),但该写法在多配置生成器下无效。 - 多配置生成器(Ninja Multi-Config、Visual Studio):必须依赖生成器表达式
$<CONFIG>,因为配置阶段无法预知具体构建配置,每个配置的构建过程相互独立。
内容的提问来源于stack exchange,提问作者Mariusz
相关产品推荐
相关产品推荐

