在Python中,你僅僅需要輸入python,就可以運行你想要運行的代碼。Python的解釋器會運行它們,并且在運行中導(dǎo)入它所需的庫和其它東西。C是完全不同的東西,你需要事先編譯你的源文件,并且手動將它們整合為一個可以自己運行的二進制文件。手動來做這些事情很痛苦,在上一個練習(xí)中只需要運行make就能完成。
這個練習(xí)是GNU make 的速成課,由于你在學(xué)C語言,所以你就必須掌握它。Make 將貫穿剩下的課程,等效于Python(命令)。它會構(gòu)建源碼,執(zhí)行測試,設(shè)置一些選項以及為你做所有Python通常會做的事情。
有所不同的是,我會向你展示一些更智能化的Makefile魔法,你不需要指出你的C程序的每一個愚蠢的細節(jié)來構(gòu)建它。我不會在練習(xí)中那樣做,但是你需要先用一段時間的“低級 make”,我才能向你演示“大師級的make”。
使用make的第一階段就是用它已知的方式來構(gòu)建程序。Make預(yù)置了一些知識,來從其它文件構(gòu)建多種文件。上一個練習(xí)中,你已經(jīng)使用像下面的命令來這樣做了:
$ make ex1
# or this one too
$ CFLAGS="-Wall" make ex1
第一個命令中你告訴make,“我想創(chuàng)建名為ex1的文件”。于是Make執(zhí)行下面的動作:
ex1存在嗎?ex1開頭?ex1.c。我知道如何構(gòu)建.c文件嗎?cc ex1.c -o ex1來構(gòu)建它。cc從ex1.c文件來為你構(gòu)建ex1。上面列出的第二條命令是一種向make命令傳遞“修改器”的途徑。如果你不熟悉Unix shell如何工作,你可以創(chuàng)建這些“環(huán)境變量”,它們會在程序運行時生效。有時你會用一條類似于export CFLAGS="-Wall"的命令來執(zhí)行相同的事情,取決于你所用的shell。然而你可以僅僅把它們放到你想執(zhí)行的命令前面,于是環(huán)境變量只會在程序運行時有效。
在這個例子中我執(zhí)行了CFLAGS="-Wall" make ex1,所以它會給make通常使用的cc命令添加-Wall選項。這行命令告訴cc編譯器要報告所有的警告(然而實際上不可能報告所有警告)。
實際上你可以深入探索使用make的上述方法,但是先讓我們來看看Makefile,以便讓你對make了解得更多一點。首先,創(chuàng)建文件并寫入以下內(nèi)容:
CFLAGS=-Wall -g
clean:
rm -f ex1
將文件在你的當前文件夾上保存為Makefile。Make會自動假設(shè)當前文件夾中有一個叫做Makefile的文件,并且會執(zhí)行它。此外,一定要注意:確保你只輸入了 TAB 字符,而不是空格和 TAB 的混合。
譯者注:上述代碼中第四行
rm前面是一個 TAB ,而不是多個等量的空格。
Makefile向你展示了make的一些新功能。首先我們在文件中設(shè)置CFLAGS,所以之后就不用再設(shè)置了。并且,我們添加了-g標識來獲取調(diào)試信息。接著我們寫了一個叫做clean的部分,它告訴make如何清理我們的小項目。
確保它和你的ex1.c文件在相同的目錄中,之后運行以下命令:
$ make clean
$ make ex1
如果代碼能正常工作,你應(yīng)該看到這些:
$ make clean
rm -f ex1
$ make ex1
cc -Wall -g ex1.c -o ex1
ex1.c: In function 'main':
ex1.c:3: warning: implicit declaration of function 'puts'
$
你可以看出來我執(zhí)行了make clean,它告訴make執(zhí)行我們的clean目標。再去看一眼Makefile,之后你會看到在它的下面,我縮進并且輸入了一些想要make為我運行的shell命令。你可以在此處輸入任意多的命令,所以它是一個非常棒的自動化工具。
注
如果你修改了
ex1.c,添加了#include<stdio>,輸出中的關(guān)于puts的警告就會消失(這其實應(yīng)該算作一個錯誤)。我這里有警告是因為我并沒有去掉它。
同時也要注意,即使我們在Makefile中并沒有提到ex1,make仍然會知道如何構(gòu)建它,以及使用我們指定的設(shè)置。
上面那些已經(jīng)足夠讓你起步了,但是讓我們以一種特定的方式來破壞make文件,以便你可以看到發(fā)生了什么。找到rm -f ex1的那一行并去掉縮進(讓它左移),之后你可以看到發(fā)生了什么。再次運行make clean,你就會得到下面的信息:
$ make clean
Makefile:4: *** missing separator. Stop.
永遠記住要縮進,以及如果你得到了像這種奇奇怪怪的錯誤,應(yīng)該復(fù)查你是否都使用了 TAB 字符,由于一些make的變種十分挑剔。
all:ex1,可以以單個命令make構(gòu)建ex1。man make來了解關(guān)于如何執(zhí)行它的更多信息。man cc來了解關(guān)于-Wall和-g行為的更多信息。Makefile文件,并且嘗試理解它做了什么。