在為Linux開發應用程序時,絕大多數情況下使用的都是C語言,因此幾乎每一位Linux 程序員面臨的首要問題都是如何靈活運用C編譯器。 目前Linux 下最常用的C語言編譯器是GCC(GNU Compiler Collection),它是GNU項目中符合ANSI C標准的編譯系統,能夠編譯用C、C++和Object C等語言編寫的程序。GCC不僅功能非常強大,結構也異常靈活。最值得稱道的一點就是它可以通過不同的前端模塊來支持各種語言,如Java、 Fortran、Pascal、Modula-3和Ada等。
開放、自由和靈活是Linux的魅力所在,而這一點在GCC上的體現就是程序員通過它能夠更好地控制整個編譯過程。在使用GCC編譯程序時,編譯過程可以被細分為四個階段:
◆ 預處理(Pre-Processing)
◆ 編譯(Compiling)
◆ 匯編(Assembling)
◆ 鏈接(Linking)
Linux程序員可以根據自己的需要讓 GCC在編譯的任何階段結束,以便檢查或使用編譯器在該階段的輸出信息,或者對最後生成的二進制文件進行控制,以便通過加入不同數量和種類的調試代碼來為 今後的調試做好准備。和其它常用的編譯器一樣,GCC也提供了靈活而強大的代碼優化功能,利用它可以生成執行效率更高的代碼。
GCC提供了30多條警告信息和三個警告級別,使用它們有助於增強程序的穩定性和可移植性。此外,GCC還對標准的C和C++語言進行了大量的擴展,提高程序的執行效率,有助於編譯器進行代碼優化,能夠減輕編程的工作量。
GCC起步
在學習使用GCC之前,下面的這個例子能夠幫助用戶迅速理解GCC的工作原理,並將其立即運用到實際的項目開發中去。首先用熟悉的編輯器輸入清單1所示的代碼:
清單1:hello.c
#include int main(void){printf ("Hello world, Linux programming!\\n");return 0;}
然後執行下面的命令編譯和運行這段程序:
# gcc hello.c -o hello# ./helloHello world, Linux programming!
從程序員的角度看,只需簡單地執行一條GCC命令就可以了,但從編譯器的角度來看,卻需要完 成一系列非常繁雜的工作。首先,GCC需要調用預處理程序 cpp,由它負責展開在源文件中定義的宏,並向其中插入“#include”語句所包含的內容;接著,GCC會調用ccl和as將處理後的源代碼編譯成目 標代碼;最後,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.c和foo2.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這樣的工具。
更多內容請看Linux應用 Linux應用技巧 日常應用管理專題,或