一、make
編譯過程
//預處理,#開頭的**全被解決掉(預編譯,包含庫,巨集定義等等)hello.i上千行.
gcc -e hello.c >> hello.i
//編譯,檢查語法錯誤,生成.s檔案,彙編**,大概26行.
gcc -s hello.i
//彙編。產生字尾.o的object目標檔案,二進位制,不可以執行,缺少庫資訊.
gcc -c hello.s
二、常見引數
-f
:執行make的時候,帶上-f 《檔名》
引數,來指定make命令從**讀取makefile檔案;而如果我們不顯式指定,則make就會在當前目錄下依次查詢名字為gnumakefile
,makefile
,和makefile
的檔案來作為其makefile
檔案.
-
:讓make忽略該命令的錯誤,例如,通常在makefile
中使用-include
來代替include
,忽略由於包含檔案不存在或者無法建立時的錯誤提示,make繼續執行。
@
:關閉回顯。不顯示命令,只顯示結果.而make引數-s
或--slient
則是禁止所有執行命令的顯示.
$(shell pwd)
:獲取當前目錄的絕對路徑 例如:-include $(shell pwd)/src/c_src
?=
:變數在之前沒有賦值的情況下才會對這個變數進行賦值.
:=
:直接展開定義變數.
=
:遞迴展開,可能陷入無限迴圈.
$@
"代表規則中的目標檔名.
$<
"代表規則的第乙個依賴的檔名.
$^
"代表規則中所有依賴檔案的列表,檔名用空格分割.
如果一行以tab
字元開始,make程式將此行作為乙個命令列來處理.
三、內嵌函式
1、filter
過濾
c_src = $(filter %.c, $(sources))
cpp_src = $(filter %.cpp,$(sources))
替換引用
c_objs = $(c_srcs:%.c=../obj/%.o)
cpp_objs = $(cpp_srcs:%.cpp=../obj/%.o)
2、wildcard
擴充套件萬用字元
$(wildcard pattern)
:列出當前目錄下所有符合模式「pattern」
格式的檔名.
$(wildcard *.c)
返回值為當前目錄下所有.c
原始檔列表.
c_src = $(wildcard *.c) $(wildcard src/*.c)
獲取根目錄、子目錄src下的所有.c原始檔。
3、patsubst
替換萬用字元
$(patsubst ,,)
:查詢中的單詞(單詞以「空格」、「tab」或「回車」「換行」分隔)是否符合模式
,如果匹配的話,則以
替換.
$(patsubst %.c,%.o, a.c b.c)
:把字串「a.c b.c」符合模式[%.c]的單詞替換成[%.o],返回結果是「a.o b.o」
objs_file := $(patsubst %,obj/%,$(objs))
:把字串objs
替換到obj
目錄下.用於生成的目標檔案統一彙總到目錄下obj下.
objects := $(patsubst %.c,%.o,$(wildcard *.c))
:先使用wildcard
函式獲取工作目錄下的.c檔案列表;之後將列表中所有檔名的字尾.c替換為.o。這樣我們就可以得到在當前目錄可生成的.o檔案列表。
4、notdir
去除路徑
現有如下檔案結構:
proj
│──── pj1.c
│──── pj2.c
└──── src
│─── sr1.c
└─── sr2.c
makefile如下:
c_src=
$(wildcard *.c ./src/*.c)
nodir=
$(notdir $(c_src)
)objs=
$(patsubst %.c,%.o,$(nodir)
)all:
@echo $(c_src)
@echo $(nodir)
@echo $(objs)
輸出顯示:
pj1.c pj2.c .
/src/sr1.c .
/src/sr2.c
pj1.c pj2.c sr1.c sr2.c
pj1.o pj2.o sr1.o sr2.o
四、makefile
的靜態模式
靜態模式規則是這樣乙個規則:規則存在多個目標,並且不同的目標可以根據目標檔案的名字來自動構造出依賴檔案。靜態模式規則比多目標規則更通用,它不需要多個目標具有相同的依賴。但是靜態模式規則中的依賴檔案必須是相類似的而不是完全相同的。
首先,我們來看一下靜態模式規則的基本語法:
targets …: target-pattern: prereq-patterns …
commands
...
eachtarget
is matched against thetarget-pattern
to extract a part of the target name, called thestem
. this stem is substituted into each of theprereq-patterns
to make the prerequisite names (one from each prereq-pattern).
用%
從目標模式targets
的目標名字中抽取一部分字串(稱為「莖」,即抽取的%
匹配的部分)。使用「莖」替代依賴模式prereq-patterns
中的相應部分來產生對應目標的依賴檔案。例如:
objects = foo.o bar.o
all: $(objects)
$(objects)
: %.o: %.c
$(cc)
-c $(cflags)
$< -o $@
上例中,規則描述了所有的.o檔案的依賴檔案為對應的.c檔案,對於目標「foo.o」,取其莖「foo」替代對應的依賴模式「%.c」中的模式字元「%」之後可得到目標的依賴檔案「foo.c」。這就是目標「foo.o」的依賴關係「foo.o: foo.c」,
再例如:
sources := home.c etc.c src/sr1.c mod/mod.cpp
c_srcs =
$(filter %.c, $(sources)
)cpp_srcs =
$(filter %.cpp,$(sources)
)#目標檔案統一輸出到obj目錄,字串增加../obj/
c_objs =
$(c_srcs:%.c=
../obj/%.o)
cpp_objs =
$(cpp_srcs:%.cpp=
../obj/%.o)
#構建時需要再還原回去,字串去掉../obj/
$(c_objs)
:../obj/%.o:%.c
@mkdir -p ../obj
@mkdir -p $(
dir $@)
#建立子目錄
$(cc)
-c $(cflags)
$< -o $@
$(cpp_objs)
:../obj/%.o:%.cpp
@mkdir -p ../obj
@mkdir -p $(
dir $@)
$(cxx)
-c $(cflags)
$< -o $@
makefile 引數說明
k引數 如果某個目標出錯,依賴這個目標的規則都不執行,其它規則執行。例 還是這個makefile檔案 r1 r2 r3 echo 1 r2 r21 echo 2 cat ew ew檔案不存在,故意讓這條指定出錯 r21 echo 21 r3 r31 echo 3 r31 echo 31 執行命令ma...
Makefile中的引數
g 編譯器編譯時加入debug資訊 wall 就是開啟所有的警告 wall 這個的意思是wring all 意思在編譯和鏈結過程中顯示所有警告資訊 例 gcc o hello hello.c i home hello include l home hello lib lworld上面這句表示在編譯h...
makefile常用函式
一 字串處理函式 1.subst from,to,text 函式名稱 字串替換函式 subst。函式功能 把字串 text 中的 from 字元替換為 to 返回值 替換後的新字串。2.patsubst pattern,replacement,text 函式名稱 模式替換函式 patsubst。函式...