Liam0205 / liam0205.github.io

Deployment of my weblog.
https://liam0205.github.io
35 stars 5 forks source link

为什么不能在动态库里静态链接? | 始终 #170

Open Liam0205 opened 5 years ago

Liam0205 commented 5 years ago

https://liam.page/2017/04/03/not-to-link-libstdc-statically-and-why/

因为各种复杂的原因,工作中遇到了某个模块当中的一个动态库(Linux Dynamic Shared Object,我们称其为 A.so)需要使用与整个模块不同版本的 gcc 进行编译。由于 A.so 使用了高版本 libstdc++.so 中提供的接口;因此,如果让 A.so 与整个模块运行在同一个环境(即,依赖同一个低版本的 libstdc++.so),那么,整个程序运行时将会由动态链接器提示「

Liam0205 commented 5 years ago

你好,我看了你这篇文章,有个问题想请教,如何才能正确解决开头提到的问题? 比如我现在也有个场景,需要给一个gcc 4.6 c++03的项目开发一个动态库,如果我用gcc 4.8 c++11开发,如何能在项目中正确调用? ——innoink

其实你的问题跟文章中提到的问题不完全一样。

我当时依赖的 A.so 是第三方开发的库,并且以 A.so 的二进制形式发布。因此我手头只有 A.so 的共享对象文件和相应的 .h 头文件。对于这个情况,答案就是「无法解决」,问题根源是 libstdc++.so 高版本不向下兼容低版本的 ABI;同时尝试文章提到的各种 tricky 的办法也有无法绕过的坑。

你现在的情况,假设你要开发一个 foo.so 出来,那么你手头使用 foo 的源代码的。你只需要拿着源代码,去低版本的 gcc 上编译出适用于低版本的 foo.so 就可以了。至于 C++ 标准版本的问题……,如果你们公司使用的是低版本的编译器,就不要想着用高版本的 C++ 标准去写代码了。这里有绕不过去的坎。

lyl625760 commented 4 years ago

学习了,写的真好。 不过我发现gcc 4.9 编译出的so可以再 gcc 4.7的机器上面运行。

lyl625760 commented 4 years ago

"我们注意到,被 .so 依赖的静态库 .a 是没有机会被装载进内存的。因此,在生成 A.so 的过程中,将 libstdc++.a 静态链接进去,是不可行的。因为,这部分静态链接的指令永远没有机会被装载进进程空间执行。"

大神,这句话不对吧 ? 我感觉 .so 会自动打包依赖的静态库 .a 中的代码,运行时不需要.a, 只会运行so库。这个例子我运行过,main是可以运行的 https://blog.csdn.net/sevenjoin/article/details/78041377

Martin-HZK commented 1 month ago

写的真不错!