gcc是Linux/Unix上非常強大的C語言編譯器。并且如今也支持C++的編譯。與VC不同,gcc是完全跨平臺的。到目前為止很多工具都使用gcc作為其編譯環(huán)境。使用gcc編譯器,就是學習它眾多的編譯參數。就是用連字符-連接的參數。
編譯的C語言源文件
直接在gcc后面加上要編譯的C語言源文件
//main.c
#include <stdio.h>
int main(int argc, char const *argv[])
{
printf("程序猿編碼\n");
return 0;
}
編譯輸出:

gcc main.c這種默認的情況下會生成一個名為a.out的可執(zhí)行文件。
注意:在Linux系統(tǒng)下,后綴名真的不是很重要的事,甚至沒有后綴名都可以。這些都沒有關系,比如你寫一個shell的腳本,其實加不加后綴都是可以運行的。此時后綴的目的是為了便于用戶管理和區(qū)分文件而已。By the way,如果你執(zhí)行./main.c,那么系統(tǒng)會把它也當做shell腳本來運行,根本不管什么后綴。
-o選項
最常用的編譯選項,用于指定要生成的可執(zhí)行文件的名稱。例如:
gcc -o main main.c
需要體會的一點是:gcc對于參數的位置無要求!比如也可以寫作。
gcc main.c -o main
唯一要注意的就是-o后面一定要緊跟要生成的可執(zhí)行文件名。
編譯出的可執(zhí)行文件,在Windows下就是exe。但Linux下,后綴名無限制。一般不指定后綴就可以了。
-g選項
用于給生成的可執(zhí)行文件加上調試信息,只有這樣才可使用gdb調試。
gcc -g -o main main.c
同樣參數-g的也可寫在hello.c后面。
想要了解GDB調試可以參考《GDB調試入門,看這篇就夠了!》
-c 選項
終止鏈接器的運行,輸出文件為匯編后的目標文件*.o
#include <stdio.h>
int main(int argc, char const *argv[])
{
printf("程序猿編碼\n");
return 0;
}
編譯輸出:

想要知道生成可執(zhí)行程序過程為成哪四個步驟《參考GCC編譯過程(預處理->編譯->匯編->鏈接)》
-O2 選項
對源碼進行優(yōu)化,使編譯出的程序,運行效率更高。注意是大寫的英語字母O,不是阿拉伯數字0
gcc -O2 main.c -o main
O是Optimize之意。同樣還有O1,但是優(yōu)化效果不如O2,缺省是O0
-D 選項
給編譯的源文件傳遞一個宏。
gcc main.c -DHELLO -DWORLD=10
相當于:
//在main.c中定義了
# define HELLO
# define WORLD 10
-E 選項
gcc -E 指示gcc對源代碼進行預處理,結果直接輸出到終端。
靜態(tài)鏈接庫
靜態(tài)鏈接庫是后綴名為.a的文件。它有多個后綴為你.o的目標文件組成。使用-c參數可以使編譯在鏈接前終止,所以生成的是源文件對應的目標文件。
gcc -c test1.c test2.c
ar rcs libvector.a test1.o test2.o
ar是archive檔案的縮寫。上面命令生成了.a的靜態(tài)庫文件,在鏈接時,要如下:
gcc -c main.c
gcc -static -o p2 main.o ./libvector.a
編譯靜態(tài)庫時先使用-rcs選項,再利用ar工具產生,然后把一些文件可重定位文件打包在一起。靜態(tài)庫的介紹請《參考gcc 靜態(tài)庫制作之ar命令使用》
動態(tài)鏈接庫
后綴名為.so的是動態(tài)共享鏈接庫文件,其中的s就是shared共享的意思,如下命令:
gcc -shared -fPIC -o libvector.so test1.c test2.c
gcc -o p2 main.c ./libvector.so
完成了生成.so以及鏈接.so的操作。-fPIC指示生成與位置無關的代碼。
-l 選項
-lm選項,在編譯時會進入系統(tǒng)庫路徑搜索,鏈接“數學庫”。常用的庫會自動鏈接,無需指定。
系統(tǒng)缺省的庫路徑為:/lib、/usr/lib、/usr/local/lib、/usr/lib64。
來看看個例子,將二進制轉換為十進制的程序:
#include <stdio.h>
#include <math.h>
int binaryToDecimal(long binarynum){
int decimalnum = 0, temp = 0, remainder;
while (binarynum!=0){
remainder = binarynum % 10;
binarynum = binarynum / 10;
decimalnum = decimalnum + remainder*pow(2,temp);
temp++;
}
return decimalnum;
}
int main(int argc, char const *argv[])
{
long binarynum;
printf("Enter a binary number: ");
scanf("%ld", &binarynum);
printf("Equivalent decimal number is: %d", binaryToDecimal(binarynum));
printf("\n");
return 0;
}
編譯輸出:

在這個程序中,我們創(chuàng)建了一個用戶定義的函數binaryToDecimal(),用于二進制到十進制的轉換。該程序將二進制數(由用戶輸入)作為輸入,并使用函數將其轉換為十進制數。
在程序中,有帶有數學函數 pow,通過 man手冊打開pow庫函數。則會看到需要連接 -lm選項。

-L選項
如果該庫不在系統(tǒng)缺省路徑下(比如第三方庫,自定義的庫),還要使用-L選項指定路徑。
-L/home/share/mylib
使用c99標準編譯
如果想讓編譯器以c99編譯可以使用:
gcc -std=c99 main.c
包含非系統(tǒng)的頭文件
-I選項指定頭文件的位置。一般和L選項聯用。比如:
gcc mysql_test.c -I /usr/local/include/mysql -L/usr/local/lib -lmysqlclient -o test
-M檢查所需的頭文件
gcc -M main.c
以makefile風格顯示源文件的依賴關系。會列出所有包含的所有頭文件。會列出標準庫的頭文件。
如果不想顯示標準庫的頭文件,請使用 -MM 選項代替 -M。

歡迎關注公眾號【程序猿編碼】,添加本人微信號(17865354792),回復:領取學習資料。或者回復:進入技術交流群。網盤資料有如下:
