前言
- 本筆記主要記錄Makefile一些概念要點。
概念
Chapter 4:書寫命令
- 每條規則中的命令和作業系統 Shell 的命令列是一致的。
- 每條命令必須以 Tab 鍵開頭,除非,命令是緊跟在依賴規則後面的分號後的。
- make 一般是使用環境變數 SHELL 中所定義的系統 Shell 來執行命令,預設情況下是 /bin/sh —— UNIX 的標準 Shell 解釋執行的。
4.1 顯示命令
- 是否顯示命令
- 在命令列前使用 @ 字元,那麼該命令將不被make顯示出來。
- 只顯示,不執行
- make 執行時,帶入 make 引數 -n 或 --just-print。
- 作用:一般用於除錯,檢視make執行的順序。
- 全面禁止,命令的顯示:
- make 引數 -s 或 --silent 或 --quiet 則是全面禁止命令的顯示。
4.2 命令執行 *
- 當依賴目標新於目標時,make 會一條一條的執行其後的命令。
- 如果要讓上一條命令的結果應用在下一條命令時,你應該使用分號分隔這兩條命令。
- 例子1:輸出為:【當前目錄路徑】
exec:
cd /home/lss
pwd
* 例子2:輸出為:/home/lss
exec:
cd /home/lss; pwd
- 命令解析器尋找順序
- 首先,在 SHELL 所指定的路徑中找尋 --> 在當前碟符中的當前目錄中尋找 --> 在 PATH 環境變數中所定義的所有路徑中尋找。
- MS-DOS 中,如果定義的命令直譯器沒有找到,其會給你的命令直譯器加上諸如 .exe 、.com 、.bat 、.sh 等字尾。
4.3 命令出錯
- 每當命令執行完後,make 會檢測每個命令的返回碼,碼為零則成功。
- 忽略命令失敗
- 方法一:減號
- 在命令前( Tab 鍵後)加上一個減號 - 即可。
- 方法二:全域性(分兩種)
- 給 make 加上 -i 或是 --ignore-errors 引數
- 果一個規則是以 .IGNORE 作為目標的,該規則中的所有命令將會忽略錯誤。
- 方法一:減號
- 命令失敗,但只終止當前規則
- make 的引數的是 -k 或是 --keep-going
- 意思是:某規則中的命令出錯了,就終止該規則的執行,但繼續執行其它規則。
- make 的引數的是 -k 或是 --keep-going
4.4 巢狀執行 make
- 總控 Makefile + 各個子目錄 Makefile。
- 父級 Makefile
- -C 切換到其它目錄
subsystem:
make -C subdir # 或者:cd subdir && make
-
傳遞變數到下級,宣告方法:
export <variable ...>;
- 注:注意 等號:(意思是 export 後,就不是 延時變數)
export variable = value
等價於export variable := value
- 傳遞時預設不覆蓋,加上 -e 即可覆蓋下級重新賦值的變數
-
不想讓該變數傳遞到下級,宣告方法:
unexport <variable ...>;
-
注意兩個變數 *
- SHELL 和 MAKEFLAGS 這兩個變數不管你是否 export,其總是要傳遞到下層 Makefile 中。
- MAKEFLAGS
- 包含了 make 的引數資訊。
- 不想讓 MAKEFLAGS 往下傳遞的做法
subsystem:
cd subdir && $(MAKE) MAKEFLAGS=
-
不往下傳遞的 引數
- make 命令中 -C , -f , -h, -o 和 -W 引數是不往下傳遞的。
-
資訊列印 *
- -w 或是 --print-directory 會在 make 的過程中輸出目前的工作目錄。如:執行
make -w
時
- -w 或是 --print-directory 會在 make 的過程中輸出目前的工作目錄。如:執行
# 進入該目錄時會答應如下資訊
make: Entering directory `/home/hchen/gnu/make'.
# 在完成下層 make 後離開目錄時:
make: Leaving directory `/home/hchen/gnu/make'
* 當你使用 **-C** 引數來指定 **make** 下層 **Makefile** 時,**-w** 會被自動開啟的。如果引數中有 **-s(--slient)**或是 **--no-print-directory** ,那麼,**-w** 總是失效的。
4.5 定義命令包
- 相當於 C 中的函式。
- 語法以 define 開始,以 endef 結束。
- 例子:
- run-yacc
- 命令包名字
- 中間兩句就是 命令包內容
- run-yacc
define run-yacc
yacc $(firstword $^)
mv y.tab.c $@
endef
- 呼叫方法
- 採用 $
foo.c:foo.y
$(run-yacc)
參考
- 《GUN Makefile》
- 《跟我一起寫Makefile》