Makefile書寫命令相關內容
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, -mIgnored for compatibility. (忽略的相容性) -B, --always-makeUnconditionally make all targets. (無條件完成所有目標) -C DIRECTORY, --directory=DIRECTORY Change to DIRECTORY before doing anything. (在做任何事情之前切換到目錄) -dPrint 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, --helpPrint this message and exit. (列印該資訊並退出) -i, --ignore-errorsIgnore 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-goingKeep 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-timesUse 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-basePrint make's internal database. (列印make的內部資料庫) -q, --questionRun no commands; exit status says if up to date. (執行任何命令;退出狀態表示是否最新) -r, --no-builtin-rulesDisable the built-in implicit rules. (禁用內建的隱式規則) -R, --no-builtin-variablesDisable the built-in variable settings. (禁用內建變數設定) -s, --silent, --quietDon't echo commands. (不要echo命令) -S, --no-keep-going, --stop Turns off -k. -t, --touchTouch targets instead of remaking them. (觸控目標,而不是重做) -v, --versionPrint the version number of make and exit. (列印make和exit的版本號) -w, --print-directoryPrint the current directory. (列印當前目錄) --no-print-directoryTurn 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-variablesWarn when an undefined variable is referenced. (引用未定義的變數時發出警告) This program built for x86_64-pc-linux-gnu Report bugs to <[email protected]> 複製程式碼
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 在執行命令包時,命令包中的每個命令會被依次獨立執行。