2013-02-25 21 views
1

我認爲在這個行業應該有一個最佳實踐,所以我在這裏問。連接EXE時厭倦了寫非直接.so,如何獲得救濟?

這個問題是關於使用Linux上的gcc將共享庫(.so)鏈接到可執行文件。但讓我從Windows開始。

假設我正在開發A.EXE,B.DLL,C1.DLL。的依賴性是

A -> B -> C1 

這意味着:一個從B調用API,和B通過從C1調用API實現本身。 A不直接在C1中調用API。你知道,在鏈接A.EXE(使用Visual C++)時,我只需要列出B.lib(import lib)作爲A的鏈接組件(在makefile中);但是,如果鏈接組件在鏈接組件中, C1不必出現在A的makefile中。所以有一天我想用C2取代C1以更好地實現B,由於C1的替換,我不必更改A的makefile。

這很棒,因爲它遵循了理性思想:makefile只涉及與它直接相關的東西。有了這種便利,人們傾向於在Windows上編寫DLL而不是LIB--我認爲是這樣。

現在我轉向linux上的gcc。在相同的依賴的情況,在A的生成文件,我必須明確列出C1或C2爲紐帶組分,這樣的:

gcc -o A a1.o a2.o -lB -lC1 

這麼折騰,想象你有十個項目A1,A2,... A10調用B,您必須修改10個makefile才能從C1切換到C2。

如何獲得解脫?

+0

您沒有在Linux上的DLL 。你有共享對象庫,這是不同的野獸。 – 2013-02-25 08:00:31

+0

謝謝。我提到Windows DLL只是因爲我需要引用我知道的預期行爲。 – 2013-02-25 08:42:06

+0

但是,您需要了解(以及如何)'.so'文件在Linux上不像'.dll'在Windows上運行。 – 2013-02-25 08:43:06

回答

1

確保您libB取決於libCldd libB.so);應該已經編譯了libB,如gcc -o libB.so -shared -fPIC *.c -L/path/to/libC -lC -Wl,-rpath,/path/to/libC

注意libB.so需要與-rpath爲了能夠找到libC.so,或使用LD_LIBRARY_PATH環境變量編譯(上述ldd命令不能顯示libC.so => not found

+0

我不確定你必須傳遞'-Wl, - allow-shlib-undefined';我從來沒有做。 – 2013-02-25 08:14:09

+0

你說得對,它不需要那個開關。編輯。 – Unknown 2013-02-25 08:17:52

3

當鏈接某些共享庫libfoo.so,你可以與其他共享庫鏈接libbar.so它:當您使用-lfoolibbar.so將被自動鏈接,而不要求其

gcc -fPIC -g -Wall -c foo1.c 
    gcc -fPIC -g -Wall -c foo2.c 
    gcc -shared -o libfoo.so foo1.o foo2.o -lbar 

然後。

因此,您不必在C1的makefile中明確列出C1或C2作爲鏈接組件。

你就必須這樣做,如果你只有靜態庫lib*.a

所以,你可以制定一個計劃,以

gcc -Wall -g prog.c -lfoo 

單獨(不提libbar.so明確)。

嘗試實例(我的Debian系統)上運行的GTK共享庫ldd

ldd /usr/lib/x86_64-linux-gnu/libgtk-3.so.0 

我建議閱讀Levine's linker & loader book瞭解的Windows .dll和Linux .so之間的區別;他們是不同的野獸。另請閱讀Program Library HowTo。您可能需要(或不)使用GNU libtool

順便說一句,你還可以使用pkg-config,這將使依賴...

+0

我在opensuse 11.3上試過了。你的''gcc -Wall -g prog.c -lfoo''將會失敗,並顯示ld的警告:libbar.so,./libfoo.so需要,找不到(嘗試使用-rpath或-rpath-link)'' 。爲了成功,我必須編寫鏈接器命令''gcc -Wall -g prog.c -lfoo -Wl,-rpath-link,.'',這意味着,我仍然需要libbar.so當生成main。與Windows相比,它不是一個負擔嗎?任何救濟? – 2013-09-18 02:51:05