前言:
本文主要認(rèn)識與學(xué)習(xí)Linux
環(huán)境下常用的編譯器——gcc
(編譯C
代碼)/g++
(編譯C++
代碼)的常用指令等、程序?qū)崿F(xiàn)的兩大環(huán)境、動態(tài)庫與靜態(tài)庫的理解等。
一.程序?qū)崿F(xiàn)的兩個環(huán)境
任何一個C
程序的實現(xiàn)都要經(jīng)過翻譯環(huán)境與執(zhí)行環(huán)境。
在翻譯環(huán)境中又分為4個部分,預(yù)編譯、編譯、匯編與鏈接。在各個階段主要完成的任務(wù)有:
- 預(yù)編譯(預(yù)處理):頭文件的包含、注釋的刪除、#define符號的替換
- 編譯:將C語言代碼轉(zhuǎn)化為匯編代碼
- 匯編:把匯編指令轉(zhuǎn)化為二進制指令
- 鏈接:合并符號表和段表,生成可執(zhí)行程序
二.gcc如何完成
通過gcc
指令的不同選項可查看各階段所形成的文件
格式:gcc [選項] [目標(biāo)文件名] -o [生成文件名]
首先在Test.c
文件中寫好C
代碼:
//Test.c
#include<stdio.h>
#define N 100
//這是一段注釋.....
int main()
{
int n = 0;
printf("Hello World\n");
printf("%d\n", n + N);
return 0;
}
1.預(yù)處理
查看 Test.c
預(yù)處理后的結(jié)果,-E
選項的作用是讓 gcc
在預(yù)處理結(jié)束后停止編譯過程;-o
的作用是將預(yù)處理后的內(nèi)容保存到 test.i
文件中
gcc -E Test.c -o test.i
如圖所示,預(yù)處理階段進行了頭文件包含、注釋的刪除、#define的替換等。
2.編譯
接下來將剛剛生成的 test.i
進行編譯,并在編譯之后停下來,將結(jié)果寫入 test.s
中。gcc
所用選項為 -S
。
gcc -S test.i -o test.s
我們雖然可能沒學(xué)習(xí)過匯編語言,但依舊隱約認(rèn)識到這些就是匯編代碼;可見編譯階段就是將C代碼翻譯為匯編指令。
3.匯編
gcc
所用選項為 -c
;-o
將結(jié)果寫入到test.o
中。
gcc -c test.s -o test.o
正如我們所見,匯編完成之后都這這樣的亂碼。其實匯編之后,生成的文件為二進制文件,是用來給計算機看的,咱們已經(jīng)看不懂了。
4.鏈接
編譯完成之后就進入了鏈接階段,鏈接完成之后就會生成可執(zhí)程序 test
了。
gcc test.o -o Test
但是關(guān)于鏈接,我們需要知道它在鏈接什么。
比如為什么沒有定義過函數(shù) printf
、return
…等,但卻可以使用它的功能?
其實,系統(tǒng)把這些函數(shù)的實現(xiàn)都被做到名為
libc.so.6
的庫文件中去了,在沒有特別指定時,gcc
會到系統(tǒng)默認(rèn)的搜索路徑/usr/lib
下進行查找,也就是鏈接到libc.so.6
庫函數(shù)中去,這樣就能實現(xiàn)函數(shù)printf
了,而這也就是鏈接的作用。
三.動態(tài)庫與靜態(tài)庫
函數(shù)庫一般分為動、靜態(tài)庫兩種。二者的區(qū)別可以理解為私有與公共的區(qū)別。就好比我們需要讀一本《C和指針》,有兩種方法可以選。一種是自己買一本,只有自己可以用,用起來還挺方便,缺點就是得花錢;第二種是去圖書館借書,圖書館的資源被所有人共享。
gcc
進行函數(shù)庫的鏈接時可選擇靜態(tài)鏈接或者動態(tài)鏈接。
- 靜態(tài)鏈接就類似于自己買書看,只給自己看同時還費錢(浪費內(nèi)存),靜態(tài)鏈接時會將庫文件的代碼全部加入到可執(zhí)行文件中,因此生成的文件比較大。
- 動態(tài)鏈接類似于去圖書館借書。函數(shù)庫就放在某個固定的地方,哪個程序想去使用就去自己去加載它。
Linux
下gcc
默認(rèn)使用動態(tài)鏈接。
對比下二者生成的文件大小
//采用靜態(tài)鏈接
gcc -static Test.c -o Test_static
//默認(rèn)采用動態(tài)鏈接
gcc Test.c -o Test
若在靜態(tài)鏈接時出錯,可能是因為你的Linux
沒有安裝C語言的靜態(tài)庫,須手動安裝。
//安裝C語言靜態(tài)庫
yum install -y glibc-static
由此可見靜態(tài)鏈接比動態(tài)鏈接生成的可執(zhí)行文件大。
四.gcc常用選項
以下是gcc編譯器常用選項匯總
-E 只激活預(yù)處理,這個不生成文件,你需要把它重定向到一個輸出文件里面;
-S 編譯到匯編語言不進行匯編和鏈接;
-c 編譯到目標(biāo)代碼;
-o 文件輸出到 文件;
-static 此選項對生成的文件采用靜態(tài)鏈接;
-g 生成調(diào)試信息。GNU 調(diào)試器可利用該信息;
-shared 此選項將盡量使用動態(tài)庫,所以生成文件比較小,但是需要系統(tǒng)由動態(tài)庫.;
-O0
-O1
-O2
-O3 編譯器的優(yōu)化選項的4個級別,-O0表示沒有優(yōu)化,-O1為缺省值,-O3優(yōu)化級別最高;
-w 不生成任何警告信息;
-Wall 生成所有警告信息。文章來源:http://www.zghlxwxcb.cn/news/detail-541433.html
本文到此結(jié)束,碼文不易,還請多多支持哦!文章來源地址http://www.zghlxwxcb.cn/news/detail-541433.html
到了這里,關(guān)于Linux的編譯器——gcc/g++(預(yù)處理、編譯、匯編、鏈接)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!