建構系統、函式庫與相依性

引入路徑與函式庫路徑

要使用一個函式庫,你得做兩件分開的事,而每一件都需要工具鏈在磁碟上找到某樣東西。首先,編譯器必須找到函式庫的標頭檔,才知道有哪些函式存在;其次,連結器必須找到函式庫已編譯的檔案,才能把程式碼接上。引入路徑是用來搜尋標頭檔的目錄清單,函式庫路徑則是用來搜尋函式庫檔的目錄清單——兩個不同的搜尋,發生在建構的兩個不同階段。

當編譯器看到 #include <foo.h>,它會走訪引入路徑來找 foo.h:一組內建的標準目錄(像 /usr/include),加上任何你用 -I 旗標加入的額外目錄,例如 gcc -I/opt/foo/include。當連結器被要求以 -lfoo 連結一個函式庫時,它會走訪函式庫路徑來找名為 libfoo.a 或 libfoo.so 的檔案:標準目錄像 /usr/lib,加上任何你用 -L 加入的目錄,例如 gcc -L/opt/foo/lib -lfoo。所以一個非標準函式庫的典型建構會同時傳入兩者:-I 找標頭、-L 加 -l 找到並連結函式庫。

為什麼重要:「fatal error: foo.h: No such file or directory」是編譯器告訴你標頭檔不在引入路徑上;連結時的「cannot find -lfoo」或「undefined reference」則是連結器告訴你函式庫不在函式庫路徑上(或根本沒被要求)。認出是這兩個搜尋裡哪一個失敗了,就正好知道該加哪個旗標。還要記得第三條、各自獨立的路徑:即使建構成功,共享函式庫在執行期還必須透過共享函式庫搜尋路徑被找到。

使用一個裝在標準目錄之外的函式庫: gcc -I/opt/foo/include main.c -L/opt/foo/lib -lfoo -o app ^ 引入路徑(標頭) ^ 函式庫路徑 ^ 連結 缺 -I -> 「foo.h: No such file or directory」 缺 -L -> 「cannot find -lfoo」

-I 把編譯器指向標頭檔;-L 把連結器指向函式庫;-l 指名要連結的函式庫。

引入路徑(編譯期)與函式庫路徑(連結期)都是建構期的搜尋,且與執行期的共享函式庫搜尋路徑是分開的。建構可能成功,但若共享函式庫不在那第三條執行期路徑上,程式仍可能無法啟動。

又稱
header search path-I and -L標頭搜尋路徑