歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Unix知識 >> 關於Unix >> GCC 手冊(續)

GCC 手冊(續)

日期:2017/3/6 15:25:35   编辑:關於Unix
續 連接器選項(LINKER OPTION) 下面的選項用於編譯器連接目標文件,輸出可執行文件的時候.如果編譯器不進行 連 接,他們就毫無意義. object-file-name 如果某些文件沒有特別明確的後綴a special recognized suffix, G CC 就認為他們 是目標文件或庫文件. (根據 續

連接器選項(LINKER OPTION)

下面的選項用於編譯器連接目標文件,輸出可執行文件的時候.如果編譯器不進行 連
接,他們就毫無意義.

object-file-name

如果某些文件沒有特別明確的後綴a special recognized suffix, GCC就認為他們
是目標文件或庫文件. (根據文件內容,連接器能夠區分目標文件和庫文件).如果GC
C執行連接操作,這些目標文件將成為連接器的輸入文件.

-llibrary

連接名為library的庫文件.

連接器在標准搜索目錄中尋找這個庫文件,庫文件的真正名字是`liblibrary.a'.連
接器會 當做文件名得到准確說明一樣引用這個文件.

搜索目錄除了一些系統標准目錄外,還包括用戶以`-L'選項指定的路徑.

一般說來用這個方法找到的文件是庫文件---即由目標文件組成的歸檔文件(archiv
e file).連接器處理歸檔文件的 方法是:掃描歸檔文件,尋找某些成員,這些成員的
符號目前已被引用,不過還沒有被定義.但是,如果連接器找到普通的 目標文件,而不
是庫文件,就把這個目標文件按平常方式連接進來.指定`-l'選項和指定文件名的唯
一區別是, `-l選項用`lib'和`.a'把library包裹起來,而且搜索一些目錄.

-lobjc

這個-l選項的特殊形式用於連接Objective C程序.

-nostartfiles

不連接系統標准啟動文件,而標准庫文件仍然正常使用.

-nostdlib

不連接系統標准啟動文件和標准庫文件.只把指定的文件傳遞給連接器.

-static

在支持動態連接(dynamic linking)的系統上,阻止連接共享庫.該選項在其他系統上
無效.

-shared

生成一個共享目標文件,他可以和其他目標文件連接產生可執行文件.只有部分系統
支持該選項.

-symbolic

建立共享目標文件的時候,把引用綁定到全局符號上.對所有無法解析的引用作出警
告(除非用連接編輯選項 `-Xlinker -z -Xlinker defs'取代).只有部分系統支持該
選項.

-Xlinker option

把選項option傳遞給連接器.可以用他傳遞系統特定的連接選項, GNU CC無法識別這
些選項.

如果需要傳遞攜帶參數的選項,你必須使用兩次`-Xlinker',一次傳遞選項,另一次傳
遞他的參數. 例如,如果傳遞`-assert definitions',你必須寫成`-Xlinker -asse
rt -Xlinker definitions',而不能寫成`-Xlinker "-assert definitions"',因為
這樣會把整個 字符串當做一個參數傳遞,顯然這不是連接器期待的.

-Wl,option

把選項option傳遞給連接器.如果option中含有逗號,就在逗號處分割成多個選項.


-u symbol

使連接器認為取消了symbol的符號定義,從而連接庫模塊以取得定義.你可以使用多
個 `-u'選項,各自跟上不同的符號,使得連接器調入附加的庫模塊.



目錄選項(DIRECTORY OPTION)

下列選項指定搜索路徑,用於查找頭文件,庫文件,或編譯器的某些成員:

-Idir

在頭文件的搜索路徑列表中添加dir 目錄.

-I-

任何在`-I-'前面用`-I'選項指定的搜索路徑只適用於`#include "file"'這種情況
;他們不能用來搜索`#include <file>'包含的頭文件.

如果用`-I'選項指定的搜索路徑位於`-I-'選項後面,就可以在這些路徑中搜索所有
的 `#include'指令. (一般說來-I選項就是這麼用的.)

還有, `-I-'選項能夠阻止當前目錄(存放當前輸入文件的地方)成為搜索`#include
"file"'的第一選擇.沒有辦法克服`-I-'選項的這個效應.你可以指定 `-I.'搜索那
個目錄,它在調用編譯器時是當前目錄.這和預處理器的默認行為不完全一樣,但是結
果通常 令人滿意.

`-I-'不影響使用系統標准目錄,因此, `-I-'和`-nostdinc'是不同的選項.

-Ldir

在`-l'選項的搜索路徑列表中添加dir目錄.

-Bprefix

這個選項指出在何處尋找可執行文件,庫文件,以及編譯器自己的數據文件.

編譯器驅動程序需要執行某些下面的子程序: `cpp', `clearcase/" target="_blank" >cc1' (或C++的 `cc1plus')
, `as'和`ld'.他把prefix當作欲執行的程序的 前綴,既可以包括也可以不包括`ma
chine/version/'.

對於要運行的子程序,編譯器驅動程序首先試著加上`-B'前綴(如果存在).如果沒有
找到文件,或沒有指定 `-B'選項,編譯器接著會試驗兩個標准前綴`/usr/lib/gcc/'
和 `/usr/local/lib/gcc-lib/'.如果仍然沒能夠找到所需文件,編譯器就在`PATH'
環境變量 指定的路徑中尋找沒加任何前綴的文件名.

如果有需要,運行時(run-time)支持文件`libgcc.a'也在`-B'前綴的搜索范圍之內.
如果這裡沒有找到,就在上面提到的兩個標准前綴中尋找,僅此而已.如果上述方法
沒有找到這個文件,就不連接他了.多數 情況的多數機器上, `libgcc.a'並非必不可
少.

你可以通過環境變量GCC_EXEC_PREFIX獲得近似的效果;如果定義了這個變量,其值就
和上面說的 一樣用做前綴.如果同時指定了`-B'選項和GCC_EXEC_PREFIX變量,編譯
器首先使用 `-B'選項,然後才嘗試環境變量值.



警告選項(WARNING OPTION)

警告是針對程序結構的診斷信息,程序不一定有錯誤,而是存在風險,或者可能存在
錯誤.

下列選項控制GNU CC產生的警告的數量和類型:

-fsyntax-only

檢查程序中的語法錯誤,但是不產生輸出信息.

-w

禁止所有警告信息.

-Wno-import

禁止所有關於#import的警告信息.

-pedantic

打開完全服從ANSI C標准所需的全部警告診斷;拒絕接受采用了被禁止的語法擴展的
程序.

無論有沒有這個選項,符合ANSI C標准的程序應該能夠被正確編譯(雖然極少數程序
需要`-ansi' 選項).然而,如果沒有這個選項,某些GNU擴展和傳統C特性也得到支持
使用這個選項可以拒絕這些程序.沒有理由 使用這個選項,他存在只是為了滿足一
些書呆子(pedant).

對於替選關鍵字(他們以`__'開始和結束) `-pedantic'不會產生警告信息. Pedant
ic 也不警告跟在__extension__後面的表達式.不過只應該在系統頭文件中使用這種
轉義措施,應用程序最好 避免.

-pedantic-errors

該選項和`-pedantic'類似,但是顯示錯誤而不是警告.

-W

對下列事件顯示額外的警告信息:

*

非易變自動變量(nonvolatile automatic variable)可能在調用longjmp時發生改變
這些警告僅在優化編譯時發生.

編譯器只知道對setjmp的調用,他不可能知道會在哪裡調用longjmp,事實上一個 信
號處理例程可以在程序的任何地點調用他.其結果是,即使程序沒有問題,你也可能會
得到警告,因為無法在可能出現問題 的地方調用longjmp.

*

既可以返回值,也可以不返回值的函數. (缺少結尾的函數體被看作不返回函數值)例
如,下面的函數將導致這種警告:

foo (a)

{

if (a > 0)

return a;

}

由於GNU CC不知道某些函數永不返回(含有abort和longjmp),因此有可能出現 虛假
警告.

*

表達式語句或逗號表達式的左側沒有產生作用(side effect).如果要防止這種警告
,應該把未使用的表達式強制轉換 為void類型.例如,這樣的表達式`x[i,j]'會導致
警告,而`x[(void)i,j]'就不會.

*

無符號數用`>'或`<='和零做比較.

-Wimplicit-int

警告沒有指定類型的聲明.

-Wimplicit-function-declaration

警告在聲明之前就使用的函數.

-Wimplicit

同-Wimplicit-int和-Wimplicit-function-declaration.

-Wmain

如果把main函數聲明或定義成奇怪的類型,編譯器就發出警告.典型情況下,這個函數
用於外部連接, 返回int數值,不需要參數,或指定兩個參數.

-Wreturn-type

如果函數定義了返回類型,而默認類型是int型,編譯器就發出警告.同時警告那些不
帶返回值的 return語句,如果他們所屬的函數並非void類型.

-Wunused

如果某個局部變量除了聲明就沒再使用,或者聲明了靜態函數但是沒有定義,或者某
條語句的運算結果顯然沒有使用, 編譯器就發出警告.

-Wswitch

如果某條switch語句的參數屬於枚舉類型,但是沒有對應的case語句使用枚舉元素,
編譯器 就發出警告. ( default語句的出現能夠防止這個警告.)超出枚舉范圍的ca
se語句同樣會 導致這個警告.

-Wcomment

如果注釋起始序列`/*'出現在注釋中,編譯器就發出警告.

-Wtrigraphs

警告任何出現的trigraph (假設允許使用他們).

-Wformat

檢查對printf和scanf等函數的調用,確認各個參數類型和格式串中的一致.

-Wchar-subscripts

警告類型是char的數組下標.這是常見錯誤,程序員經常忘記在某些機器上char有符
號.

-Wuninitialized

在初始化之前就使用自動變量.

這些警告只可能做優化編譯時出現,因為他們需要數據流信息,只有做優化的時候才
估算數據流信息.如果不指定 `-O'選項,就不會出現這些警告.

這些警告僅針對等候分配寄存器的變量.因此不會發生在聲明為volatile的變量上面
,不會發生在已經 取得地址的變量,或長度不等於1, 2, 4, 8字節的變量.同樣也不
會發生在結構,聯合或數組上面,即使他們在 寄存器中.

注意,如果某個變量只計算了一個從未使用過的值,這裡可能不會警告.因為在顯示警
告之前,這樣的計算已經被 數據流分析刪除了.

這些警告作為可選項是因為GNU CC還沒有智能到判別所有的情況,知道有些看上去錯
誤的代碼其實是正確的.下面是 一個這樣的例子:

{

int x;

switch (y)

{

case 1: x = 1;

break;

case 2: x = 4;

break;

case 3: x = 5;

}

foo (x);

}

如果y始終是1, 2或3,那麼x總會被初始化,但是GNU CC不知道這一點.下面是 另一個
普遍案例:

{

int save_y;

if (change_y) save_y = y, y = new_y;

...

if (change_y) y = save_y;

}

這裡沒有錯誤,因為只有設置了save_y才使用他.

把所有不返回的函數定義為volatile可以避免某些似是而非的警告.

-Wparentheses

在某些情況下如果忽略了括號,編譯器就發出警告.

-Wtemplate-debugging

當在C++程序中使用template的時候,如果調試(debugging)沒有完全生效,編譯器就
發出警告. (僅用於C++).

-Wall

結合所有上述的`-W'選項.通常我們建議避免這些被警告的用法,我們相信,恰當結
合宏的使用能夠 輕易避免這些用法。

剩下的`-W...'選項不包括在`-Wall'中,因為我們認為在必要情況下,這些被編譯器
警告 的程序結構,可以合理的用在"干淨的"程序中.

-Wtraditional

如果某些程序結構在傳統C中的表現和ANSI C不同,編譯器就發出警告.

*

宏參出現在宏體的字符串常量內部.傳統C會替換宏參,而ANSI C則視其為常量的一部
分.

*

某個函數在塊(block)中聲明為外部,但在塊結束後才調用.

*

switch語句的操作數類型是long.

-Wshadow

一旦某個局部變量屏蔽了另一個局部變量,編譯器就發出警告.

-Wid-clash-len

一旦兩個確定的標識符具有相同的前len個字符,編譯器就發出警告.他可以協助你開
發一些將要在某些 過時的,危害大腦的編譯器上編譯的程序.

-Wpointer-arith

任何語句如果依賴於函數類型的大小(size)或者void類型的大小,編譯器就發出警告
GNU C為了 便於計算void *指針和函數指針,就把這些類型的大小定義為1.

-Wcast-qual

一旦某個指針強制類型轉換以便移除類型修飾符時,編譯器就發出警告.例如,如果把
const char * 強制轉換為普通的char *時,警告就會出現.

-Wcast-align

一旦某個指針類型強制轉換時,導致目標所需的地址對齊(alignment)增加,編譯器就
發出警告.例如,某些機器上 只能在2或4字節邊界上訪問整數,如果在這種機型上把
char *強制轉換成int *類型, 編譯器就發出警告.

-Wwrite-strings

規定字符串常量的類型是const char[length],因此,把這樣的地址復制給 non-con
st char *指針將產生警告.這些警告能夠幫助你在編譯期間發現企圖寫入字符串常
量 的代碼,但是你必須非常仔細的在聲明和原形中使用const,否則他們只能帶來麻
煩;所以我們沒有讓 `-Wall'提供這些警告.

-Wconversion

如果某函數原形導致的類型轉換和無函數原形時的類型轉換不同,編譯器就發出警告
這裡包括定點數和浮點數的 互相轉換,改變定點數的寬度或符號,除非他們和缺省
聲明(default promotion)相同.

-Waggregate-return

如果定義或調用了返回結構或聯合的函數,編譯器就發出警告. (從語言角度你可以
返回一個數組,然而同樣會 導致警告.)

-Wstrict-prototypes

如果函數的聲明或定義沒有指出參數類型,編譯器就發出警告. (如果函數的前向引
用說明指出了參數類型,則允許後面 使用舊式風格的函數定義,而不會產生警告.)


-Wmissing-prototypes

如果沒有預先聲明函數原形就定義了全局函數,編譯器就發出警告.即使函數定義自
身提供了函數原形也會產生這個警告. 他的目的是檢查沒有在頭文件中聲明的全局
函數.

-Wmissing-declarations

如果沒有預先聲明就定義了全局函數,編譯器就發出警告.即使函數定義自身提供了
函數原形也會產生這個警告.這個選項 的目的是檢查沒有在頭文件中聲明的全局函
數.

-Wredundant-decls

如果在同一個可見域某定義多次聲明,編譯器就發出警告,即使這些重復聲明有效並
且毫無差別.

-Wnested-externs

如果某extern聲明出現在函數內部,編譯器就發出警告.

-Wenum-clash

對於不同枚舉類型之間的轉換發出警告(僅適用於C++).

-Wlong-long

如果使用了long long 類型就發出警告.該警告是缺省項.使用`-Wno-long-long' 選
項能夠防止這個警告. `-Wlong-long'和`-Wno-long-long'僅在 `-pedantic'之下才
起作用.

-Woverloaded-virtual

(僅適用於C++.)在繼承類中,虛函數的定義必須匹配虛函數在基類中聲明的類型特征
(type signature).當 繼承類聲明了某個函數,它可能是個錯誤的嘗試企圖定義一個
虛函數,使用這個選項能夠產生警告:就是說,當某個函數和基類 中的虛函數同名,但
是類型特征不符合基類的任何虛函數,編譯器將發出警告.

-Winline

如果某函數不能內嵌(inline),無論是聲明為inline或者是指定了-finline-functi
ons 選項,編譯器都將發出警告.

-Werror

視警告為錯誤;出現任何警告即放棄編譯.



調試選項(DEBUGGING OPTION)

GNU CC擁有許多特別選項,既可以調試用戶的程序,也可以對GCC排錯:

-g

以操作系統的本地格式(stabs, COFF, XCOFF,或DWARF).產生調試信息. GDB能夠使
用這些調試信息.

在大多數使用stabs格式的系統上, `-g'選項啟動只有GDB才使用的額外調試信息;這
些信息使GDB 調試效果更好,但是有可能導致其他調試器崩潰,或拒絕讀入程序.如果
你確定要控制是否生成額外的信息, 使用`-gstabs+', `-gstabs', `-gxcoff+', `
-gxcoff', `-gdwarf+',或`-gdwarf' (見下文).

和大多數C編譯器不同, GNU CC允許結合使用`-g'和`-O'選項.優化的代碼偶爾制造
一些驚異的結果:某些聲明過的變量根本不存在;控制流程直接跑到沒有預料到的地
方;某些語句因為計算結果是常量或已經確定而 沒有執行;某些語句在其他地方執行
,因為他們被移到循環外面了.

然而它證明了調試優化的輸出是可能的.對可能含有錯誤的程序使用優化器是合理的


如果GNU CC支持輸出多種調試信息,下面的選項則非常有用.

-ggdb

以本地格式(如果支持)輸出調試信息,盡可能包括GDB擴展.

-gstabs

以stabs格式(如果支持)輸出調試信息,不包括GDB擴展.這是大多數BSD系統上DBX使
用的格式.

-gstabs+

以stabs格式(如果支持)輸出調試信息,使用只有GNU調試器(GDB)理解的GNU擴展.使
用這些擴展有可能導致 其他調試器崩潰或拒絕讀入程序.

-gcoff

以COFF格式(如果支持)輸出調試信息.這是在System V第四版以前的大多數System
V系統上SDB使用的 格式.

-gxcoff

以XCOFF格式(如果支持)輸出調試信息.這是IBM RS/6000系統上DBX調試器使用的格
式.

-gxcoff+

以XCOFF格式(如果支持)輸出調試信息,使用只有GNU調試器(GDB)理解的GNU擴展.使
用這些擴展有可能導致 其他調試器崩潰或拒絕讀入程序.

-gdwarf

以DWARF格式(如果支持)輸出調試信息.這是大多數System V第四版系統上SDB使用的
格式.

-gdwarf+

以DWARF格式(如果支持)輸出調試信息,使用只有GNU調試器(GDB)理解的GNU擴展.使
用這些擴展有可能導致 其他調試器崩潰或拒絕讀入程序.

-glevel

-ggdblevel

-gstabslevel

-gcofflevel -gxcofflevel

-gdwarflevel

請求生成調試信息,同時用level指出需要多少信息.默認的level值是2.

Level 1輸出最少量的信息,僅夠在不打算調試的程序段內backtrace.包括函數和外
部變量的描述,但是 沒有局部變量和行號信息.

Level 3包含更多的信息,如程序中出現的所有宏定義.當使用`-g3'選項的時候,某些
調試器支持 宏擴展.

-p

產生額外代碼,用於輸出profile信息,供分析程序prof使用.

-pg

產生額外代碼,用於輸出profile信息,供分析程序gprof使用.

-a

產生額外代碼,用於輸出基本塊(basic block)的profile信息,它記錄各個基本塊的
執行次數,供諸如 tcov此類的程序分析.但是注意,這個數據格式並非tcov期待的.最
終GNU gprof 將處理這些數據.

-ax

產生額外代碼,用於從'bb.in'文件讀取基本塊的profile參數,把profile的結果寫到
'bb.out' 文件. `bb.in'包含一張函數列表.一旦進入列表中的某個函數, profile
操作就開始,離開最外層的函數後, profile操作就結束.以`-'為前綴名的函數排除
在profile操作之外.如果函數名不是唯一的,它可以寫成 `/path/filename.d:func
tionname'來澄清. `bb.out'將列出一些有效的文件名.這四個函數名具有 特殊含義
: `__bb_jumps__'導致跳轉(jump)頻率寫進`bb.out'. `__bb_trace__'導致基本塊
序列通過 管道傳到`gzip',輸出`bbtrace.gz'文件. `__bb_hidecall__'導致從跟蹤
(trace)中排除call 指令. `__bb_showret__'導致在跟蹤中包括返回指令.

-dletters

編譯的時候,在letters指定的時刻做調試轉儲(dump).用於調試編譯器.大多數轉儲
的文件名 通過源文件名添加字詞獲得(例如`foo.c.rtl'或`foo.c.jump').

-dM

預處理結束的時候轉儲所有的宏定義,不輸出到文件.

-dN

預處理結束的時候轉儲所有的宏名.

-dD

預處理結束的時候轉儲所有的宏定義,同時進行正常輸出.

-dy

語法分析(parse)的時候在標准錯誤轉儲調試信息.

-dr

RTL階段後轉儲到`file.rtl'.

-dx

僅對函數生成RTL,而不是編譯.通常和`r'聯用.

-dj

第一次跳轉優化後轉儲到`file.jump'.

-ds

CSE (包括有時候跟在CSE後面的跳轉優化)後轉儲到`file.cse'.

-dL

循環優化後轉儲到`file.loop'.

-dt

第二次CSE處理(包括有時候跟在CSE後面的跳轉優化)後轉儲到`file.cse2'.

-df

流程分析(flow analysis)後轉儲到`file.flow'.

-dc

指令組合(instruction combination)後轉儲到`file.combine'.

-dS

第一次指令安排(instruction schedule)後轉儲到`file.sched'.

-dl

局部寄存器分配後轉儲到`file.lreg'.

-dg

全局寄存器分配後轉儲到`file.greg'.

-dR

第二次指令安排(instruction schedule)後轉儲到`file.sched2'.

-dJ

最後一次跳轉優化後轉儲到`file.jump2'.

-dd

推遲分支調度(delayed branch scheduling)後轉儲到`file.dbr'.

-dk

寄存器-堆棧轉換後轉儲到`file.stack'.

-da

產生以上所有的轉儲.

-dm

運行結束後,在標准錯誤顯示內存使用統計.

-dp

在匯編輸出加注指明使用了哪些模式(pattern)及其替代模式.

-fpretend-float

交叉編譯的時候,假定目標機和宿主機使用同樣的浮點格式.它導致輸出錯誤的浮點
常數,但是在目標機上運行的時候, 真實的指令序列有可能和GNU CC希望的一樣.

-save-temps

保存那些通常是``臨時''的中間文件;置於當前目錄下,並且根據源文件命名.因此,
用`-c -save-temps'選項編譯`foo.c '會生成` foo.cpp'和`foo.s' 以及`foo.o'文
件.

-print-file-name=library

顯示庫文件library的全路徑名,連接時會使用這個庫---其他什麼事情都不作.根據
這個選項, GNU CC既不編譯,也不連接,僅僅顯示文件名.

Copyright © Linux教程網 All Rights Reserved