學習C和C++的同學應該都知道,gcc是一款跨平台的C/C++編譯器,可以在Linux/Windows平台下使用,具有十分強大的功能,結構也十分靈活,並且可以通過不同的前端模塊來支持各種語言,如Java、Fortran、Pascal、Modula-3和Ada的編譯。許多有名的工程和庫都是使用gcc進行編譯的,如nginx,libevent等。今天我們重點介紹gcc組件中可以用來編譯C++程序的g++組件的使用。
g++可以在命令行使用,也可以通過配置IDE的編譯環境來調用系統配置的g++環境,大家可以根據需要自行配置。下面是一些博主本人使用g++編譯程序的一些經驗和總結。
1. g++編譯過程
g++在對源程序執行編譯工作時,需要經過以下四個步驟:
(1) 預處理:對源程序中的宏定義、包含頭文件等進行處理,生成后綴名為.i的文件(使用)
使用格式:
g++ -E hello.cpp -o hello.i
hello.cpp是需要編譯的源文件,-o 選項指定輸出的文件名。這里使用-E選項編譯生成hello.i 文件
(2) 轉化為匯編文件:使用-S 選項,可以將預處理之后的.i文件轉換為目標機器的匯編代碼.S文件
使用格式:
g++ -S hello.i -o hello.s
使用該參數可以將.i 文件編譯生成.s 文件,輸出文件名同樣使用-o 選項指定。
(3) 匯編文件->目標文件,即轉換為機器代碼:使用-c選項
使用格式:
g++ -c hello.s -o hello.o
(4) 鏈接:將上一步產生的目標文件鏈接為可執行文件,使用-o參數
使用格式:
g++ hello.o -o hello
以上過程是g++工具編譯cpp源程序的具體過程,在實際使用時我們可以不用按照流程一步步編譯,可以一步到位將源程序編譯為可執行文件,只需要使用如下命令:
g++ hello.cpp -o hello
2.g++常用編譯選項
在使用g++工具進行編譯時,我們可以附加一些編譯選項讓編譯更加智能,從而方便我們查看編譯錯誤和警告。g++提供了許多有用的編譯選項,下面總結一些常用選項:
-o FILE: 指定輸出文件名,在編譯為目標代碼時,這一選項不是必須的。如果FILE沒有指定,缺省文件名是a.out
-c: 只編譯生成目標文件,不鏈接
-m486: 針對 486 進行代碼優化
-Wall: 允許發出gcc能提供的所有有用的警告,也可以用-W(warning)來標記指定的警告
使用格式:
1 g++ -Wall hello.cpp -o hello
-Werror: 把所有警告轉換為錯誤,以在警告發生時中止編譯過程;
-v: 顯示在編譯過程的每一步中用到的命令 ;
-static: 鏈接靜態庫,即執行靜態鏈接,g++默認是鏈接動態庫,如果需要鏈接靜態庫需要使用本選項進行指定;
-g: 在可執行程序中包含標准調試信息, 使用該選項生成的可執行文件可以用gdb工具進行調試;
-w: 關閉所有警告,建議不要使用該選項
-shared: 生成共享目標文件。通常用在建立共享庫時;
-On: 這是一個優化選項,如果在編譯時指定該選項,則編譯器會根據n的值(n取0到3之間)對代碼進行不同程度的優化,其中-O0 表示不優化,n的值越大,優化程度越高;
-L: 庫文件依賴選項,該選項用於指定編譯的源程序依賴的庫文件路徑,庫文件可以是靜態鏈接庫,也可以是動態鏈接庫,linux系統默認的庫路徑是/usr/lib,如果需要的庫文件不在這個路徑下就要用-L指定
g++ foo.cpp -L/home/lib -lfoo -o foo
-I: 該選項用於指定編譯程序時依賴的頭文件路徑,linux平台默認頭文件路徑在/usr/include下,如果不在該目錄下,則編譯時需要使用該選項指定頭文件所在路徑
gcc foo.cpp -I/home/include -o foo
3.編譯動態庫
g++除了可以編譯源程序生成可執行文件,也可以編譯動態鏈接庫,方法如下:
(1) 分步完成
gcc -fPIC -c func.cpp -o func.o gcc -shared -o libfunc.so func.o
(2) 一步完成
gcc -fPIC -shared -o libfunc.so func.cpp
4. make和Makefile
上面已經介紹了g++工具在命令行的使用,我們可以使用g++在命令行來對單個或者多個源程序文件進行編譯。但是,如果遇到需要同時編譯許多文件的情況,g++命令行編譯就太麻煩了,這個時候就需要使用make進行自動化編譯。我們可以編寫make工具的規則文件——Makefile,在該文件中定義一些編譯的規則,然后利用make工具自動調用g++進行批量編譯,這樣可以大大提高效率。有興趣的同學可以自行查找make的使用,這里就不展開了。
參考資料:
1.https://blog.csdn.net/kwame211/article/details/84560400
2.https://blog.csdn.net/drdairen/article/details/53740092