Make介紹
摘自:
http://www.reibang.com/p/2cd82c90d184
1壮啊、什么是 Makefile
? 一個(gè)企業(yè)級(jí)項(xiàng)目乐横,通常會(huì)有很多源文件蕴坪,有時(shí)也會(huì)按功能、類型瓣俯、模塊分門(mén)別類的放在不同的目錄中夹抗,有時(shí)候也會(huì)在一個(gè)目錄里存放了多個(gè)程序的源代碼外莲。
這時(shí),如何對(duì)這些代碼的編譯就成了個(gè)問(wèn)題兔朦。Makefile 就是為這個(gè)問(wèn)題而生的偷线,它定義了一套規(guī)則,決定了哪些文件要先編譯沽甥,哪些文件后編譯声邦,哪些文件要重新編譯。
整個(gè)工程通常只要一個(gè) make 命令就可以完成編譯摆舟、鏈接亥曹,甚至更復(fù)雜的功能邓了。可以說(shuō)媳瞪,任何一個(gè) Linux 源程序都帶有一個(gè)Makefile 文件骗炉。
2、Makefile 的優(yōu)點(diǎn)
管理代碼的編譯蛇受,決定該編譯什么文件句葵,編譯順序,以及是否需要重新編譯兢仰;節(jié)省編譯時(shí)間乍丈。如果文件有更改,只需重新編譯此文件即可把将,無(wú)需重新編譯整個(gè)工程轻专;一勞永逸。Makefile 通常只需編寫(xiě)一次察蹲,后期就不用過(guò)多更改请垛。
3、命名規(guī)則
一般來(lái)說(shuō)將 Makefile 命名為 Makefile 或 makefile 都可以洽议,但很多源文件的名字是小寫(xiě)的宗收,所以更多程序員采用的是 Makefile 的名字,因?yàn)檫@樣可以將 Makefile 居前顯示绞铃。
如果將 Makefile 命為其它名字镜雨,比如 Makefile_demo嫂侍,也是允許的儿捧,但使用的時(shí)候應(yīng)該采用以下方式:
make -f? Makefile_demo
4、基本規(guī)則
Makefile 的基本格式為:
目標(biāo): 依賴
(tab)規(guī)則
目標(biāo) --> 需要生成的目標(biāo)文件
依賴 --> 生成該目標(biāo)所需的一些文件
規(guī)則 --> 由依賴文件生成目標(biāo)文件的手段
tab --> 每條規(guī)則必須以 tab 開(kāi)頭挑宠,使用空格不行
例如我們經(jīng)常寫(xiě)的 gcc test.c -o test菲盾,使用 Makefile 可以寫(xiě)成:
test: test.c
gcc test.c -o test
其中,第一行中的 test 就是要生成的目標(biāo)各淀,test.c 就是依賴懒鉴,第二行就是由 test.c 生成 test 的規(guī)則。
Makefile 中有時(shí)會(huì)有多個(gè)目標(biāo)碎浇,但 Makefile 會(huì)將第一個(gè)目標(biāo)定為終極目標(biāo)临谱。
5、工作原理
目標(biāo)的生成
檢查規(guī)則中的依賴文件是否存在奴璃;
若依賴文件不存在悉默,則尋找是否有規(guī)則用來(lái)生成該依賴文件。
比如上圖中苟穆,生成 calculator 的規(guī)則是 gcc main.o add.o sub.o mul.o div.o -o抄课,Makefile 會(huì)先檢查 main.o唱星、add.o、sub.o跟磨、 mul.o间聊、 div.o 是否存在,如果不存在抵拘,就會(huì)再尋找是否有規(guī)則可以生成該依賴文件哎榴。
比如缺少了 main.o 這個(gè)依賴,Makefile 就會(huì)在下面尋找是否有規(guī)則生成 main.o仑濒。當(dāng)它發(fā)現(xiàn) gcc main.c -o main.o這條規(guī)則可以生成 main.o 時(shí)叹话,它就利用此規(guī)則生成 main.o,然后再生成終極目標(biāo) calculator墩瞳。
整個(gè)過(guò)程是向下尋找依賴驼壶,再向上執(zhí)行命令,生成終極目標(biāo)喉酌。
目標(biāo)的更新
檢查目標(biāo)的所有依賴热凹,任何一個(gè)依賴有更新時(shí),就重新生成目標(biāo)泪电;
目標(biāo)文件比依賴文件時(shí)間晚般妙,則需要更新。
比如相速,修改了 main.c碟渺,則 main.o 目標(biāo)會(huì)被重新編譯,當(dāng) main.o 更新時(shí)突诬,終極目標(biāo) calculator 也會(huì)被重新編譯苫拍。其它文件的更新也是類推。
6旺隙、命令執(zhí)行
make:使用此命令即可按預(yù)定的規(guī)則生成目標(biāo)文件绒极。 如果 Makefile 文件的名字不為 Makefile 或 makefile,則應(yīng)加上 -f 選項(xiàng)蔬捷,比如:
make -f Makefile_demo
make clean:清除編譯過(guò)程中產(chǎn)生的中間文件(.o文件)及最終目標(biāo)文件垄提。
如果當(dāng)前目錄下存在名為 clean 的文件,則該命令不執(zhí)行周拐。
解決辦法是偽目標(biāo)聲明:.PHONY:clean铡俐。
特殊符號(hào):
- :表示此命令即使執(zhí)行出錯(cuò),也依然繼續(xù)執(zhí)行后續(xù)命令妥粟。如:-rm a.o build/
@:表示該命令只執(zhí)行审丘,不回顯。一般規(guī)則執(zhí)行時(shí)會(huì)在終端打印出正在執(zhí)行的規(guī)則罕容,而加上此符號(hào)后將只執(zhí)行命令备恤,不回顯執(zhí)行的規(guī)則稿饰。如:@echo $(SOURCE)
7、普通變量
變量定義及賦值:
變量直接采用賦值的方法即可完成定義露泊,如:
INCLUDE = ./include/
變量取值:
? ? ? ? ? 用括號(hào)括起來(lái)再加個(gè)美元符喉镰,如:
? ? ? ? ? FOO = $(OBJ)
系統(tǒng)自帶變量:
通常都是大寫(xiě),比如 CC惭笑、PWD侣姆、CFLAG,等等沉噩。
有些有默認(rèn)值捺宗,有些沒(méi)有。比如常見(jiàn)的幾個(gè):
CPPFLAGS : 預(yù)處理器需要的選項(xiàng) 如:-I
CFLAGS:編譯的時(shí)候使用的參數(shù) –Wall –g -c
LDFLAGS :鏈接庫(kù)使用的選項(xiàng) –L -l
變量的默認(rèn)值可以修改川蒙,比如 CC 默認(rèn)值是 cc蚜厉,但可以修改為 gcc:CC=gcc
8、自動(dòng)變量
常用自動(dòng)變量:
Makefile 提供了很多自動(dòng)變量畜眨,但常用的為以下三個(gè)昼牛。這些自動(dòng)變量只能在規(guī)則中的命令中使用,其它地方使用都不行康聂。
$@ --> 規(guī)則中的目標(biāo)
$< --> 規(guī)則中的第一個(gè)依賴條件
$^ --> 規(guī)則中的所有依賴條件
例如:
app: main.c func1.c fun2.c ?gcc $^ - o $@
其中:$^ 表示 main.c func1.c fun2.c贰健,$< 表示 main.c,$@ 表示 app恬汁。
模式規(guī)則:
模式規(guī)則是在目標(biāo)及依賴條件中使用 % 來(lái)匹配對(duì)應(yīng)的文件伶椿,比如在目錄下有 main.c、func1.c氓侧、func2.c 三個(gè)文件脊另,對(duì)這三個(gè)文件的編譯可以由一條規(guī)則完成:
%.o:%.c ? $(CC) –c $< -o $@
這條模式規(guī)則表示:
main.o 由 main.c 生成, ? func1.o 由 func1.c 生成甘苍, ? func2.o 由 func2.c 生成尝蠕。
這就是模式規(guī)則的作用烘豌,可以一次匹配目錄下的所有文件载庭。
9、函數(shù)
Makefile 也為我們提供了大量的函數(shù)廊佩,同樣經(jīng)常使用到的函數(shù)為以下兩個(gè)囚聚。需要注意的是,Makefile 中所有的函數(shù)必須都有返回值标锄。在以下的例子中顽铸,假如目錄下有 main.c、func1.c料皇、func2.c 三個(gè)文件谓松。
通配符:
用于查找指定目錄下指定類型的文件星压,跟的參數(shù)就是目錄+文件類型,比如:
src = $(wildcard ./src/*.c)
這句話表示:找到 ./src 目錄下所有后綴為 .c 的文件鬼譬,并賦給變量 src娜膘。
命令執(zhí)行完成后,src 的值為:main.c func1.c fun2.c优质。
patsubst:
匹配替換竣贪,例如以下例子,用于從 src 目錄中找到所有 .c 結(jié)尾的文件巩螃,并將其替換為 .o 文件演怎,并賦值給 obj。
obj = $(patsubst %.c ,%.o ,$(src))
命令執(zhí)行完成后避乏,obj 的值為 main.o func1.o func2.o爷耀。
特別地,如果要把所有 .o 文件放在 obj 目錄下拍皮,可用以下方法:
obj = $(patsubst ./src/%.c, ./obj/%.o, $(src))
10畏纲、小結(jié)
Makefile 其實(shí)提供了非常非常多的功能,但本文所寫(xiě)的對(duì)于一般的企業(yè)應(yīng)用完全夠用了春缕。特別對(duì)于初學(xué)者盗胀,學(xué)習(xí)一些基礎(chǔ)知識(shí)(如本文),再輔一些案例(如本系列的幾個(gè)案例)锄贼,完全可以達(dá)到企業(yè)用人標(biāo)準(zhǔn)了票灰。正所謂要抓住事物的主要矛盾,可以先把基礎(chǔ)知識(shí)吃透再去延伸 Makefile 的其它知識(shí)宅荤。