国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
gcc的使用簡(jiǎn)介與命令行參數(shù)說(shuō)明

參考:《GNU gcc嵌入式系統(tǒng)開(kāi)發(fā) 作者:董文軍》

(一) gcc的基本用法

(二) 警告提示功能選項(xiàng)

(三) 庫(kù)操作選項(xiàng)

(四) 調(diào)試選項(xiàng)

(五) 交叉編譯選項(xiàng)

(一) gcc的基本用法

使用gcc編譯器時(shí),必須給出一系列必要的調(diào)用參數(shù)和文件名稱(chēng)。不同參數(shù)的先后順序?qū)?zhí)行結(jié)果沒(méi)有影響,只有在使用同類(lèi)參數(shù)時(shí)的先后順序才需要考慮。如果使用了多個(gè) -L 的參數(shù)來(lái)定義庫(kù)目錄,gcc會(huì)根據(jù)多個(gè) -L 參數(shù)的先后順序來(lái)執(zhí)行相應(yīng)的庫(kù)目錄。

因?yàn)楹芏鄃cc參數(shù)都由多個(gè)字母組成,所以gcc參數(shù)不支持單字母的組合,Linux中常被叫短參數(shù)(short options),如 -dr 與 -d -r 的含義不一樣。gcc編譯器的調(diào)用參數(shù)大約有100多個(gè),其中多數(shù)參數(shù)我們可能根本就用不到,這里只介紹其中最基本、最常用的參數(shù)。

gcc最基本的用法是:gcc [options] [filenames]

其中,options就是編譯器所需要的參數(shù),filenames給出相關(guān)的文件名稱(chēng),最常用的有以下參數(shù):

-c   

只編譯,不鏈接成為可執(zhí)行文件。編譯器只是由輸入的 .c 等源代碼文件生成 .o 為后綴的目標(biāo)文件,通常用于編譯不包含主程序的子程序文件。

-o output_filename   

確定輸出文件的名稱(chēng)為output_filename。同時(shí)這個(gè)名稱(chēng)不能和源文件同名。如果不給出這個(gè)選項(xiàng),gcc就給出默認(rèn)的可執(zhí)行文件 a.out 。

-g

產(chǎn)生符號(hào)調(diào)試工具(GNU的 gdb)所必要的符號(hào)信息。想要對(duì)源代碼進(jìn)行調(diào)試,就必須加入這個(gè)選項(xiàng)。

-O

對(duì)程序進(jìn)行優(yōu)化編譯、鏈接。采用這個(gè)選項(xiàng),整個(gè)源代碼會(huì)在編譯、鏈接過(guò)程中進(jìn)行優(yōu)化處理,這樣產(chǎn)生的可執(zhí)行文件的執(zhí)行效率可以提高,但是編譯、鏈接的速度就相應(yīng)地要慢一些,而且對(duì)執(zhí)行文件的調(diào)試會(huì)產(chǎn)生一定的影響,造成一些執(zhí)行效果與對(duì)應(yīng)源文件代碼不一致等一些令人“困惑”的情況。因此,一般在編譯輸出軟件發(fā)行版時(shí)使用此選項(xiàng)。

-O2

比 -O 更好的優(yōu)化編譯、鏈接。當(dāng)然整個(gè)編譯鏈接過(guò)程會(huì)更慢。

-Idirname

將 dirname 所指出的目錄加入到程序頭文件目錄列表中,是在預(yù)編譯過(guò)程中使用的參數(shù)。

說(shuō)明:

C程序中的頭文件包含兩種情況:

#include

#include "stdio.h"

其中,使用尖括號(hào)(<>),預(yù)處理程序 cpp 在系統(tǒng)默認(rèn)包含文件目錄(如/usr/include)中搜索相應(yīng)的文件;使用雙引號(hào),預(yù)處理程序 cpp 首先在當(dāng)前目錄中搜尋頭文件,如果沒(méi)有找到,就到指定的 dirname 目錄中去尋找。

在程序設(shè)計(jì)中,如果需要的這種包含文件分別分布在不同的目錄中,就需要逐個(gè)使用 -I 選項(xiàng)給出搜索路徑。

-Ldirname

將dirname所指出的目錄加入到程序函數(shù)庫(kù)文件的目錄列表中,是在鏈接過(guò)程中使用的參數(shù)。在默認(rèn)狀態(tài)下,鏈接程序 ld 在系統(tǒng)默認(rèn)路徑中(如 /usr/lib)尋找所需要的庫(kù)文件。這個(gè)選項(xiàng)告訴鏈接程序,首先到 -L 指定的目錄中去尋找,然后到系統(tǒng)默認(rèn)路徑中尋找;如果函數(shù)庫(kù)存放在多個(gè)目錄下,就需要依次使用這個(gè)選項(xiàng),給出相應(yīng)的存放目錄。

-lname

鏈接時(shí)裝載名為 libname.a 的函數(shù)庫(kù)。該函數(shù)庫(kù)位于系統(tǒng)默認(rèn)的目錄或者由 -L 選項(xiàng)確定的目錄下。例如,-lm 表示鏈接名為 libm.a 的數(shù)學(xué)函數(shù)庫(kù)。

例子:假定有一個(gè)程序名為 test.c 的C語(yǔ)言源代碼文件,要生成一個(gè)可執(zhí)行文件。

#include

int main(void)

{

printf("Hello world/n");

return 0;

}

最簡(jiǎn)單的辦法:gcc test.c -o test

首先,gcc需要調(diào)用預(yù)處理程序 cpp,由它負(fù)責(zé)展開(kāi)在源文件中定義的宏,并向其中插入“#include”語(yǔ)句所包含的內(nèi)容;接著,gcc調(diào)用ccl 和 as,將處理后的源代碼編譯成目標(biāo)代碼;最后,gcc調(diào)用鏈接程序 ld,把生成的目標(biāo)代碼鏈接成一個(gè)可執(zhí)行程序。因此,默認(rèn)情況下,預(yù)編譯、編譯鏈接一次完成。

編譯過(guò)程的分步執(zhí)行:

為了更好地理解gcc的工作過(guò)程,我們可以讓在gcc工作的4個(gè)階段中的任何一個(gè)階段中停止下來(lái)。相關(guān)的參數(shù)有:

-E

預(yù)編譯后停下來(lái),生成后綴為 .i 的預(yù)編譯文件。

-c

編譯后停下來(lái),生成后綴為 .o 的目標(biāo)文件。

-S

匯編后停下來(lái),生成后綴為 .s 的匯編源文件。

第一步:進(jìn)行預(yù)編譯,使用 -E 參數(shù)

gcc -E test.c -o test.i

查看 test.i 文件中的內(nèi)容,會(huì)發(fā)現(xiàn) stdio.h 的內(nèi)容確實(shí)都插到文件里去了,而其他應(yīng)當(dāng)被預(yù)處理的宏定義也都做了相應(yīng)的處理。

第二步:將 test.i 編譯為目標(biāo)代碼,使用 -c 參數(shù)

gcc -c test.c -o test.o

第三步:生成匯編源文件

gcc -S test.c -o test.s

第四步:將生成的目標(biāo)文件鏈接成可執(zhí)行文件

gcc test.o - o test

對(duì)于稍微復(fù)雜的情況,比如有多個(gè)源代碼文件、需要鏈接庫(kù)或有其他比較特別的要求,就要給定適當(dāng)?shù)恼{(diào)用選項(xiàng)參數(shù)。

例子:整個(gè)源代碼程序由兩個(gè)文件 testmain.c 和 testsub.c 組成,程序中使用了系統(tǒng)提供的數(shù)學(xué)庫(kù)(所有與浮點(diǎn)相關(guān)的數(shù)學(xué)運(yùn)算都必須使用數(shù)學(xué)庫(kù))。

gcc testmain.c testsub.c -lm -o test

其中,-lm 表示鏈接系統(tǒng)的數(shù)學(xué)庫(kù) libm.a 。

說(shuō)明:

在編譯一個(gè)包含許多源文件的工程時(shí),若只用一條gcc命令來(lái)完成編譯是非常浪費(fèi)時(shí)間的。假如項(xiàng)目中有100個(gè)源文件需要編譯,并且每個(gè)源文件中都包含一萬(wàn)行代碼,如果像上面那樣僅用一條gcc命令來(lái)完成編譯工作,那么gcc需要將每個(gè)源文件都重新編譯一遍,然后再全部鏈接起來(lái)。很顯然,這樣浪費(fèi)的時(shí)間相當(dāng)多,尤其是當(dāng)用戶只是修改了其中某個(gè)文件的時(shí)候,完全沒(méi)有必要將每個(gè)文件都重新編譯一遍,因?yàn)楹芏嘁呀?jīng)生成的目標(biāo)文件是不會(huì)發(fā)生改變的。要解決這個(gè)問(wèn)題,需要借助像make這樣的工具。

(二) 警告提示功能選項(xiàng)

gcc包含完整的出錯(cuò)檢查和警告提示功能,它們可以幫助Linux程序員寫(xiě)出更加專(zhuān)業(yè)的代碼。

(1) -pedantic 選項(xiàng)

當(dāng)gcc在編譯不符合ANSI/ISO C 語(yǔ)言標(biāo)準(zhǔn)的源代碼時(shí),將產(chǎn)生相應(yīng)的警告信息。

[cpp] view plain copy

print?

#include 

void main(void)  

{  

long long int var = 1;  

printf("It is not standard C code!/n");  

}  

它有以下問(wèn)題:

> main 函數(shù)的返回值被聲明為 void,但實(shí)際上應(yīng)該是 int。

> 使用了 GNU 語(yǔ)法擴(kuò)展,即使用 long long 來(lái)聲明64位整數(shù),不符合 ANSI/ISO C 語(yǔ)言標(biāo)準(zhǔn)。

> main 函數(shù)在終止前沒(méi)有調(diào)用 return 語(yǔ)句。

(2) -Wall 選項(xiàng)

除了 -pedantic 之外,gcc 還有一些其他編譯選項(xiàng),也能夠產(chǎn)生有用的警告信息。這些選項(xiàng)大多以 -W 開(kāi)頭。其中最有價(jià)值的當(dāng)數(shù) -Wall 了,使用它能夠使 gcc 產(chǎn)生盡可能多的警告信息。

gcc 給出的警告信息雖然從嚴(yán)格意義上說(shuō)不能算作錯(cuò)誤,但卻和可能成為錯(cuò)誤來(lái)源。一個(gè)優(yōu)秀的程序員應(yīng)該盡量避免產(chǎn)生警告信息,使自己的代碼始終保持簡(jiǎn)潔、優(yōu)美和健壯的特性。

建議:gcc 給出的警告信息是很有價(jià)值的,它們不僅可以幫助程序員寫(xiě)出更加健壯的程序,而且還是跟蹤和調(diào)試程序的有力工具。建議在用 gcc 編譯源代碼時(shí)始終帶上 -Wall 選項(xiàng),并把它逐漸培養(yǎng)成一種習(xí)慣,這對(duì)找出常見(jiàn)的隱式編程錯(cuò)誤很有幫助。

(3) -Werror 選項(xiàng)

在處理警告方面,另一個(gè)常用的編譯選項(xiàng)是 -Werror。它要求 gcc 將所有的警告當(dāng)成錯(cuò)誤進(jìn)行處理,這在使用自動(dòng)編譯工具(如 Make 等)時(shí)非常有用。如果編譯時(shí)帶上 -Werror 選項(xiàng),那么 gcc 會(huì)在所有產(chǎn)生警告的地方停止編譯,迫使程序員對(duì)自己的代碼進(jìn)行修改。只有當(dāng)相應(yīng)的警告信息消除時(shí),才可能將編譯過(guò)程繼續(xù)朝前推進(jìn)。

(4) -Wcast-align 選項(xiàng)

當(dāng)源程序中地址不需要對(duì)齊的指針指向一個(gè)地址需要對(duì)齊的變量地址時(shí),則產(chǎn)生一個(gè)警告。例如,char * 指向一個(gè) int * 地址,而通常在機(jī)器中 int 變量類(lèi)型是需要地址能被2或4整除的對(duì)齊地址。

(5) 其他常用選項(xiàng)

-v                            輸出 gcc 工作的詳細(xì)過(guò)程

--target-help       顯示目前所用的gcc支持CPU類(lèi)型

-Q                           顯示編譯過(guò)程的統(tǒng)計(jì)數(shù)據(jù)和每一個(gè)函數(shù)名

(三) 庫(kù)操作選項(xiàng)

在Linux下開(kāi)發(fā)軟件時(shí),完全不使用第三方函數(shù)庫(kù)的情況是比較少見(jiàn)的,通常來(lái)講都需要借助一個(gè)或多個(gè)函數(shù)庫(kù)的支持才能夠完成相應(yīng)的功能。

從程序員的角度看,函數(shù)庫(kù)實(shí)際上就是一些頭文件(.h)和庫(kù)文件(.so 或 .a)的集合。雖然Linux下的大多數(shù)函數(shù)都默認(rèn)將頭文件放到 /usr/include/ 目錄下,而庫(kù)文件則放到 /usr/lib/ 目錄下,但并不是所有的情況都是這樣。正因如此,gcc 在編譯時(shí)必須有自己的辦法來(lái)查找所需要的頭文件和庫(kù)文件。常用的方法有:

(1) -I

可以向 gcc 的頭文件搜索路徑中添加新的目錄。

(2) -L

如果使用了不在標(biāo)準(zhǔn)位置的庫(kù)文件,那么可以通過(guò) -L 選項(xiàng)向 gcc 的庫(kù)文件搜索路徑中添加新的目錄。

(3) -l

Linux下的庫(kù)文件在命名時(shí)有一個(gè)約定,就是應(yīng)該以 lib 這3個(gè)字母開(kāi)頭,由于所有的庫(kù)文件都遵循了同樣的規(guī)范,因此在用 -l 選項(xiàng)指定鏈接的庫(kù)文件名時(shí)可以省去 lib 這3個(gè)字母。例如,gcc 在對(duì) -lfoo 進(jìn)行處理時(shí),會(huì)自動(dòng)去鏈接名為 libfoo.so 的文件。

(4) -static

Linux下的庫(kù)文件分為兩大類(lèi),分別是:動(dòng)態(tài)鏈接庫(kù)(通常以 .so 結(jié)尾)和靜態(tài)鏈接庫(kù)(通常以 .a 結(jié)尾)。

兩者的差別僅在程序執(zhí)行時(shí)所需的代碼是在運(yùn)行時(shí)動(dòng)態(tài)加載的,還是在編譯時(shí)靜態(tài)加載的。

默認(rèn)情況下,gcc 在鏈接時(shí)優(yōu)先使用動(dòng)態(tài)鏈接庫(kù),只有當(dāng)動(dòng)態(tài)鏈接庫(kù)不存在時(shí)才考慮使用靜態(tài)鏈接庫(kù)。

如果需要的話,可以在編譯時(shí)加上 -static 選項(xiàng),強(qiáng)制使用靜態(tài)鏈接庫(kù)。

(5) -shared

生成一個(gè)共享的目標(biāo)文件,它能夠與其他的目標(biāo)一起鏈接生成一個(gè)可執(zhí)行的文件。

(四) 調(diào)試選項(xiàng)

對(duì)于Linux程序員來(lái)講,gdb(GNU Debugger)通過(guò)與 gcc 的配合使用,為基于Linux的軟件開(kāi)發(fā)提供了一個(gè)完善的調(diào)試環(huán)境。常用的有:

(1) -g 和 -ggdb

默認(rèn)情況下,gcc 在編譯時(shí)不會(huì)將調(diào)試符號(hào)插入到生成的二進(jìn)制代碼中,因?yàn)檫@樣會(huì)增加可執(zhí)行文件的大小。如果需要在編譯時(shí)生成調(diào)試符號(hào)信息,可以使用 gcc 的 -g 或 -ggdb 選項(xiàng)。

gcc 在產(chǎn)生調(diào)試符號(hào)時(shí),同樣采用了分級(jí)的思路,開(kāi)發(fā)人員可以通過(guò)在 -g 選項(xiàng)后附加數(shù)字1、2、3指定在代碼中加入調(diào)試信息的多少。默認(rèn)的級(jí)別是2(-g2),此時(shí)產(chǎn)生的調(diào)試信息包括:擴(kuò)展的符號(hào)表、行號(hào)、局部或外部變量信息。

級(jí)別3(-g3)包含級(jí)別2中的所有調(diào)試信息以及源代碼中定義的宏。

級(jí)別1(-g1)不包含局部變量和與行號(hào)有關(guān)的調(diào)試信息,因此只能夠用于回溯跟蹤和堆棧轉(zhuǎn)儲(chǔ)。

回溯追蹤:指的是監(jiān)視程序在運(yùn)行過(guò)程中函數(shù)調(diào)用歷史。

堆棧轉(zhuǎn)儲(chǔ):則是一種以原始的十六進(jìn)制格式保存程序執(zhí)行環(huán)境的方法。

注意:使用任何一個(gè)調(diào)試選項(xiàng)都會(huì)使最終生成的二進(jìn)制文件的大小急劇增加,同時(shí)增加程序在執(zhí)行時(shí)的開(kāi)銷(xiāo),因此,調(diào)試選項(xiàng)通常僅在軟件的開(kāi)發(fā)和調(diào)試階段使用。

(2) -p 和 -pg

會(huì)將剖析(Profiling)信息加入到最終生成的二進(jìn)制代碼中。剖析信息對(duì)于找出程序的性能瓶頸很有幫助,是協(xié)助Linux程序員開(kāi)發(fā)出高性能程序的有力工具。

(3) -save-temps

保存編譯過(guò)程中生成的一些列中間文件。

# gcc test.c -o test -save-temps

除了生成執(zhí)行文件test之外,還保存了test.i 和 test.s 中間文件,供用戶查詢(xún)調(diào)試。

(五) 交叉編譯選項(xiàng)

通常情況下使用 gcc 編譯的目標(biāo)代碼都與使用的機(jī)器是一致的,但 gcc 也支持交叉編譯的功能,能夠編譯其他不同CPU的目標(biāo)代碼。

使用 gcc 開(kāi)發(fā)嵌入式系統(tǒng),我們幾乎都是以通用的PC機(jī)(X86)平臺(tái)來(lái)做宿主機(jī),通過(guò) gcc 的交叉編譯功能對(duì)其他嵌入式CPU的開(kāi)發(fā)任務(wù)。

(具體的選項(xiàng)設(shè)置,此處省略)

GCC常用參數(shù)詳解

簡(jiǎn)介

gcc and g++現(xiàn)在是gnu中最主要和最流行的c & c++編譯器 .gcc/g++在執(zhí)行編譯工作的時(shí)候,總共需要以下幾步:

1.預(yù)處理,生成.i的文件[預(yù)處理器cpp]

2.將預(yù)處理后的文件不轉(zhuǎn)換成匯編語(yǔ)言,生成文件.s[編譯器egcs]

3.有匯編變?yōu)槟繕?biāo)代碼(機(jī)器代碼)生成.o的文件[匯編器as]

4.連接目標(biāo)代碼,生成可執(zhí)行程序[鏈接器ld]

GCC能夠處理的后綴有:

a. *.c *.C (C語(yǔ)言)

b. *.cxx *.cc (C++語(yǔ)言)

c. *.m (面向?qū)ο蟮腃)

d. *.i (預(yù)處理后的C語(yǔ)言源文件)

e. *.ii (預(yù)處理后的C++語(yǔ)言源文件)

f. *.s *.S (匯編語(yǔ)言)

h. *.h (頭文件)

目標(biāo)文件可以是:

a. *.o 編譯連接后的目標(biāo)文件

b. *.a 庫(kù)文件 

gcc與g++有什么區(qū)別?

gcc和g++都是GNU(組織)的一個(gè)編譯器。

誤區(qū)一:gcc只能編譯c代碼,g++只能編譯c++代碼

兩者都可以,但是請(qǐng)注意:

1.后綴為.c的,gcc把它當(dāng)作是C程序,而g++當(dāng)作是c++程序;后綴為.cpp的,兩者都會(huì)認(rèn)為是c++程序,注意,雖然c++是c的超集,但是兩者對(duì)語(yǔ)法的要求是有區(qū)別的。C++的語(yǔ)法規(guī)則更加嚴(yán)謹(jǐn)一些。

2.編譯階段,g++會(huì)調(diào)用gcc,對(duì)于c++代碼,兩者是等價(jià)的,但是因?yàn)間cc命令不能自動(dòng)和C++程序使用的庫(kù)聯(lián)接,所以通常用g++來(lái)完成鏈接,為了統(tǒng)一起見(jiàn),干脆編譯/鏈接統(tǒng)統(tǒng)用g++了,這就給人一種錯(cuò)覺(jué),好像cpp程序只能用g++似的。

誤區(qū)二:gcc不會(huì)定義__cplusplus宏,而g++會(huì)

實(shí)際上,這個(gè)宏只是標(biāo)志著編譯器將會(huì)把代碼按C還是C++語(yǔ)法來(lái)解釋?zhuān)缟纤?,如果后綴為.c,并且采用gcc編譯器,則該宏就是未定義的,否則,就是已定義。

誤區(qū)三:編譯只能用gcc,鏈接只能用g++

嚴(yán)格來(lái)說(shuō),這句話不算錯(cuò)誤,但是它混淆了概念,應(yīng)該這樣說(shuō):編譯可以用gcc/g++,而鏈接可以用g++或者gcc -lstdc++。因?yàn)間cc命令不能自動(dòng)和C++程序使用的庫(kù)聯(lián)接,所以通常使用g++來(lái)完成聯(lián)接。但在編譯階段,g++會(huì)自動(dòng)調(diào)用gcc,二者等價(jià)。

參數(shù)詳解

無(wú)選項(xiàng)編譯鏈接

將test.c預(yù)處理、匯編、編譯并鏈接形成可執(zhí)行文件。這里未指定輸出文件,默認(rèn)輸出為a.out。

例子用法:

gcc test.c

無(wú)選項(xiàng)鏈接

gcc test.o -o test

將編譯輸出文件test.o鏈接成最終可執(zhí)行文件test。

-x language filename  

設(shè)定文件所使用的語(yǔ)言,使后綴名無(wú)效,對(duì)以后的多個(gè)有效.也就是根據(jù)約定C語(yǔ)言的后綴名稱(chēng)是.c的,而C++的后綴名是.C或者.cpp,如果你很個(gè)性, 決定你的C代碼文件的后綴名是.pig 哈哈,那你就要用這個(gè)參數(shù),這個(gè)參數(shù)對(duì)他后面的文件名都起作用,除非到了下一個(gè)參數(shù)的使用。  

可以使用的參數(shù)嗎有下面的這些  

`c', `objective-c', `c-header', `c++', `cpp-output', `assembler', and `assembler-with-cpp'.  

看到英文,應(yīng)該可以理解的。  

例子用法:  

gcc -x c hello.pig  

-x none filename  

關(guān)掉上一個(gè)選項(xiàng),也就是讓gcc根據(jù)文件名后綴,自動(dòng)識(shí)別文件類(lèi)型  

例子用法:  

gcc -x c hello.pig -x none hello2.c  

-c  

只激活預(yù)處理,編譯,和匯編,也就是他只把程序做成obj文件  

例子用法:  

gcc -c hello.c  

他將生成.o的obj文件

gcc -c test.s

將匯編輸出文件test.s編譯輸出test.o文件。 

-S  

只激活預(yù)處理和編譯,就是指把文件編譯成為匯編代碼。  

例子用法:  

gcc -S hello.c  

他將生成.s的匯編代碼,你可以用文本編輯器察看

gcc -S test.i  

將預(yù)處理輸出文件test.i匯編成test.s文件

-E  

只激活預(yù)處理,這個(gè)不生成文件,你需要把它重定向到一個(gè)輸出文件里面.  

例子用法: 

gcc -E hello.c >; pianoapan.txt  

gcc -E hello.c | more  

慢慢看吧,一個(gè)hello word 也要與處理成800行的代碼

gcc -E test.c -o test.i 

-o  

制定目標(biāo)名稱(chēng),缺省的時(shí)候,gcc 編譯出來(lái)的文件是a.out,很難聽(tīng),如果你和我有同感,改掉它,哈哈  

例子用法:  

gcc -o hello.exe hello.c (哦,windows用習(xí)慣了)  

gcc -o hello.asm -S hello.c 

-pipe  

使用管道代替編譯中臨時(shí)文件,在使用非gnu匯編工具的時(shí)候,可能有些問(wèn)題  

gcc -pipe -o hello.exe hello.c  

-ansi  

關(guān)閉gnu c中與ansi c不兼容的特性,激活ansi c的專(zhuān)有特性(包括禁止一些asm inline typeof關(guān)鍵字,以及UNIX,vax等預(yù)處理宏, 

-fno-asm  

此選項(xiàng)實(shí)現(xiàn)ansi選項(xiàng)的功能的一部分,它禁止將asm,inline和typeof用作關(guān)鍵字。       

-fno-strict-prototype  

只對(duì)g++起作用,使用這個(gè)選項(xiàng),g++將對(duì)不帶參數(shù)的函數(shù),都認(rèn)為是沒(méi)有顯式的對(duì)參數(shù)的個(gè)數(shù)和類(lèi)型說(shuō)明,而不是沒(méi)有參數(shù).  

而gcc無(wú)論是否使用這個(gè)參數(shù),都將對(duì)沒(méi)有帶參數(shù)的函數(shù),認(rèn)為城沒(méi)有顯式說(shuō)明的類(lèi)型  

-fthis-is-varialble  

就是向傳統(tǒng)c++看齊,可以使用this當(dāng)一般變量使用.  

-fcond-mismatch  

允許條件表達(dá)式的第二和第三參數(shù)類(lèi)型不匹配,表達(dá)式的值將為void類(lèi)型  

-funsigned-char  

-fno-signed-char  

-fsigned-char  

-fno-unsigned-char  

這四個(gè)參數(shù)是對(duì)char類(lèi)型進(jìn)行設(shè)置,決定將char類(lèi)型設(shè)置成unsigned char(前兩個(gè)參數(shù))或者 signed char(后兩個(gè)參數(shù))  

-include file  

包含某個(gè)代碼,簡(jiǎn)單來(lái)說(shuō),就是便以某個(gè)文件,需要另一個(gè)文件的時(shí)候,就可以用它設(shè)定,功能就相當(dāng)于在代碼中使用#include;  

例子用法:  

gcc hello.c -include /root/pianopan.h  

-imacros file  

將file文件的宏,擴(kuò)展到gcc/g++的輸入文件,宏定義本身并不出現(xiàn)在輸入文件中  

-Dmacro 

以字符串“1”定義 MACRO 宏 

相當(dāng)于C語(yǔ)言中的#define macro  

-Dmacro=defn

以字符串“DEFN”定義 MACRO 宏  

相當(dāng)于C語(yǔ)言中的#define macro defn  

-Umacro 

取消對(duì) MACRO 宏的定義 

相當(dāng)于C語(yǔ)言中的#undef macro 

-undef  

取消對(duì)任何非標(biāo)準(zhǔn)宏的定義  

-Idir  

在你是用#include"file"的時(shí)候,gcc/g++會(huì)先在當(dāng)前目錄查找你所制定的頭文件,如果沒(méi)有找到,他回到缺省的頭文件目錄找,如果使用-I制定了目錄,他  

回先在你所制定的目錄查找,然后再按常規(guī)的順序去找.  

對(duì)于#include;,gcc/g++會(huì)到-I制定的目錄查找,查找不到,然后將到系統(tǒng)的缺省的頭文件目錄查找  

-I-  

就是取消前一個(gè)參數(shù)的功能,所以一般在-Idir之后使用  

-idirafter dir  

在-I的目錄里面查找失敗,講到這個(gè)目錄里面查找.  

-iprefix prefix  

-iwithprefix dir  

一般一起使用,當(dāng)-I的目錄查找失敗,會(huì)到prefix+dir下查找  

-nostdinc  

使編譯器不再系統(tǒng)缺省的頭文件目錄里面找頭文件,一般和-I聯(lián)合使用,明確限定頭文件的位置  

-nostdin C++  

規(guī)定不在g++指定的標(biāo)準(zhǔn)路經(jīng)中搜索,但仍在其他路徑中搜索,.此選項(xiàng)在創(chuàng)libg++庫(kù)使用  

-C  

在預(yù)處理的時(shí)候,不刪除注釋信息,一般和-E使用,有時(shí)候分析程序,用這個(gè)很方便的  

-M  

生成文件關(guān)聯(lián)的信息。包含目標(biāo)文件所依賴(lài)的所有源代碼你可以用gcc -M hello.c來(lái)測(cè)試一下,很簡(jiǎn)單。  

-MM  

和上面的那個(gè)一樣,但是它將忽略由#include;造成的依賴(lài)關(guān)系。  

-MD  

和-M相同,但是輸出將導(dǎo)入到.d的文件里面  

-MMD  

和-MM相同,但是輸出將導(dǎo)入到.d的文件里面  

-Wa,option  

此選項(xiàng)傳遞option給匯編程序;如果option中間有逗號(hào),就將option分成多個(gè)選項(xiàng),然后傳遞給會(huì)匯編程序  

-Wl.option  

此選項(xiàng)傳遞option給連接程序;如果option中間有逗號(hào),就將option分成多個(gè)選項(xiàng),然后傳遞給會(huì)連接程序. 

-llibrary  

制定編譯的時(shí)候使用的庫(kù)  

例子用法  

gcc -lcurses hello.c  

使用ncurses庫(kù)編譯程序  

-Ldir  

制定編譯的時(shí)候,搜索庫(kù)的路徑。比如你自己的庫(kù),可以用它制定目錄,不然  

編譯器將只在標(biāo)準(zhǔn)庫(kù)的目錄找。這個(gè)dir就是目錄的名稱(chēng)。  

-O0  

-O1  

-O2  

-O3  

編譯器的優(yōu)化選項(xiàng)的4個(gè)級(jí)別,-O0表示沒(méi)有優(yōu)化,-O1為缺省值,-O3優(yōu)化級(jí)別最高

例子用法: 

gcc -O1 test.c -o test

使用編譯優(yōu)化級(jí)別1編譯程序。級(jí)別為1~3,級(jí)別越大優(yōu)化效果越好,但編譯時(shí)間越長(zhǎng)

-g  

只是編譯器,在編譯的時(shí)候,產(chǎn)生調(diào)試信息。  

-gstabs  

此選項(xiàng)以stabs格式聲稱(chēng)調(diào)試信息,但是不包括gdb調(diào)試信息.  

-gstabs+  

此選項(xiàng)以stabs格式聲稱(chēng)調(diào)試信息,并且包含僅供gdb使用的額外調(diào)試信息.  

-ggdb  

此選項(xiàng)將盡可能的生成gdb的可以使用的調(diào)試信息. 

-static  

此選項(xiàng)將禁止使用動(dòng)態(tài)庫(kù),所以,編譯出來(lái)的東西,一般都很大,也不需要什么  

動(dòng)態(tài)連接庫(kù),就可以運(yùn)行. 

-share  

此選項(xiàng)將盡量使用動(dòng)態(tài)庫(kù),所以生成文件比較小,但是需要系統(tǒng)由動(dòng)態(tài)庫(kù). 

-traditional  

試圖讓編譯器支持傳統(tǒng)的C語(yǔ)言特性 

-IDIRECTORY 

指定額外的頭文件搜索路徑DIRECTORY

-LDIRECTORY 

指定額外的函數(shù)庫(kù)搜索路徑DIRECTORY

-lLIBRARY 

連接時(shí)搜索指定的函數(shù)庫(kù)LIBRARY

-m486

針對(duì) 486 進(jìn)行代碼優(yōu)化 

-shared 

生成共享目標(biāo)文件。通常用在建立共享庫(kù)時(shí)  

-static

禁止使用共享連接

-w 

不生成任何警告信息

-Wall 

生成所有警告信息

-save-temps

一次獲得全部的中文輸出文件,正常的進(jìn)行編譯連接,.i、.s、.o為后綴,文件名相同

-fsyntax-only

不會(huì)執(zhí)行預(yù)處理、編譯、匯編、連接,只會(huì)測(cè)試輸入文件的語(yǔ)法是否正確

-std

指定C方言,如:-std=c99,gcc默認(rèn)的方言是GNU C

多源文件的編譯方法

如果有多個(gè)源文件,基本上有兩種編譯方法:

[假設(shè)有兩個(gè)源文件為test.c和testfun.c]

1. 多個(gè)文件一起編譯

用法:#gcc testfun.c test.c -o test

作用:將testfun.c和test.c分別編譯后鏈接成test可執(zhí)行文件。

2. 分別編譯各個(gè)源文件,之后對(duì)編譯后輸出的目標(biāo)文件鏈接。

用法:

#gcc -c testfun.c //將testfun.c編譯成testfun.o

#gcc -c test.c //將test.c編譯成test.o

#gcc -o testfun.o test.o -o test //將testfun.o和test.o鏈接成test

以上兩種方法相比較,第一中方法編譯時(shí)需要所有文件重新編譯,而第二種方法可以只重新編譯修改的文件,未修改的文件不用重新編譯。

FAQ

1、為什么會(huì)出現(xiàn)undefined reference to 'xxxxx'錯(cuò)誤?

首 先這是鏈接錯(cuò)誤,不是編譯錯(cuò)誤,也就是說(shuō)如果只有這個(gè)錯(cuò)誤,說(shuō)明你的程序源碼本身沒(méi)有問(wèn)題,是你用編譯器編譯時(shí)參數(shù)用得不對(duì),你沒(méi)有指定鏈接程序要用到得 庫(kù),比如你的程序里用到了一些數(shù)學(xué)函數(shù),那么你就要在編譯參數(shù)里指定程序要鏈接數(shù)學(xué)庫(kù),方法是在編譯命令行里加入-lm。

2、-l參數(shù)和-L參數(shù)

-l參數(shù)就是用來(lái)指定程序要鏈接的庫(kù),-l參數(shù)緊接著就是庫(kù)名,那么庫(kù)名跟真正的庫(kù)文

件名有什么關(guān)系呢?

就拿數(shù)學(xué)庫(kù)來(lái)說(shuō),他的庫(kù)名是m,他的庫(kù)文件名是libm.so,很容易看出,把庫(kù)文件名的頭lib和尾.so去掉就是庫(kù)名了。

好 了現(xiàn)在我們知道怎么得到庫(kù)名了,比如我們自已要用到一個(gè)第三方提供的庫(kù)名字叫l(wèi)ibtest.so,那么我們只要把libtest.so拷貝到/usr /lib里,編譯時(shí)加上-ltest參數(shù),我們就能用上libtest.so庫(kù)了(當(dāng)然要用libtest.so庫(kù)里的函數(shù),我們還需要與 libtest.so配套的頭文件)。

放在/lib和/usr/lib和/usr/local/lib里的庫(kù)直接用-l參數(shù)就能鏈接了,但如果庫(kù)文件

沒(méi) 放在這三個(gè)目錄里,而是放在其他目錄里,這時(shí)我們只用-l參數(shù)的話,鏈接還是會(huì)出錯(cuò),出錯(cuò)信息大概是:“/usr/bin/ld: cannot find -lxxx”,也就是鏈接程序ld在那3個(gè)目錄里找不到libxxx.so,這時(shí)另外一個(gè)參數(shù)-L就派上用場(chǎng)了,比如常用的X11的庫(kù),它放在/usr /X11R6/lib目錄下,我們編譯時(shí)就要用-L/usr/X11R6/lib -lX11參數(shù),-L參數(shù)跟著的是庫(kù)文件所在的目錄名。

再比如我們把libtest.so放在/aaa/bbb/ccc目錄下,那鏈接參數(shù)就是-L/aaa/bbb/ccc -ltest

另 外,大部分libxxxx.so只是一個(gè)鏈接,以RH9為例,比如libm.so它鏈接到/lib/libm.so.x,/lib/libm.so.6又 鏈到/lib/libm-2.3.2.so,如果沒(méi)有這樣的鏈接,還是會(huì)出錯(cuò),因?yàn)閘d只會(huì)找libxxxx.so,所以如果你要用到xxxx庫(kù),而只有 libxxxx.so.x或者libxxxx-x.x.x.so,做一個(gè)鏈接就可以了ln -s libxxxx-x.x.x.so libxxxx.so,手工來(lái)寫(xiě)鏈接參數(shù)總是很麻煩的,還好很多庫(kù)開(kāi)發(fā)包提供了生成鏈接參數(shù)的程序,名字一般叫xxxx-config,一般放在/usr /bin目錄下,比如gtk1.2的鏈接參數(shù)生成程序是gtk-config,執(zhí)行g(shù)tk-config --libs就能得到以下輸出"-L/usr/lib -L/usr/X11R6/lib -lgtk -lgdk -rdynamic -lgmodule -lglib -ldl -lXi -lXext -lX11 -lm",這就是編譯一個(gè)gtk1.2程序所需的gtk鏈接參數(shù),xxx-config除了--libs參數(shù)外還有一個(gè)參數(shù)是--cflags用來(lái)生成頭 文件包含目錄的,也就是-I參數(shù),在下面我們將會(huì)講到。你可以試試執(zhí)行g(shù)tk-config --libs --cflags,看看輸出結(jié)果?,F(xiàn)在的問(wèn)題就是怎樣用這些輸出結(jié)果了,最笨的方法就是復(fù)制粘貼或者照抄,聰明的辦法是在編譯命令行里加入這個(gè) `xxxx-config --libs --cflags`,比如編譯一個(gè)gtk程序:gcc gtktest.c `gtk-config --libs --cflags`這樣就差不多了。注意`不是單引號(hào),而是1鍵左邊那個(gè)鍵。除了xxx-config以外,現(xiàn)在新的開(kāi)發(fā)包一般都用pkg-config 來(lái)生成鏈接參數(shù),使用方法跟xxx-config類(lèi)似,但xxx-config是針對(duì)特定的開(kāi)發(fā)包,但pkg-config包含很多開(kāi)發(fā)包的鏈接參數(shù)的生 成,用pkg-config --list-all命令可以列出所支持的所有開(kāi)發(fā)包,pkg-config的用法就是pkg-config pagName --libs --cflags,其中pagName是包名,是pkg-config--list-all里列出名單中的一個(gè),比如gtk1.2的名字就是 gtk+,pkg-config gtk+ --libs --cflags的作用跟gtk-config --libs --cflags是一樣的。比如:gcc gtktest.c `pkg-config gtk+ --libs --cflags`。

3、-include和-I參數(shù)

-include用來(lái)包含頭文件,但一般情況下包含頭文件都在源碼 里用#include xxxxxx實(shí)現(xiàn),-include參數(shù)很少用。-I參數(shù)是用來(lái)指定頭文件目錄,/usr/include目錄一般是不用指定的,gcc知道去那里找,但 是如果頭文件不在/usr/include里我們就要用-I參數(shù)指定了,比如頭文件放在/myinclude目錄里,那編譯命令行就要加上-I /myinclude參數(shù)了,如果不加你會(huì)得到一個(gè)"xxxx.h: No such file or directory"的錯(cuò)誤。-I參數(shù)可以用相對(duì)路徑,比如頭文件在當(dāng)前目錄,可以用-I.來(lái)指定。上面我們提到的--cflags參數(shù)就是用來(lái)生成-I 參數(shù)的。

4、幾個(gè)相關(guān)的環(huán)境變量

PKG_CONFIG_PATH:用來(lái)指定pkg-config用到的pc文件的路徑,默認(rèn)是/usr/lib/pkgconfig,pc文件是文本文件,擴(kuò)展名是.pc,里面定義開(kāi)發(fā)包的安裝路徑,Libs參數(shù)和Cflags參數(shù)等等。

CC:用來(lái)指定c編譯器。

CXX:用來(lái)指定cxx編譯器。

LIBS:跟上面的--libs作用差不多。

CFLAGS:跟上面的--cflags作用差不多。

CC,CXX,LIBS,CFLAGS手動(dòng)編譯時(shí)一般用不上,在做configure時(shí)有時(shí)用到,一般情況下不用管。

環(huán)境變量設(shè)定方法:export ENV_NAME=xxxxxxxxxxxxxxxxx

CPATH、C_INCLUDE_PATH  

用逗號(hào)隔開(kāi)的目錄列表,提供頭文件搜索位置

COMPILER_PATH

用逗號(hào)隔開(kāi)的目錄列表,以提供GCC子程序的搜索位置

GCC_EXEC_PREFIX

當(dāng)GCC調(diào)用子程序時(shí),需要“加在前面”的前置名稱(chēng)

LIBRARY_PATH

用逗號(hào)隔開(kāi)的目錄列表,以提供連接庫(kù)的位置

LD_LIBRARY_PATH

用逗號(hào)隔開(kāi)的目錄列表,以提供共享庫(kù)文件的搜索位置

TMPDIR

臨時(shí)文件所使用的目錄

5、關(guān)于交叉編譯

交叉編譯通俗地講就是在一種平臺(tái)上編譯出能運(yùn)行在體系結(jié)構(gòu)不同的另一種平臺(tái)上,比 如在我們地PC平臺(tái)(X86 CPU)上編譯出能運(yùn)行在sparc CPU平臺(tái)上的程序,編譯得到的程序在X86 CPU平臺(tái)上是不能運(yùn)行的,必須放到sparc CPU平臺(tái)上才能運(yùn)行。當(dāng)然兩個(gè)平臺(tái)用的都是linux。

這種方法在異平臺(tái)移植和嵌入式開(kāi)發(fā)時(shí)用得非常普遍。

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
gcc/g++ 編譯器使用簡(jiǎn)介
pkg
Gcc簡(jiǎn)介
c Ubuntu系統(tǒng)下GTK安裝
使用 SCons 輕松建造程序
C語(yǔ)言編譯器MINGW的使用說(shuō)明
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服