2009-12-02 69 views
5

这里的现状我在:链接应用程序li​​bbz2.so.1而非libbz2.so.1.0

我想发布在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

谢谢。

回答

3

为什么不直接链接静态呢?

我已经完成了在Ubuntu上构建以及在RHEL上部署使用静态构建的良好效果。

+0

* facepalm * ...因为这太明显了。出于某种原因,我认为bzip2会被授权LGPL,它禁止静态链接,但它似乎是BSD,它允许它......静态链接它。谢谢。 – Fred 2009-12-02 20:37:20

+1

没有汗水。但为什么你认为LGPL有什么可以说你如何链接?您可以使用LGPL和GPL代码的静态或动态链接 - 您的限制是如何分发您的应用程序等pp,以及是否需要提供源代码。这完全独立于您的构建过程。 – 2009-12-02 20:45:08

+3

好吧,我应该更精确。 LGPL禁止静态链接到专有应用程序。 作为人们寻找完整的答案,这里是如何做到这一点,如果你想带*号部分*库和动态带*号部分*其他库静态链接: G ++ -Wl,-Bstatic -lbz2轮候册, - Bdynamic -lotherlib -o main.cpp中TEST.bin,烧写它 – Fred 2009-12-02 21:08:48

4

这里有一些背景来解释链接。在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但由于apparency其SONAME在二进制的事项,你的依赖仍然是这个libbz2.so.1

 
$ ldd a.out | grep bz2 
     libbz2.so.1 => /lib64/libbz2.so.1 (0x00002b3d1a000000) 

除了静态的诡计(它可以以有趣的方式破坏事物)之外,没有简单的办法摆脱混乱(理想情况下,图书馆会做像glibc一样好的符号版本,永远不会或很少更改其SONAME)。

+0

甚至可以用 CP /lib64/libbz2.so.1 libblah.so 而不是LN(如果有人认为LD莫名其妙的痕迹名libbz2更强的例子.so.1 – Jaro 2014-02-06 04:39:48