前言
本文用于記錄我在學習和工作中遇到的各種GCC選項,雖然這些選項可以在GNU的手冊上查到,不過這里做個總結,可以避免每次都去查手冊,算是一個備忘吧。本文的內容會不斷更新擴充。
1 常用的編譯選項
選項 | 作用 |
---|---|
-o | 指定輸出文件名稱 |
-E | 只進行預處理 |
-S | 只進行預處理、編譯 |
-c | 只預處理、編譯、匯編,但不鏈接 |
-D | 使用-D name[=definition]預定義名為name的宏,若不指定值則默認宏的內容為1 |
-l(小寫的L) | 使用-l libname或者-llibname,使鏈接器在鏈接時搜索名為libname.a/libname.so(靜態/動態)的庫文件 |
-L | 使用-Ldir添加搜索目錄,即鏈接器在搜索-l選項指定的庫文件時,除了系統的庫目錄還會(優先)在-L指定的目錄下搜索 |
-I(大寫的i) | 使用-I dir,將目錄dir添加為頭文件搜索目錄 |
-include | 使用-include file,等效于在被編譯的源文件開頭添加#include "file" |
-static | 指定靜態鏈接(默認是動態鏈接) |
-O0~3 | 開啟編譯器優化,-O0為不優化,-O3為最高級別的優化 |
-Os | 優化生成代碼的尺寸,使能所有-O2的優化選項,除了那些讓代碼體積變大的 |
-Og | 優化調試體驗,在保留調試信息的同時保持快速的編譯,對于生成可調試代碼,比-O0更合適,不會禁用調試信息。 |
-Wall | 使編譯器輸出所有的警告信息 |
-march | 指定目標平臺的體系結構,如-march=armv4t,常用于交叉編譯 |
-mtune | 指定目標平臺的CPU以便GCC優化,如-mtune=arm9tdmi,常用于交叉編譯 |
2 其他編譯選項
2.1 -x language
通常gcc通過源文件的后綴來判斷該源文件是由什么語言編寫的(雖然Linux中后綴沒有意義),換句話說,如果我們的文件名不帶后綴,那么gcc就無法判斷源文件的語言類型了,也就無法完成編譯。舉例來說:例1我用c語言編寫了一段代碼,將其保存在文件名為main.lll中,執行gcc main.lll會報錯:
main.lll:filenotrecognized:Fileformatnotrecognized collect2:error:ldreturned1exitstatus 12
例2在u-boot中,生成鏈接腳本的命令為arm-linux-gcc -E -Wp,-MD,./.u-boot.lds.d ...... -x assembler-with-cpp -std=c99 -P -o u-boot.lds arch/arm/cpu/u-boot.lds,如果把其中的-x assembler-with-cpp去掉,則編譯器給出如下信息(且不會生成鏈接腳本):
linkerinputfileunusedbecauselinkingnotdone 1
至此,-x language的作用就很好理解了,當我們的源文件不添加常規的后綴時,使用該選項來告訴gcc源文件使用了哪種編程語言,其中的language表明的就是語言類型,其可取的值有(不是全部):
c c-header cpp-output c++ c+±header c+±cpp-output objective-c objective-c-header objective-c-cpp-output objective-c++ objective-c+±header objective-c+±cpp-output assembler assembler-with-cpp
2.2 -fno-xxx
-fno-common遇到多個弱定義的全局符號時輸出一條警告信息。
-fno-ident忽略#ident命令。
-fno-builtin遇到與內建函數同名的函數時不去鏈接內建函數,除非函數名以__builtin_開頭,也可以使用-fno-builtin-function來針對特定的函數。
2.3 -fxxx
-ffreestanding告訴編譯器要編譯的目標處于獨立的環境。在獨立的環境中,標準庫可能不存在,程序的入口也不一定是main。使用該選項的典型例子有bootloader、OS kernel等,這些程序不依賴標準庫,也不需要編譯器給它們添加.init段。
-fomit-frame-pointer在不需要幀指針的函數中省略掉幀指針。所謂幀指針,指的是指向一個函數的棧幀的底部的指針(棧頂指針是沒辦法省的)。比如x86平臺就使用ebp作為幀指針。省略掉幀指針的好處是可以多出一個可用的寄存器,壞處是不利于棧回溯。值得注意的是,有些平臺的過程調用規范指定必須使用幀指針,此時該選項無效;同時,與該選項對應的-fno-omit-frame-pointer也不保證幀指針一定會被使用。
2.4 -Wxxx
-W/-Wextra-W是-Wextra的舊稱。顯然,-Wextra更具有可讀性,顧名思義,該選項可以使能一些額外的警告標志。所謂額外,是針對-Wall而言的,-Wall并沒有使能所有的警告,盡管它有個all。
-Wshadow使用該選項時,如果本地的變量或類型聲明遮蔽了另一個變量、參數、類型、類成員(C++)、實例變量(Objective-C)或內建函數,則gcc會報警告。
-Wconversion當使用該選項時,如果隱式類型轉換會更改變量的值,則gcc會給出警告。這樣的隱式轉換有實數與整數的轉換、有符號數與無符號數的轉換、轉向更小類型的轉換等。當然,上述轉換中,如果最終沒有改變變量的值,那么就不會產生警告,如abs(2.0)。
2.5 -Wno-xxx
-Wno-sign-conversion關閉有符號數和無符號數之間進行類型轉換時產生的警告,即使用了該選項,那么有符號數和無符號數之間轉換時gcc就不報警告了。
2.6 給鏈接器使用的選項:-Wl,options
這里所說的鏈接器是指集成在可執行文件gcc中的鏈接器,而不是單獨使用的ld。當我們通過gcc間接使用鏈接器時,需要在鏈接器的編譯選項前面加上-Wl,,然后跟著編譯選項,即標題中的options。GCC手冊中的相應介紹如下:
那么,為什么需要-Wl,前綴呢?GNU的鏈接器手冊中是這樣解釋的(很好懂,就不翻譯了):
接下來就介紹一些用于鏈接器的選項:
-Wl,-rpath=dir在編譯鏈接時,鏈接器會在dir目錄下搜索動態庫。同時,把動態庫搜索路徑dir添加到可執行文件中,以便可執行文件加載運行時使用。要注意該選項與-L選項的區別,-L選項用于編譯鏈接時添加庫文件的搜索路徑;而該選項僅限于動態庫,并且既可以在編譯鏈接時添加搜索路徑,同時也能將搜索路徑添加到可執行文件中。
3 ARM架構專有的編譯選項
-mthumb使編譯器生成THUMB指令
-marm使編譯器生成ARM指令
-mthumb-interwork使編譯器生成支持ARM和Thumb指令集之間相互調用的代碼,默認是-mno-thumb-interwork
-
GCC
+關注
關注
0文章
109瀏覽量
25245 -
編譯器
+關注
關注
1文章
1656瀏覽量
49905
原文標題:參考文獻
文章出處:【微信號:技術讓夢想更偉大,微信公眾號:技術讓夢想更偉大】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
淺談gcc編譯器
GCC編譯器你需要知道的入門知識
嵌入式Linux工具之GCC常用編譯選項

GCC編譯優化指南
Linux系統下Gcc的基本用法和選項
基于GCC實現支持MISRAC的安全編譯器

STM32 GCC編譯環境搭建

【GCC編譯運行報錯】error while loading

評論