2012-10-03 102 views
0

我有一個C++項目,當前沒有鏈接任何外部動態庫。我正在考慮在將來需要構建一些boost庫(而不是僅標頭)。目前,在開發階段,我使用三種不同的工具鏈構建我的項目:g++,LLVM/Clang++Intel C++,平臺爲Linux。這些編譯器AFAIK彼此是二進制兼容的,例如, g ++編譯的應用程序可以使用英特爾C++編譯的動態庫。鏈接器如何選擇使用不同編譯器編譯的動態庫

我已經構建了boost二進制文件並將它們安裝到不同的文件夾中。例如build_gccbuild_icc。然後我將這些文件夾的路徑添加到系統LIBRARY_PATH。問題是:如果我現在使用g++Intel C++構建項目並鏈接一些動態庫(例如,寫

-lboost_math_tr1 
makefile

,如何鏈接器決定哪些確切的庫文件來鏈接,如果從不同的編譯器的二進制文件相互兼容?

問題的動機很簡單:Intel C++是一個優化的編譯器,所以如果我建立的東西吧,我希望他們對與Intel C++編譯器編譯動態庫鏈接,而不是對一個與g++編譯。當然,我知道我可以在makefile中簡單地使用多個條件語句來爲每個使用的工具鏈設置庫二進制文件的確切目錄,但這只是有點不方便。我在遊蕩,鏈接器是否足夠聰明,可以識別它應該使用的確切的共享庫文件,還是僅僅使用系統中的第一個匹配項LIBRARY_PATH

回答

1

鏈接器將不知道。如果第一個找到的庫不兼容,它甚至會保留,而不是搜索所有庫,直到找到兼容的庫。

確認是這樣的:

$ cat foo.c 
int main() { 
    return 0; 
} 
$ mkdir bar 
$ touch bar/libm.so 
$ gcc foo.c -o foo -Lbar -lm 
/usr/bin/ld: error: b/libm.so: file is empty 
collect2: error: ld returned 1 exit status 

OTOH,動態鏈接的美在於能夠與一個更好的交流dylib,而無需重新編譯。 所以你可以鏈接到g ++版本,但是如果性能很差,請在目標主機上安裝icc版本(在g ++版本之前要搜索的地方),你的應用程序會神奇地使用它(只要它們是兼容的)。

,你也可以使用LD_LIBRARY_PATH變量在運行應用程序時,搜索庫在非標準位置:

LD_LIBRARY_PATH=/path/to/super/libs/ ./app-dylinked-with-generic-libs 
+0

簡單而完整的解釋。謝謝。 – Dmitry

0

PATH環境變量用於查找可執行文件,而不是查找庫。每個編譯器都有一組標準位置查找庫,以及使用-L顯式指定的位置。它不會關心哪個編譯器創建了庫。

0

您需要將這些庫添加到$LIBRARY_PATH(鏈接)和$LD_LIBRARY_PATH(運行時),而不是$PATH。我覺得你可以在你的Makefile中一次設置這些變量來決定鏈接哪個二進制文件。

+0

感謝並指出,編輯的問題。 – Dmitry