Use Shared Library in Linux
執行檔如何尋找 shared library
ELF 將依賴的 shared library 存在 .dynamic
section 的 DT_NEED
欄位。
1 | $ readelf -d main |
如果是絕對路徑, dynamic linker 直接去該路徑存取 shared library。如果是相對路徑,則會依照以下順序到不同路徑下找 library:
LD_LIBRARY_PATH
環境變數指定的路徑.dynamic
section 中DT_RUNPATH
欄位記錄的路徑/etc/ld.so.conf
設定的路徑(實際上是讀取/etc/ld.so.cache
)/lib
/usr/lib
因為一個個搜尋路徑很慢,所以指令 ldconfig
除了更新系統中 library 的 SO-NAME soft link 外,還會將這些 SO-NAME 以特殊的形式存在 /etc/ld.so.cache
作為 cache 以加快搜尋。所以增加、刪除或更新 shared library 以及修改 /etc/ld.so.conf
後,都要執行 ldconfig
來更新 SO-NAME。
環境變數
幾個跟 dynamic linking 有關的常用環境變數。
LD_LIBRARY_PATH
臨時改變 shared library 的搜尋路徑,開發跟 debug 的時候很好用。
1 | $ LD_LIBRARY_PATH=/home/foo ls |
LD_PRELOAD
可以指定預先 load 的 shared library 或 object file,無論執行檔或使用的 shared library 有沒有依賴它。因為會使用先 load 的 shared library 的 symbol,所以可以用來改掉原本執行檔使用的 shared library,例如 standard C library。
1 | $ LD_PRELOAD=./libfoo.so ./main |
LD_DEBUG
可以看 dynamic linker 的 debug 訊息,設成 help
可以看可設定的值。
建立 & 安裝 shared library
build 出 shared library:
1 | $ gcc -shared -fPIC -Wl,-soname,mysoname -o library_name sources |
-shared
表示輸出 shared library,-fPIC
表示使用 PIC。-Wl
可以將參數傳給 linker。-soname
是指定 SO-NAME,如果不指定,shared library 預設沒有 SO-NAME,即無法用 ldconfig
建 soft link。shared library 的 SO-NAME 可以用 readelf -d
查看。
去除 symbol 資訊可以讓 shared library 檔案變小,常用在 release 時:
1 | $ strip libfoo.so |
安裝 shared library 通常是放到系統相關的路徑下,例如 /lib
、/usr/lib
等,然後執行 ldconfig
更新 soft link。不過通常安裝會用 make install
之類的指令,不需要手動 copy 跟 ldconfig
。
Related Posts & Ref
- ld-linux manual
- 《程式設計師的自我修養》ch8
- Dynamic Linking Basic
- Dynamic Linking PIC
- Dynamic Linking Relocation
- Shared Library Versioning
- Explicit Runtime Linking