CMake FetchContent_Declare 的用法
导入目标(IMPORTED targets)是 CMake 中用于表示已存在的外部构建产物(库文件或可执行文件)的抽象概念。它允许你在不构建这些目标的情况下,像使用普通 CMake 目标一样使用它们。
1. 核心概念
导入目标不生成构建规则,仅作为现有二进制文件的“包装器”,携带头文件路径、链接依赖等元信息。
2. 创建导入目标
使用 add_library() 配合 IMPORTED 选项:
1 2 3 4 5 6 7 8 9 10 11
| add_library(my_lib STATIC IMPORTED)
add_library(my_other_lib SHARED IMPORTED)
add_library(header_only_lib INTERFACE IMPORTED)
add_executable(my_tool IMPORTED)
|
3. 设置导入目标属性
创建后需通过 set_target_properties 设置关键属性:
1 2 3 4 5 6 7 8 9 10 11
| set_target_properties(my_lib PROPERTIES IMPORTED_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/libs/libmylib.a" INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/include" )
set_target_properties(my_lib PROPERTIES IMPORTED_LOCATION_DEBUG "${CMAKE_CURRENT_SOURCE_DIR}/libs/debug/libmylib.a" IMPORTED_LOCATION_RELEASE "${CMAKE_CURRENT_SOURCE_DIR}/libs/release/libmylib.a" )
|
4. 常用导入目标属性
| 属性 |
用途 |
IMPORTED_LOCATION |
库/可执行文件路径 |
IMPORTED_LOCATION_<CONFIG> |
特定配置下的路径 |
INTERFACE_INCLUDE_DIRECTORIES |
头文件搜索路径 |
INTERFACE_LINK_LIBRARIES |
链接依赖 |
INTERFACE_COMPILE_DEFINITIONS |
编译定义 |
IMPORTED_IMPLIB |
Windows DLL 的导入库(.lib) |
5. 使用导入目标
创建后,直接链接即可自动传递所有接口属性:
1 2
| add_executable(my_app main.cpp) target_link_libraries(my_app PRIVATE my_lib my_other_lib)
|
6. 实际应用场景
1. 使用预编译第三方库
1 2 3 4 5 6
| add_library(sdl2 SHARED IMPORTED) set_target_properties(sdl2 PROPERTIES IMPORTED_LOCATION "${SDL2_DIR}/lib/libSDL2.so" INTERFACE_INCLUDE_DIRECTORIES "${SDL2_DIR}/include" ) target_link_libraries(my_game PRIVATE sdl2)
|
2. 使用 find_package 提供的导入目标
1 2 3
| find_package(OpenSSL REQUIRED) target_link_libraries(my_app PRIVATE OpenSSL::SSL OpenSSL::Crypto)
|
3. 包装自定义查找逻辑
1 2 3 4 5 6
| add_library(curl::libcurl UNKNOWN IMPORTED) set_target_properties(curl::libcurl PROPERTIES IMPORTED_LOCATION "${CURL_LIBRARY}" INTERFACE_INCLUDE_DIRECTORIES "${CURL_INCLUDE_DIR}" )
|
7. 全局导入目标 vs 目录级导入目标
- 全局(
GLOBAL):在所有目录可见(默认,但需注意作用域)
- 非全局:仅在当前目录及子目录可见
1
| add_library(my_lib STATIC IMPORTED GLOBAL)
|
8. 与别名目标的区别
1 2 3 4 5
| add_library(my_lib_alias ALIAS my_lib)
add_library(external_lib STATIC IMPORTED)
|
9. 完整示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| cmake_minimum_required(VERSION 3.15) project(ImportTargetExample)
add_library(fast_math STATIC IMPORTED) set_target_properties(fast_math PROPERTIES IMPORTED_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/lib/libfastmath.a" INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/include" INTERFACE_COMPILE_DEFINITIONS "USE_FAST_MATH" )
add_executable(calculator main.cpp) target_link_libraries(calculator PRIVATE fast_math)
|
10. 优势总结
- 封装性:隐藏外部库的实现细节
- 一致性:使用统一的
target_link_libraries 语法
- 传递性:自动处理依赖关系
- 可移植性:通过属性区分不同平台/配置
导入目标是现代 CMake 最佳实践的重要组成部分,推荐在处理外部依赖时优先使用。