您好,登錄后才能下訂單哦!
GCC的幾個重要選項解釋
詳細可見:[GNU Compiler Collection (GCC)]
https://gcc.gnu.org/onlinedocs/gcc/
https://gcc.gnu.org/onlinedocs/gcc/Option-Summary.html
-c 編譯或者匯編代碼,但是不鏈接
-S 在編譯之后停止,但不匯編
-E 預處理后停止,但不編譯
-o 指定輸出文件的名稱
-v 顯示編譯的每個階段使用的命令
-std 指定要用的語言標準
-g 產生調試信息
-pg 產生額外信息,被gprof用來做profilling
-O 優化可執行代碼
-W 設置編譯器的警報級別
-pedantic以ANSI/ISO C標準列出的所有警告,不符合該語言標準的地方將產生相應的警告信息
-I 指定文件包含的目錄
-L 指定庫目錄(編譯時的庫搜索目錄)
-D 預定義在源代碼中出現的宏
-U 取消所有定義的宏
-f 指定用來控制編譯器行為的選項
-m 指定與硬件相關的選項
GCC相關信息查看
-help 顯示此幫助說明
-target-help 顯示目標機器特定的命令行選項
-help={target|optimizers|warnings|params|[^]{joined|separate|undocumented}}[,...]
顯示特定類型的命令行選項
(使用‘-v --help’顯示子進程的命令行參數)
-version 顯示編譯器版本信息
-dumpspecs 顯示所有內建 spec 字符串
-dumpversion 顯示編譯器的版本號
-dumpmachine 顯示編譯器的目標處理器
-print-search-dirs 顯示編譯器的搜索路徑
-print-libgcc-file-name 顯示編譯器伴隨庫的名稱
-print-file-name=<庫> 顯示 <庫> 的完整路徑
-print-prog-name=<程序> 顯示編譯器組件 <程序> 的完整路徑
-print-multi-directory 顯示不同版本 libgcc 的根目錄
-print-multi-lib 顯示命令行選項和多個版本庫搜索路徑間的映射
-print-multi-os-directory 顯示操作系統庫的相對路徑
-print-sysroot 顯示目標庫目錄
-print-sysroot-headers-suffix 顯示用于尋找頭文件的 sysroot 后綴
目前了解的GCC相關具體選項
-fpic
用于生成位置無關代碼,位置無關碼的作用:
1、程序在運行期間動態加載到內存中;
2、程序在不同場合與不同程序組合后加載到內存(一般用于動態鏈接庫)
3、在運行期間不同地址相互之間的映射;(如bootloader)
簡言之,位置無關碼就是可以在進程的任意內存位置執行的目標碼,動態鏈接庫必須使用。
-L.
搜索相應庫文件路徑,.是指當前路徑;
-march=armv7-a
-march=armv7-a是指編譯出來的匯編語言是針對armv7架構的;
-mtune=contex-a8
與上面一樣,這個則是針對板子上的CPU選項是contex-a8類型的;
-mfloat-abi=soft/softfp/hard
"soft"選項:表明不使用FPU硬件,而是使用GCC的整數算術運算來模擬浮點運算。此選項為默認,因此一定要修改為softfp。
"softfp"選項:表明要使用FPU硬件來做浮點運算,只是,函數的參數傳遞到整數寄存器(r0-r3)中,然后再傳遞到FPU中。
"hard"選項:表明要使用FPU硬件來做浮點運算,并且,函數的參數直接傳遞到FPU的寄存器(s0、d0)中。
-mfpu=vfpv3-d16
指定了目標機器上可用的浮點硬件(或硬件仿真),-mfloat-abi=softfp/hard,使用硬浮點指令而不指定-mfpu的話,默認使用的是-mfpu=vfp,即不會做neon SIMD優化。因此采用neon 內置或neon 匯編,必須指定-mfpu=neon。Advanced SIMD (aka NEON) is mandatory for AArch74, so no command line option is needed to instruct the compiler to use NEON.
-mthumb-interwork
這個編譯選項則是支持編譯出來的匯編語言可以支持ARM和THUMB指令集;
-mno-thumb-interwork
缺省情況下是"-mno-thumb-interwork",因為指定了"-mthumb-interwork"產生的代碼稍微大一些;
-Wno-write-strings
會忽略掉C++ char* 轉const char*的警告,這樣并不會很安全;
-Wno-trigraphs
關閉ANSI C的三字母詞編譯出現的錯誤;在ANSI C標準中,定義了9個三字母詞(trigraph),三字母詞就是幾個字符的序列,合起來表示另一個字符。
-fno-tree-vectorize
關閉程序中的向量化的選項;gcc -O3會自動打開 -ftree-vectorize選項
-fno-inline
忽略代碼中的inline關鍵字,該選項使編譯器將內聯函數以普通函數正常對待,等同于無優化選項的處理。
-fshort-enums
支持給enum類型分配它聲明的值域范圍的字節數,即enum類型等于大小足夠的最小整數類型。
typedef enum num{
one = 1,
two = 2,
three = 3,
four = 4,
}NUM;
NUM num1;
sizeof(num1)不增加這個-fshort-enums選項的時候為4,增加后為大小為1;-fno-short-enums則是無這個選項優化處理。gcc是默認沒有-fshort-enums這個選項的;
-Wundef
當一個沒有定義的符號出現在 #if 中時,給出警告。
-fexpensive-optimizations
執行代價高昂的優化技術,但是不一定保證運行時性能能提升,反而可能一定程度上會產生負面影響.
-frename-registers
在寄存器分配后,通過使用rename registers來避免預定代碼中的虛假依賴。
-fomit-frame-pointer
能夠提高程序性能;原理上最主要的區別是少了棧幀的切換和棧地址的保存;在gdb 執行disassemble命令時,由于沒有保存相應棧調用地址,而導致無法追蹤函數調用順序的問題;
-Wno-psabi
Processor Suppliment aBI (psABI)
-fno-strict-aliasing
在編譯選項中加入-fstrict-aliasing的優勢在于向編譯器說明不同類型的lvalue將指向不相關的內存區域,編譯器可以做大量的優化。而選項-fno-strict-aliasing向編譯器表明不同類型的lvalue可能指向相關的內存區域,因此編譯器不會做出一些極端的優化而造成不安全
-funwind-tables(為何會產生大量unwind符號?)
unwind table,這個表記錄了與函數相關的信息,共三個字段:函數的起始地址,函數的結束地址,一個 info block 指針。
Similar to ‘-fexceptions’, except that it just generates any needed static data, but does not affect the generated code in any other way.
-fexceptions
Enable exception handling
注:大量unwind符號的產生部分是由于-funwind-tables以及-fexceptions,該選項會使object產生符號__aeabi_unwind_cpp_prN,在鏈接之后會在庫文件中生成unwind符號。但是即使不定義這兩個選項,如果代碼中顯式拋出了異常,編譯器會默認添加-fexceptions,如果強制手工添加-fno-exceptions會報錯。stack unwind 即從拋出異常的函數開始,沿著調用鏈向上找到 catch 所在的函數,然后從拋異常的地方開始,清理調用鏈上各棧幀內已經創建了的局部變量,這一整個過程。
-fstack-protector
在關鍵函數的堆棧中設置保護值。在返回地址和返回值之前,都將驗證這個保護值。如果出現了緩沖區溢出,保護值不再匹配,程序就會退出。程序每次運行,保護值都是隨機的,不會被遠程猜出。
-finline-limit=64
對偽指令數超過n的函數,編譯程序將不進行內聯展開,默認為600。增大此值將增加編譯時間和編譯內存用量并且生成的二進制文件體積也會變大,此值不宜太大。
-fsigned-char
設定char的缺省模式為signed char
-no-canonical-prefixes
Do not expand any symbolic links, resolve references to ‘/../’ or ‘/./’, or make the path absolute when generating a relative prefx.
-fdata-sections 以及 -ffunction-sections
將每個函數或符號創建為一個sections,其中每個sections名與function或data名保持一致。即使compiler為每個function和data item分配獨立的section
-Wl,–gc-sections(為何導致符號的缺失?)
指示鏈接器去掉不用的section(其中-wl, 表示后面的參數 -gc-sections 傳遞給鏈接器),鏈接操作以section作為最小的處理單元(結合-ffunction-sections),只要一個section中有某個符號被引用,該section就會被放入output中。
什么是"被引用",個人認為是指"被調用",或者符號被export引起的鏈接器認為這是一個接口
-Wa,--noexecstack
執行ld鏈接器堆棧段不可執行機制(其中-wl, 表示后面的參數 -gc-sections 傳遞給assembler)
-frtti
RTTI(Run-Time Type Identification),通過運行時類型信息程序能夠使用基類的指針或引用來檢查這些指針或引用所指的對象的實際派生類型。-frtti選項使編譯器為每個有虛函數的類添加一些信息以支持rtti特性,例如dynamic_cast typeid之類,不過這個選項默認就是打開的,一般都是用-fno-rtti來關閉這個特性節約空間
-fvisibility=hidden
能夠實現隱藏符號表的作用,nm查看符號表可以看到符號類型從T變為t,至于如何去除局部符號t,可以調用strip -x來去掉。從動態共享庫中盡可能少地輸出符號是一個好的實踐經驗。輸出一個受限制的符號會提高程序的模塊性,并隱藏實現的細節。在庫中減少符號的數目還可以減少庫的內存印跡,減少動態鏈接器的工作量。動態鏈接器裝載和識別的符號越少,程序啟動和運行的速度就越快。
對于接口函數,可以在函數聲明前添加__attribute__ ((visibility ("default"))),使其符號被單獨導出。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。