C:如何同时链接到不同的库版本

时间:2018-03-12 13:23:25

标签: c gcc ubuntu-16.04 dynamic-linking debian-stretch

我制作了一个动态库(libfoo.so)需要libcrypto.so。 哪个在构建平台上工作正常(我在Ubuntu 16.04中构建它)。但是,当我将同一个库移动到Debian Stretch 9.3时,它开始抱怨缺少libcrypto.so.1.0.0。 openssl包安装在Debian Stretch中,但libcrypto.so被命名为libcrypto.so.1.0.2。 经过一番挖掘,我发现虽然如此 Ubuntu 16.04上的libcrypto.so被命名为libcrypto.so.1.0.0(其SONAME也是libcrypto.so.1.0.0),实际上是版本1.0.2。

这是一个问题:我不想为Debian重新编译一个特殊版本,无论如何我的库可以在两个Linux发行版上使用吗?是否同时与.so版本或其他方法链接?

忘了提一下,我用gcc编译器,我的库用C语言编写。

2 个答案:

答案 0 :(得分:2)

在我看来(虽然我之前没有这样做过)...如果你不太担心你的共享对象的大小libfoo.so,...我认为你最好的选择是静态链接libcrypto.a(您选择的版本的libcrypto的静态版本)

虽然我怀疑你可能会遇到其他c库之间在不同版本(Debian和Ubuntu)之间不能很好地运行...即使你要让它上班,维护也会是一场噩梦

(如果您在运行时将.so对象加载到另一台机器上编译的程序中,则下面的内容可能无关紧要)

即使您完全静态地链接二进制文件......它可能无法正常工作

https://unix.stackexchange.com/questions/227910/will-my-linux-binary-work-on-all-distros

  

对于任何比静态链接的hello世界更复杂的东西,答案可能是否定的。   如果不在分布X上测试它,假设X的答案是否定的。

答案 1 :(得分:1)

我发现一种黑客可能会解决这个问题。

我制作libcrypto.so.1.0.0的本地副本并使用patchelf更改其SONAME

patchelf --set-soname libcrypto.so libcrypto.so.1.0.0

然后构建我的库并链接到该本地副本而不是系统库,它将显示为NEEDED libcrypto.so而不是之前的NEEDED libcrypto.so.1.0.0,并且它能够在Debian和Ubuntu上工作。

但是对于其他发行版,用户可能需要确保libcrypto.so存在,或者他们必须创建libcrypto.so.1.x.x

的符号链接