gcc 使用匯總

gcc 使用匯總

#########################text 1####################################
Gcclinux下面最常用的編譯軟件,通常用來編譯C程序,但是也可以通過設置編譯多種語言寫成的程序。
下面簡單介紹gcc常用的使用的參數。
-o 選擇產生的目標文件的名稱
-l 選擇要使用到的鏈接庫
-c 只編譯不連接
 
例如:編譯一個多線程的程序可以使用命令:
gcc –lpthread –o test test.c
即將test.c 文件編譯,生成可執行文件test, -lpthread的目的是使程序在連接的時候連接pthread庫從而支持多線程的程序。要是程序裏面沒有使用線程可以將這個選項去掉。
########################text2######################################

Linux開發應用程序大多數情況下使用的都是C言,因此幾乎一位Linux程序的首要問題都是如何靈活運用C編譯器。目前Linux下最常用的C編譯器是GCCGNU Compiler Collection),它是GNU目中符合ANSI C準的編譯,能夠編譯CC++Object C寫的程序。GCC功能非常大,構也異常靈活。最得稱道的一點就是它可以通不同的前端模來支持各種語言,如JavaFortranPascalModula-3Ada等。

放、自由和靈活是Linux的魅力所在,而一點在GCC上的體就是程序它能更好地控制整個編譯過程。在使用GCC編譯程序編譯過程可以被四個段:
預處理(Pre-Processing
編譯Compiling
彙編Assembling
接(Linking
Linux程序可以根據自己的需要GCC編譯的任何束,以便檢查或使用編譯器在該階段的出信息,或者最後生成的二制文件行控制,以便通加入不同數量和種類調試今後的調試做好準。和其它常用的編譯器一GCC也提供了靈活而大的代碼優化功能,利用它可以生成行效率更高的代
GCC提供了30多條警告信息和三個警告級別,使用它有助於增程序的定性和可移植性。此外,GCC還對標準的CC++行了大量的展,提高程序的行效率,有助於編譯行代碼優化,能輕編程的工作量。
GCC
在學使用GCC之前,下面的個例子能幫助用迅速理解GCC的工作原理,並將其立即運用到實際開發中去。首先用熟悉的編輯入清1所示的代
1hello.c
#include <stdio.h>
int main(void)
{
printf ("Hello world, Linux programming!/n");
return 0;
}

然後行下面的命令編譯和運行段程序:
# gcc hello.c -o hello
# ./hello
Hello world, Linux programming!

從程序的角度看,只需簡單行一條GCC命令就可以了,但從編譯器的角度來看,卻需要完成一系列非常繁的工作。首先,GCC需要調預處理程序cpp,由它負責在源文件中定的宏,並向其中插入“#include”句所包含的內容;接着,GCC調cclas理後的源代碼編譯成目;最後,GCC調接程序ld,把生成的目碼鏈接成一個可行程序。
了更好地理解GCC的工作程,可以把上述編譯過程分成幾個步驟單行,並每步的運行果。第一預編譯,使用-E參數可以GCC預處束後停止編譯過程:
# gcc -E hello.c -o hello.i

hello.cpp文件中的內容,會發現stdio.h的內容確都插到文件裏去了,而其它當被預處理的宏定也都做了相理。下一是將hello.i編譯爲可以通使用-c參數來完成:
# gcc -c hello.i -o hello.o

GCC
.i文件看成是預處理後的C言源代,因此上述命令將自過預處步驟編譯過程,也可以使用-x參數GCC從指定的步驟開編譯。最後一是將生成的目文件接成可行文件:
# gcc hello.o -o hello

在採用模化的設計思想開發時,通常整個程序是由多個源文件成的,相地也就形成了多個編譯單元,使用GCC很好地管理編譯單元。假有一個由foo1.cfoo2.c兩個源文件成的程序,們進編譯,並最生成可行程序foo,可以使用下面條命令:
# gcc foo1.c foo2.c -o foo

如果同時處理的文件不止一個,GCC仍然會按照預處理、編譯接的程依次行。如果深究起來,上面條命令大致相當於依次行如下三條命令:
# gcc -c foo1.c -o foo1.o
# gcc -c foo2.c -o foo2.o
# gcc foo1.o foo2.o -o foo

編譯一個包含多源文件的工程,若只用一條GCC命令來完成編譯是非常浪費時間的。假設項目中有100個源文件需要編譯,並且個源文件中都包含10000行代,如果像上面那樣僅用一條GCC命令來完成編譯工作,那GCC需要將個源文件都重新編譯一遍,然後再全部接起來。很然,這樣時間相當多,尤其是當用只是修改了其中某一個文件的候,完全沒有必要將個文件都重新編譯一遍,因很多已生成的目文件是不會改的。要解決問題關鍵是要靈活運用GCC,同時還要藉助像Make這樣的工具。
警告提示功能
GCC包含完整的出錯檢查和警告提示功能,它可以幫助Linux程序寫出更加專業美的代。先來讀讀2所示的程序,段代寫得很糟糕,仔細檢查一下不挑出很多毛病:
main函數的返回被聲明void,但實際應該int
使用了GNU展,即使用long long來聲明64位整數,不符合ANSI/ISO C準;
main函數在止前沒有調return句。
2illcode.c
#include <stdio.h>
void main(void)
{
long long int var = 1;
printf("It is not standard C code!/n");
}

下面來看看GCC是如何幫助程序發現這錯誤的。當GCC編譯不符合ANSI/ISO C準的源代碼時,如果加上了-pedantic選項,那使用了法的地方將生相的警告信息:
# gcc -pedantic illcode.c -o illcode
illcode.c: In function `main':
illcode.c:9: ISO C89 does not support `long long'
illcode.c:8: return type of `main' is not `int'

需要注意的是,-pedantic編譯選項並不能保編譯程序與ANSI/ISO C準的完全兼容,它僅僅只能用來幫助Linux程序個目越來越近。或者話說-pedantic選項幫助程序員發現一些不符合ANSI/ISO C準的代,但不是全部,事上只有ANSI/ISO C準中要求編譯斷的那些情況,纔有可能被GCC發現並提出警告。
除了-pedantic之外,GCC有一些其它編譯選項也能夠產生有用的警告信息。選項大多以-W開頭,其中最有價的當數-Wall了,使用它能使GCC生儘可能多的警告信息:
# gcc -Wall illcode.c -o illcode
illcode.c:8: warning: return type of `main' is not `int'
illcode.c: In function `main':
illcode.c:9: warning: unused variable `var'

GCC
出的警告信息然從格意不能算作是錯誤,但卻很可能成爲錯誤的棲身之所。一個秀的Linux程序員應該儘量避免生警告信息,使自己的代保持簡潔美和健壯的特性。
理警告方面,另一個常用的編譯選項-Werror,它要求GCC將所有的警告當成錯誤進理,在使用自動編譯工具(如Make等)非常有用。如果編譯時帶-Werror選項,那GCC會在所有生警告的地方停止編譯,迫使程序員對自己的代碼進行修改。只有當相的警告信息消除,纔可能將編譯過繼續朝前推行情況如下:
# gcc -Wall -Werror illcode.c -o illcode
cc1: warnings being treated as errors
illcode.c:8: warning: return type of `main' is not `int'
illcode.c: In function `main':
illcode.c:9: warning: unused variable `var'

Linux程序GCC出的警告信息是很有價的,它可以幫助程序寫出更加健壯的程序,而且是跟蹤和調試程序的有力工具。建在用GCC編譯源代碼時終帶-Wall選項,並把它逐種習慣這對找出常錯誤很有幫助。
Linux開發軟,完全不使用第三方函數的情況是比的,通常來都需要藉助一個或多個函數的支持才能完成相的功能。從程序的角度看,函數庫實際上就是一些文件(.h)和文件(.so或者.a)的集合。Linux下的大多數函數都默文件放到/usr/include/下,而文件放到/usr/lib/下,但並不是所有的情況都是這樣。正因如此,GCC編譯時有自己的法來找所需要的文件和文件。
GCC採用搜索目法來找所需要的文件,-I選項可以向GCC文件搜索路徑中添加新的目。例如,如果在/home/xiaowp/include/下有編譯時所需要的文件,GCC夠順利地找到它,就可以使用-I選項
# gcc foo.c -I /home/xiaowp/include -o foo

,如果使用了不在準位置的文件,那可以通-L選項GCC文件搜索路徑中添加新的目。例如,如果在/home/xiaowp/lib/下有所需要的文件libfoo.soGCC夠順利地找到它,可以使用下面的命令:
# gcc foo.c -L /home/xiaowp/lib -lfoo -o foo

得好好解一下的是-l選項,它指示GCC文件libfoo.soLinux下的文件在命名有一個定,那就是應該lib三個字母開頭,由於所有的文件都遵循了同範,因此在用-l選項指定接的文件名可以省去lib三個字母,也就是GCC-lfoo,會自接名libfoo.so的文件。
Linux下的文件分兩大動態鏈(通常以.so尾)和靜態鏈(通常以.a尾),兩者的別僅在程序所需的代是在運行時動態的,是在編譯時的。默情況下,GCC時優先使用動態鏈,只有當動態鏈不存在才考使用靜態鏈,如果需要的可以在編譯時加上-static選項制使用靜態鏈。例如,如果在/home/xiaowp/lib/下有所需要的文件libfoo.solibfoo.aGCC只用到靜態鏈,可以使用下面的命令:
# gcc foo.c -L /home/xiaowp/lib -static -lfoo -o foo

 ###############################text3################################################

GCC for Win32 開發環境介紹(4)


第三章 GCC粗探——GCC的組成與附加參數


第一節 GCC的家族成員


總的來說,GCC應該是一個編譯器。可是,爲什麼我還要在這裏介紹GCC的家族成員呢?其實,整套的GCC環境並不是由GCC構成的,他是由多個包所組成的。這些包的互相作用產生了GCC的開發環境。其中,有一些包是你開發應用程序所必備的基本包。離開這些包你將無法正常使用GCC


GCC的基本包列表。


GCC的基本開發環境,主要由一下幾個包構成。Binutils,這個是輔助GCC的工具包,裏面包含了連接器,彙編器,動態靜態庫生成程序,等等。GCC,這個包是GCC本身。當然GCC包中還包括一下幾個包,如core,java,ada等,每個包都代表了一種語言。然後,就是win32api,mingw-runtime,這個是在Win32下使用的標準函數包。如果,你使用的是Cygwin或者是在Unix環境下,那麼這個包就是GlibC


所以,由上所述。GCC的基本包有:binutils gcc glibc/[win32api,mingw-runtime]有了這些包。你基本能夠開始編譯應用程序了。


當然,如果說你想要寫一個小程序。自然這些包已經夠了。但是如果你要寫一個較大的工程。那麼,這些包也許就不能很好的勝任你的工作了。因爲,對於一個大的項目,需要編譯的文件不只一個,而且還有依賴關係等等。

所以,GCC中還包括gmake包用於管理項目。當然,還有automake。但是我個人還是不太喜歡automakeautomake其實是幫助你自動的管理你的項目,當然實現這個自動也是比較麻煩的,所以與其用automake管理中小型項目,不如用gmake自己寫個腳本。不過,automake通常用於源代碼發佈的應用,如果在開發時使用會延長開發週期。

Gmake,automake,都是通過編譯腳本來批量的編譯程序。他們能夠更具你所給定的依賴關係,來自動的判斷需要重新編譯的源代碼,然後編譯。這點的確可以幫助開發人員減輕不少的人力和開發週期。比如,你用Makefile管理一個項目,那麼在你第一次編譯程序以後,如果你的源代碼沒有做過任何編輯,那麼下次再調用gmake的程序時,gmake就不會再去一一編譯每個文件。而是簡單的連接一下主程序,或者什麼都不作的退出(這要取決於你寫的Makefile腳本)


但是,對於有些開發人員來說,上面這些包還是不能滿足他們的要求。因爲他們要調試程序。所以,GCC還包括另一個包。那就是GDBgdbGCC開發的,用於跟蹤調試的,命令符型調試器。它的功能還是比較強大的。基本,你能在VC下做到的,GDB也可以。不過,GDB的命令還是比較多的。掌握一些基本的調試命令一般就夠使用了。


總結

GCC開發環境包括如下幾大包。

binary

基本包

提供基本的彙編器,連接器等

gcc

基本包

各種語言的編譯器,包括C,C++,Ada,Java

Win32api,mingwi-runtime/glibc

基本包

系統函數庫

Gmake/automake

需要包

管理項目編譯的程序

gdb

附加包

調試程序


第二節 GCC的常用編譯參數


VC,TC等編譯器不同,GCC其實是可以很方便的在提示符下編譯程序的。GCC在提示符下編譯程序,並沒有如同VC那樣的冗長而晦澀的編譯參數。相反,卻有着比VC更靈活且簡短的參數。

不得不承認,不懂GCC編譯參數的人,確實會損失一些GCC的強大功能。所以,我下面簡單介紹一下GCC的一些基本編譯參數。這裏,我以C編譯器爲例。


編譯二進制代碼

$gcc -c yours.c -o yours.o

使用這段指令,GCC將會把yours.c編譯成yours.o的二進制代碼。其中,yours.o就類似於VC,TC中的.obj文檔。


編譯最簡單的小程序。

$gcc -o yours yours.c

通過這條指令,GCC將會把yours.c源代碼編譯成名爲yours的可執行程序。當然,您也可以將yours.c改成我們剛纔介紹的yours.o文件。這樣,gcc將使用編譯剛纔編譯好的二進制文檔來鏈接程序。這裏,格式的特點是,-o 後面是一串文件列表,第一個參數是所編譯程序的文件名,從第二個開始,就是您編譯和連接該可執行程序所需要的二進制文檔或者源代碼。


編譯時將自己的頭文件目錄設爲默認頭文件目錄

$gcc -I”Your_Include_Files_Document_Path” -c yours.c -o yours.o

這條指令中的-I參數將會把Your_Include_Files_Document_Path添加到你默認的頭文件目錄中。這樣您將可以使用 #include <your_include.h>來導入頭文件。


編譯時使用自己的靜態庫存放目錄

$gcc -L”Your_Lib_Files_Document_Path” -o yours yours.o

這條指令將會讓GCC在連接時除了在默認Lib存放目錄中搜索指定的靜態庫以外,還會在Your_Lib_Files_Document_Path中搜索。


編譯時使用靜態連接庫

$gcc -lyour_lib -o yours yours.o

這條指令將會讓GCC在連接時把 libyour_lib.a中您所用到的函數連接到可執行程序中。此處注意,GCC所使用的靜態連接庫是lib*.a格式的。在連接時,只且僅需要提供*的內容就可以了。


編譯時使用優化

$gcc -O2 -c yours.c -o yours.o

使用優化方式編譯程序,其中除了-O2以外,還有-O3 -O1等等。他們代表不同的優化等級。最常用的,是-O2優化。當然,還有針對特殊CPU的優化,這裏就不介紹了。


編譯時顯示所有錯誤和警告信息

$gcc -Wall -c yours.c -o yours.o

GCC在默認情況下,將對一些如變量申請未使用這樣的問題或者申請了沒有給予初始值的問題忽略。但是,如果使用了-Wall參數,編輯器將列出所有的警告信息。這樣,您就可以知道您的代碼中有多少可能會在其他操作系統下出錯的地方了。(用這個指令看看你的代碼有多少地方寫的不怎麼合適。)


編譯連接時,加入調試代碼

$gcc -g -o yours yours.c

正如同VCdebug編譯模式一樣,GCC也有debug模式。添加了-g 參數編譯的可執行程序比普通程序略爲大一些,其中添加了一些調試代碼。這些代碼將被gdb所支持。


連接時縮小代碼體積

$gcc -s -o yours yours.o

這個參數,似乎我沒有在Unix環境下看到過。也不知道具體什麼作用。因爲有人說Visual-MinGW生成的代碼小,於是研究了一下她的編譯參數,發現release模式的編譯參數就加了這一項。貌似編譯後的代碼的確縮小了很多。


獲得幫助

$gcc --help

這條指令從意思上就能看出,獲得gcc的幫助信息。如果您有什麼特殊需要,也許這個指令能幫上點小忙。


第三節 如何寫一個簡單的Makefile


說了半天Makefile管理項目,我想現在該說一下如何寫了。其實,Makefile文件總體還是比較容易寫的,基本只要你會使用命令行,就可以寫Makefile。下面我簡單介紹一下Makefile的構成和書寫。


一個輸出 HelloWorld 的簡單Makefile

all:

echo HelloWorld

這個Makefile代碼,運行後將在屏幕上打印一個HelloWorldall其實是類似C代碼中的main函數。gmake程序將在運行Makefile代碼時,首先運行此處的代碼。注意,此處echo前面的是<tab>GCC對空格很敏感的。


添加依賴項的Makefile

all:depend

@echo I am the main

depend:closeecho

@echo I am the depend

closeecho:

@echo off

這個Makefile代碼,的作用還是輸出句子。不同的是她添加了幾個指令塊之間的依賴關係。其中all依賴於dependdepend依賴於closeecho。這樣,程序在編譯時將根據腳本的依賴關係來判斷文件編譯的先後順序。


執行Makefile

$make -f Makefile

通常情況下,不用-f參數,make程序將在當前目錄下搜索名爲Makefile的文件作爲需要執行的文件。而使用-f將指定Makefile的文件名。


一個完整的Makefile

all:yours

@echo OK

yours:yours.o

gcc -o yours yours.o

yours.o:yours.c

gcc -c yours.c -o yours.o


更多有關Makefile的詳細內容請查相關資料。



文外音:

的確,發現了。我這個系列的文章進展的並沒有我預期和承諾的那麼快。確實挺讓我感到無奈的。不過,幸好你能夠理解我。總體來說,本文主要是簡單介紹一下GCC的一些基礎。因爲我發現有許多讀者對GCC並不是很瞭解。

說來也挺無奈的,最近發現原來周圍有個小人當道。此人姓名我也就隱去了。從去年開始,就常常在和我聊得比較好的幾個女生面前造我的謠。所以,原本應該9月該出來的文章拖延到了9月底。說起這個人,我希望大家要以此人爲鑑。不要像他那樣。

這人自稱在硬件方面很行,不過據我所知,他無非就是可以把各種型號的主板和硬件編號背出來而已。連基本的線程進程都搞不清楚。還成天鼓吹32bit的機器是淘汰的機器。不得不承認,這位滿口髒話爲人無恥的傢伙的確硬件方面挺不錯的。但是,我還是覺得做技術的人不要太追求表面的東西,不要追求過於超前的東西,同時也更要注意自己的品行道德。

也許是年紀大了,發了一些牢騷。希望各位不要建議。不過,事以至次,我也無力挽回了。

最後感謝各位對我的支持,更感謝那些願意爲我效力的朋友們。同時,如果您有什麼問題或者建議,都可以提出來。爲了您能及時準確的得到回覆請到http://blog.csdn.net/visioncat上發表你的留言。謝謝

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