CMake现代用法:target_sources/target_link_libraries/接口库
请介绍 CMake 3.x 的现代 target 模型,包括 target_sources、target_include_directories、target_compile_definitions 的 PRIVATE/PUBLIC/INTERFACE 可见性,以及 INTERFACE 库在纯头文件库中的使用。
回答
Yahuda
现代 CMake Target 模型:
可见性说明符:
PRIVATE:仅目标自身使用。PUBLIC:目标和链接它的目标都使用。INTERFACE:仅链接它的目标使用(目标自身不编译)。
add_library(mylib STATIC src/core.cpp)
target_include_directories(mylib
PUBLIC include # 头文件路径传播给使用者
PRIVATE src/internal # 使用者看不到
)
target_compile_definitions(mylib
PUBLIC MYLIB_API # 传播给使用者
PRIVATE MYLIB_INTERNAL # 仅自己
)
# 链接
add_executable(myapp main.cpp)
target_link_libraries(myapp PRIVATE mylib fmt::fmt)
INTERFACE 库(纯头文件):
add_library(myheaderlib INTERFACE)
target_include_directories(myheaderlib INTERFACE include)
target_compile_features(myheaderlib INTERFACE cxx_std_20)
# 使用者得到所有包含路径和特性
add_executable(app main.cpp)
target_link_libraries(app PRIVATE myheaderlib)
target_sources(C++20 推荐):
# 源文件放在 target 上而非全局变量
add_library(mylib)
target_sources(mylib PRIVATE
src/core.cpp
src/utils.cpp
)
优势:
- 依赖关系清晰,无全局变量作用域问题。
- 生成器表达式支持条件编译:
$<CONFIG:Debug>。 - 包管理友好:
find_package(fmt)+target_link_libraries(app PRIVATE fmt::fmt)。