天天看點

gcc cc c++ g++編譯入門

gcc cc c++ g++編譯入門

常用編譯選項:

-E:對源檔案做預處理操作。可以結合-o生成 .i格式的預處理檔案。

-S:将輸入檔案加工至編譯階段。可以處理源檔案即預處理檔案。

-c:将指定檔案加工至彙編階段,但不進行連結操作。

-C:阻止編譯器删除源檔案和頭檔案中的注釋。-o:用來指定輸出檔案。結合-E、-S、-c使用能實作編譯出不同格式的輸出檔案。

-o和命名的輸出檔案名之間隻能是空格,不能插入其他檔案名。

-std=編譯标準:這裡的編譯标準有很多的版本,比如C11,C++11,GNU17,GNU++17等。

簡單示例:

編譯時,gcc和cc是一樣的,c++和g++是一樣的。下面都以gcc為例:

1.gcc test.c

編譯test.c,會自動生成一個擴充名為.out的可執行檔案

2.gcc test.c –o test

編譯test.c檔案并生成一個檔案名為test的可執行檔案

3.gcc –o test test.c

編譯test.c檔案并生成一個檔案名為test的可執行檔案

4.gcc –o test test.c –I …/code/project/include/ -L …/code/project/lib –lxl64

這裡的第4點在下面【編譯選項補充說明】中會詳細解釋。

5.gcc –E test.c –o test.i

對test.c進行預處理操作并生成預處理檔案test.i

6.gcc –s test.i –o test.s

對test.i進行處理,生成彙編代碼檔案。

7.gcc –s test.c –o test.s

8.gcc –c test.c –o test.o

編譯test.c檔案并生成擴充名為.o的二進制對象檔案。

9.gcc test.o –o test

對二進制對象檔案test.o進行處理并生成可執行檔案test。

編譯選項補充說明:

①–I …/code/project/include/

(這裡-I是大寫的i)表示将…/code/project/include/目錄作為優先尋找頭檔案的目錄,是以尋找的順序是:…/code/project/include -> /usr/include -> /usr/local/include。這裡頭檔案如果分别放在不同的目錄中,隻需要重複使用“-I + 路徑”即可。

②-L …/code/project/lib

表示将…/code/project/lib/目錄作為優先尋找庫檔案的目錄,是以尋找的順序是:…/code/project/lib -> /usr/lib -> /usr/local/lib

③-lxl64

表示在上面的庫檔案目錄中尋找libxl64庫,程式test.c連結的庫的庫名是xl64。(這裡-lxl64前面的l是L的小寫,後面緊接着的是庫名,而不是庫檔案名。比如我們這裡連結的是一個EXCEL庫,這是個靜态庫,庫名是xl64,庫檔案名是libxl64.a。顯然,把庫檔案名的字首lib和字尾.a或.so去掉就是庫名了。)如果編譯指令中加入了” -static”表示尋找靜态庫。

④如果我們要用到一個第三方提供的庫libxl.a那麼我們隻要把這個庫檔案拷貝到程式的lib檔案夾下面,編譯時加上”-xl”,那麼就能用上libxl.a庫了。

⑤能用上庫還沒完,如果想要用到這個庫裡面的函數,我們還需要與這個庫配套的頭檔案,可以将庫檔案了解為“一種另類的源檔案”。即與這個庫配套的頭檔案裡包含了函數的聲明,而這個庫檔案裡就是這些函數的實作(即定義)。

gcc編譯順序:

在編譯器對工程進行編譯的時候,各個檔案之間存在着依賴關系,比如如果檔案a中include一個頭檔案b,我們就認為a依賴于b。這種依賴關系決定了編譯這兩個檔案的先後順序,即先編譯a後編譯b。

在gcc編譯指令中,檔案名出現的先後順序決定了編譯的先後順序。比如test.c包含了頭檔案libxl.h(在目錄…/project/include/下),如果編譯檔案中使用下面的指令:

gcc –I …/project/include/ -L … /project/lib –lxl64 –o test test.c

會顯示“對XXX未定義的引用”,這裡的’XXX’是出錯的函數名,比如xlCreateBookA。正确的用法應該是:

gcc –o test test.c –I …/project/include/ -L … /project/lib –lxl64

結語:總之,不管後面需要連結上多少庫或是包含多少頭檔案,它總是會将輸入檔案編譯成輸出檔案,是以像gcc –o test test.c這樣将輸入輸出檔案寫在前面總沒有錯。

繼續閱讀