庫檔案如何載入到記憶體?程式編譯如何找到這些庫檔案並載入?
阿新 • • 發佈:2019-02-06
一、庫檔案是怎麼載入進入記憶體的?
linux下的庫有兩種:靜態庫和共享庫(動態庫)。
二者的不同點在於程式碼被載入的時刻不同。 靜態庫的程式碼在編譯過程中已經被載入可執行程式,因此體積較大。共享庫的程式碼是在可執行程式執行時才載入記憶體的,在編譯過程中僅簡單的引用,因此程式碼體積較小。共享庫的好處是,不同的應用程式如果呼叫相同的庫,那麼在記憶體裡只需要有一份該共享庫的例項。
一般靜態庫的字尾是.a,它由原始檔編譯生成一堆.o,每個.o裡都包含這個編譯單元的符號表,然後用ar命令將很多.o轉換成.a形成。而動態庫的字尾為.so,由gcc加特定引數編譯產生。
二、程式編譯時如何找到這些庫檔案,並載入進來?
編譯器將先後搜尋:
1) elf檔案的DT_RPATH段(在編譯時指定目錄);
2) 環境變數LD_LIBRARY_PATH中指定的路徑;
3) /etc/ld.so.cache檔案列表;
4) /lib/,/usr/lib目錄;
如果找不到則會連結失敗。因此,如果出現找不到庫的情況,可以:
1)在編譯時-rpath指定目錄;
2)修改.bash_profile檔案在LD_LIBRARY_PATH中加入指定目錄;
3)修改/etc/ld.so.conf加入指定目錄,然後呼叫ldconfig重新生成/etc/ld.so.cache;
4)將動態庫放入/lib/,/usr/lib兩個預設路徑;