CodeWalk

CMake现代用法:target_sources/target_link_libraries/接口库

作者:Yahuda · 2026-05-30 12:55

请介绍 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)