CMake库目标target_link_libraries PRIVATE语义及依赖传递问题咨询
CMake 链接依赖问题解答
答案是e1是否需要链接lib2不是必然的,会根据lib1、lib2的库类型有不同表现,具体分场景说明如下:
前置说明
你给出的配置target_link_libraries(lib1 PRIVATE lib2)、target_link_libraries(e1 PRIVATE lib1)中,PRIVATE关键字的语义是:lib2是lib1的私有依赖,仅在链接lib1自身时生效,不会被加入lib1的公开链接接口,正常情况下lib1的消费者不需要感知lib2的存在。但静态库属于未完成链接的目标文件归档,该特性会导致实际行为和纯动态库场景有差异。
分场景说明
场景1:lib1为动态库(无论lib2是静态/动态库)
e1不需要链接lib2:
- 如果lib2是动态库:lib1在自身链接生成动态库的阶段,已经在文件内记录了对lib2的依赖,e1只需要直接链接lib1即可,运行时系统加载lib1时会自动加载对应的lib2。
- 如果lib2是静态库:lib1在自身链接阶段已经把lib2的代码整合到了最终生成的动态库文件中,e1链接lib1时所有符号都能被解析,不需要额外再链接lib2。
场景2:lib1为静态库,lib2为动态库
e1必须链接lib2:
静态库仅会把自身源码编译出的目标文件打包成归档文件,不会处理依赖的动态库的符号解析。当e1链接静态lib1时,lib1内部引用的lib2的符号还处于未解析状态,链接器要求必须提供对应的lib2来完成符号解析,因此CMake会自动将lib2加入e1的链接依赖列表。
场景3:lib1和lib2均为静态库
默认配置下e1必须链接lib2:
和上述静态库的特性一致,lib1作为静态库不会把依赖的静态lib2的代码合并到自身的归档文件中,最终链接e1的时候需要同时提供lib1和lib2两个静态库才能完成所有符号的解析。只有当你自定义了构建逻辑,手动把lib2的目标文件合并到lib1的归档中时,e1才不需要额外链接lib2,这不属于CMake的默认行为。
内容的提问来源于stack exchange,提问作者einpoklum
相关产品推荐
相关产品推荐

