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