gpt4 book ai didi

c++ - 将应用程序链接到 libbz2.so.1 而不是 libbz2.so.1.0

转载 作者:IT王子 更新时间:2023-10-29 01:15:17 27 4
gpt4 key购买 nike

这是我目前所处的情况:

我想在 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.1libbz2.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/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com