掃描二維碼
隨時隨地手機看文章
?peng@ubuntu:/mnt/hgfs/code/phone$?tree?.
.
├──?allfree
│???├──?allfree.c
│???└──?Makefile
├──?create
│???├──?create.c
│???└──?Makefile
├──?delete
│???├──?delete.c
│???└──?Makefile
├──?display
│???├──?display.c
│???└──?Makefile
├──?include
│???├──?Makefile
│???└──?phone.h
├──?init
│???├──?init.c
│???└──?Makefile
├──?login
│???├──?login.c
│???└──?Makefile
├──?main
│???├──?main.c
│???└──?Makefile
├──?Makefile
├──?menu
│???├──?Makefile
│???└──?menu.c
├──?scripts
│???└──?Makefile
└──?search
????├──?Makefile
????└──?search.c
11?directories,?22?files
直接看下編譯結(jié)果吧:peng@ubuntu:/mnt/hgfs/code/phone$?make
make[1]:?Entering?directory?'/mnt/hgfs/code/phone/allfree'
make[1]:?Nothing?to?be?done?for?'all'.
make[1]:?Leaving?directory?'/mnt/hgfs/code/phone/allfree'
make[1]:?Entering?directory?'/mnt/hgfs/code/phone/create'
make[1]:?Nothing?to?be?done?for?'all'.
make[1]:?Leaving?directory?'/mnt/hgfs/code/phone/create'
make[1]:?Entering?directory?'/mnt/hgfs/code/phone/delete'
make[1]:?Nothing?to?be?done?for?'all'.
make[1]:?Leaving?directory?'/mnt/hgfs/code/phone/delete'
make[1]:?Entering?directory?'/mnt/hgfs/code/phone/display'
make[1]:?Nothing?to?be?done?for?'all'.
make[1]:?Leaving?directory?'/mnt/hgfs/code/phone/display'
make[1]:?Entering?directory?'/mnt/hgfs/code/phone/init'
make[1]:?Nothing?to?be?done?for?'all'.
make[1]:?Leaving?directory?'/mnt/hgfs/code/phone/init'
make[1]:?Entering?directory?'/mnt/hgfs/code/phone/login'
make[1]:?Nothing?to?be?done?for?'all'.
make[1]:?Leaving?directory?'/mnt/hgfs/code/phone/login'
make[1]:?Entering?directory?'/mnt/hgfs/code/phone/menu'
make[1]:?Nothing?to?be?done?for?'all'.
make[1]:?Leaving?directory?'/mnt/hgfs/code/phone/menu'
make[1]:?Entering?directory?'/mnt/hgfs/code/phone/search'
make[1]:?Nothing?to?be?done?for?'all'.
make[1]:?Leaving?directory?'/mnt/hgfs/code/phone/search'
make[1]:?Entering?directory?'/mnt/hgfs/code/phone/main'
make[1]:?Nothing?to?be?done?for?'all'.
make[1]:?Leaving?directory?'/mnt/hgfs/code/phone/main'
gcc?-Wall?-O3?-o?phone?allfree/*.o?create/*.o?delete/*.o?display/*.o?init/*.o?login/*.o?menu/*.o?search/*.o?main/*.o?-lpthread
phone?make?done!?
運行結(jié)果如下:'@' '$' '$$' '-' '-n '的說明'@'@echo??--compiling?module----;??//?屏幕輸出??--compiling?module----
echo??--compiling?module----;??//?沒有@?屏幕輸出echo??--compiling?module----???
' - '-rm dir;
-mkdir aaadir;
' $ '美元符號$,主要擴展打開makefile中定義的變量' $$ '$$ 符號主要擴展打開makefile中定義的shell變量$(wildcard?*.c)?
返回值為當前目錄下所有.c 源文件列表。$(patsubst?%.c,%.o,x.c.c?bar.c)
函數(shù)的返回結(jié)果 是?x.c.o?bar.o
SRC?=?(?notdir?./src/a.c?)?
去除文件a . c 的路徑信息 , 使用 (notdir ./src/a.c) 去除文件a.c的路徑信息,使用 (notdir./src/a.c)去除文件a.c的路徑信息,使用(SRC)得到的是不帶路徑的文件名稱,即a.c。INCLUDES?=?-I./inc
$(CC)?-c?$(INCLUDES)?$(SRC)
$(addsuffix?SUFFIX,NAMES…)?
函數(shù)功能:為“NAMES…”中的每一個文件名添加后綴“SUFFIX”。參數(shù)“NAMES…” 為空格分割的文件名序列,將“SUFFIX”追加到此序列的每一個文件名 的末尾。返回值:以單空格分割的添加了后綴“SUFFIX”的文件名序列。函數(shù)說明:示例:$(addsuffix?.c,foo?bar)?
返回值為foo.c?bar.c
include?file.dep
即把file.dep文件在當前Makefile文件中展開,亦即把file.dep文件的內(nèi)容包含進當前Makefile文件在 include前面可以有一些空字符,但是絕不能是[Tab]鍵開始。
$(foreach?,,?)
這個函數(shù)的意思是,把參數(shù)names?:=?a?b?c?d
files?:=?$(foreach?n,$(names),$(n).o)
上面的例子中,$(name)中的單詞會被挨個取出,并存到變量“n”中,“$(n).o”每次根據(jù)“$(n)”計算出一個值,這些值以空格分隔,最后作為foreach函數(shù)的返回,所以,$(files)的值是“a.o b.o c.o d.o”。注意,foreach中的參數(shù)是一個臨時的局部變量,foreach函數(shù)執(zhí)行完后,參數(shù)的變量將不在作用,其作用域只在foreach函數(shù)當中。$(call?variable,param1,param2,...)
函數(shù)功能:在執(zhí)行時,將它的參數(shù)“ param”依次賦值給臨時變量“ $(1)”、“ $(2)” call 函數(shù)對參數(shù)的數(shù)目沒有限制,也可以沒有參數(shù)值,沒有參數(shù)值的“ call”沒有任何實際存在的意義。執(zhí)行時變量“ variable”被展開為在函數(shù)上下文有效的臨時變量,變量定義中的“ $(1)”作為第一個參數(shù),并將函數(shù)參數(shù)值中的第一個參數(shù)賦值給它;變量中的“ $(2)”一樣被賦值為函數(shù)的第二個參數(shù)值;依此類推(變量**$(0)**代表變量“ variable”本身)。之后對變量“ variable” 表達式的計算值。返回值:參數(shù)值“ param”依次替換“ $(1)”、“ $(2)”…… 之后變量“ variable”定義的表達式的計算值。函數(shù)說明:$”(當然,除非此變量名是一個計算的變量名)。reverse?=?$(2)$(1)
foo?=?$(call?reverse,a,b)
all:
?@echo?"foo=$(foo)"
執(zhí)行結(jié)果:foo=ba
即a替代了(2)$(Target)$(Target) 在scripts/Makefile中定義了,即phone$(Target)依賴于mm@?$(foreach?n,$(Modules),$(call?modules_make,$(n)))
Modules是所有的目錄名字集合, foreach 會遍歷字符串$(Modules)中每個詞語, 每個詞語會賦值給n, 同時執(zhí)行語句:call?modules_make,$(n)
$(MAKE) -C $(1)所替代,$(MAKE) 有默認的名字make -C:進入子目錄執(zhí)行make$(1) :是步驟4中$(n),即每一個目錄名字最終步驟4的語句就是進入到每一個目錄下,執(zhí)行每一個目錄下的MakefileObjs?:=?$(patsubst?%.c,%.o,$(Source))
patsubst 把字串$ource中以.c 結(jié)尾的單詞替換成以.o 結(jié)尾的字符 而Source?:=?$(wildcard?./*.c)
wildcard 會列舉出當前目錄下所有的.c文件所以第6步最終就是將子目錄下的所有的.c文件,編譯生成對應文件名的.o文件$(CC)?$(CFLAGS)?-o?$(Target)?$(AllObjs)?$(Libs)
這幾個變量都在文件scripts/Makefile中定義$(CC) :替換成gcc,制定編譯器$(CFLAGS) :替換成-Wall -O3,即編譯時的優(yōu)化等級-o $(Target):生成可執(zhí)行程序phone$(AllObjs) :AllObjs?:=?$(addsuffix?/*.o,$(Modules))
addsuffix 會將 /*.o追加到$(Modules)中所有的詞語后面,也就是我們之前在子目錄下編譯生成的所有的.o文件$(Libs) :替換為-lpthread,即所需要的動態(tài)庫版權申明:內(nèi)容來源網(wǎng)絡,版權歸原創(chuàng)者所有。除非無法確認,我們都會標明作者及出處,如有侵權煩請告知,我們會立即刪除并表示歉意。謝謝!