GCC的幾個重要選項解釋

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相關具體選項

111111.jpg

-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 AArch64, 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"))),使其符號被單獨導出。


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