1、執行make程序shell
make的退出狀態:vim
0 --- 表示執行成功ide
1 --- 表示執行make時使用了「-q」參數,並且當前工程中存在過期的目標文件函數
2 --- 執行過程當中出現了錯誤,同時會提示錯誤信息ui
1 指定makefile文件spa
執行make時,使用選項「-f」「--file」「--makefile」選項來指定所要執行的makefile文件。例如:「make –f altmake」命令行
當在make的命令行選項中出現多個「-f」參數時,全部經過「-f」指定的文件都將被做爲make解析執行的makefile文件。debug
默認狀況下,若是沒有使用「-f」「--file」「--makefile」指定文件,則make會在當前工做目錄中依次搜索名爲「GNUmakefile」「makefile」「Makefile」的文件。調試
2 指定終極目標code
默認狀況下,終極目標就是makefile中,除了以「.」開始的第一個規則中的第一個目標。可是也能夠指定具體執行哪一個目標,格式爲:「make TARGET_NAME」。
make在執行時設置了一個特殊變量「MAKECMDGOALS」,記錄了命令行參數指定的終極目標列表,沒有經過命令行參數指定終極目標時,此變量爲空。注:此變量僅用於特殊場合,在makefile中不要對它進行從新定義。
部分約定的僞目標和空目標命令以下:
all |
makefile的頂層目標,通常此目標做爲默認的終極目標 |
clean |
刪除全部由make建立的文件 |
mostlyclean |
相似於clean |
distclean |
... |
realclean |
... |
clobber |
... |
install |
將make成功建立的可執行文件拷貝到shell環境變量「PATH」指定的某個目錄中。典型地,可執行文件被拷貝到「/usr/local/bin」,庫文件被拷貝到「/usr/local/lib」 |
|
打印出全部被更改的源文件列表 |
tar |
建立一個tar文件 |
shar |
建立一個源代碼的shell文檔 |
dist |
建立源文件發佈的壓縮包 |
TAGS |
建立當前目錄下的全部源文件的符號信息文件,該文件能夠被vim使用 |
check |
檢查make最終生成的文件 |
test |
... |
3 替代命令的執行
所謂的替代,就是替代make默認動做的執行,包括:
-n --just-print --dry-run --recon |
只打印出重建過時目標所需執行的命進行重建令,而並不對目標 |
-t --touch |
更新全部目標文件的時間戳,並不更新內容 |
-q --question |
不執行任何命令,而且不打印任何輸出信息,只檢查所指定的目標是否已是最新的。若是最新,返回0;不然,返回1。根據其返回值來判斷是否須要執行目標更新的操做 |
-W FILE --what-if=FILE --assume-new=FILE --new-file=FILE |
將當前系統時間做爲指定文件FILE的時間戳。更改文件的時間戳後,執行make時,因爲依賴文件的時間戳已更新,所以目標將會被重建。經過這種方式並結合「-n」,能夠在修改一個文件後檢查本次修改操做會形成哪些目標須要被更新,但並不執行更新的命令,只是打印命令;
與「-t」結合,make將忽略其餘規則的命令,只對依賴於「-W」指定文件的目標執行「touch」命令,在沒有使用「-s」時,能夠看到哪些文件執行了「touch」。
與「-q」結合,因爲將當前時間做爲指定文件的時間戳,而目標文件相對於系統當前時間是過期的,所以make的返回狀態在沒有錯誤發生時爲1,存在錯誤時爲2 |
4 防止特定文件重建
有時修改工程中的某一個文件,並不但願重建那些依賴於這個文件的目標,好比說咱們在一個頭文件中加入了一個宏定義、或者增長一個函數聲明,這些修改不會對已經編譯完成的程序產生任何的影響,此時,不須要進行重建操做。爲了不從新編譯整個工程,能夠以下處理:
1> 使用make對特定目標進行重建操做
2> 使用「make –o HEADERFILE」能夠避免依賴於頭文件HEADERFILE的目標被重建。可使用多個「-o HEADERFILE」指定多個這樣的頭文件。可是注意:「-o」的這種用法僅限於.h頭文件。
3> 使用「make -t」命令來改變已存在的全部目標文件的時間戳,將其時間修改到系統當前時間。
5 替換變量定義
執行make時,命令行參數的格式爲「V=X」,表示定義變量V,值爲X,並用這個變量替換makefile中的同名變量。一般用這種方式傳遞一個公共變量給make。例如,使用「CFLAGS」指定編譯參數:
cc –c $(CFLAGS) foo.c
這樣就能夠經過改變「CFLAGS」的值來控制編譯選項。咱們能夠在makefile中爲它指定值,如:
CFLAGS = -g,如此編譯語句變爲:cc –c –g foo.c
爲了防止命令行參數的定義覆蓋makefile中的同名定義,能夠在makefile中使用指示符「override」聲明這個變量。
6 make的命令行選項
-b |
忽略,提供其它版本make的兼容性 |
||||||||||||
-m |
... |
||||||||||||
-B |
強制重建全部規則的目標 |
||||||||||||
--always-make |
... |
||||||||||||
-C DIR |
將工做目錄切換到「DIR」以後執行make;若是存在多個「-C」選項,那麼make的最終工做目錄是第一個指定的目錄。 |
||||||||||||
--directory=DIR |
... |
||||||||||||
-d |
make執行過程當中打印出全部的調試信息,包括make構造依賴關係鏈、重建目標過程的全部信息,等價於「—debug = a」 |
||||||||||||
--debug[=OPTIONS] |
make執行過程當中打印出調試信息,使用「OPTIONS」控制調試信息級別,默認是「OPTIONS = b」,其可選值以下所示:
|
||||||||||||
-e |
使用系統環境變量覆蓋makefile中同名的環境變量 |
||||||||||||
--environment-overrides |
... |
||||||||||||
-f=FILE |
執行make執行的makefile文件FILE |
||||||||||||
--file=FILE |
... |
||||||||||||
--makefile=FILE |
... |
||||||||||||
-h |
打印幫助信息 |
||||||||||||
--help |
... |
||||||||||||
-i |
執行過程當中忽略規則命令執行的錯誤 |
||||||||||||
--ignore-errors |
... |
||||||||||||
-I DIR |
指定被包含makefile文件的搜索目錄 |
||||||||||||
--include-dir=DIR |
... |
||||||||||||
-j [JOBS] |
指定可同時執行的命令數目 |
||||||||||||
--jobs[=JOBS] |
... |
||||||||||||
-k |
執行規則命令出現錯誤時不終止make的執行,make將盡最大可能地執行全部的命令,直到出現致命錯誤才終止 |
||||||||||||
--keep-going |
... |
||||||||||||
-I LOAD |
若是系統負荷超過「LOAD指定的浮點數」,那麼make將再也不啓動新的任務 |
||||||||||||
--load-average[=LOAD] |
... |
||||||||||||
--max-load[=LOAD] |
... |
||||||||||||
-n |
只打印出所要執行的命令,而不真正執行 |
||||||||||||
--just-print |
... |
||||||||||||
--dry-run |
... |
||||||||||||
--recon |
... |
||||||||||||
-o FILE |
指定「FILE」文件不須要被重建,同時依賴「FILE」的目標也不須要重建 |
||||||||||||
--old-file=FILE |
... |
||||||||||||
--assume-old=FILE |
... |
||||||||||||
-p |
執行make命令前,打印出make讀取的全部makefile的數據,同時打印出make的版本信息。若是隻是須要打印這些信息而不執行命令,可使用「make -qp」;查看make執行前的預設規則和變量,可使用「make –p –f /dev/null」 |
||||||||||||
--print-data-base |
... |
||||||||||||
-q |
不執行任何命令,也無任何輸出。make只是返回一個查詢狀態,0表示沒有目標須要重建;1表示存在須要重建的目標;2表示發生錯誤 |
||||||||||||
--question |
... |
||||||||||||
-r |
取消全部內嵌的隱含規則,但不取消make內嵌的隱含變量 |
||||||||||||
--no-builtin-rules |
... |
||||||||||||
-R |
取消全部內嵌的隱含變量,同時取消全部內嵌的隱含規則,所以默認會打開「-r」選項 |
||||||||||||
--no-builtin-variables |
... |
||||||||||||
-s |
取消命令執行過程的打印 |
||||||||||||
--silent |
... |
||||||||||||
--quiet |
... |
||||||||||||
-S |
取消「-k」選項。在遞歸的make過程當中,子make經過「MAKEFLAGS」變量繼承上層的命令行選項,使用「-S」選項會取消上層傳遞的「-k」 |
||||||||||||
--no-keep-going |
... |
||||||||||||
--stop |
... |
||||||||||||
-t |
更新全部目標文件的時間戳爲當前系統時間,防止make對全部過時目標文件的重建 |
||||||||||||
--touch |
... |
||||||||||||
-v |
查看make版本信息 |
||||||||||||
--version |
... |
||||||||||||
-w |
在make進入一個目錄讀取makefile以前打印出工做目錄信息 |
||||||||||||
--print-directory |
... |
||||||||||||
--no-print-directory |
取消「-w」選項 |
||||||||||||
-W FILE |
設定「FILE」文件的時間戳爲系統當前時間,可是並不改變該文件實際的最後修改時間,主要是爲了實現對全部依賴於文件「FILE」的目標的強制重建 |
||||||||||||
--what-if=FILE |
... |
||||||||||||
--new-file=FILE |
... |
||||||||||||
--assume-file=FILE |
... |
||||||||||||
--warn-undefined-variables |
使用makefile中沒有定義的變量時給出警告信息 |
2、makefile相關函數
1 函數的調用
格式:
$(FUNCTION ARGUMENTS)
或者
${FUNCTION ARGUMENTS}
FUNCTION爲調用的內部函數名【用戶自定義的函數須要經過call來調用】;ARGUMENTS爲函數的參數,多個參數之間不能以逗號「,」或者空格做爲分隔符,這是由於「,」已被做爲多個參數的分隔符,而前置空格會被忽略掉。若是須要在函數參數中使用「,」或者空格做爲分隔符,必須先將其賦給一個變量,而後再使用變量來分割,以下:
comma := , empty := space := $(empty) $(empty) foo := a b c bar := $(subst $(space), $(comma), $(foo)) 表示bar := a,b,c
2 文本處理函數
2.1 $(subst, FROM, TO, TEXT)
函數名:subst --- 字符串替換
函數功能:將字符串「TEXT」中的「FROM」替換爲「TO」。
返回值:替換後的字符串
實例:
$(subst, ee, EE, feet on the street)
返回字符串:「fEEt on the strEEt」
2.2 $(patsubst PATTERN, REPLACEMENT, TEXT)
函數名:patsubst --- 模式替換
函數功能:在「TEXT」中搜索以空格分割的單詞,將符合模式「PATTERN」的部分替換爲「REPLACEMENT」。在「PATTERN」和「REPLACEMENT」中,只有第一個出現的%會被做爲模式字符來處理,以後出現的%只做爲一個普通字符;若是參數中須要將第一個出現的%也看成普通字符處理,只須要使用「\」進行轉義便可。
返回值:替換後的字符串
實例:
$(patsubst %.c, %.o, x.c.c bar.c)
返回字符串:x.c.o bar.o
2.3 $(strip STRINT)
函數名:strip --- 去除空格
函數功能:去除字符串開頭和結尾的空格;合併字符串之間的多個空格爲一個空格
返回值:去除多餘空格後的字符串
實例:
STR = A B C
LOSTR = $(strip $(STR))
返回字符串:「A B C」
2.4 $(findstring FIND, IN)
函數名:findstring --- 查找字符串
函數功能:在字符串「IN」中查找「FIND」。
返回值:若找到則返回「FIND」,不然返回空。
實例:
$(findstring a, a b c)
返回字符串:「a」
2.5 $(filter PATTERN, TEXT)
函數名:filter --- 過濾函數
函數功能:過濾掉「TEXT」中全部不符合模式「PATTERN」的單詞;如有多個「PATTERN」,則以空格隔開。
返回值:「TEXT」中與「PATTERN」匹配的字符串。
實例:
sources := foo.c bar.c baz.s ugh.h foo : $(sources) cc $(filter %.c %s, $(sources)) –o foo
2.6 $(filter-out PATTERN, TEXT)
函數名:filter-out --- 反過濾函數
函數功能:與filter的功能恰好相反。
2.7 $(sort LIST)
函數名:sort --- 排序
函數功能:對LIST中的單詞以首字母進行排序,同時去掉重複的單詞
返回值:排好序的字符串
實例:
$(sort foo bar lose foo)
返回字符串:「bar foo lose」
2.8 $(word N, TEXT)
函數名:word --- 取單詞
函數功能:返回「TEXT」中的第N個單詞,N從1開始計數。
返回值:第N個單詞或者空。
實例:
$(word 2, foo bar baz)
返回字符串:「bar」
2.9 $(wordlist S, E, TEXT)
函數名:wordlist --- 取子串
函數功能:返回「TEXT」中第S個~第E個單詞組成的子串。
返回值:第S~E個單詞或者返回空。
實例:
$(wordlist 2, 3, foo bar baz)
返回字符串:「bar baz」
2.10 $(words TEXT)
函數名:words --- 統計單詞個數
函數功能:計算「TEXT」中的單詞個數
返回值:單詞個數
實例:
$(words, foo bar)
返回值:2
2.11 $(firstword NAMES)
函數名:firstword --- 取首單詞
函數功能:返回「NAMES」中的第一個單詞
返回值:第一個單詞
實例:
$(firstword foo bar baz)
返回字符串:「foo」
3 文件名處理函數
3.1 $(dir NAMES)
函數名:dir --- 取目錄
函數功能:從文件名列表「NAMES」中取出各個文件名的目錄部分,就是包含在文件名中的最後一個斜線\以前的部分。
返回值:返回目錄部分列表。若是文件名中沒有目錄部分,那麼認爲當前文件的目錄爲「./」。
實例:
$(dir src/foo.c hacks)
返回字符串:「src. ./」
3.2 $(notdir NAMES)
函數名:notdir --- 取文件名
函數功能:從文件名列表「NAMES」中取出各個文件的文件名部分,就是包含在文件名中的最後一個斜線\以後的部分。
返回值:文件名列表。
實例:
$(notdir src/foo.c hacks)
返回字符串爲:「foo.c hacks」
3.3 $(suffix NAMES)
函數名:suffix --- 取後綴
函數功能:從「NAMES」列表中取出各個文件名的後綴,就是文件名中最後一個「.」以後的部分。
返回值:文件後綴列表。若是文件名沒有後綴,則返回空。
實例:
$(suffix src/foo.c src-1.0/bar.c hacks)
返回字符串:「.c .c」
3.4 $(basename NAMES)
函數名:basename --- 取前綴
函數功能:從「NAMES」序列中取出各個文件名的前綴部分,指的是文件名中最後一個點號「.」以前的部分。
返回值:前綴序列或空字符串。
實例:
$(basename src/foo.c src-1.0/bar.c /home/jack/.font.cache-1 hacks)
返回字符串:「src/foo src-1.0/bar /home/jack/.font hacks」
3.5 $(addsuffix SUFFIX, NAMES)
函數名:addsuffix --- 加後綴
函數功能:爲「NAMES」列表中的每一個文件加上後綴「SUFFIX」。
返回值:加上後綴的文件名列表。
實例:
$(addsuffix .c, foo bar)
返回字符串:「foo.c bar.c」
3.6 $(addprefix PREFIX, NAMES)
函數名:addprefix --- 加前綴
函數功能:爲「NAMES」列表中的每一個文件加上前綴「PREFIX」。
返回值:加上前綴的文件名列表。
實例:
$(addprefix src/, foo bar)
返回字符串:「src/foo src/bar」
3.7 $(join LIST1, LIST2)
函數名:join --- 對應單詞拼接
函數功能:將字符串LIST2中的第一個單詞拼接到字符串LIST1中第一個單詞以後合併爲一個單詞;將字符串LIST2中的第二個單詞拼接到字符串LIST1中第二個單詞以後合併爲一個單詞;...,依次類推。
返回值:拼接後的字符串。若是LIST1中和LIST2中的數目不一樣,則兩者中多餘的部分也將被返回。
實例:
$(join a b, .c .o)
返回字符串:「a.c b.o」
3.8 $(wildcard PATTERN)
函數名:wildcard --- 獲取符合某個模式的文件名
函數功能:列出當前目錄下全部符合模式「PATTERN」格式的文件名。
返回值:返回當前目錄下全部符合模式「PATTERN」的文件名。
實例:
$(wildcard *.c)
返回字符串:「當前目錄下全部.c文件的列表」
4 其餘函數
4.1 foreach函數
格式:$(foreach VAR, LIST, TEXT)
函數功能:執行時,將「LIST」列表中使用空格分隔的單詞依次取出賦值給變量「VAR」,而後執行「TEXT」表達式。重複直到「LIST」中的最後一個單詞爲止。「TEXT」中的變量或函數引用在執行時才被展開,所以若是在「TEXT」中存在對「VAR」的引用,那麼「VAR」的值在每一次展開時將會獲得不一樣的值。
返回值:以空格分隔的屢次表達式「TEXT」的計算結果。
實例:
dirs := a b c d files := $(foreach dir, $(dirs), $(wildcard $(dir)/*))
a b c d是四個目錄,展開過程依次以下:
第一次:「$(wildcard a/*)」
第二次:「$(wildcard b/*)」
第三次:「$(wildcard c/*)」
...
此函數所實現的功能等價於以下語句:
files := $(wildcard a/* b/* c/* d/*)
注:此函中的「VAR」是一個臨時變量,其在「foreach」函數的上下文中有效,它的定義不會影響其餘部分定義的同名「VAR」變量的值,在函數的執行過程當中是一個「直接展開」式的變量。
# 列出上級目錄中的文件名和目錄名 dirs := .. files := $(foreach dir, $(dirs), $(wildcard $(dir)/*)) demo2 : @echo $(notdir $(files))
4.2 if函數
格式:$(if CONDITION, THEN-PART[, ELSE-PART])
函數功能:若是「CONDITION」非空,就將「THEN-PART」做爲函數的計算表達式;若是「CONDITION」爲空,就將「ELSE-PART」做爲函數的計算表達式。
4.3 call函數
格式:$(call VARIABLE, PARAMS)
函數功能:使用call能夠實現對用戶自定義函數的引用。咱們能夠將一個變量定義爲一個複雜的表達式,用「call」函數根據不一樣的參數對它進行展開來得到不一樣的結果。在執行時,將參數"PARAMS"中的變量值依次賦值給臨時變量"$(1)"、"$(2)"、"$(3)",執行時,變量VARIABLE被展開爲在函數上下文中有效的臨時變量,變量中定義的"$(1)"做爲其第一個參數,依次類推。變量"$(0)"表明"VARIABLE"自己。以後,計算變量「VARIABLE」定義的表達式。
注:"VARIABLE"不能定義爲直接展開式,只能定義爲遞歸展開式。
實例:
reverse = $(2) $(1) foo = $(call reverse, a, b)
變量「foo」的值爲「ba」。
4.4 value函數
格式:
$(value VARIABLE)
函數功能:不對變量「VARIABLE」進行任何展開操做,直接返回變量「VARIABLE」的值。這裏的「VARIABLE」是一個變量名,通常不包含「$」。
返回值:變量「VARIABLE」所定義的文本值。
4.5 eval函數
eval函數用於在makefile中構建一個可變的規則結構關係。eval函數執行時會對它的參數進行兩次展開。第一次展開過程由函數自己完成;第二次展開過程是在make解析時完成。
4.6 origin函數
函數功能:origin用於獲取變量的定義類型:"$(origin VARIABLE)","VARIABLE"一般是一個變量名而不是一個引用,所以通常不包含"$"。
返回值:「VARIABLE」的定義類型,主要包括以下幾種:
undefined |
無定義 |
default |
內部變量,好比「CC」「MAKE」「RM」等 |
environment |
系統環境變量,而且make沒有使用命令行選項「-e」 |
environment override |
系統環境變量,而且make使用了命令行選項「-e」,即便用環境變量的值替換makefile中定義的同名變量值 |
file |
makefile文件中定義的變量 |
command line |
命令行變量 |
override |
使用override聲明的在makefile中定義的變量 |
automatic |
自動化變量 |
4.7 shell函數
傳入一個shell命令,返回shell的執行結果。如:
contents := $(shell cat foo)
將變量文件foo的內容賦值給變量contents,文件中的換行符在變量中使用空格代替。
demo2 : contents := $(shell cat ../install.log.syslog) @echo $(contents)
5 控制函數
控制函數用於在make執行過程當中檢測到錯誤時,爲用戶提供消息,而且控制make過程是否繼續。
5.1 $(error TEXT)
函數功能:產生致命錯誤,提示用戶「TEXT」,並退出make的執行。須要說明的是:error函數通常不出如今直接展開式的變量定義中,不然在make讀取makefile時將會提示致命錯誤並退出。
返回值:空。
實例:以下...
5.2 $(warning TEXT)
函數功能:只提示用戶「TEXT」信息,而不會退出make。
返回值:空
實例:以下...
foo = control function demo2 : ifdef foo $(error error : $(foo)) else $(warning : $(foo)) endif # makefile:5: *** error : control function. Stop.
foo = control function demo2 : ifndef foo $(error error : $(foo)) else $(warning : $(foo)) endif # makefile:7: : control function # make: `demo2' is up to date.