只討論C語言。編程
「二進制代碼」——指被可以計算機直接執行的代碼(至於到底是操做系統層的命令,仍是CPU的機器指令,這裏不作深刻討論)。函數
通常是.h文件。編碼
頭文件的功能在於指示編程人員和編譯器:哪些函數能夠調用?這些函數應該怎麼調用(參數和返回值)?操作系統
頭文件不指示任何庫的存儲位置。全部須要的庫文件,應位於默認目錄或指定目錄。指針
通常是.o或.obj文件。code
中間代碼文件包括:接口
中間代碼文件的使命在連接完成後就結束了。進程
庫是一個文件。內存
庫的內容是造成庫的若干個中間代碼文件內容的集合。編譯器
庫和中間代碼文件的格式不同。
在Windows中被稱爲「靜態連接庫」。
靜態庫本質上是一個庫。在Linux中通常爲.a文件,在Windows中爲.lib文件。
假設若干個可執行文件在連接時使用了相同的靜態庫。實際上,靜態庫產生的二進制編碼被放進了可執行文件中。當這些可執行文件運行的時候,每一個可執行文件產生的進程,在內存中各有一份上述二進制編碼的副本。
靜態連接庫的使命在連接完成後就結束了。
同一個可執行文件產生的進程在內存中共用一份代碼段。這是Linux操做系統內存管理的特性,與靜態庫無關。
在Windows中被稱爲「動態連接庫」。
共享庫本質上是一個庫。在Linux中通常爲.so文件,在Windows中爲.dll文件。
假設若干個可執行文件在連接時使用了相同的共享庫。實際上,共享庫被可執行文件所引用,其二進制編碼並無被放進可執行文件中。當這些可執行文件運行時,被不一樣可執行文件使用的、同一個由共享庫產生的二進制編碼,在內存中只有一個副本。這個副本由全部可執行文件的全部進程共用。
靜態庫和共享庫的格式不一樣,二者的大小不具備可比性。
過程:由源文件生成中間代碼文件。
命令:gcc
選項:-c
過程:用中間代碼文件生成靜態庫。
命令:ar
選項:-r
過程:用中間代碼文件生成共享庫。
命令:gcc
選項:-shared -fPIC
注意:
-fPIC
,則生成「僞共享庫」。「僞共享庫」既不會被放入可執行文件,又不能被多個引用其的可執行文件共享。過程:用中間代碼文件和靜態庫(可無)生成可執行文件。
結果:可執行文件包含運行所須要的所有二進制代碼(包括被調用的系統函數的二進制代碼)。可執行文件通常能夠獨立運行。
命令:gcc
選項:-static
過程:用中間代碼文件、靜態庫(可無)和共享庫(可無)生成可執行文件。
結果:
命令:gcc
選項:無
靜態編譯 = 編譯 + 靜態連接
動態編譯 = 編譯 + 動態連接
可使用ldd命令來查看可執行文件所依賴的共享庫。
gcc命令的其餘經常使用選項:
-Wl,-rpath,./
:可執行文件運行時,將所在目錄加入共享庫的查找範圍。-include
:查找頭文件並加入編譯。-I
(大寫的i):將目錄的全部頭文件加入編譯。-l
(小寫的L):查找庫並加入編譯(後面緊跟庫的縮寫)。-L
:將目錄加入庫的查找範圍。應將-L
放在gcc命令的最後,不然某些時候會出錯。GCC會自動地將一些頭文件和庫加入編譯和連接:
/include/
、/usr/include/
/lib/
、/usr/lib/