[Linux] 在 Makefile 裡的 if 敘述裡執行多行指令

[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,883 次)

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料