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