附錄B Linux 下編譯 C 程式

小昇發表於2015-05-24

我們都知道,C 程式原始碼檔案必須要編譯成可執行檔案才能執行,那麼如何在 Linux 下編譯 C 程式呢?當然,首先想到的是使用 Code::Blocks 等 IDE(整合開發環境),只需按一下按鈕就會自動完成編譯操作。而我們接下來要介紹的是如何在命令列介面下完成 C 程式的編譯。

Linux 下使用的標準 C 編譯器是由 FSF(自由軟體基金會)提供的 GCC(GNU Compiler Collection,GNU 編譯器套件)。GCC 是屬於 GNU 專案的自由軟體,現在已經被大多數類 Unix 系統採納為標準的編譯器,GCC 同樣適用於微軟的 Windows。

你可以先檢查一下 Linux 系統上是否安裝了 GCC:

$ gcc -v

如果提示未找到命令,可以用下面的命令安裝:

$ sudo apt-get install gcc

如果想簡單地編譯一個源程式檔案,只需輸入:

$ gcc 源程式檔名稱

例如,想要編譯一個名為 test.c 的源程式檔案,只需輸入:

$ gcc test.c

GCC 會將 test.c 編譯連結成可執行檔案,並且命名為 a.out。可以執行 a.out 檢視一下:

$ ./a.out

如果想指定輸出可執行檔案的名稱,可以使用 -o 選項。沿用上例,若想要將編譯好的可執行檔案命名為 testprogram,可以這樣寫:

$ gcc test.c -o testprogram

GCC 會將 test.c 編譯連結成可執行檔案 testprogram。

若有多個原始檔也是用類似的方法。例如要將原始檔 a.c 和 b.c 編譯連結成可執行檔案 c.out,可以這樣寫:

$ gcc a.c b.c -o c.out

GCC 會將 a.c 和 b.c 分別編譯後連結成可執行檔案 c.out。

一個大型的專案由許許多多的原始檔組成,若每次修改後,都要將所有的原始檔全部重新編譯,就會浪費大量的時間。那麼可不可以只重新編譯修改過的原始檔呢?

我們都知道,C 程式的編譯過程由編譯和連結兩個階段組成。編譯階段將原始碼檔案(.c)編譯彙編成目的碼檔案(.o),連結階段則是將目的碼檔案和庫檔案連結生成可執行檔案。

那麼如果我們先將所有的原始檔編譯成對應的目的碼檔案,再連結所有的目的碼檔案來生成可執行檔案,就可以解決上面的問題了。如果有原始檔修改了,只需重新編譯它的目的碼檔案,再重新連結一下就可以了。

下面舉一個例子,有兩個原始檔 main.c 和 max.c,分別如下:

main.c:

#include <stdio.h>

int main()
{
    printf("max(15,5) = %d",max(15,5));
    return 0;
}

max.c:

int max(int a, int b)
{
    if(a > b) return a;
    else return b;
}

要 GCC 編譯生成目的碼檔案,使用 -c 選項:

$ gcc -c main.c max.c

會生成對應的目的碼檔案 main.o 和 max.o,再連結它們生成可執行檔案 main.out:

$ gcc main.o max.o -o main.out

但是想像一下,一個大型的專案可能由數百甚至上千個原始檔組成,如果還是使用這種一個一個輸入檔名的方式,那麼每次連結所有的目的碼檔案將會是一場噩夢。

這時就需要使用 make 工具了。make 可以通過建立 Makefile 檔案來自動完成編譯和連結,每次重新編譯連結時,只需輸入命令 make,它就會自動將修改過的原始檔重新編譯,並連結生成最終的可執行檔案。

Makefile 檔案的格式為:
# 註釋一行
編譯生成的檔案:編譯所需的檔案…
<TAB>編譯指令
注意:<TAB>代表製表符(按下 Tab 鍵)。

對於上面的例子,Makefile 檔案就可以這樣寫:

# This is a Makefile !
main.out:max.o main.o
      gcc max.o main.o -o main.out
max.o:max.c
      gcc -c max.c
main.o:main.c
      gcc -c main.c

Makefile 檔案從上往下逐步細化。編寫好後執行 make 命令:

$ make

make 程式就會自動遞迴地進行編譯和連結,生成可執行檔案。

相關文章