ubuntu下用GNU(gcc/g++)進行編譯

主要介紹在ubuntu下利用GNU進行編譯的過程和部分指令的含義, 幫助新手小白入門。

(Part A.)寫在前面的話

step1. 常說到的GNU、gcc和g++什麼關係?

關於這個可能會困擾到你的問題,推薦gcc與g++的關係,博主給出了簡短而詳實的解釋。

總結就是兩句話:1. gcc是GNU的簡稱;2. g++包含gcc。

step2. 安裝GNU的方案網上一大堆,這裏也推薦一篇是我之前自己總結的ubuntu下CPP開發與GNU的安裝

 

(Part B.) 下面介紹下在ubuntu下利用g++編譯cpp文件

step1. 寫一個簡單的測試程序,當然要用到hello world啦!  命名爲test.cpp

#include <iostream>

int main()
{
	std::cout << "Hello World!" << std::endl;

	return 1;
}

step2. 利用下述指令可以直接生成一個可執行文件

$ g++ test.cpp -o test

然後執行就可以看到打印結果啦

$ ./test
Hello World!

 

(Part C.)過程詳解

上面Part B部分一行指令直接由.cpp源碼文件生成了可執行文件(僅有文件名,沒有擴展名)。這一過程主要包括四個階段:預處理、編譯、彙編、鏈接,下面分別對各個過程進行介紹。

step 0. 首先明確一下g++的命令格式

g++ [指令] 待處理文件 [指令] 輸出文件

step 1. 預處理

預處理主要是針對文件中#include和宏指令進行處理的,處理的方式就是將這些指令對應的內容插入到其對應的地方。指令語句爲:

$ g++ -E test.cpp -o test.i

其中,-E是指的調用預處理指令,用來處理test.cpp文件,處理的目的是生成一個.i的文件,我們用-o test.i來指明(對於cpp的預處理文件,也可以是.ii的後綴)。運行上述指令後,會在同級目錄下生成test.i預處理文件。如下:

#include <iostream>
#define NUM 100

int main()
{
	std::cout << NUM << std::endl;	
	std::cout << "Hello World!" << std::endl;
	return 1;
}

上面一段代碼是我們的實驗代碼,運行預處理指令後,會將#include和#define的內容插入到.i文件中,如下圖所示:

宏指令NUM已經被100代替, 同時注意到main函數是從兩萬八千多行開始的, 之前的代碼,其實就是#include的內容。

step 2. 編譯

編譯就是對預處理文件.i進行詞法分析,語法分析,語義分析,最終產生彙編文件.s,可以簡單理解爲將C代碼“翻譯”成彙編代碼。

$ g++ -S test.i -o test.s

 運行上述指令後,會在同級目錄下生成test.s彙編文件。

step 3. 彙編

彙編是將彙編代碼翻譯成機器可執行的指令,生成目標文件.o。整個過程較爲簡單,幾乎只是按照彙編指令和機器指令進行一一翻譯。

$ g++ -c test.c -o test.o

運行上述指令後,會在同級目錄下生成test.o目標文件。

step 4.鏈接

鏈接就是將全部的目標文件按照一定規則連接在一起,共同生成可執行文件的過程。

$ g++ test.o -o test

其中,鏈接指令是沒有指令關鍵字的,所以g++後面直接鍵入需要連接的目標文件。之後會生成test可執行文件,一般可執行文件是沒有後綴的。

step 5. 運行

運行可執行文件,即可得到預料的輸出結果,如下所示。

$ ./test
100
Hello World!

 

(Part D. )總結

四個過程:預處理(.i文件) -> 編譯(.s文件) -> 彙編(.o文件) -> 鏈接(可執行文件)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章