2009-12-02 66 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