4

我生成了一个动态库(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.soUbuntu 16.04 上的命名为libcrypto.so.1.0.0(its SONAMEalso libcrypto.so.1.0.0),但实际上是 1.0.2 版本。

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

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

4

2 回答 2

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 world 更复杂的东西,答案可能是否定的。如果不对分布 X 进行测试,假设 X 的答案是否定的。

于 2018-03-12T15:40:58.290 回答
1

我发现一种hacky方式可以解决这个问题。

我制作了一个本地副本libcrypto.so.1.0.0并用于patchelf更改其SONAME

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

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

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

于 2018-03-12T16:51:52.367 回答