CMake编译传递
传递使用要求 (Transitive Usage Requirements)
Target的使用要求可以传递到依赖项. target_link_libraries()命令有 PRIVATE、INTERFACE 和 PUBLIC关键字来控制传递.
当创建动态库时,
- 若源文件(例如cpp)中包含第三方头文件,而头文件(例如hpp)中不包含该第三方文件头,采用
PRIVATE。 - 若源文件和头文件中都包含该第三方文件头,采用
PUBLIC。 - 若头文件中包含该第三方文件头,而源文件(例如cpp)中不包含,采用
INTERFACE。
举个例子吧. 有三个库archive、archiveExtras、serialization以及一可执行文件consumer。

add_library(archive archive.cpp)
target_compile_definitions(archive INTERFACE USING_ARCHIVE_LIB)
add_library(serialization serialization.cpp)
target_compile_definitions(serialization INTERFACE USING_SERIALIZATION_LIB)
add_library(archiveExtras extras.cpp)
target_link_libraries(archiveExtras PUBLIC archive)
target_link_libraries(archiveExtras PRIVATE serialization)
# archiveExtras is compiled with -DUSING_ARCHIVE_LIB
# and -DUSING_SERIALIZATION_LIB
add_executable(consumer consumer.cpp)
# consumer is compiled with -DUSING_ARCHIVE_LIB
target_link_libraries(consumer archiveExtras)由于archive是archiveExtras的PUBLIC 依赖项, 因此它的使用要求也会传递给consumer. 因为serialization是archiveExtras的私有依赖,所以它的使用要求不会传递给consumer.
接口库 (Interface Libraries)
INTERFACE 目标没有 LOCATION 且是可变的,而且其他方面类似于 IMPORTED target.
它可以指定使用要求, 例如 INTERFACE_INCLUDE_DIRECTORIES、INTERFACE_COMPILE_DEFINITIONS、INTERFACE_COMPILE_OPTIONS、INTERFACE_LINK_LIBRARIES 和 INTERFACE_POSITION_INDEPENDENT_CODE.只有 target_include_directories()、target_compile_definitions()、target_compile_options() 和 target_link_libraries() 命令的 INTERFACE 模式可以与 INTERFACE 库一起使用.INTERFACE库的主要用例是仅含头文件的库.
add_library(Eigen INTERFACE)
target_include_directories(Eigen INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
$<INSTALL_INTERFACE:include/Eigen>
)
add_executable(exe1 exe1.cpp)
target_link_libraries(exe1 Eigen)这里, 来自Eigen目标的使用要求在编译时被消耗和使用, 但它对链接没有影响.
参考链接
- CMake transitive usage requirements
- CMake target_Link_libraries interface dependencies