原文:C track: compiling C programs.
盡管有些計算機語言(如 Schema 或者 Basic)通常使用交互式的解釋器(當你輸入命令後,就可立即執行),但 C 語言不是。C 的源文件總是要通過一個叫做編譯器(compiler)的程序編譯成二進制代碼然後運行。這就是我們接下來要詳細說明的幾個步驟。
你需要4種文件進行編譯C 程序:
還有其他的各種文件,尤其是靜態庫文件(".a
" files or ".lib" on Windows)以及共享庫文件(".so
" files or ".dll" on Windows)。但通常,你不需要直接與他們打交道。
在編譯器開始編譯源文件之前,源文件由預處理器(preprocessor)進行處理。預處理器是一個真實的單獨的程序(通常叫做"cpp
", for "C preprocessor"),而由編譯器在編譯前自動調用。預處理器的工作就是講源文件轉換成另外一個源文件(你也可以認為是對源文件的修改或者擴展)。修改後的文件可能作為一個真實的文件存在文件系統中,也可能僅僅是在發送給編譯器之前在內存中作短暫的保留。另外,你不需要特別關注預處理,但是你需要知道預處理是干什麼滴。
預處理指令以符號("#
")開始. 在多種預處理指令中,有兩種最為重要:
還有其他的各種預處理指令,我們將會根據需要進行有所處理。
在 C 預處理器包含了所有的頭文件並且展開所有的 #define
和 #include
語句(也有其他一些在源文件中出現的預處理指令)後,編譯器就可以編譯程序了。編譯器將 C 源文件編譯成目標文件(object code),包含二進制版本源代碼並以 ".o" 結尾的文件。 然而,目標文件並不能直接運行。為了能夠生成可執行文件,你還需要加入被#include
d 包含的庫函數代碼(這個通過 #include 包含函數聲明是不一樣的)。這就是下一節要講到的鏈接器 linker 的工作。
通常,編譯由以下方式被調用:
% gcc -c foo.c
符號 %
是 unix 提示符. 它告訴編譯器對文件 foo.c
運行預處理程序並編譯成目標文件 foo.o。
-c
選項意思是由編譯器將源文件編譯成目標文件而不會調用鏈接器。如果你的整個程序就一個源文件,你也可以這麼做:
% gcc foo.c -o foo
它告訴編譯器在文件 foo.c 運行預處理器,編譯並鏈接產生一個可執行文件
foo。
-o
表示二進制可執行文件(程序)將以其隨後的單詞作為文件名。 如果你不制定 -o 選項,或者僅僅是輸入
gcc foo.c,由於某種歷史原因,可執行文件將以
a.out
命名。
請注意編譯器的名字,我們使用的是 gcc,
代表 "GNU C compiler" 或者 "GNU compiler collection" 。也有其他的編譯器;他們中大多數都以 cc("C compiler")命名。在
Linux 操作系統中 cc 是
gcc 的別名。
鏈接器的工作就是將一組目標文件(.o 文件)一起鏈接到一個二進制可執行文件。這包括從你的源代碼文件編譯的目標文件,以及預編譯的庫文件(library files)。 這些文件 .a
或者 .so 作為結尾命名,通常你不需要知道他們,因為他們中大多數可以由鏈接器(
linker)定位並根據需要自動鏈接。
像預處理器一樣,鏈接器也是一個叫做 ld 獨立的程序。也如預處理器一樣,鏈接器在你使用編譯器時自動被調用。鏈接器通常使用的方式如下:
% gcc foo.o bar.o baz.o -o myprog
這一行是告訴編譯器一起將三個目標文件(foo.o
, bar.o
, and baz.o)
鏈接成一個名為 myprog 的二進制可執行文件
.
這就是你需要知道如何編譯你的 C 程序的事情。通常,我們也推薦 -Wall
選項:
% gcc -Wall -c foo.cc
-Wall
選項讓編譯器對合法但是可以的代碼結構發出警告,並且幫助你輕松捕獲一些 bugs。如果你想要更多的編譯檢查項:
% gcc -Wall -Wstrict-prototypes -ansi -pedantic -c foo.cc
-Wstrict-prototypes
選項是讓編譯器對代碼中沒有正確原型的函數做出警告。-ansi
和 -pedantic
是讓編譯器對代碼中不可移植的結構(e.g. 一些在 gcc 中合法而不滿足標准 C compilers 的代碼結構;這些結構通常是需要避免的)做出警告。
Kernighan and Ritchie, The C Programming Language, 2nd Ed.
The man page for gcc
. Type: man gcc
at the unix prompt.
The GNU Info documentation on gcc
. Warning! This is far more information than most people could possibly absorb in the average millenium.
Info documentation on gcc
can be accessed through the GNU emacs editor by typing "M-x info" (where "M-x" means to hit the meta-key and "x" simultaneously), or "C-h i" (where "C-h" means to hit the control key and "i" simultaneously), followed by "mgcc<return>". Type "minfo<return>" instead for a quick tour of how to use info. You can also access the info documentation from the unix command line by typing info gcc
.