前者是前面的變量可使用後面的變量。可是=右側不能包含本身的變量名,不然會循環調用spa
後者是前面的變量不能使用後面的變量,只能使用前面定義好的變量命令行
延時變量用 =, ?=, 定義, 或用define 定義code
當即變量用:= 來定義,前面的變量不能使用後面的變量,只能使用前面已定義好了的變量字符串
#!/bin/sh #變量賦值時,=兩邊空格無關緊要,通常都寫上空格 #!/bin/sh y = $(x) bar x = foo m := $(n) tea n := green all: @echo $y @echo $m
輸出:foo bar
teaget
若是你要傳遞變量到下級 Makefile 中,那麼你可使用這樣的聲明string
格式 export <variable ...> 自動化
如:export variable = valueclass
export variable += value變量
若是你不想讓某些變量傳遞到下級 Makefile 中,那麼你能夠這樣聲明object
unexport <variable ...>
若是你要傳遞全部的變量,那麼,只要一個 export 就好了。後面什麼也不用跟,表示傳遞全部的變量。
include <filename> 上層的文件中定義的變量會以系統環境變量的方式傳遞到下層的文件中
也能夠說:被嵌套的文件中的變量在嵌套文件中爲全局變量
nullstring 是一個 Empty 變量,其中什麼也沒有,space := $(nullstring)
表示若是沒有定義,則使用此值,若是定義了,則用定義的值
FOO ?= bar 其含義是,若是 FOO 沒有被定義過,那麼變量 FOO 的值就是「bar」 ,若是 FOO 先前被定義過,那麼這條語將什麼也不作
方式一:「$(var:a=b)」或是「${var:a=b}」
替換變量中的共有的部分,如上格式,是將var的變量中全部在「a」字符串後就結尾(空格或回車)的「a」替換爲「b」字符串
foo := a.o b.o c.o bar := $(foo:.o=.c) #等價與 bar := a.c b.c c.c
方式二:$(var:%.o=%.c)
被替換字串中都含有相同的部分(或者說是模式相同,以下foo中都含有.o),將相同的部分進行替換(以下將foo中的.o替換爲.c)
foo := a.o b.o c.o bar := $(foo:%.o=%.c) #等價與 bar := a.c b.c c.c
目的:能夠更加容易地定義多目標的規則,可讓咱們的規則變得更加的有彈性和靈活 。
語法:<targets ...>;: <target-pattern>;: <prereq-patterns ...>;
<commands>;
targets定義了一系列的目標文件,能夠有通配符。是目標的一個集合。
target-parrtern是指明瞭targets的模式,也就是的目標集模式。
prereq-parrterns是目標的依賴模式,它對target-parrtern造成的模式再進行一次依賴目標的定義。
objects = foo.o bar.o all: $(objects) $(objects): %.o: %.c $(CC) -c $(CFLAGS) $< -o $@ # $(object)爲目標文件 # %.o爲目標集的模式(可認爲%表明全部目標中的不一樣部分,.o爲全部目標中相同的部分) # %.c爲目標的依賴文件,即將目標集的模式替換爲依賴模式(將目標集的文件不一樣的部分%不變,相同的部分.o替換爲.c結尾)
上面的例子中,指明瞭咱們的目標從$object中獲取,「%.o」代表要全部以「.o」結尾的目標,也就是「foo.o bar.o」,也就是變量$object集合的模式,而依賴模式「%.c」則取模式「%.o」的「%」,也就是「foo bar」,併爲其加下「.c」的後綴,因而,咱們的依賴目標就是「foo.c bar.c」。
而命令中的「$<」和「$@」則是自動化變量,「$<」表示全部的依賴目標集(也就是「foo.c bar.c」),「$@」表示目標集(也就是「foo.o bar.o」)。因而,上面的規則展開後等價於下面的規則:
foo.o : foo.c $(CC) -c $(CFLAGS) foo.c -o foo.o bar.o : bar.c $(CC) -c $(CFLAGS) bar.c -o bar.o
把變量的值再當成變量
x = y y = z z = "123" a := $($(x)) #a的值爲123
咱們可使用「+=」操做符給變量追加值,如:
objects = main.o foo.o bar.o utils.o
objects += another.o
首先須要知道:
makefile中每條命令的開頭必須以[Tab]鍵開頭,除非,命令是緊跟在依賴規則後面的分號後的
在命令行之間中的空格或是空行會被忽略,可是若是該空格或空行是以 Tab 鍵開頭的,那麼make 會認爲其是一個空命令
結束標誌
一、空行、ifeq、define、ifndef等並不識別爲命令集的結束
二、新的目標或者變量定義會識別爲命令集的結束
簡而言之:一條規則的命令會一直向下搜索,直到遇到非命令相關的部分(例如目標,變量定義等),通俗的說就是遇到沒有Tab 鍵開頭行一條規則就結束。
-n make 執行時,帶入 make 參數「-n」或「--just-print」 ,那麼其只是顯示命令,但不會執行命令
-s make 參數「-s」或「--slient」則是全面禁止命令的顯示,但執行命令
-k make 的參數的是「-k」或是「--keep-going」 ,這個參數的意思是,若是某規則中的命令出錯了,那麼就終目該規則的執行,但繼續執行其它規則
-i make 加上「-i」或是「--ignore-errors」參數,那麼,Makefile 中全部命令都會忽略錯誤。而若是一個規則是以「.IGNORE」做爲目標的,那麼這個規則中的全部命令將會忽略錯誤
具體可經過make --help查看
就是將一些相同的命令序列定義在一個變量裏,造成一個命令包。定義這種命令序列的語法以「define」開始,以「endef」結束,例如
#!/bin/sh define commds echo "hello" echo "world" endef all: echo "commds package start" ${commds} echo "commds package end"
輸出:commds package start
hello
world
commds package end
在 Makefile 的命令行前加一個減號「-」 (在Tab 鍵以後) ,標記爲無論命令出不出錯都認爲是成功的