Linux程式設計——GCC的使用
工欲善其事, 必先利其器。而gcc是Linux系統下最常見的編譯器,本文學習gcc 編譯器的使用。
gcc 支援編譯的一些原始檔字尾名
gcc 編譯程式的流程
Linux的可執行檔案並沒有像 Windows 那樣有明顯的.exe字尾名, 只需向其分配x(可執行)許可權即可 sudo chmod +x excutefile
作為Linux程式設計師,我們可以讓gcc在編譯的任何階段結束,以便檢查或使用該階段的輸出(這個很重要)
用 gcc 編譯一個經典 C 程式
開啟的vim環境中輸入i進入編輯模式,輸入以下程式碼:
// filename: hello.c #include <stdio.h> int main(int argc, char **argv) { printf("Hello, Linux!"); } /** *在Terminal開啟後的介面中輸入:$gcc hello.c -o hello *如果沒有error,說明編譯成功,將會在當前目錄生成一個可執行檔案 hello *繼續輸入:./hello 就會執行該程式,在bash上打印出 Hello, Linux! **/
儲存為hello.c檔案
gcc hello.c -o hello --- 第二個hello為檔名,名字任意取定(但是不能違反bash的規則)gcc hello.c -o
, 但是作為一名優秀的程式設計師還是取個有意義的名字吧!
從程式設計師的角度來看,一個簡單的-o選項可以省略很多中間步驟一次性輸出可執行檔案; 但從編譯器的角度來看,這條命令的背後是一系列的繁雜的工作。
gcc 到底揹著我們做了什麼
首先gcc會呼叫預處理程式cpp,由它負責展開在源程式中定義的巨集(上例:#include <stdio.h>),向其中插入#include語句所包含的內容(原地展開stdio.h包含的程式碼)
在終端中輸入
$ gcc -E hello.c -o hello.i
還記得.i字尾嗎?hello.i這是一個經過前處理器處理之後的C原始檔,在bash試試這個命令,然後用vim開啟它。
gcc的-E引數可以讓gcc在預處理結束後停止編譯過程。
第二步,將hello.i編譯為目的碼,gcc預設將.i檔案看成是預處理後的C語言原始碼,因此它會直接跳過預處理,開始編譯過程。
$ gcc -c hello.i -o hello.o
同樣,用vim開啟.o檔案看看和.i .c檔案有什麼不同?應該是一片亂碼,是吧?(它已經是二進位制檔案了)
請記住,gcc預處理原始檔的時候(第一步),不會進行語法錯誤的檢查。
語法檢查會在第二步進行,比如花括號不匹配、行末尾沒有分號、關鍵字錯誤......
第三步,gcc聯結器將目標檔案連結為一個可執行檔案,一個大致的編譯流程結束
gcc hello.o -o hello
gcc 編譯模組化的程式
現在很多軟體都是採用的模組化開發,通常一個程式都是有很多個原始檔組成,相應的就形成了多個編譯單元。gcc能夠很好的處理這些編譯單元,最終形成一個可執行程式
程式碼編輯和輸入參考上述使用vim程式輸入,並在Terminal介面使用gcc進行編譯。
// hello.h
extern void print();
這是個標頭檔案,將會在hello_main.c中呼叫
// hello_print.c
#include <stdio.h>
void print()
{
printf ("Hello, Linux\n");
}
// hello_main.c
#include "hello.h"
void print();
int main(int argc, char **argv)
{
print();
}
// Terminal中 $gcc hello_print.c hello_main.c -o hello 進行編譯
// 將會打印出 Hello, Linux
以上的gcc hello_print.c hello_main.c -o hello
可以看成是執行了一下3條命令
$ gcc -c hello_print.c -o hello_print.o
$ gcc -c hello_main.c -o hello_main.o
$ gcc hello_print.o hello_main.o -o hello