#1 make是乙個命令,他會按照自己的規則執行名字為makefile、makefile或者之類的名字,或者通過 make -f 1.txt 這樣來指定執行乙個檔案。
#2 make命令解析檔案的最基本、最重要的途徑就是如下格式:
: [tab]
對上面這兩行**的解讀:
1 - 想要得到target,材料是prerequisites,工具是commands。
2 - target是必須的,prerequisites和commands至少要有乙個存在。
3 - target可以有多個,像prerequisites一樣,多個目標之間用空格分割。
#3 注意:makefile什麼都不是,我們面向的應該是make這個命令是如何使用的,makefile只是按照make命令要求寫的乙個標準格式檔案。
#4 偽目標(用來指定非編譯動作,因為正常情況下,make動作都會輸出目標檔案,如果我想做某個動作而不是輸出目標檔案,就要指定目標動作為偽目標)
clean:
rm -rf *
make動作是針對makefile(或者-f指定乙個檔案)中的「目標」而言的,如果不指定,那麼就取「第乙個目標」,如果指定,則取指定的目標。
針對上面這種情況,有乙個bug,如果當前目錄中有乙個叫做clean的檔案,那麼make就會以為下面的命令列是用來生成clean檔案的,所以不會再去執行。針對這種情況,
需要把clean明確指定為偽目標: .phony:clean
clean:
rm -rf *
#5 前置條件(材料)
: [tab]
只要前置條件列表和之前不一樣了,或者裡面的內容發生更新了,那麼就使用commands重新構建target。
注:如果某個target後面沒有前置條件,那麼每次執行make ,commands都一定會執行。
#6 再說偽目標
有時候也可以這樣用:當commands是空的時候,偽目標類似巨集定義,比如 all:1.c 2.c 3.c ,此時make或者make all,相當於make 1.c ,make 2.c , make 3.c
會依次執行all所指代的前置條件。
注:這也是幾乎所有makefile都在用的一點,需要輸出多個目標的時候,就先定乙個總的來代替多個目標
#7 命令
命令用來表示如何生成target,命令有一行或者多行「shell命令」組成。
預設情況下命令前面要有tab鍵,如果想換成別的,可以設定環境變數.recipeprefix,比如.recipeprefix = >
all:
> echo hello, world
#8 「命令」注意要點
命令可以有多行,但是不同於shell指令碼,這多行是由多個程序一起執行的,所以相互之間沒有關聯。比如:
all:
export a=1
echo $a
針對上面這個檔案,做make或者make all,無法正確獲得a的值。
可以用如下幾種方法來解決:
1 - 命令放在一行,用分號隔開
all:
export a=1;echo $a
2 - 命令放在不同的行,用\連線
all:
export a=1 \
echo $a
3 - 通過偽目標標註
.oneshell:
all:
export a=1
echo $a
#9 語法
#9-1 「回聲」
預設情況下,會向標準輸出列印每一條command。即使是以#開頭,都會列印(但是前置tab不可少,少了就不是command了)。這叫做「回聲」
如果想關閉,只需要在command前面加乙個@就行了。
實際工作過程中,一般會給command的注釋前面加上@
#9-2 「萬用字元」
和bash的萬用字元使用一樣,*,?,[1-2]等
#9-3 「模式匹配」
%.o: %.c代表對當前目錄下所有.c檔案做.o依賴,比如當前目錄下有1.c和2.c,那麼以上的語句等於:
1.o:1.c
2.o:2.c
#9-4 「變數和賦值」
有四種賦值方式:
1 - variable = value # 在執行時擴充套件,允許遞迴擴充套件
2 - variable := value # 在定義時擴充套件
3 - variable ?= value # 只有在該變數為空時才設定值
4 - variable += value # 將值追加到變數的尾端
#9-5 「內建變數」
提供了一些預設的環境變數,比如$(cc) 指向當前使用的編譯器,$(make) 指向當前使用的make工具。
更多見#9-6 「自動變數」
$@ - 當前commands對應的target
$< - 第乙個prerequisites
$? - 較當前target時間點而言,所有更新過的prerequisites(比較有用,可以用來取到所有近期變動過的prerequisites)
$^ - 指代所有的prerequisites
$* - 所有%匹配的檔名,無字尾(比如前面的 %o:%.c,在這個依賴關係的commands中使用$*,就指代所有的檔名,比如上例中的1 2)
$(@d)和$(@f) - $(@d)指$@的路徑,$(@f)指$@的檔名
$(#10 ----------------------終-----------------------
工程Makefile例項
1級makefil phony clean for subdir in subdirs do cd subdir make clean done 級makefile target lib notdir curdir a objs wildcard o cc flags fpic md 靜態庫合成動態...
Makefile工程編譯
1.寫在前面 本篇文章講的是接前面makefile之編譯多個可執行程式中第二個需求,並延伸到對正規工程的編譯。2.工程 我接觸的工程有2種情況 所有原始檔都放乙個目錄 按模組分放不同的目錄 下面按照這兩種情況講解。3.所有原始檔都放乙個目錄 不建議所有原始檔都放乙個目錄,當工程大時,乙個目錄下會有很...
Makefile工程管理
1 makefile用途 make的工作主要依賴於乙個叫makefile的檔案。makefile檔案描述了整個程式的編譯,鏈結等規則。其中包括 工程中的哪些原始檔需要編譯以及如何編譯,如何最後產生我們想要的可執行檔案。2 makefile中最重要的組成部分是規則 規則 用於說明如何生成目標檔案,規則...