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

動態/共享函式庫(.so/.dll/.dylib)

動態或共享函式庫是另一種函式庫:它不在建構時把程式碼複製進你的程式,而是讓程式碼留在磁碟上一個獨立的檔案裡,於程式執行時才被載入並接到你的程式。可以這樣想——它不像把書頁影印進你的報告,而比較像你的報告寫著「請見書架上那本參考書」——書留在原地,而許多報告都能指向同一份副本。

這些檔案有依平台而異的名稱:Linux 上是 .so(shared object,共享物件)、macOS 上是 .dylib、Windows 上是 .dll(dynamic-link library,動態連結函式庫)。當你把程式建構成對應某個共享函式庫時,你的可執行檔並不含那個函式庫的程式碼;它只含一筆記錄,記著它需要哪些函式庫、期待從它們取得哪些函式。當程式被啟動時,作業系統的動態連結器找到那些函式庫檔,把它們映射進記憶體,並把呼叫接好。因為函式庫存在於一處,許多執行中的程式能共享記憶體裡同一份副本。

為什麼重要:共享函式庫省下磁碟與記憶體(一份副本服務眾多程式),並允許更新——在共享函式庫裡修一個臭蟲,每個用到它的程式下次執行時都受益,無需重建。代價是執行期相依:若正確的函式庫缺失、或找到錯誤的版本,程式就無法啟動。那惡名昭彰的徵兆,是啟動時出現像「cannot open shared object file」的錯誤,或在 Windows 上彈出缺少 DLL 的對話框——有時被戲稱為「DLL 地獄」。

建構一個共享函式庫,以及用到它的程式: gcc -fPIC -c util.c -o util.o gcc -shared util.o -o libutil.so gcc main.c -L. -lutil -o app 現在 app 在執行期需要 libutil.so 存在,而不只是在建構期。

函式庫的程式碼留在 libutil.so 裡;程式每次執行時都載入並連結到它。

對應某共享函式庫建構出來的程式,若該函式庫在執行期缺失或找到了錯誤版本,就會無法啟動,即使它編譯與連結都沒問題。這個執行期相依,正是它與靜態函式庫最主要的實務差異。

又称
shared libraryshared objectDLL共享函式庫動態連結函式庫