- 工信部備案號 滇ICP備05000110號-1
- 滇公安備案 滇53010302000111
- 增值電信業務經營許可證 B1.B2-20181647、滇B1.B2-20190004
- 云南互聯網協會理事單位
- 安全聯盟認證網站身份V標記
- 域名注冊服務機構許可:滇D3-20230001
- 代理域名注冊服務機構:新網數碼
Makefile 是什么
一個正式的軟件工程中,源文件按類型、功能、模塊等分別放在不同的目錄下,如果每次都在命令行這樣: gcc a.c b.c c.c -o test ,顯然是非常影響效率的,那么這時候就需要 Makefile 來進行管理,在 Makefile 中指定哪些文件先編譯,那些文件后編譯,在什么情況下編譯哪些文件等操作。
Makefile 就是一個用來幫助我們編譯的工具,和 Windows 下的 IDE 類似,只不過 Makefile 需要我們自己動手編寫,一個好的 Makefile 可以極大的提升工作的效率。
Makefile 規則
target ... : prerequisites ...
command
...
target 就是我們編譯文件要生成的目標, prerequisites 就是我們編譯文件需要的依賴, command 就是用依賴生成目標所需要執行的命令。
比如我們平時使用的 gcc a.c b.c -o test
這里的 test 就是我們要生成的目標, a.c 就是我們生成目標需要的依賴,而 gcc a.c -o test 則是命令。將這行命令用 Makefile 的方式來寫就是:
test:a.c b.c
gcc a.c b.c -o test
Makefile 中的命令必須用 tab 開始,不能是空格。
Makefile 可以自動推導文件以及文件依賴關系后面的命令,在后面的示例中我們可以看到目標的依賴基本都是 .o 文件而不是 .c 文件,原因正是 Makefile 強大的自動推導功能。
通常 Makefile 中還會有一個名為 clean 的目標,用來清除編譯后產生的各種文件。一般情況下 Makefile 會根據依賴和目標的新舊來決定是否編譯,但是如果不小心修改了目標而造成目標比依賴新的情況的話,Makefile 會因為目標比依賴新而忽略這個目標下的命令,這個時候顯然會造成問題,一個解決的辦法就是使用 clean 這樣的目標來清除編譯后的文件,然后 make 重新編譯。
clean 這個目標有點特殊,他是不需要依賴的,因此也叫偽目標。一般使用方式如下:
clean:
rm *.o test -f
Makefile 使用
make 命令執行時,需要一個 Makefile 文件(文件名為 Makefile 、 makefile 、 *.mk ),以告訴 make 命令需要怎么樣的去編譯和鏈接程序。執行時只用在命令行輸入 make , Makefile 就會自動執行第一個目標下的命令。而是否執行命令則取決于依賴,如果沒有目標文件或是目標后的依賴文件比目標文件新,Makefile 就會執行其下面的命令。
Makefile 中使用 # 注釋,只注釋 # 后的一行。
Makefile 中引用其他 Makefile,用 include 指令來引用。引用的效果就是原地展開。
Makefile 命令前面加 @ 來靜默執行,即執行命令時不打印命令本身。
Makefile 變量
Makefile 中的變量和 shell 腳本中非常相似,都是直接定義,不需要類型,引用時用 $(var) 。
偽目標( .PHONY ):偽目標形式上是一個目標,但是不需要依賴,偽目標一般只是為了執行目標下面的命令(比如 clean 就是偽目標)。
Makefile 中的幾種變量賦值運算符
= 賦值,可以被賦值為變量的值,解析時取這個變量最后的值。
:= 也是賦值,被賦值為變量時解析為變量在這行語句時的值,即變量如果后面改變這里的值也不改變。
?= 如果變量前面并沒有賦值過則執行這條賦值,如果前面已經賦值過了則本行被忽略。
+= 用來給一個已經賦值的變量接續賦值,意思就是把這次的值加到原來的值的后面。
關于 = 和 := ,比如 B=$(A)bcd ,那么 B 的值取決于變量 A 最后一次被賦值的值,即使 A 在 B 之后再次被賦值,變量 B 仍然會隨著 A 的改變而改變。而 := 則只看之前 A 最后被賦值的值。
Makefile 的環境變量
Makefile 中用 export 導出的就是環境變量。一般情況下要求環境變量名用大寫,普通變量名用小寫。
環境變量和普通變量不同,可以這樣理解:環境變量類似于整個工程中所有 Makefile 之間可以共享的全局變量,而普通變量只是當前本 Makefile 中使用的局部變量。所以要注意:定義了一個環境變量會影響到工程中別的 Makefile 文件,因此要小心。
Makefile 中的自動變量
自動變量是 Makefile 中提前預定義的特殊意義的符號,類似 C 語言中的宏 __LINE__ 等,提前被定義并被賦予了特殊含義。
$@ 目標文件名,比如上文的 test 。
$< 第一個依賴文件名,如果依賴目標是以模式(即“ % “)定義的,那么” $< “將是符合模式的一系列的文件集。注意,其是一個一個取出來的。
$^ 依賴的文件集合,比如上文的 a.c b.c 。
此外還可以向 Makefile 傳參, $# 存放傳遞參數個數, $1 存放第一個參數的字符串, $2 存放第二個參數的字符串……
其他
通配符:比如在當前文件夾下有 1.c 2.c 12.c test.c 1.h 。
% 若干個任意字符,和 * 很相似,但是 % 一般只用于規則描述中,又叫做規則通配符。
* 若干個任意字符 *.c 匹配 1.c 2.c 12.c test.c 。
? 1個任意字符 ?.c 匹配 1.c 2.c 。
[] 將 [] 中的字符依次去和外面的結合匹配 [12].c 匹配 1.c 2.c 。
Makefile 與 shell 腳本非常相似,shell 腳本中能使用的 Makefile 也能使用,比如 awk 等工具
售前咨詢
售后咨詢
備案咨詢
二維碼
TOP