Linux下共享库CMake循环依赖错误:能否强制生成构建文件?
解决Linux下CMake构建循环依赖共享库的问题
遇到的CMake错误:
CMake Error: The inter-target dependency graph contains the following strongly connected component (cycle): "B" of type SHARED_LIBRARY depends on "A" (weak) "OpenPhase" of type SHARED_LIBRARY depends on "B" (weak) At least one of these targets is not a STATIC_LIBRARY. Cyclic dependencies are allowed only among static libraries. CMake Generate step failed. Build files cannot be regenerated correctly.
背景
- Linux系统原生支持共享库之间的循环依赖
- 无法修改现有库的代码结构,也不能切换为静态库
可行解决方案
方案1:通过OBJECT库间接构建共享库
CMake对OBJECT库的循环依赖限制更宽松,可先将每个库的源码编译为目标文件集合,再基于这些集合创建共享库,最后完成循环链接:
# 1. 为每个库创建OBJECT目标(仅编译源码为目标文件) add_library(A_obj OBJECT a.cpp) add_library(B_obj OBJECT b.cpp) add_library(OpenPhase_obj OBJECT openphase.cpp) # 2. 基于OBJECT目标创建共享库 add_library(A SHARED $<TARGET_OBJECTS:A_obj>) add_library(B SHARED $<TARGET_OBJECTS:B_obj>) add_library(OpenPhase SHARED $<TARGET_OBJECTS:OpenPhase_obj>) # 3. 建立循环链接关系 target_link_libraries(B PRIVATE A) target_link_libraries(OpenPhase PRIVATE B) target_link_libraries(A PRIVATE OpenPhase)
说明:此方式利用OBJECT库绕过CMake对共享库直接循环依赖的检查,最终生成的共享库与手动编译效果一致,兼容CMake 3.12及以上版本。
方案2:手动指定链接器选项,跳过CMake依赖检查
直接为每个目标添加链接器标志,手动指定循环依赖的库,绕开CMake的静态检查:
add_library(A SHARED a.cpp) add_library(B SHARED b.cpp) add_library(OpenPhase SHARED openphase.cpp) # 手动设置链接选项,包含循环依赖的库 target_link_libraries(B PRIVATE A -L$<TARGET_FILE_DIR:OpenPhase> -lOpenPhase) target_link_libraries(OpenPhase PRIVATE B -L$<TARGET_FILE_DIR:A> -lA) target_link_libraries(A PRIVATE OpenPhase -L$<TARGET_FILE_DIR:B> -lB)
说明:$<TARGET_FILE_DIR:XXX>是CMake生成器表达式,会自动替换为对应库的输出目录,确保链接器能找到库文件。若库的输出目录统一,可简化为全局指定-L路径。
方案3:合并循环依赖的库为单个共享库(可选)
若业务允许,可把循环依赖的A、B、OpenPhase合并为一个共享库,彻底消除循环依赖问题:
add_library(CombinedLib SHARED a.cpp b.cpp openphase.cpp)
说明:此方式最简洁,但需确保合并后的库不会引入其他冲突,适合循环依赖关系紧密的模块。
内容的提问来源于stack exchange,提问作者user2509663
相关产品推荐
相关产品推荐

