GCC編譯器參數

GCC編譯器參數

除了最簡單的運行gcc/g++ filename(這樣只能運行最簡單的小程序)外,GCC都需要用各種選項來實現其強大的功能。

下面是GCC的一些常用選項描述:

生成特定格式的文件:
-E          只激活預處理,但不生成文件,需要把它重定向到一個輸出文件裏面。例子:
             gcc -E hello.c > pianoapan.txt
  gcc -E hello.c | more
-C         在預處理的時候,不刪除註釋信息,一般和-E使用,有時候用這個分析程序很方便。
-S         只激活預處理和編譯,就是指把文件編譯成爲彙編代碼。
  例子: gcc -S hello.c
-c          只激活預處理,編譯,和彙編,也就是他只把程序做成obj文件
  例子: gcc -c hello.c
-o          指定目標文件名稱,例子:
  gcc -o hello hello.c

包含頭文件和庫:
-include file
  包含某個代碼,簡單來說,就是便以某個文件,需要另一個文件的時候,就可以用它設定,功能就相當於在代碼中使用#include<filename>,例子用法:
  gcc hello.c -include /root/pianopan.h
-Idir
  指定所需頭文件的位置,在使用#include"file"的時候,gcc/g++會先在當前目錄查找你所制定的頭文件,如果沒有找到,他回到缺省的頭文件目錄找,如果使用-I制定了目錄,他會先在所指定的目錄查找,然後再按常規的順序依次查找。
-I-                 參數“-Idir”的功能,所以一般在-Idir之後使用。
-Ldir
  指定編譯時,庫的搜索路徑。第三方或自己提供的庫,可以用它制定目錄,否則編譯器將只在標準庫的目錄找。這個dir就是目錄的名稱。
-llibrary
  制定編譯的時候使用的庫(指定了路徑當然還得指定庫名),常用的lib庫有lpthread(線程庫),lm(數學庫),lz(zlib庫)及lcrypto(linux下的MD5加密庫)等,當然可以添加自己或第三方的庫文件。例子:
  gcc -lncurses hello.c               使用ncurses庫編譯程序。

優化選項:
-O0/1/2/3/s               介紹如下:
-O0                  不進行優化處理。
-O/O1 GCC將執行減少代碼尺寸和執行時間的優化,對於那些會嚴重影響編譯時間的優化選項,這個級別的優化並不會執行。
-O2                  在這一級別GCC將會提供所有支持的優化,但這其中並不包括以空間換時間的優化手段,例如編譯器不會使用循環展開和函數內聯。和-O相比,該選項進一步加快了編譯時間和生成代碼的性能。
-O3                  除了-O2提供的優化選項外,還指定了-finline-functions,-funswitch-loops和-fgcse-afer-reload選項,目的只有一個就是全力執行代碼優化,但是用"-O3 -fno-inline-functions"既可以使用-O3的功能又關閉函數內嵌功能。
-Os                  這個選項是專門用來優化代碼尺寸的,-Os打開了所有-O2級別中不會顯著增長代碼尺寸的優化選項 在用GDB調試優化後的程序時,運行時的指令和你所編寫指令就有不一樣,也就會出現你所想象不到的結果。對付這種情況時,需要在編譯程序時關閉編譯優化。  

宏定義:
                   -DMACRO                         以字符串“1”(默認值)定義 MACRO 宏。
                   -DMACRO=DEFN              以字符串“DEFN”定義MACRO 宏,注意中間不能有空格。
                   -UMACRO                         取消對 MACRO 宏的定義。

語言選項(LANGUAGE OPTIONS):
-ansi

支持符合ANSI標準的C程序。

 

-frtti    開啓RTTI的支持(dynamic_cast和typeid需要用到),和vs c++不同,這在gcc中是默認選項。使用"-fno-rtti"將其禁用。

-fno-builtin

       不接受不是兩個下劃線開頭的內建函數(built-in function).目前受影響的函數有_exit, abort, abs, alloca, cos, exit, fabs, labs, memcmp, memcpy, sin, sqrt, strcmp, strcpy,strlen有時候上面的這些函數在一些地方被built-in後,會產生運算結果和預想的不一樣甚至是錯誤的,比如abs(),會導致-10*abs(x-1)== 10*abs(x-1)的怪異情況,原因是運算被優化而得到錯誤的結果

警告選項:

 

-W               編譯器的警告設置參數,擁有衆多的選項,下面舉一些常用的例子:
     -Woption 讓編譯器給出option指定的編譯警告,常用的一些如下:
                   unused-function: 遇到僅聲明過但尚未定義的靜態函數時發出警告。
                   unused-parameter: 從未用過的函數參數的警告。
                   unused-variable: 在本地聲明但從未用過的變量的警告。
                   unused-value: 經計算但從未用過的值得警告。
                   return-type: 對函數返回類型不當的警告。
                   uninitialized:在初始化之前就使用自動變量。
                   float-equal:   比較兩個浮點數是否相等。
    -Wall       給出“幾乎”所有的編譯器警告,注意是“幾乎”。下面是一些-Wall沒有輸出的警告類型:
                   sign-compare:將有符號類型和無符號類型數據進行比較時發出警告。
                   unreachable-code:如果發現從未執行的代碼時給出警告。
                   inline:如果某函數不能按要求內嵌(inline),則無論是函數聲明爲inline或者是指定了-finline-functions 選項,編譯都將發出警告。      
    -Werror               把所有的警告都視爲錯誤處理。
    -Wno-option               如果我們不想輸出某些警告信息,可以使用此參數形式,比如:
                   -Wno-unused-function
                   -Wno-unused-variable
                   -Wno-unused-parameter
                   -Wno-uninitialized

調試和可執行文件形式:
-g                 指示編譯器,在編譯的時產生調試信息。
-ggdb           此選項將盡可能的生成gdb的可以使用的調試信息(比-g生成的信息更多些)。
-pg               此選項在運行後生成一個分析文件gmon.out分析每一個模塊的運行時間等信息,可以用“gprof execname gmon.out”命令打開。
-static           此選項將禁止使用動態庫,編譯得到的程序會比較大,但可以自由運行。
-share          此選項將盡量使用動態庫,所以生成文件比較小,但是需要系統由動態庫。

上面的是一些常用的參數以及對應的選項,如有更細緻的需求,可以參考man page。

附加:使用GCC生成靜態鏈接庫或動態鏈接庫
         首先需要目標文件(*.o),用gcc/g++ -c生成,如:gcc -c test1.c test2.c test3.c
1. 生成靜態鏈接庫
         使用ar命令: ar -crv libtest.a test1.o test2.o test3.o 即可產生test.a文件。
         可以用命令 nm test.a 來看裏面的目標文件和導出函數(帶 T 標記)。
         使用的時候加上:-L(路徑) -ltest。注意這裏不是llibtest.a或llibtest,-l參數會自動添加lib和.a到首尾,然後去-L指定的目錄加載.a文件。
2.生成動態鏈接庫
         用動態庫的好處是:更新了動態庫之後鏈結它的程序不用重新編譯,但需要運行時鏈接。
         使用 gcc -o libtest.so -shared -fPIC      test1.o test2.o test3.o
         -fPIC:表示編譯爲位置獨立的代碼,不用此選項的話編譯後的代碼是位置相關的,所以動態載入時是通過代碼拷貝的方式來滿足不同進程需要,而不能達到真正代碼段共享的目的。
         可以用命令 nm test.so 來看裏面的目標文件和導出函數(帶 T 標記)。

         還有一個需要注意的地方,在不同的硬件架構和位寬平臺上的.a文件和.so文件不能互用,需要重新生成不同平臺的.o文件,然後再生成相應的.a文件和.so文件。否則編譯會出現“skipping incompatible ****.a/so”之類的錯誤。

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