[Linux] 在 Makefile 裡的 if 敘述裡執行多行指令
今天意外的發現專案的 Makefile 裡有個問題,
原本預期下面的 cppcheck 在檢查到錯誤時,make 會停下來,但是卻沒有:
run_cppcheck: @if which cppcheck 2> /dev/null; then \ ln -f -s ../cfg cfg; \ cppcheck -q --error-exitcode=2 --force; \ rm -rf cfg; \ else \ echo "cppcheck is not supported on this platform."; \ fi
檢查後發現,是因為敘述都是用分號 ; 隔開,
因此會以最後一個敘述的 exit code 為整個敘述的 exit code,
而 if 裡的最後一個敘述是 rm -rf,通常是不會遇到問題,因此 exit code 是 0,
這導致 cppcheck 的 exit code 被蓋掉了~
至於為什麼這個 if-else 要寫成這樣用 \ 合成一行呢?
這是因為 Makefile 規定每個敘述都得是一行的敘述,
對於每一行敘述,make 都會開一個新的 shell 來執行這個敘述,
所以如果想寫多行的話,就只能用 \ 將多行接成一行~
可能有人會說可以用 && 來取代分號 ;,這樣有錯誤時就會停下來了~
但是這個方法還是會導致最後的 rm -rf 沒能被執行到….
所以最後用的折衷方法,就是先將 cppcheck 的 exit code 存在變數裡,
在多行敘述的最後,再用 exit 的方式將 cppcheck 的 exit code 吐出去:
run_cppcheck: @if which cppcheck 2> /dev/null; then \ ln -f -s ../cfg cfg; \ cppcheck -q --error-exitcode=2 --force; \ RC=$$?; \ rm -rf cfg; \ exit $$RC; \ else \ echo "cppcheck is not supported on this platform."; \ fi
注意上面在指定變數時,得用 $$ 代表 $,因為單一的 $ 會被 make 認為是 Makefile 自身的變數~
上面這樣改好後,cppcheck 不論成功或失敗,rm -rf 都會執行,
而 make 也會在 cppcheck 失敗時停下來囉~
(本頁面已被瀏覽過 1,893 次)