linux中gcc的基本使用

1.gcc

在這裏插入圖片描述

GNU編譯器套件(GNU Compiler Collection)原名為GNU C語言編譯器GNU C Compiler),因為它原本只能處理C語言。GCC在發佈後很快地得到擴展,包括C、C++、Objective-C、Fortran、Java、Ada和Go語言的前端,也包括了這些語言的庫(如libstdc++、libgcj等等)。GCC的初衷是爲GNU操作系統專門編寫的一款編譯器。GNU系統是徹底的自由軟件。此處,“自由”的含義是它尊重用戶的自由。

GUN 編譯器套件包含多種前端處理器,以翻譯各種不同語言。當然,我們重點討論的是基於C語言的前端處理器 GCC。

GCC 也是一種多目標(multitarget)編譯器;換句話說,它通過使用可互換的後端處理器,爲多種不同的計算機架構生成相應的可執行程序。

GCC 不僅支持C的許多“方言”,也可以區別不同的C語言標準;也就是說,可以使用命令行選項來控制編譯器在翻譯源代碼時應該遵循哪個C標準。例如,當使用命令行參數-std=c99啓動 GCC 時,編譯器支持 C99 標準。

GUN99 c99

1.1 安裝

  • 安裝命令

    sudo apt install gcc g++
    
    # 在Linux中寫程序: gcc版本 > 4.8.5
    
  • 查看版本

    gcc -v/--version
    g++ -v/--version
    
  • gcc與g++有什麼區別?

    gcc和g++都是GNU(組織)的一個編譯器。

    • 誤區一:gcc只能編譯c代碼,g++只能編譯c++代碼。兩者都可以,但是請注意:

      • 後綴爲.c的,gcc把它當作是C程序,而g++當作是c++程序;
      • 後綴爲.cpp的,兩者都會認爲是c++程序,C++的語法規則更加嚴謹一些。
      • 編譯階段,g++會調用gcc,對於c++代碼,兩者是等價的,但是因爲gcc命令不能自動和C++程序使用的庫聯接,所以通常用g++來完成鏈接,爲了統一起見,乾脆編譯/鏈接統統用g++了,這就給人一種錯覺,好像cpp程序只能用g++似的。
    • 誤區二:gcc不會定義__cplusplus宏,而g++會

      • 實際上,這個宏只是標誌着編譯器將會把代碼按C還是C++語法來解釋
      • 如上所述,如果後綴爲.c,並且採用gcc編譯器,則該宏就是未定義的,否則,就是已定義。
    • 誤區三:編譯只能用gcc,鏈接只能用g++

      • 嚴格來說,這句話不算錯誤,但是它混淆了概念,應該這樣說:編譯可以用gcc/g++,而鏈接可以用g++或者gcc -lstdc++
      • gcc命令不能自動和C++程序使用的庫聯接,所以通常使用g++來完成聯接。但在編譯階段,g++會自動調用gcc,二者等價

1.2 gcc 工作流程

GCC 編譯器在編譯一個C語言程序時需要經過以下 4 步:

  1. 將C語言源程序預處理,生成.i文件。
    • 頭文件展開
    • 宏替換
      • define NUM 10
      • int a = NUM
    • 註釋刪除
    • xxx.c -> xxx.i
    • gcc -E xxx.c -o xxx.i
  2. 預處理後的.i文件編譯成爲彙編語言,生成.s文件。
    • xxx.i -> xxx.s (得到彙編文件)
    • gcc -S xxx.i -o xxx.s
  3. 將彙編語言文件經過彙編,生成目標文件.o文件。
    • xxx.s -> xxx.o (二進制文件)
    • gcc -c xxx.s -o xxx.o
  4. 將各個模塊的.o文件鏈接起來生成一個可執行程序文件。
    • xxx.o -> 可執行程序 (二進制的)
    • gcc xxx.o -o xxx

在這裏插入圖片描述

1.3 gcc常用參數選項

gcc編譯選項 選項的意義
-E 預處理指定的源文件,不進行編譯
-S 編譯指定的源文件,但是不進行彙編
-c 編譯、彙編指定的源文件,但是不進行鏈接
-o [file1] [file2] / [file2] -o [file1] 將文件 file2 編譯成可執行文件 file1
-I directory 指定 include 包含文件的搜索目錄
-g 在編譯的時候,生成調試信息,該程序可以被調試器調試
-D 在程序編譯的時候,指定一個宏
-w 不生成任何警告信息
-Wall 生成所有警告信息
-On n的取值範圍:0~3。編譯器的優化選項的4個級別,-O0表示沒有優化,-O1爲缺省值,-O3優化級別最高
-l 在程序編譯的時候,指定使用的庫
-L 指定編譯的時候,搜索的庫的路徑。
-fPIC/fpic 生成與位置無關的代碼
-shared 生成共享目標文件。通常用在建立共享庫時
-std 指定C方言,如:-std=c99,gcc默認的方言是GNU C

參數 -D 使用場景: 程序調試的時候使用, 通過-D指定的宏打開log輸出

#include <stdio.h>
//#define DEBUG
int main()
{
    int a = 10;
#ifdef DEBUG
    printf("我是一個程序猿, 我不會爬樹...\n");
#endif
    for(int i=0; i<3; ++i)
    {
        printf("hello, GCC!!!\n");
    }
    return 0;
}

默認編譯第7行代碼不輸出, 如果想要輸出這句話, 可以使用-D

參數 -On 優化程序, 有4個級別
n 取值範圍: 0-3
O0 -> 不優化, O1 -> 默認的級別, O3 -> 最高級別
最簡單的例子:

int a, b, c, d;
a = 10;
b = a;
c = b;
d = c;

// 優化:
b = 10;
c = 10;
d = 10;

參數 -std , 指定編譯器規範
c最早的標準:c89
c99開始支持現在的書寫習慣

int a = 10;
func();
int b  =5;
for(int i=0; i<5; ++i)

gcc -std=c99/gnu99 test.c -o test

-DDEBUG 參數和值直接的空格可有可無

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