关于静态库依赖关系的困惑

2018-06-28 13:47:29 +08:00
 paparika

现有一个进程,依赖 libcurl.so 。此进程要接入一个 sdk,sdk 也依赖 curl。如果使用 curl 的静态库编译一个静态库 sdk,sdk 集成到进程后会不会有问题。此时原进程的 curl 地址空间和 sdk 集成的 curl 的地址空间完全独立?

3436 次点击
所在节点    Linux
5 条回复
BOYPT
2018-06-28 14:07:03 +08:00
得看 sdk 的编译参数;默认参数下应该是 sdk 用一套 libcurl,你的进程用一套 libcurl,两套 curl 独立;

但是 sdk 编译时候用--whole-archive 静态链接 libcurl.a 的话,libcurl 的名空间可以全暴露出来,可以给你的进程链接,如果要避免这个情况可以用--no-whole-archive
xiaoxuxu
2018-06-29 13:18:12 +08:00
一般来说两种方法:
1. SDK 不要静态链 curl,链接 executable 的时候先链接 SDK,最后链接 libcurl.so ,这样整个进程使用同一份 libcurl 动态库;
2. 编译 SDK 成动态库,同时静态链接 libcurl,但是将 libcurl 符号全部隐藏(使用 ld script 控制);最后链接 executable 时分别链接 SDK.solibcurl.so 。这样 SDK 当中使用的是自身静态链接的 curl,executable 其他部分使用的是动态链接的 libcurl.so ,不会冲突(前提是保证 SDK 中的 curl 的 symbol 全部隐藏);

如果 SDK 必须编译成静态库,那么选择方法 1 是最方便的。如果必须使用两个版本的 libcurl,可以使用方法 2.
paparika
2018-06-29 14:35:46 +08:00
@xiaoxuxu 谢谢回复。请教另外一个问题,编一个动态库,它依赖另外一个静态库,那么此动态库是不是会直接包含静态库代码?编好之后外部直接引用动态库,与静态库不再发生联系吧
iwtbauh
2018-06-29 19:07:35 +08:00
不要这样做,这会浪费大量内存。降低用户体验。
尽量重用动态库,因为动态库实质上只有一份装入了内存,并使用写时复制技术保护。
xiaoxuxu
2018-08-02 17:30:58 +08:00
@paparika 是的。生成动态库的时候,所依赖的静态库部分都编进去了。没用到的静态库部分不会编进去。如果需要把静态库的所有内容都强制放到动态库里,可以加上 whole-archive 选项。最终动态库的使用方肯定都不需要再用到这个静态库了。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/466555

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX