GCC編譯過程和動態靜態庫

2021-09-29 11:02:55 字數 2877 閱讀 4709

outline

[toc]

本質上來說庫是一種可執行**的二進位制形式,可以被作業系統載入記憶體執行。庫有兩種:靜態庫(.a、.lib)和動態庫(.so、.dll)。 windows上對應的是.lib .dll linux上對應的是.a .so

編譯過程:

之所以成為【靜態庫】,是因為在鏈結階段,會將彙編生成的目標檔案.o與引用到的庫一起鏈結打包到可執行檔案中。因此對應的鏈結方式稱為靜態鏈結。

試想一下,靜態庫與彙編生成的目標檔案一起鏈結為可執行檔案,那麼靜態庫必定跟.o檔案格式相似其實乙個靜態庫可以簡單看成是一組目標檔案(.o/.obj檔案)的集合,即很多目標檔案經過壓縮打包後形成的乙個檔案。靜態庫特點總結:

linux靜態庫命名規範,必須是」lib[your_library_name].a」:lib為字首,中間是靜態庫名,擴充套件名為==.a==

通過上面的流程可以知道,linux建立靜態庫過程如下:

首先,將**檔案編譯成目標檔案.o(staticmath.o)

gcc -c staticmath.c -o staticmath.o
然後,通過ar工具將目標檔案打包成.a靜態庫檔案注意帶引數-c,否則直接編譯為可執行檔案

ar -crv libstaticmath.a staticmath.o
使用生成靜態庫libstaticmath.alinux下使用靜態庫,只需要在編譯的時候,指定靜態庫的搜尋路徑(-l選項)、指定靜態庫名(不需要lib字首和.a字尾,-l選項)

gcc test.c -l ./ -lstaticmath
為什麼需要動態庫,其實也是靜態庫的特點導致。

空間浪費是靜態庫的乙個問題。

動態庫在程式編譯時並不會被連線到目標**中,而是在程式執行是才被載入。不同的應用程式如果呼叫相同的庫,那麼在記憶體裡只需要有乙份該共享庫的例項,規避了空間浪費問題。動態庫在程式執行是才被載入,也解決了靜態庫對程式的更新、部署和發布頁會帶來麻煩。使用者只需要更新動態庫即可,增量更新

建立動態庫

動態鏈結庫的名字形式為 lib***.so,字首是lib,字尾名為「.so」。

引用動態庫編譯成可執行檔案(跟靜態庫方式一樣):

g++ testdynamiclibrary.cpp -l../dynamiclibrary -ldynmath
然後執行:./a.out,發現竟然報錯了!!!

解決方法:首先使用export ld_library_path=.:$ld_library_path將當前目錄加入ld_library_path變數中。再次執行

編譯過程可以被細分為四個階段:

預處理( pre-processing )

編譯( compiling )

彙編( asse mbling )

鏈結( linking )gcc編譯過程

1)gcc 預處理階段:主要對包含的標頭檔案(#include )和巨集定義(#define,#ifdef … )進行處理。可以使用「gcc -e」 讓gcc 在預處理之後停止編譯過程,生成 *.i 檔案。

gcc -e hello.c -o hello.i
2)gcc 編譯階段:gcc 首先要檢查**的規範性,是否有語法錯誤等。以確定**實際要做的工作,在檢查無誤後,gcc 把**翻譯成組合語言。使用者可以使用-s 選項進行檢視,該選項只進

行編譯而不進行彙編,生成彙編**。

gcc -s hello.i -o hello.s
3)gcc 彙編階段:生成目標** .o ;有兩種方式:使用 gcc 直接從源**生成目標** gcc -c .s -o .o 以及使用彙編器從彙編**生成目標** as .s -o *.o

gcc -c hello.s -o hello.o 

as hello.s -o hello.o

也可以直接使用as .s, 將執行彙編、鏈結過程生成可執行檔案a.out, 可以像上面使用-o 選項指定輸出檔案的格式。

4)gcc 鏈結階段:生成可執行檔案;可以生成的可執行檔案格式有: a.out//,當然可能還有其它格式。

gcc hello.o 生成可執行檔案 a.out

gcc hello.o -o hello 生成可執行檔案 hello

GCC執行過程 gcc編譯靜態庫和動態庫

1 預處理階段 這個階段主要是處理原始檔中的 ifdef include和 define命令 命令 gcc e c o i 2 編譯階段 輸入的是中間檔案 i,編譯後生成組合語言檔案 s 命令 gcc s i o s 3 彙編階段 輸入的是彙編檔案 s,輸出的轉換生成的機器語言 o 命令 gcc c...

gcc編譯靜態庫和動態庫

一 動態鏈結庫 1.建立hello.so動態庫 cpp view plain copy print?include voidhello 編譯 gcc fpic shared hello.c o libhello.so include void hello 編譯 gcc fpic shared hel...

gcc編譯靜態庫 動態庫

今天,乙個同事編譯靜態庫,我也趁此機會在溫習一下,先google一下,然後在自己實驗。首先,在網上抄個例子,內容如下 建靜態庫 hellos.h ifndef hello s h define hello s h void prints char str endif hellos.c include...