如何在CMake中让测试目标获取库的私有依赖(无需手动指定)
解决库私有依赖供测试目标访问的CMake方案
下面是几种无需手动逐个指定私有依赖的可行方案,对应你提到的“保护级别”或“友元”思路:
1. 内部接口目标方案(推荐)
创建一个仅用于内部的接口目标,把库的私有依赖、私有头目录统一管理,让库和测试目标都链接这个接口:
# 定义内部接口目标,仅用于库和测试内部共享 add_library(library_internal INTERFACE) # 添加私有头目录到接口 target_include_directories(library_internal INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/private_headers ) # 添加所有私有依赖到接口 target_link_libraries(library_internal INTERFACE some_private_dep another_private_dep ) # 你的库目标,以PRIVATE方式链接内部接口 add_library(library SHARED source.cpp) target_link_libraries(library PRIVATE library_internal ) # 库的公共头目录单独设置 target_include_directories(library PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/public_headers ) # 测试目标,直接链接库和内部接口 add_executable(testing test.cpp) target_link_libraries(testing PRIVATE library library_internal )
这种方式相当于把私有依赖设为“保护级别”,只有关联的内部目标(库和测试)能访问,不会暴露给库的公共使用者。
2. 直接复用库的私有属性
利用CMake的目标属性,直接让测试目标继承库的私有依赖和头目录,无需额外维护接口目标:
# 定义你的库目标 add_library(library SHARED source.cpp) target_include_directories(library PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/public_headers PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/private_headers ) target_link_libraries(library PRIVATE some_private_dep another_private_dep ) # 测试目标 add_executable(testing test.cpp) # 链接库本身,同时继承库的私有依赖 target_link_libraries(testing PRIVATE library $<TARGET_PROPERTY:library,PRIVATE_LINK_LIBRARIES> ) # 继承库的私有头目录 target_include_directories(testing PRIVATE $<TARGET_PROPERTY:library,PRIVATE_INCLUDE_DIRECTORIES> )
这种方式类似给测试目标设置为库的“友元”,直接读取库的私有属性,无需重复配置依赖。
不推荐的方案:临时修改依赖可见性
你提到的“暂时将库的所有依赖设为公共,链接测试后再恢复”不建议使用,因为CMake的目标属性是全局生效的,修改后可能会意外影响库的其他使用者,导致私有依赖被暴露给公共API的消费者,引发依赖冲突或不必要的编译依赖。
内容的提问来源于stack exchange,提问作者Eyjafl
相关产品推荐
相关产品推荐

