Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将应用程序链接到libbz2.so.1而不是libbz2.so.1.0_C++_C_Linux_G++ - Fatal编程技术网

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

C++ 将应用程序链接到libbz2.so.1而不是libbz2.so.1.0,c++,c,linux,g++,C++,C,Linux,G++,以下是我目前的情况: 我想在Linux上发布一个二进制应用程序,可以在几个发行版上运行(不是所有发行版,只是目前最重要的发行版,为了讨论这个问题,让我们把重点放在Ubuntu和Fedora上)。有问题的应用程序链接到libbz2,了解其部分工作。一个简单的“Hello World”将说明这种情况: /* main.cpp */ #include <iostream> int main(int argc, char* argv[]) { std::cout << "H

以下是我目前的情况:

我想在Linux上发布一个二进制应用程序,可以在几个发行版上运行(不是所有发行版,只是目前最重要的发行版,为了讨论这个问题,让我们把重点放在Ubuntu和Fedora上)。有问题的应用程序链接到
libbz2
,了解其部分工作。一个简单的“Hello World”将说明这种情况:

/* main.cpp */
#include <iostream>

int main(int argc, char* argv[])
{
  std::cout << "Hello World!\n";
  return 0;
}
我的构建系统在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

表明此行为不是bug,而是特性。我真的不需要
libbz2.so.1.0
,我只需要链接到
libbz2.so.1
,我会很满意,但我还没有弄清楚如何链接

我已经看到了,但是接受的答案(您可以在链接器命令行上传递实际的.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


谢谢。

为什么不改为静态链接呢


我过去在Ubuntu上的构建和RHEL上的部署都是这样做的,使用静态构建效果很好。

这里有一些背景知识来解释链接的内容。在ELF平台上,传递的-L和-L标志仅在链接时定位二进制文件。如果链接器确定需要一个库,它将在该二进制文件中生成对SONAME的引用,而不管它被调用什么。例如:

$ objdump -p /lib64/libbz2.so.1 | grep SONAME SONAME libbz2.so.1 $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 $ln-s/lib64/libbz2.so.1 libblah.so $g++t.C-L.-L等等 你显然已经链接到了libblah,但是因为二进制文件中的SONAME很重要,所以你的依赖关系仍然是libbz2.so.1

$ ldd a.out | grep bz2 libbz2.so.1 => /lib64/libbz2.so.1 (0x00002b3d1a000000) $ldd a.out |格雷普bz2 libbz2.so.1=>/lib64/libbz2.so.1(0x00002B3D1A0000)
除了静态的诡计(它可以以有趣的方式破坏事物),没有简单的方法可以摆脱混乱(理想情况下,库可以像glibc一样进行很好的符号版本控制,并且永远不会或很少更改其SONAME)。

facepalm。。。因为那太明显了。出于某种原因,我想当然地认为bzip2将被授权为LGPL,这禁止静态链接,但它似乎是BSD,它允许。。。静态链接就是这样。谢谢,不用担心。但为什么你认为LGPL对你如何链接有什么意见?您可以在LGPL和GPL代码中使用静态或动态链接——您的限制是如何分发应用程序以及是否必须提供源代码。这完全独立于您的构建过程。好的,我应该更精确一些。LGPL禁止静态链接到专有应用程序。对于寻找完整答案的人来说,如果你想静态地与一些lib链接,并动态地与其他lib链接,下面是如何实现的:g++-Wl,-Bstatic-lbz2-Wl,-Bdynamic-lotherlib-o test.bin main.cppit可以是cp/lib64/libbz2.so.1 libblah.so而不是ln的一个更强大的例子(如果有人认为ld不知何故把这个名字追溯到libbz2.so.1 $ ldd a.out | grep bz2 libbz2.so.1 => /lib64/libbz2.so.1 (0x00002b3d1a000000)