如何在CMake配置阶段(而非生成阶段)获取目标的输出文件名?
在CMake配置阶段获取目标输出文件名
CMake的生成器表达式(如$<TARGET_FILE_NAME:Foo>)仅能在构建阶段求值,无法直接在配置阶段使用。要在配置阶段获取随平台变化的目标输出文件名(如libFoo.so、libFoo.dylib或Foo.dll),可以通过以下步骤实现:
核心思路
通过目标属性结合CMake预定义的平台/类型相关变量,手动拼接出完整的输出文件名:
- 获取目标的类型(共享库、静态库、模块库)
- 获取目标的输出名称(优先使用
OUTPUT_NAME属性,未设置则用目标原名) - 利用CMake预定义的前缀、后缀变量,拼接出最终文件名
实现代码示例
假设已定义共享库目标Foo:
add_library(Foo SHARED foo.cpp foo.h)
使用以下代码在配置阶段获取其输出文件名:
# 1. 获取目标类型 get_target_property(FOO_TARGET_TYPE Foo TYPE) # 2. 获取目标输出名称(优先用OUTPUT_NAME,否则用目标名) get_target_property(FOO_OUTPUT_NAME Foo OUTPUT_NAME) if(NOT FOO_OUTPUT_NAME) set(FOO_OUTPUT_NAME "Foo") endif() # 3. 根据目标类型匹配对应的前缀和后缀 if(FOO_TARGET_TYPE STREQUAL "SHARED_LIBRARY") set(FOO_PREFIX "${CMAKE_SHARED_LIBRARY_PREFIX}") set(FOO_SUFFIX "${CMAKE_SHARED_LIBRARY_SUFFIX}") elseif(FOO_TARGET_TYPE STREQUAL "STATIC_LIBRARY") set(FOO_PREFIX "${CMAKE_STATIC_LIBRARY_PREFIX}") set(FOO_SUFFIX "${CMAKE_STATIC_LIBRARY_SUFFIX}") elseif(FOO_TARGET_TYPE STREQUAL "MODULE_LIBRARY") set(FOO_PREFIX "${CMAKE_MODULE_LIBRARY_PREFIX}") set(FOO_SUFFIX "${CMAKE_MODULE_LIBRARY_SUFFIX}") endif() # 4. 拼接完整文件名 set(FOO_FULL_NAME "${FOO_PREFIX}${FOO_OUTPUT_NAME}${FOO_SUFFIX}") # 验证输出(可选) message(STATUS "Foo目标的输出文件名为:${FOO_FULL_NAME}")
关键变量说明
CMake预定义了针对不同库类型的前缀/后缀变量,会自动适配平台:
CMAKE_SHARED_LIBRARY_PREFIX/CMAKE_SHARED_LIBRARY_SUFFIX:共享库的前缀(如Linux/macOS的lib,Windows为空)和后缀(如.so/.dylib/.dll)CMAKE_STATIC_LIBRARY_PREFIX/CMAKE_STATIC_LIBRARY_SUFFIX:静态库的前缀和后缀(如.a/.lib)CMAKE_MODULE_LIBRARY_PREFIX/CMAKE_MODULE_LIBRARY_SUFFIX:模块库的前缀和后缀(如.so/.bundle/.dll)
处理版本号(可选)
如果目标设置了版本号(通过VERSION或SOVERSION属性),需要额外拼接版本信息。例如Linux下共享库的版本化文件名:
get_target_property(FOO_VERSION Foo VERSION) get_target_property(FOO_SOVERSION Foo SOVERSION) # 若设置了SOVERSION,Linux下文件名会包含该版本号 if(UNIX AND NOT APPLE AND FOO_TARGET_TYPE STREQUAL "SHARED_LIBRARY" AND FOO_SOVERSION) set(FOO_FULL_NAME "${FOO_PREFIX}${FOO_OUTPUT_NAME}${FOO_SUFFIX}.${FOO_SOVERSION}") # 若需要带完整版本号的文件名,可替换为${FOO_VERSION} endif()
内容的提问来源于stack exchange,提问作者user3667089
相关产品推荐
相关产品推荐

