Linux下gcc編譯器的使用總結

一、基本選項
GCC是開源軟件中的一個頂級的C編譯器
gcc -Wall -o hello hello.c
-W是打開警告選項
-all打開所有
-v顯示詳細信息
-c只編譯產生目標文件,不產生可執行文件,就是產生.o文件

GCC不存在鏈接次序的問題,但最好遵守定義在後、調用在前的規則

有效的管理龐大的項目,有make


二、鏈接外部庫
標準庫:
gcc -Wall main.c /usr/lib/libm.a -o calc
gcc -Wall main.c -lm -o calc

-lm相當於libm.a (僅對標準庫)
使用頭文件<math.h>時使用此選項
-I選項指明瞭在哪個目錄下搜索頭文件
gcc -Wall -I/opt/mysoft/include -o main

-L指定了搜索的庫文件目錄

指定環境變量

如果既定義了-I,-L和環境變量,則優先找-I和-L,如果沒有找到,就去找環境變量,如果環境變量還沒有找到,則去找系統路徑

推薦-I,-L這種方法

三、創建自己的庫
ar 命令:把一堆的目標文件.o合成一個庫文件
ar cr libName.a file1.o file2.o ... filen.o
查看一庫裏有多少個目標文件
ar t libName.a

gcc -Wall -c main.c libFunc.a -o hello
-c main.c 和 libFunc.a的順序不能交換


gcc -Wall main.c -L. -lfunc -o hello
gcc -Wall main.c -L/home/baiyun/study/mysoft -lfunc -o hello

四、動態庫和靜態庫
.lib .a
.dll .so

用ldd a.out來查看 a.out需要哪些動態庫



五、C語言標準
gcc如果不加選項,則使用 GNU標準編譯,加-ansi,-std,最新版是-std=c99

gcc -Wall -ansi -D_GNU_SOURCE pi.c -o pp
使用標準C來編譯 ,但鏈接時候使用GNU的庫

-ansi -pedantic兩個參數連用,就嚴格按照標準C來調用


六、-Wall選項
-Wall是以下的集合
'-Wcomment' (用來檢測註釋是否嵌套了)
'-Wformat'  (用來檢測printf和scanf中傳的值的類型是否正確)
'-Wunused'   (用來檢測是否聲明一個變量但沒有被使用)
'-Wimplicit' (用來檢測是否一個使用了一個沒有被聲明的函數)
'-Wreturn-type' (用來檢測一個函數聲明有返回值,但是實現中卻沒有返回值)
'-W'
'-Wcnversion'
'-Wshadow'
'-Wcast-qual'
'-Wwrite-strings'
'-Wtraditional'

七、預處理
gcc -Wall -DTEST main.c -o ouput
-D後面跟預處理定義的宏

要想給預定義宏加值,則用如下:
gcc -Wall -DNUM=123 main.c o ouput
gcc -Wall -DNUM="1 + 2" main.c o ouput
如果不給宏設值,則默認值是1

如果不想編譯,只需要看預處理的過程,則用-E參數(以下兩種都 可以)
gcc -E test.c
gcc -Wall -c -save-temps test.c  產生.i和.s文件 ,.s文件是彙編語言,.i文件是預處理結果,.i文件是C語言的預處理結果,.ii是 C++的預處理結果

查看GCC裏面的預定義宏
cpp -dM /dev/null

八、編譯的功能Debug
-g 指令使得編譯器把一些額外的調試信息存放到可執行文件和目標文件中,這些信息使得我們能把機器碼信息和源程序信息聯繫在一起。GCC的調試器是GDB

分析Coredump文件
gdb a.out core.2297


九、編譯優化
一個編譯器能夠產生不同平臺上的可執行文件。
1、在源碼層次進行優化,不需要對於機器碼的任何知識
    (1)、公用子表達式消除(CSE),重用已經計算出的變量
    (2)、內嵌函數(FL)
    (3)、循環優化開關 gcc -Wall -O3 -funroll-loops test.c -o test
2、機器碼層次優化
3、優化等級:
    gcc -OLEVEL
    LEVEL = 0 - 3
    0表示不優化
    等級越高,優化的強度越大

十、優化和調試
通常優化和調試是矛盾的,GCC中允許同時使用優化和-g,允許同時優化和調試

十一、編譯C++程序
GNU的C++編譯器實際上就是一個真正的C++編譯器,把C++直接編譯成彙編語言,再轉換成機器碼。其實的編譯器則是先把C++語言轉成C語言,再轉成彙編然後再轉成機器碼。所以GCC編譯器產生的C++程序的性能更高。編譯C++的過程和編譯C的過程是一樣的,但是使用的是g++命令,
gcc 和 g++的大部分命令都相同。
C++的目標文件必須用g++來鏈接,因爲g++會查找C++的標準庫

十二、編譯是怎麼樣工作的
編譯過程是由多個階段組成的,每個階段使用的工具不一樣,它包含很多工具,稱爲工具鏈。
包含下面過程 :
1、預處理
2、將源程序編譯成彙編語言
3、把彙編語言源程序編譯成最終機器碼,產生目標文件
4、創建最終可執行文件

1、cpp hello.c -o hello.i 預處理,生成 hello.i文件
2、gcc -Wall -S hello.i   編譯成彙編語言,生成hello.s文件 (用-S參數表示編譯成彙編語言的源程序)
3、as hello.s -o hello.o 生成目標文件
4、gcc hello.o 生成可執行文件     

十三、兩個和編譯相關的工具
1、優化器gprof
gcc -Wall -pg main.c -o pro
-pg參數把GCC的一些測試代碼插入到可執行文件中,可以計算函數執行的時間和次數
程序運行完成,會生成一個gmon.out的文件 ,使用gprof gmon.out來查看其中的信息


2、覆蓋測試工具 gcov
可以發現程序中哪些代碼從來沒有被調用到
gcc -Wall -fprofile-arcs -ftest-coverage cov.c
生成cov.gcno
運行程序後,生成cov.gcda

使用gcov cov.c來檢查
生成 cov.c.gcov
發佈了43 篇原創文章 · 獲贊 151 · 訪問量 19萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章