如何解决C++库MyLib与内置应用Gizmo的循环依赖问题
解决方案
1. 根目录CMakeLists.txt 调整
# 创建MyLib共享库 add_library(MyLib SHARED src/App.cpp) # 对外暴露include目录下的公共头文件(比如App.hpp) target_include_directories(MyLib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) # 引入Gizmo子模块 add_subdirectory(apps/Gizmo) # 让MyLib内部链接Gizmo(PRIVATE表示仅库内部使用,不对外暴露Gizmo的依赖) target_link_libraries(MyLib PRIVATE Gizmo) # 给MyLib添加Gizmo头文件的私有访问权限,仅库内部代码可用 target_include_directories(MyLib PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/apps/Gizmo)
2. Gizmo目录下CMakeLists.txt 调整
# 将Gizmo编译为静态库,避免共享库之间的循环依赖问题 add_library(Gizmo STATIC Gizmo.cpp) # 链接MyLib的公共接口(PRIVATE表示Gizmo依赖MyLib,但不会把MyLib的依赖传递给其他链接Gizmo的目标) target_link_libraries(Gizmo PRIVATE MyLib) # 设置Gizmo的头文件目录,若后续有其他组件需要使用Gizmo则保留PUBLIC,否则改为PRIVATE target_include_directories(Gizmo PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
关键说明
- 循环依赖解决:把Gizmo设为静态库后,MyLib作为共享库可以直接将Gizmo的代码嵌入自身,避免了Windows平台下共享库互相依赖无法加载的问题,Linux平台也能正常工作。
- 权限控制:
- MyLib的
PUBLIC头目录确保外部项目能继承App.hpp中的类; - 双向链接都用
PRIVATE,保证Gizmo和MyLib的依赖关系仅在内部生效,不会对外暴露不必要的接口。
- MyLib的
- 头文件隔离:MyLib仅通过私有路径访问Gizmo的头文件,不会将
Gizmo.hpp暴露给使用MyLib的外部项目。
特殊场景处理(可选)
如果必须将Gizmo作为共享库发布,仅Linux平台可以通过链接选项规避循环依赖,在根CMake中添加:
set_target_properties(MyLib PROPERTIES LINK_FLAGS "-Wl,--whole-archive $<TARGET_FILE:Gizmo> -Wl,--no-whole-archive")
但该方案无法在Windows平台正常运行,因此优先推荐静态库方案。
内容的提问来源于stack exchange,提问作者Carpetfizz
相关产品推荐
相关产品推荐

