C: 如何link 同时使用不同的库版本

C: How to link with different library versions at the same time

我制作一个动态库(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。 经过一番挖掘,我发现虽然 libcrypto.so on Ubuntu 16.04 被命名为 libcrypto.so.1.0.0(其 SONAMElibcrypto.so.1.0.0),它实际上是版本 1.0.2.

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

忘了说,我用的是 gcc 编译器,我的库是用 C 写的。

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

尽管我怀疑您可能 运行 进入其他在不同发行版(Debian 和 Ubuntu )之间表现不佳的 c 库......即使您要让它工作维护也是如此噩梦

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

即使您要完全静态 link 二进制文件...它也可能无法工作

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

For anything that is more complex than a statically linked hello world, the answer is probably no. Without testing it on distribution X, assume the answer is no for X.

我发现一个 hacky 方法可能会解决这个问题。

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

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

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

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

创建一个 symlink