make[電腦程式]

make[電腦程式]
make[電腦程式]
更多義項 ▼ 收起列表 ▲

make,常指一條計算機指令,是在安裝有GNU Make的計算機上的可執行指令。該指令是讀入一個名為makefile 的檔案,然後執行這個檔案中指定的指令。 有時make又指GNU Make,GNU Make 是一個用來控制和其他一些版本的軟體。

GNU Make

定義

GNU Make是一個用來 控制 執行檔和其他一些 從源檔案來的非原始碼檔案 版本的軟體 。

Make可以從一個名為makefile的檔案中獲得如何構建你所寫程式的依賴關係,Makefile中列出了每個目標檔案以及如何由其他檔案來生成它。 當你編寫一個程式時,你可以為它編寫一個makefile檔案,這樣你就可以使用Make來編譯和安裝這個程式。

功能

Make 使最終用戶可以在不知道構建細節的情況下構建和安裝你的軟體,因為這些細節都記錄在了你提供的Makefile中 。

基於源檔案的改動,Make可以自動知道那些檔案需要更新;它也會自動決定檔案更新的適當順序,以避免要更新的檔案依賴於另一個同樣需要更新的檔案。因此,在你修改了程式的原始碼並且執行Make後,你不必重新完全編譯你的所有檔案,只需要重新編譯那些直接或間接受到影響的檔案就好了。

Make不限於任何一種特定的語言。對於程式中任何一種非源檔案, makefile檔案中可以指定shell指令去生成它。shell 指令可以執行編譯器生成目標檔案,執行連結器生成執行檔,執行ar更新庫檔案,執行TeX(一個文本排版軟體)或Makeinfo去格式化文檔。

Make不限於用來生成軟體包。你可以用make來控制安裝和卸載軟體包,或者用來生成標籤表,以及其他的任何你想要做的,當然前提是你寫好怎么做(╬▔皿▔)凸。

1.

Make 使最終用戶可以在不知道構建細節的情況下構建和安裝你的軟體,因為這些細節都記錄在了你提供的Makefile中 。

2.

基於源檔案的改動,Make可以自動知道那些檔案需要更新;它也會自動決定檔案更新的適當順序,以避免要更新的檔案依賴於另一個同樣需要更新的檔案。因此,在你修改了程式的原始碼並且執行Make後,你不必重新完全編譯你的所有檔案,只需要重新編譯那些直接或間接受到影響的檔案就好了。

3.

Make不限於任何一種特定的語言。對於程式中任何一種非源檔案, makefile檔案中可以指定shell指令去生成它。shell 指令可以執行編譯器生成目標檔案,執行連結器生成執行檔,執行ar更新庫檔案,執行TeX(一個文本排版軟體)或Makeinfo去格式化文檔。

4.

Make不限於用來生成軟體包。你可以用make來控制安裝和卸載軟體包,或者用來生成標籤表,以及其他的任何你想要做的,當然前提是你寫好怎么做(╬▔皿▔)凸。

Make的規則和目標

Makefile告訴Make怎樣執行一系列的指令去依靠源檔案生成一個目標檔案。Makefile中聲明了一個依賴關係的列表,這個列表應當包含所有檔案(無論是源檔案或者目標)作為輸入 。

以下是個簡單的規則示例:

當你執行make的時候你可以指定特定的目標去更新,否則Make會更新Makefile目標列表中第一個目標。當然作為這個目標輸入的其他目標會先更新。make 用makefile確定那些目標檔案應該被更新,然後那些目標檔案實際上需要更新。如果一個目標檔案比他的所有依賴都新,這樣他就是最新的了,不需要再去重新生成了。其他檔案確實需要更新,要按照正確的順序,在用來生成其他檔案之前先更新自己。

Makefiles和約定

GNU制訂了一些如何編寫Makefiles的約定,所用的GNU軟體包必須遵守。即使你不打算成為GNU軟體,在你的程式中遵循這些約定也是一個好主意,這樣用戶就可以像其他許多軟體包一樣構建你的軟體包,而且不需要學習任何特殊的東西 。

這些約定可以在章節``Makefile conventions'' (147 k characters)和章節GNU Coding Standards (147 k characters)中看到。

通俗點的解釋

當你寫一個簡單的程式,只有一到兩個源檔案的時候,輸入

% cc file1.c file2.c

就沒什麼問題,但如果有很多源檔案就會很煩人──編譯的時間也會很長。

一個方法就是使用目標檔案,只在源檔案有改變的情況下才重新編譯源檔案。因此你可以這樣做:

% cc file1.o file2.o ... file37.c ...

上次編譯後,file37.c 發生了改變,但其他檔案沒有。這樣做可以讓編譯過程快很多,但是也不能解決累人的輸入問題。

或者我們可以使用一個shell script來解決輸入問題,但是也需要重新編譯所有檔案,在大型項目上很沒有效率。

如果有成百上千的源檔案的話怎么辦?如果我們在與很多人合作寫程式,別人對源檔案進行了修改,又沒有告訴你,該怎么辦?

也許我們可以把以上兩種方法結合,寫一種像shellscript 一樣的東西。這種檔案包含某種技巧可以決定什麼時候該對源檔案進行編譯。如今所有我們要的就是一個程式可以懂得這種技巧,因為要懂得這種技巧,shell 還沒那么大的能耐。

這個程式就叫 make。它讀入一個檔案,叫makefile ,這個檔案決定了源檔案之間的依賴關係。而且決定了源檔案什麼時候該編譯什麼時候不應該編譯。例如,某個規則可以說 “ 如果 fromboz.o 比 fromboz.c 要舊,意思就是有人修改了 fromboz.c,因此我們需要重新編譯這個檔案。”這個makefile還有規則通知 make 該 怎么 重新編譯源檔案,因此 make 是一個強大得多的工具。

makefile通常和相關的源檔案保存在同一個目錄下,可以叫做 makefile,Makefile 或者 MAKEFILE。大多數程式設計師會使用 Makefile 這個名字,因為這樣可以讓這個檔案被放在目錄列 表的頂端,可以很容易得看見。

make命令

這是一個非常簡單的 make 檔案:

foo: foo.c

cc -o foo foo.c

包含兩行,一行是依賴關係,一行是執行動作。

依賴關係的那一行包含了程式的名字 (叫做 target),緊跟著一個冒號,然後是空格,最後是源檔案的 名字。當 make讀入這一行的時候,會檢查 foo 是否存在;如果存在,就比較 foo 和 foo.c 最後的修改時間有什 么不同。如果 foo 不存在,或者比 foo.c 要舊,就檢查執行動作那一行看看該怎么做。換句話 說,就是 foo.c 需要重新編譯的時候該怎么辦。

執行動作那一行以一個 tab (按下 tab) 開始,然後是你在命令行下產生 foo 所執行的命令。如果 foo 過期了,或者不存在,make 就會 執行這個命令來產生foo。換句話說,這就是重新編譯 foo.c 的規則。

因此,當你輸入 make 時,它會確定 foo 和 foo.c 在修改時間上是否同步。這個原則可以在 Makefile 里擴展到成百上千的目標檔案上──實際上,在 FreeBSD 里,你只要在合適的目錄下輸入 make world 就可以編譯整個作業系統!

makefile另一個有用的特點就是目標檔案不一定就是程式。例如,我們可以 有這樣的 make 檔案。

foo: foo.c

cc -o foo foo.c

install:

cp foo /home/me

我們可以輸入如下的命令告訴 make 該執行哪個目標:

% make target

make 會只執行這個目標而忽略其他的目標。例如,如果我們輸入 make foo,就只有 foo 被執行,必要的情況下重新編譯 foo 而不會繼續執行 install 這個目標。

如果我們只是輸入 make 這個命令,make 總會尋找第一個目標,並且在執行完以後就不管其他的目標了。例如,如果我們輸入 make foo,make 就會轉到 foo 這個目標,在必要的情況下重新編譯 foo,而不會執行 install 目標, 然後就停止了。

一定要注意,install 這個目標不依賴任何其他的東西!這意味著我們一旦輸入 make install,這個目標下的所有命令都將被執行。這種情況下,foo 將被安裝到用戶的家目錄下。應用程式的makefile正是這樣寫的,以便程式在正確編譯後可以被安裝到正確的目錄。

要嘗試解釋的話會比較容易讓人混淆。如果你不太懂 make 是如何工作的,最好的辦法就是先寫一個簡單的程式例如 “hello world” 以及和上面的例子相同的 make 檔案再去實驗。然後 再進一步,使用多個源檔案,或者讓你的源檔案包含一個頭檔案。 touch 命令在這裡就非常有用了──它能讓在不改變檔案內容的情況下改變檔案的日期。

想進一步學習如何編寫makefile請參考引用4 .

相關詞條

相關搜尋

熱門詞條

聯絡我們