天天看點

gcc編譯基本用法

gcc的基本用法

指令格式:gcc [選項] [檔案名]

編譯的四個階段:

-E:僅執行編譯預處理; 

-c:僅執行編譯操作,不進行連接配接操作;

-S:将C代碼轉換為彙編代碼; 

-o:指定生成的輸出檔案。

–c是使用GNU彙編器将源檔案轉化為目标代碼之後就結束,在這種情況下,隻調用了C編譯器(ccl)和彙編器(as),而連接配接器(ld)并沒有被執行,是以輸出的目标檔案不會包含作為Linux程式在被裝載和執行時所必須的包含資訊,但它可以在以後被連接配接到一個程式

-c表示隻編譯(compile),而不連接配接成為可執行檔案。生成同名字的 .o 目标檔案。通常用于編譯不包含主程式的子程式檔案。

gcc -c hello.c

生成:hello.o

-o選項用于說明輸出(output)檔案名,gcc将生成一個目标(object)檔案xx。

gcc hello.c -o xqf

或者:gcc -o xqf hello.c(順序可以調換)

輸出:xqf 為程式可執行檔案

-g 選項産生符号調試工具(GNU的gdb)所必要的符号資訊,插入到生成的二進制代碼中。表示編譯DEBUG版本。

想要對源代碼進行調試,就必須加入這個選項。當然,會增加可執行檔案的大小。

gcc study.c -o xqf

gcc -g study.c -o xqf_g

結果如下:(确實加了 -g 可執行檔案後變大了一點)

-rwxr-xr-x 1 root root 12393 Apr 19 21:39 xqf_g

-rwxr-xr-x 1 root root 11817 Apr 19 20:48 xqf

gcc 在産生調試符号時,同樣采用了分級的思路,開發人員可以通過在 -g 選項後附加數字1、2、3指定在代碼中加入調試資訊的多少。預設的級别是2(-g2),此時産生的調試資訊包括:擴充的符号表、行号、局部或外部變量資訊。

級别3(-g3)包含級别2中的所有調試資訊以及源代碼中定義的宏。

級别1(-g1)不包含局部變量和與行号有關的調試資訊,是以隻能夠用于回溯跟蹤和堆棧轉儲。

回溯追蹤:指的是監視程式在運作過程中函數調用曆史。

堆棧轉儲:則是一種以原始的十六進制格式儲存程式執行環境的方法。

-pedantic 選項:當gcc在編譯不符合ANSI/ISO C 語言标準的源代碼時,将産生相應的警告資訊

[objc] 

view plain​

 ​copy

#include <stdio.h>

int main()
{
long long int var = 1;
"hello world!\n");
return 0;
}      

gcc -pedantic -o mm study.c 

study.c: In function ‘main’:

study.c:5: warning: ISO C90 does not support ‘long long’

-Wall選項:使gcc産生盡可能多的警告資訊,警告資訊很有可能是錯誤的來源,特别是隐式程式設計錯誤,是以盡量保持0 warning。

用上面的代碼:study.c,編譯如下

gcc -Wall -o he study.c 

study.c: In function ‘main’:

study.c:5: warning: unused variable ‘var’

-Werror 選項:要求gcc将所有的警告當作錯誤進行處理。

同樣是上面的程式:study.c

gcc -Werror -o haha study.c

竟然沒有錯誤!! 

改一下study.c

#include <stdio.h>

[objc] 

view plain​

 ​copy

{
long long int var = 1;
"hello world!\n");
//return 0;
}      

再編譯:

gcc -Werror -o haha study.c

cc1: warnings being treated as errors

study.c: In function ‘main’:

study.c:4: error: return type of ‘main’ is not ‘int’

gcc -Wall -o hehe study.c

study.c:3: warning: return type of ‘main’ is not ‘int’

study.c: In function ‘main’:

study.c:5: warning: unused variable ‘var’

是以說:并不是所有的warning都變成 error。具體的,後面再深究。

-fPIC選項。PIC指Position Independent Code。共享庫要求有此選項,以便實作動态連接配接(dynamic linking)。

-I 選項(大寫的 i):向頭檔案搜尋目錄中添加新的目錄。

1、用#include"file"的時候,gcc/g++會先在目前目錄查找你所制定的頭檔案,如

果沒有找到,他回到預設的頭檔案目錄找。

如果使用-I制定了目錄,他會先在你所制定的目錄查找,然後再按正常的順序去找.

2、用#include<file>,gcc/g++會到-I制定的目錄查找,查找不到,然後将到系統的缺

省的頭檔案目錄查找

例如:

gcc –I /usr/dev/mysql/include test.c –o test.o

-l選項(小寫的 l)說明庫檔案的名字。如果庫檔案為 libtest.so, 則選項為: -ltest

-L選項說明庫檔案所在的路徑。

例如:-L.(“.”表示目前路徑)。

      -L/usr/lib (“/usr/lib” 為路徑。注:這裡的路徑是絕對路徑)

如果沒有提供 -L選項,gcc 将在預設庫檔案路徑下搜尋

-shared選項指定生成動态連接配接庫,不用該标志外部程式無法連接配接。相當于一個可執行檔案, 生成 .so 檔案

-static 選項,強制使用靜态連結庫,生成 .a 檔案。因為gcc在連結時優先選擇動态連結庫,隻有當動态連結庫不存在時才使用靜态連結庫。加上該選項可強制使用靜态連結庫。

.so 和 .a 的差別:運作時動态加載,編譯時靜态加載

具體的例子在文章:linux so檔案生成與連結中有講。

多個檔案一起編譯:

檔案:test_a.c  test_b.c

兩種編譯方法:

1、一起編譯

gcc test_a.c test_b.c -o test

2、分别編譯各個源檔案,之後對編譯後輸出的目标檔案連結

gcc -c test_a.c

gcc -c test_b.c

gcc -o test_a.o test_b.o -o test

比較:第一中方法編譯時需要所有檔案重新編譯;第二種植重新編譯修改的檔案,未修改的不用重新編譯