一、命令顯示
1.@關閉命令的回顯
2.make帶入引數“-n”或“--just-print”,只是顯示命令,但不會執行命令,這個功能方便除錯 Makefile。
3.make 引數“-s”或“--slient”全面禁止命令的顯示。
二、命令執行
make 逐條執行其後的命令。 如果打算上一條命令結果應用到下一條命令,需要把要執行的命令寫在同一行使用分號;隔開。
test:
cd ./path1
pwd
複製程式碼
執行結果:
root@chenwr-pc:/home/workspace/my_workspace/study/makefile# make test
cd ./path1
pwd
/home/workspace/my_workspace/study/makefile
複製程式碼
test:
cd ./path1;pwd
複製程式碼
執行結果:
root@chenwr-pc:/home/workspace/my_workspace/study/makefile# make test
cd ./path1;pwd
/home/workspace/my_workspace/study/makefile/path1
複製程式碼
三、命令出錯
makefile使用mkdir建立目錄時,不存在時makefile正常執行,但是目錄存在則無法mkdir時出現報錯,這個並不應該影響到後面命令的執行。
test:
@mkdir path1
@echo continue
複製程式碼
執行結果:
root@chenwr-pc:/home/workspace/my_workspace/study/makefile# make test
mkdir: cannot create directory ‘path1’: File exists
make: *** [test] Error 1
複製程式碼
命令執行錯誤直接終止。 解決辦法 (1)Makefile命令列前加一個減號- (2)全域性的辦法,給 make 加上“-i”或是“--ignore-errors”引數。
test:
-@mkdir path1
@echo continue
複製程式碼
執行結果:
root@chenwr-pc:/home/workspace/my_workspace/study/makefile# make test
mkdir: cannot create directory ‘path1’: File exists
make: [test] Error 1 (ignored)
continue
複製程式碼
root@chenwr-pc:/home/workspace/my_workspace/study/makefile# make test --ignore-errors
mkdir: cannot create directory ‘path1’: File exists
make: [test] Error 1 (ignored)
continue
複製程式碼
如果一個規則是以“.IGNORE”作為目標的,那麼這個規則中的所有命令將會忽略錯誤。
.IGNORE: test
test:
@mkdir path1
@cat no_exist_file
@echo continue
複製程式碼
執行結果:
root@chenwr-pc:/home/workspace/my_workspace/study/makefile# make test
mkdir: cannot create directory ‘path1’: File exists
make: [test] Error 1 (ignored)
cat: no_exist_file: No such file or directory
make: [test] Error 1 (ignored)
continue
複製程式碼
四、巢狀執行make
根據功能和模組將相關的檔案放置在不同的資料夾中,每個資料夾中單獨建立一個Makefile來進行管理維護。最外層有個總控Makefile,可以實現全編譯。
定義$(MAKE)巨集變數的意思是,定義成一個變數便於make引數傳遞,利於維護。
subdir = ./path1
test:
cd $(subdir) && $(MAKE)
複製程式碼
執行結果:
root@chenwr-pc:/home/workspace/my_workspace/study/makefile# make test
cd ./path1 && make
make[1]: Entering directory `/home/workspace/my_workspace/study/makefile/path1'
gcc -c hello.c
make[1]: Leaving directory `/home/workspace/my_workspace/study/makefile/path1'
複製程式碼
總控Makefile中的引數要傳遞給子目錄下的Makefile。 只需在總控Makefile的變數前新增export即可,相反如果特定變數不想傳遞下去則使用unexport。
總控Makefile
export subdir = ./path1
test:
cd $(subdir) && $(MAKE)
複製程式碼
子目錄path1中的Makefile
hello.o: hello.c
gcc -c hello.c
echo $(subdir)
複製程式碼
執行結果:
root@chenwr-pc:/home/workspace/my_workspace/study/makefile# make test
cd ./path1 && make
make[1]: Entering directory `/home/workspace/my_workspace/study/makefile/path1'
gcc -c hello.c
echo ./path1
./path1
make[1]: Leaving directory `/home/workspace/my_workspace/study/makefile/path1'
複製程式碼
如果很多變數要傳遞,只需要新增export關鍵字,後面不需要跟變數名。
export
subdir = ./path1
other = 666
test:
cd $(subdir) && $(MAKE) && rm *.o
複製程式碼
執行結果:
root@chenwr-pc:/home/workspace/my_workspace/study/makefile# make test
cd ./path1 && make && rm *.o
make[1]: Entering directory `/home/workspace/my_workspace/study/makefile/path1'
gcc -c hello.c
./path1
666
make[1]: Leaving directory `/home/workspace/my_workspace/study/makefile/path1'
複製程式碼
注意: SHELL、MAKEFLAGE這兩個變數比較特殊,不管是否export它們都會傳遞到子目錄Makefile中。MAKEFLAGE還是系統級別的環境變數。
總控Makefile定義的變數傳遞到下級Makefile中,如果下級Makefile有定義同名的變數。下級Makefile變數值不會被覆蓋。如果想要覆蓋,執行makefile的時傳遞引數-e -e, --environment-overrides Environment variables override makefiles. 覆蓋makefile環境變數。
make的引數還蠻多的
root@chenwr-pc:/home/workspace/my_workspace/study/makefile# make --help
Usage: make [options] [target] ...
Options:
-b, -m Ignored for compatibility.
(忽略的相容性)
-B, --always-make Unconditionally make all targets.
(無條件完成所有目標)
-C DIRECTORY, --directory=DIRECTORY
Change to DIRECTORY before doing anything.
(在做任何事情之前切換到目錄)
-d Print lots of debugging information.
(列印大量除錯資訊)
--debug[=FLAGS] Print various types of debugging information.
(列印各種型別的除錯資訊)
-e, --environment-overrides
Environment variables override makefiles.
(環境變數覆蓋makefile)
-f FILE, --file=FILE, --makefile=FILE
Read FILE as a makefile.
(將檔案讀取為makefile)
-h, --help Print this message and exit.
(列印該資訊並退出)
-i, --ignore-errors Ignore errors from commands.
(忽略來自命令的錯誤)
-I DIRECTORY, --include-dir=DIRECTORY
Search DIRECTORY for included makefiles.
(搜尋包含makefile的目錄)
-j [N], --jobs[=N] Allow N jobs at once; infinite jobs with no arg.
(一次允許N個作業;沒有引數的無限作業)
-k, --keep-going Keep going when some targets can't be made.
(當一些目標無法達成時,繼續執行)
-l [N], --load-average[=N], --max-load[=N]
Don't start multiple jobs unless load is below N.
(除非負載小於N,否則不要啟動多個作業)
-L, --check-symlink-times Use the latest mtime between symlinks and target.
(使用符號連結和目標之間的最新時間)
-n, --just-print, --dry-run, --recon
Don't actually run any commands; just print them.
(不要實際執行任何命令;只是列印)
-o FILE, --old-file=FILE, --assume-old=FILE
Consider FILE to be very old and don't remake it.
(考慮檔案是非常舊的,不要重新建立)
-p, --print-data-base Print make's internal database.
(列印make的內部資料庫)
-q, --question Run no commands; exit status says if up to date.
(執行任何命令;退出狀態表示是否最新)
-r, --no-builtin-rules Disable the built-in implicit rules.
(禁用內建的隱式規則)
-R, --no-builtin-variables Disable the built-in variable settings.
(禁用內建變數設定)
-s, --silent, --quiet Don't echo commands.
(不要echo命令)
-S, --no-keep-going, --stop
Turns off -k.
-t, --touch Touch targets instead of remaking them.
(觸控目標,而不是重做)
-v, --version Print the version number of make and exit.
(列印make和exit的版本號)
-w, --print-directory Print the current directory.
(列印當前目錄)
--no-print-directory Turn off -w, even if it was turned on implicitly.
(關閉-w,即使它是隱式開啟的)
-W FILE, --what-if=FILE, --new-file=FILE, --assume-new=FILE
Consider FILE to be infinitely new.
(認為檔案是無限新的)
--warn-undefined-variables Warn when an undefined variable is referenced.
(引用未定義的變數時發出警告)
This program built for x86_64-pc-linux-gnu
Report bugs to <bug-make@gnu.org>
複製程式碼
make 的引數“-k”或“--keep-going”,引數意思是,如果某規則中的命令出錯了,那麼就終目該規則的執行,但繼續執行其它規則。
但是 make 命令中的有幾個引數並不往下傳遞,它們是“-C”,“-f”,“-h”“-o”和“-W”。 當你使用“-C”引數來指定 make 下層 Makefile 時,“-w”會被自動開啟的。如果引數中有“-s”(“--slient”)或是“--no-print-directory”,那麼,“-w”總是失效的。
五、定義命令包
makefile中的命令包寫法類似C語言中的define
define my_action
touch smile
endef
test:
$(my_action)
複製程式碼
定義一個my_action 它的功能是建立個smile檔案。呼叫方式也跟引用變數的方式是一樣的。make 在執行命令包時,命令包中的每個命令會被依次獨立執行。