GCC生成動態連結庫(.so檔案):-shared和-fPIC選項

2020-07-16 10:05:28
Linux 下動態連結庫(shared object file,共用物件檔案)的檔案字尾為.so,它是一種特殊的目標檔案(object file),可以在程式執行時被載入(連結)進來。使用動態連結庫的優點是:程式的可執行檔案更小,便於程式的模組化以及更新,同時,有效記憶體的使用效率更高。

GCC 生成動態連結庫

如果想建立一個動態連結庫,可以使用 GCC 的-shared選項。輸入檔案可以是原始檔、組合檔案或者目標檔案。

另外還得結合-fPIC選項。-fPIC 選項作用於編譯階段,告訴編譯器產生與位置無關程式碼(Position-Independent Code);這樣一來,產生的程式碼中就沒有絕對地址了,全部使用相對地址,所以程式碼可以被載入器載入到記憶體的任意位置,都可以正確的執行。這正是共用庫所要求的,共用庫被載入時,在記憶體的位置不是固定的。

例如,從原始檔生成動態連結庫:

$ gcc -fPIC -shared func.c -o libfunc.so

從目標檔案生成動態連結庫:

$ gcc -fPIC -c func.c -o func.o
$ gcc -shared func.o -o libfunc.so

-fPIC 選項作用於編譯階段,在生成目標檔案時就得使用該選項,以生成位置無關的程式碼。

GCC 將動態連結庫連結到可執行檔案

如果希望將一個動態連結庫連結到可執行檔案,那麼需要在命令列中列出動態連結庫的名稱,具體方式和普通的原始檔、目標檔案一樣。請看下面的例子:

$ gcc main.c libfunc.so -o app.out

將 main.c 和 libfunc.so 一起編譯成 app.out,當 app.out 執行時,會動態地載入連結庫 libfunc.so。

當然,必須要確保程式在執行時可以找到這個動態連結庫。你可以將連結庫放到標準目錄下,例如 /usr/lib,或者設定一個合適的環境變數,例如 LIBRARY_PATH。不同系統,具有不同的載入連結庫的方法。