2011-07-30 238 views
2

從位於/ some/lib中的共享庫libA.so開始。 我建立依賴於libA.so中的功能的庫(libB.so)。所以,在創建libB.so時,我在g ++命令行中包含-L/some/lib -lA。 012-libB.so也將駐留在/ some/lib中。鏈接依賴關係

現在,我正在構建一個將使用libB.so的可執行文件。我向g ++鏈接器提供了預期的-L/some/lib和-lB。但是我得到一個錯誤,因爲它找不到「libA.so」。如果我將「-lA」添加到鏈接器行,則程序鏈接。

我不明白爲什麼它找不到「libA.so」。我當然不明白爲什麼在鏈接器行中包含「-lA」讓它找到它。它似乎已經知道它需要libA.so,並且libA.so與libB.so的路徑相同。

有人可以解釋這一點嗎?我不喜歡在每個想要鏈接libB.so的可執行文件中都明確地加上「-lA」的想法。我做了其他事情嗎?

回答

4

雖然僅鏈接到libB,但鏈接程序查找libA,但找不到它,因爲它不在鏈接程序/加載程序的可找到路徑中。您必須在鏈接階段設置LD_LIBRARY_PATH(和/或LD_RUN_PATH),否則鏈接libB-rpath /some/lib

只需假裝一分鐘libB本身就是一個可執行文件,我們稱之爲foo。您不能只在命令行中說./foo,因爲找不到libA(請檢查ldd foo以檢查加載程序路徑)。相反,您需要

LD_LIBRARY_PATH=/some/lib ./foo 

或者您需要編譯rpath。 (在g++中,你會說g++ -Wl,-rpath,/some/lib ...將選項傳遞給鏈接器。)相同的加載時間解析過程適用於動態庫本身。

+0

爲什麼「-lA」將它放在可找到的路徑中?在我看來,「-lA」似乎將它放在需要找到的對象列表中,而不是找到它的路徑。 – John

+0

讓我們來看一個簡單的程序:當你說'g ++ -o foo foo.o - lA -L/some/lib',*鏈接器*找到庫libA,但是你仍然不能運行*程序,因爲* loader *沒有找到它。你需要像我的例子那樣運行程序,設置'LD_LIBRARY_PATH'。不要混淆鏈接和加載! –

+0

如果最終的可執行文件只使用libB中的函數/類,爲什麼它仍然需要鏈接到libA?在Windows中,你真的不需要。 –