| 目錄(?)[+] |
通過(guò)一篇文章的介紹達(dá)到能夠編寫簡(jiǎn)單 Makefile 以及能夠看懂普通的 Makefile 之目的。
make 是一個(gè)老牌的構(gòu)建(build)工具,1970年問(wèn)世以來(lái)已經(jīng)度過(guò)了45年的時(shí)光而魅力不減,這在技術(shù)發(fā)展日新月異的今天是不可思議的。make 在大型的軟件項(xiàng)目中發(fā)揮著巨大作用。我是在學(xué)習(xí) Linux kernel 時(shí)才第一次接觸它,Android 系統(tǒng)也是用 make 和 python 等腳本一起構(gòu)建系統(tǒng),所以掌握 make 知識(shí)是你邁進(jìn)這些系統(tǒng)的第一道坎。你一定要給予 make 足夠的重視,不要以為掌握了 C/C++、Java 這些主力編程語(yǔ)言就可以掌控世界,當(dāng)你迷失在海量的 Makefile 以及各種 .py,.sh 時(shí),沒有構(gòu)建系統(tǒng)的知識(shí)是令人抓狂的。
make 的優(yōu)點(diǎn)是你可以把程序中各元素之間的關(guān)系告訴 make,之后 make 會(huì)根據(jù)這些關(guān)系和時(shí)間戳去判斷應(yīng)該重新編譯哪些步驟以產(chǎn)生你需要的程序。這就是我們常說(shuō)的增量編譯。
通常 make 是根據(jù) Makefile/makefile 執(zhí)行工作的,Makefile 中包含了一組用來(lái)編譯程序的規(guī)則。一項(xiàng)規(guī)則可分為三個(gè)部分:目標(biāo)(target)、必要條件(prereq)以及所要執(zhí)行的命令(command)。
target: prereq1 prereq2
commands
C 文件只有一個(gè) main.c
#include <stdio.h>
int main(int argc, char** argv) {
printf("hello, makefile!\n");
}
第一個(gè) Makefile
#first makefile
hello-makefile: main.c
gcc -o hello-makefile main.c
解讀如下:
這個(gè) Makefile 是由一項(xiàng)任務(wù)(規(guī)則)組成,目標(biāo)是一個(gè)叫作 hello-makefile 的可執(zhí)行文件,必要條件是 main.c 文件,而命令是一個(gè) gcc 的編譯命令。
執(zhí)行結(jié)果如下:
$ make
gcc -o hello-makefile main.c
第二個(gè) Makefile
#final target
hello-makefile: main.o
gcc -o hello-makefile main.o
#main.o
main.o: main.c
gcc -c main.c
解讀如下:
將上述步驟分解成兩步,為了生成 hello-makefile 需要依賴一個(gè)條件是 main.o,而接著將 main.o 作為目標(biāo)再寫一條規(guī)則。通常一個(gè) Makefile 就是由這樣多個(gè)不同的規(guī)則組合而成。
執(zhí)行結(jié)果如下:
$ make
gcc -c main.c
gcc -o hello-makefile main.o
從上而下的結(jié)構(gòu)
就像上面的 Makefile 那樣,默認(rèn)從最上層的工作目標(biāo)(通常稱為 all)開始工作,把有些工作目標(biāo)如 clean 工作放在文件的最底部。
特殊符號(hào)
井號(hào)(#)用來(lái)表示注釋
反斜杠(\)當(dāng)作續(xù)行符
通配符
與常用 shell 通配符一致。
星號(hào)(*)代表任意數(shù)量的任意字符,問(wèn)號(hào)(?)代表一個(gè)任意字符。
.PHONY
假想工作目標(biāo),并且可以避免名字沖突。出現(xiàn)在如下場(chǎng)合:
.PHONY: clean
clean:
rm -f *.o
常用的 .PHONY如下:
all 執(zhí)行編譯應(yīng)用程序的所有工作
install 從已編譯的二進(jìn)制文件進(jìn)行程序的安裝
clean 清楚生成的二進(jìn)制文件
distclean 清楚所有生成的文件
TAGS 建立可供編輯器使用的標(biāo)記表
check 執(zhí)行與程序相關(guān)的任何測(cè)試
變量
$(variable)
${}
變量名稱是單一字符的就不用括號(hào)了。
VPATH
告訴 make 如果在當(dāng)前目錄沒有找到,就去指定的目錄找。比如:
VPATH = src include
C++ 標(biāo)示
有時(shí)需要輸入一些參數(shù)告訴 gcc 做一些事,比如加入 -I 選項(xiàng)告知啟動(dòng)隱含編譯規(guī)則:
CPPFLAGS = -I include
有時(shí)需要調(diào)用其他的 makefile,只需要用 include 將其加入就可以了:
include /home/linc/workspace/lab/OpenCV-android-sdk-2.4.11/sdk/native/jni/OpenCV.mk
讀讀《GNU Make 項(xiàng)目管理》吧,更深入的知識(shí)和經(jīng)驗(yàn)都可以在書中找到。