引用文章A:http://blog.csdn.net/liang13664759/article/details/1771246shell
文章介紹:很是詳細的文章,講解上都是比較基礎的知識。express
本文可能會持續更新部分引用文章。但博文自己更新內容並不會太多。主要由於我的寫做水平問題,並不適合講解專業性質的知識,容易誤人子弟。ide
文章中會記錄一些比較經常使用的指令和函數,方便快速查找。函數
一,基本使用。性能
makefile基本依賴規則:默認狀況下,會找到第一個目標指令,而後檢測其對應依賴,而後進行初步的索引和指令執行(一般爲編譯指令)。在依賴上,咱們可使用模式規則(%.o : %c)的方式來動態識別依賴。ui
上述方式可以知足大部分基本狀況。再複雜的情景,則不是本文須要完成的內容裏。spa
一個例子:操作系統
%.o : %c.net
gcc -c %(<) -o $(@)debug
dest : main.o
gcc main.o -o dest
這個例子中,main.o會經過上述模式規則自動被生成main.o(須要已存在main.c)。
二,經常使用操做和變量。
1,僞目標:.PHONY: 用來指定目標爲 僞目標。常見的僞目標爲:clean。此指令一般省略。 2,經常使用make參數: *: -n,--just-print,--dry-run,--recon。不執行參數,這些參數只是打印命令,無論目標是否更新,把規則和連帶規則下的命令打印出來,但不執行,這些參數對於咱們調試makefile頗有用處。 *: -t,--touch。 這個參數的意思就是把目標文件的時間更新,但不更改目標文件。也就是說,make僞裝編譯目標,但不是真正的編譯目標,只是把目標變成已編譯過的狀態。 *:-W <file>,--what-if=<file>,--assume-new=<file>,--new-file=<file>。 這個參數須要指定一個文件。通常是是源文件(或依賴文件),Make會根據規則推導來運行依賴於這個文件的命令,通常來講,能夠和「-n」參數一同使用,來查看這個依賴文件所發生的規則命令。 *:-q,--question。 這個參數的行爲是找目標的意思,也就是說,若是目標存在,那麼其什麼也不會輸出,固然也不會執行編譯,若是目標不存在,其會打印出一條出錯信息。 *:-d,至關於「--debug=a」。 *:-e,--environment-overrides。 指明環境變量的值覆蓋makefile中定義的變量的值。 *:-f=<file>,--file=<file>,--makefile=<file>。 指定須要執行的makefile。 *:-I <dir>,--include-dir=<dir>。 指定一個被包含makefile的搜索目標。可使用多個「-I」參數來指定多個目錄。 *:-p,--print-data-base。 輸出makefile中的全部數據,包括全部的規則和變量。這個參數會讓一個簡單的makefile都會輸出一堆信息。若是你只是想輸出信息而不想執行makefile,你可使用「make -qp」命令。若是你想查看執行makefile前的預設變量和規則,你可使用「make –p –f /dev/null」。這個參數輸出信息會包含着你的makefile文件的文件名和行號,因此,用這個參數來調試你的makefile會是頗有用的,特別是當你的環境變量很複雜的時候。 *:-q,--question。 不運行命令,也不輸出。僅僅是檢查所指定的目標是否須要更新。若是是0則說明要更新,若是是2則說明有錯誤發生。 *:-r,--no-builtin-rules。 禁止make使用任何隱含規則。 *:-R,--no-builtin-variabes。 禁止make使用任何做用於變量上的隱含規則。 3,自動化變量: *:$@ 表示規則中的目標文件集。在模式規則中,若是有多個目標,那麼,"$@"就是匹配於目標中模式定義的集合。 *:$% 僅當目標是函數庫文件中,表示規則中的目標成員名。例如,若是一個目標是"foo.a(bar.o)",那麼,"$%"就是"bar.o","$@"就是"foo.a"。若是目標不是函數庫文件(Unix下是[.a],Windows下是[.lib]),那麼,其值爲空。 *:$< 依賴目標中的第一個目標名字。若是依賴目標是以模式(即"%")定義的,那麼"$<"將是符合模式的一系列的文件集。注意,其是一個一個取出來的。 *:$? 全部比目標新的依賴目標的集合。以空格分隔。 *:$^ 全部的依賴目標的集合。以空格分隔。若是在依賴目標中有多個重複的,那個這個變量會去除重複的依賴目標,只保留一份。 *:$+ 這個變量很像"$^",也是全部依賴目標的集合。只是它不去除重複的依賴目標。 *:$* 這個變量表示目標模式中"%"及其以前的部分。
三,經常使用函數。
函數調用,很像變量的使用,也是以「$」來標識的,其語法以下:$(<function> <arguments> )
$(subst <from>,<to>,<text> )
名稱:字符串替換函數——subst。
功能:把字串<text>中的<from>字符串替換成<to>。
返回:函數返回被替換事後的字符串。
$(patsubst <pattern>,<replacement>,<text> )
名稱:模式字符串替換函數——patsubst。
功能:查找<text>中的單詞(單詞以「空格」、「Tab」或「回車」「換行」分隔)是否符合模式<pattern>,若是匹配的話,則以<replacement>替換。這裏,<pattern>能夠包括通配符「%」,表示任意長度的字串。若是<replacement>中也包含「%」,那麼,<replacement>中的這個「%」將是<pattern>中的那 個「%」所表明的字串。(能夠用「/」來轉義,以「/%」來表示真實含義的「%」字符)
返回:函數返回被替換事後的字符串。
$(strip <string> )
名稱:去空格函數——strip。
功能:去掉<string>字串中開頭和結尾的空字符。
返回:返回被去掉空格的字符串值。
$(findstring <find>,<in> )
名稱:查找字符串函數——findstring。
功能:在字串<in>中查找<find>字串。
返回:若是找到,那麼返回<find>,不然返回空字符串。
$(filter <pattern...>,<text> )
名稱:過濾函數——filter。
功能:以<pattern>模式過濾<text>字符串中的單詞,保留符合模式<pattern>的單詞。能夠有多個模式。
返回:返回符合模式<pattern>的字串。
$(filter-out <pattern...>,<text> )
名稱:反過濾函數——filter-out。
功能:以<pattern>模式過濾<text>字符串中的單詞,去除符合模式<pattern>的單詞。能夠有多個模式。
返回:返回不符合模式<pattern>的字串。
$(sort <list> )
名稱:排序函數——sort。
功能:給字符串<list>中的單詞排序(升序)。
返回:返回排序後的字符串。
$(word <n>,<text> )
名稱:取單詞函數——word。
功能:取字符串<text>中第<n>個單詞。(從一開始)
返回:返回字符串<text>中第<n>個單詞。若是<n>比<text>中的單詞數要大,那麼返回空字符串。
$(wordlist <s>,<e>,<text> )
名稱:取單詞串函數——wordlist。
功能:從字符串<text>中取從<s>開始到<e>的單詞串。<s>和<e>是一個數字。
返回:返回字符串<text>中從<s>到<e>的單詞字串。若是<s>比<text>中的單詞數要大,那麼返回空字符串。若是<e>大於<text>的單詞數,那麼返回從<s>開始,到<text>結束的單詞串。
$(words <text> )
名稱:單詞個數統計函數——words。
功能:統計<text>中字符串中的單詞個數。
返回:返回<text>中的單詞數。
$(firstword <text> )
名稱:首單詞函數——firstword。
功能:取字符串<text>中的第一個單詞。
返回:返回字符串<text>的第一個單詞。
$(dir <names...> )
名稱:取目錄函數——dir。
功能:從文件名序列<names>中取出目錄部分。目錄部分是指最後一個反斜槓(「/」)以前的部分。若是沒有反斜槓,那麼返回「./」。
返回:返回文件名序列<names>的目錄部分。
$(notdir <names...> )
名稱:取文件函數——notdir。
功能:從文件名序列<names>中取出非目錄部分。非目錄部分是指最後一個反斜槓(「/」)以後的部分。
返回:返回文件名序列<names>的非目錄部分。
示例: $(notdir src/foo.c hacks)返回值是「foo.c hacks」。
$(suffix <names...> )
名稱:取後綴函數——suffix。
功能:從文件名序列<names>中取出各個文件名的後綴。
返回:返回文件名序列<names>的後綴序列,若是文件沒有後綴,則返回空字串。
示例:$(suffix src/foo.c src-1.0/bar.c hacks)返回值是「.c .c」。
$(basename <names...> )
名稱:取前綴函數——basename。
功能:從文件名序列<names>中取出各個文件名的前綴部分。
返回:返回文件名序列<names>的前綴序列,若是文件沒有前綴,則返回空字串。
示例:$(basename src/foo.c src-1.0/bar.c hacks)返回值是「src/foo src-1.0/bar hacks」。
$(addsuffix <suffix>,<names...> )
名稱:加後綴函數——addsuffix。
功能:把後綴<suffix>加到<names>中的每一個單詞後面。
返回:返回加事後綴的文件名序列。
示例:$(addsuffix .c,foo bar)返回值是「foo.c bar.c」。
$(addprefix <prefix>,<names...> )
名稱:加前綴函數——addprefix。
功能:把前綴<prefix>加到<names>中的每一個單詞後面。
返回:返回加過前綴的文件名序列。
示例:$(addprefix src/,foo bar)返回值是「src/foo src/bar」。
$(join <list1>,<list2> )
名稱:鏈接函數——join。
功能:把<list2>中的單詞對應地加到<list1>的單詞後面。若是<list1>的單詞個數要比<list2>的多,那麼,<list1>中的多出來的單詞將保持原樣。若是<list2>的單詞個數要比<list1>多,那麼,<list2>多出來的單詞將被複制到<list2>中。
返回:返回鏈接事後的字符串。
示例:$(join aaa bbb , 111 222 333)返回值是「aaa111 bbb222 333」。
$(foreach <var>,<list>,<text> )
這個函數的意思是,把參數<list>中的單詞逐一取出放到參數<var>所指定的變量中,而後再執行<text>所包含的表達式。每一次<text>會返回一個字符串,循環過程當中,<text>的所返回的每一個字符串會以空格分隔,最後當整個循環結束時,<text>所返回的每一個字符串所組成的整個字符串(以空格分隔)將會是foreach函數的返回值。
因此,<var>最好是一個變量名,<list>能夠是一個表達式,而<text>中通常會使用<var>這個參數來依次枚舉<list>中的單詞。舉個例子:
$(if <condition>,<then-part> )
$(if <condition>,<then-part>,<else-part> )
可見,if函數能夠包含「else」部分,或是不含。即if函數的參數能夠是兩個,也能夠是三個。<condition>參數是if的表達式,若是其返回的爲非空字符串,那麼這個表達式就至關於返回真,因而,<then-part>會被計算,不然<else-part>會被計算。、
而if函數的返回值是,若是<condition>爲真(非空字符串),那個<then-part>會是整個函數的返回值,若是<condition>爲假(空字符串),那麼<else-part>會是整個函數的返回值,此時若是<else-part>沒有被定義,那麼,整個函數返回空字串。
$(call <expression>,<parm1>,<parm2>,<parm3>...)
當make執行這個函數時,<expression>參數中的變量,如$(1),$(2),$(3)等,會被參數<parm1>,<parm2>,<parm3>依次取代。而<expression>的返回值就是call函數的返回值。例如:
shell函數 shell函數也不像其它的函數。顧名思義,它的參數應該就是操做系統Shell的命令。它和反引號「`」是相同的功能。這就是說,shell函數把執行操做系統命令後的輸出做爲函數返回。因而,咱們能夠用操做系統命令以及字符串處理命令awk,sed等等命令來生成一個變量,如: contents := $(shell cat foo) files := $(shell echo *.c) 注意,這個函數會新生成一個Shell程序來執行命令,因此你要注意其運行性能,若是你的Makefile中有一些比較複雜的規則,並大量使用了這個函數,那麼對於你的系統性能是有害的。特別是Makefile的隱晦的規則可能會讓你的shell函數執行的次數比你想像的多得多。