GNU Make 相容的 Makefile 教學:使用方式

PUBLISHED ON MAY 20, 2018 — BUILD AUTOMATION

    由於 make 本身沒有函式庫,Makefile 中所撰寫的行為要透過外部程式來實現,使用 make 的前提是熟悉系統上的指令。在撰寫 Makefile 時,最好先自行手動輸入一下相關的指令,確認指令可以正常運作,再將其寫入 Makefile 中。

    使用 make 指令

    GNU Make 預設的設定檔有以下三個 (按優先次序):

    • GNUmakefile
    • makefile
    • Makefile

    工作目錄內存在這三個設定檔之一時,make 會自動去讀取;除了這三個以外,可以加上 -f 參數來指定 make 所用的設定檔。如下例:

    $ make -f my_workflow.mk
    

    其他的用法,於相關文章會說明。

    任務 (tasks)

    Makefile 的核心概念是任務 (tasks),我們在撰寫 Makefile 時就是撰寫所需的任務。而任務間有相依性,make 會自動處理相依性,這就是 Makefile 比一般的腳本語言命令稿來得好的地方。

    Makefile 的「虛擬碼」如下:

    任務: 相依性
    	指令
    

    由此可知,任務包含三個部分:

    • 任務名稱
    • 相依性:其他的任務
    • 指令:實際運作的系統指令

    實際的 Makefile 會複雜得多,因為 Makefile 內除了要撰寫系統指令外,還會加上 Makefile 本身的語法。

    Hello World

    在程式設計中,Hello World 是用來確認開發環境可正常運作的微型程式,這個傳統來自於 The C Programming Language 這部 C 經典入門書。我們遵循這個傳統,撰寫 make 版的 Hello World。

    在工作目錄下,加入 Makefile 檔案,並撰寫以下文字:

    hello:
    	@echo "Hello World"
    

    先不要在意 Makefile 的語法,我們的目的是要確認程式可正常運作。

    在相同目錄下,輸入 make 指令:

    $ make
    Hello World
    

    若可順利執行,代表我們第一個 Makefile 撰寫成功;若失敗,需依照錯誤訊息除錯。最常見的錯誤就是在指令的地方沒有使用 TAB 來縮進,這是 make 的一個特殊設計。

    基本概念

    我們將先前的 Makefile 重看一次,這次我們會說明其語法:

    hello:
    	@echo "Hello World"
    

    在我們這個例子中,任務名稱是 hello。此任務沒有相依的任務,故相依性部分留白即可。

    實際的指令是 echo "Hello World"echo 是系統上的指令,而非 Makefile 語法,而 "Hello World" 是一般的字串,在此為 echo 的參數。在指令前加 @ (at symbol) 可壓抑將該指令本身輸出到命令列的行為,讀者可自行將 @ 拿掉即可知其差異。

    在 Makefile 中,第一個出現的任務即為預設任務。以本例來說,不論輸入 makemake hello 的效力皆相同。