- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
这是我目前所处的情况:
我想在 Linux 上分发一个二进制应用程序,该应用程序可以在多个发行版上运行(不是所有发行版,目前只有主要发行版很重要,为了本次讨论,让我们关注 Ubuntu 和 Fedora)。有问题的应用程序链接到 libbz2
的一些工作。一个简单的“Hello World”将说明情况:
/* main.cpp */
#include <iostream>
int main(int argc, char* argv[])
{
std::cout << "Hello World!\n";
return 0;
}
应用程序是这样构建的:
g++ -lbz2 -o test.bin main.cpp
我的构建系统是在 Ubuntu 上。当我使用 ldd 对生成的二进制文件执行检查时,它会将 libbz2.so.1.0 列为运行时依赖项。当我将这个应用程序带到 Fedora 机器上时,该应用程序不运行并且 ldd 显示它找不到 libbz2.so.1.0
。 Fedora 只有libbz2.so.1
和libbz2.so.1.0.4
,没有libbz2.so.1.0
。
Red Hat's Bugzilla database显示此行为不是错误,而是功能。我并不真的需要 libbz2.so.1.0
,我对简单地链接到 libbz2.so.1
感到满意,但我还没有弄清楚如何。
我看到一个similar question asked here previously ,但接受的答案(您可以在链接器命令行上传递实际的 .so 文件而不是 -l)似乎不起作用。我尝试使用以下命令进行构建:
g++ /lib/libbz2.so.1 -o test.bin main.cpp
但是,ldd 仍然提到该应用程序依赖于 libbz2.so.1.0
,即使我将全名传递给 g++。
现在,问题是,在 Ubuntu 上是否有一种方法可以构建应用程序,使其仅依赖于 libbz2.so.1
而不是 libbz2.so.1.0
?
谢谢。
最佳答案
这里有一些背景知识可以解释链接的内容。在 ELF 平台上,您传递的 -L 和 -l 标志仅在链接时定位二进制文件。如果链接器链接器确定需要一个库,它会在该二进制文件中生成对该 SONAME 的引用,而不管它被称为什么。例如:
$ objdump -p /lib64/libbz2.so.1 | grep SONAME SONAME libbz2.so.1
因此,无论 libbz2 的名称是什么,它都会显示为依赖项。再举个例子,做一些完全崩溃的事情:
$ ln -s /lib64/libbz2.so.1 libblah.so$ g++ t.C -L. -l blah
你显然已经链接到 libblah,但因为它在那个二进制文件中的 SONAME 很重要,你的依赖仍然是这个 libbz2.so.1
$ ldd a.out | grep bz2 libbz2.so.1 => /lib64/libbz2.so.1 (0x00002b3d1a000000)
除了 -static 欺骗(它可以以有趣的方式破坏事物)之外,没有简单的方法摆脱困惑(理想情况下,库会像 glibc 一样进行良好的符号版本控制,并且从不或很少更改其 SONAME)。
关于c++ - 将应用程序链接到 libbz2.so.1 而不是 libbz2.so.1.0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1835489/
我是一名优秀的程序员,十分优秀!