1.makefile文件的主要結(jié)構(gòu)簡介:
makefile文件里面主要有三種內(nèi)容:
1.變量聲明:
變量聲明就是一種基本的嚴(yán)格字符替換的操作。
比如在前面聲明了:objects=program.o foo.o utils.o
那么在后面出現(xiàn)的所有$(objects)或者${objects}都會(huì)被自動(dòng)替換成上面的那個(gè)字符序列,而且是嚴(yán)格替換,即不帶空格的。
2.映射法則
3.命令:
映射法則和命令通常都是聯(lián)合起來組成這樣的結(jié)構(gòu)形式:
target... : prerequisites..
command
可以簡單地理解為通過prerequisites,也就是先決的依賴文件,采取后面描述的相應(yīng)的命令(這里的命令都是linux里的shell命令)command之后(一般是)生成了文件target。命令的前面都要按以下tab建留一段空白來表示它是命令。
有的target后面并沒有先決條件,也就是后面的命令是無條件執(zhí)行的。
這個(gè)結(jié)構(gòu)總的作用就是告訴make,target是不是out of date,具體視它的依賴文件而定,target不存在也視為out of date。然后就是如果過期了,那么更新,就是運(yùn)行下面的命令來更新。
2.前面那篇文章emacs中我們建立了兩個(gè)makefile文件,但是是空的,還沒有任何內(nèi)容。現(xiàn)在我們填上如下內(nèi)容:(這個(gè)是一個(gè)最簡單的例子,不過是一個(gè)不錯(cuò)的入門。)
在/project/hello的主目錄下面的makefile文件的內(nèi)容如下:
prefix = /usr/local
exec_prefix = $(prefix)
bindir = $(exec_prefix)/bin
export prefix
export exec_prefix
export bindir
all clean install uninstall :
cd src && $(MAKE) $@
.PHONY: all clean install uninstall
在/project/hello/src目錄下面的makefile文件內(nèi)容如下:
all: hello
hello: main.c
$(CC) -o $@ main.c
clean:
rm hello
install:
install -d $(bindir)
install -m 0755 hello $(bindir)
uninstall:
rm $(bindir)/hello
.PHONY: all clean install uninstall
我們等下詳細(xì)說明,先看下運(yùn)行情況:
現(xiàn)在makefile支持這四個(gè)命令:make,make install ,make clean和make uninstall。
我們從上圖可以看出可以直接從終端調(diào)用我們生成的程序hello,然后返回“hello,the world!”。
首先我們看主目錄下的makefile文件,前面那部分是變量聲明,這個(gè)等下還會(huì)說到。然后是export 變量,這個(gè)就是主目錄下的主makefile文件可以使用這個(gè)命令,意思是將變量和子一級(jí)目錄下的makefile共享。
然后我們看到
all clean install uninstall :
cd src && $(MAKE) $@
.PHONY: all clean install uninstall
這實(shí)際上是一個(gè)跳轉(zhuǎn)結(jié)構(gòu),首先介紹下.PHONY是個(gè)什么意思,前面說了每一個(gè)target默認(rèn)都是一個(gè)待生成文件,但是.PHONY:后面跟著的target的意思是這些target不用生成文件。那么總的來說這里的all,clean,install,uninstall在這里是些沒有依賴文件的不用生成最終target文件的執(zhí)行命令了。這些執(zhí)行命令就是前面說的make,make install ,make clean和make uninstall。make的意思實(shí)際上就是make all,這兩個(gè)命令是沒有區(qū)別的。
然后我們看到命令,cd src這個(gè)很容易理解,就是跳轉(zhuǎn)到src目錄中去了。然后&&符號(hào)的意思是邏輯與,即前一命令執(zhí)行完之后再執(zhí)行后面的命令。而后面的$(MAKE)可能是一個(gè)具有系統(tǒng)默認(rèn)值的變量,在這里應(yīng)該就是make。而$@符號(hào)的意思則是指代當(dāng)前的target。比如說我現(xiàn)在make clean ,那么命令最終就成了這個(gè)樣子:
cd src &&make clean
然后下一個(gè)make clean的命令實(shí)際上是對(duì)src子目錄下的makefile文件說的,我們看到這里簡單的:
clean:
rm hello
即把生成的可執(zhí)行文件hello刪掉即可。
然后我們?cè)賮砜醋幽夸浵履莻(gè)makefile文件如何處理make all 命令:
all: hello
hello: main.c
$(CC) -o $@ main.c
我們看到,這里首先說明all依賴于hello,然后hello依賴于main.c,而要生成或者更新hello的話需要執(zhí)行下面的命令:
cc -o hello main.c
上面的$(CC)也是具有系統(tǒng)默認(rèn)值的變量,就是cc,不過在GNU/LINUX體系下可能調(diào)用的是gcc工具。后面的選項(xiàng)-o的意思是編譯連接然后生成后面的那個(gè)名字的文件。名字在這里就是hello。
然后我們?cè)賮砜磎ake install命令執(zhí)行的情況:
install:
install -d $(bindir)
install -m 0755 hello $(bindir)
前面說過了這個(gè)變量是繼承自主目錄makefile文件中的定義,然后翻譯出來$(bindir)就是/usr/local/bin。linux系統(tǒng)在終端可以直接調(diào)用的命令存放點(diǎn)有兩個(gè)位置,另外的一個(gè)是/usr/bin。/usr/local文件夾內(nèi)部的結(jié)構(gòu)和/usr內(nèi)部的結(jié)構(gòu)非常相似。似乎講起來/usr是供系統(tǒng)內(nèi)部的軟件使用的空間,但這個(gè)規(guī)矩并不是死的。
uninstall命令我們看到就是一個(gè)刪除對(duì)應(yīng)位置hello文件的操作。所以現(xiàn)在就把linux中的install命令講講就可以了。
第一個(gè)install命令接著-d的選項(xiàng)的意思就是目錄確認(rèn),在這里我覺得有點(diǎn)多余。
第二個(gè)install命令接著-m的選項(xiàng)的意思就是把hello復(fù)制到指定的目錄中去,然后相應(yīng)文件也就是hello文件的權(quán)限設(shè)置成為0755.關(guān)于權(quán)限我覺得在這里似乎也沒有什么好說的。在這里用第二個(gè)install命令就可以搞定了,過程是復(fù)制,加權(quán)限,更新時(shí)間戳。