前言
Makefile 可以是做為我們編譯一份 C++ 程式的索引,
類似一份說明書,告訴我們先處理哪一份 C++ 檔案後,再去處理哪一份檔案。
因此當撰寫到大型的 C++ 程式時,
我們都會需要 Makefile 來協助我們決定編譯 C++ 檔案的順序。
Makefile 簡介
其實 Makefile 跟 shell script 用途差不多,
我們有時候也會透過寫 shell script 來自動化執行一些 linux 指令。
而 Makefile 透過模組化的定義,更擅長處理一些大型程式的編譯。
通常是更有架構、更有組織的程式碼,我們都會使用 Makefile。
我們的第一份 Makefile
all: myfile
myfile:
touch myfile
clean:
rm -f myfile
說明
可以看到在這份裡面我們還沒有處理任何與 C++ 有關的東西,
沒錯,Makefile 並不是只能用來單純處理 C++ 的檔案 (只是常用,我剛開始學的時候也以為是 C++ 專用)
這份 Makefile 主要分成三個 part
- all: myfile
- all 會需要 myfile 這個項目
- myfile: touch myfile
- myfile 這個項目會去 touch myfile 這個檔案 (如果不存在就會產生)
- clean: rm -f myfile
- 我們去移除 myfile 這個檔案。
執行指令的方式有:「make all」、「make myfile」、「make clean」,
而通常使用上我們只會下「make all」、「make clean」,做為建檔與刪檔使用。
註:如果我們在 terminal 只單純下 「make」 = 「make all」
後來發現這是我的大誤會,單純下 make 會執行「makefile 的第一個 target」,只是這裡剛好是 all 而已
補充 「make」 = 「make all」的誤會
我之前一直以為 「make」 = 「make all」,
總之結論是這是一個美麗的誤會,
單純下 make 會執行「makefile 的第一個 target」,只是這裡剛好是 all 而已,
我們進行以下的測試
- Makefile 裡面寫下
all2:
echo "touch2"
all:
echo "touch3"
clean:
echo "clean"
得到結果
echo "touch2"
touch2
我們沒有得到全部的輸出 (包含clean),
只有得到 touch2 的結果。
表示他是執行 Makefile 內的第一個 target。
常見問題:make: Nothing to be done for `all’
在 makefile 學習的過程中,基本上應該都會踩過一次下面敘述的雷,
我們來好好說明這是什麼意思。
make: Nothing to be done for `all'
這個要講到 makefile 的邏輯,
makefile 只有在「兩種情況」下才會產生新檔案。
- 目標檔案不存在
- 「目標檔案依賴的檔案」比「目標檔案」更新
第一點很好懂,不存在就是什麼都要從頭開始建。
第二點講之前,我們先理解 Makefile 的語法:
- 目標檔案:依賴的檔案(可為多個…, 依賴的檔案1 依賴的檔案2)
換句話說,如果當「任何的檔案都沒有被更新時」,「make 這個指令就會覺得什麼事情都不需要做」。
這就是「make: Nothing to be done for `all’」產生的原因。
那要怎麼解決上面的問題?
很簡單,但也最笨的方法就是,
每一次都先「make clean,再 make」,就沒問題了。
不過自己要先把 make clean 內容寫正確啊!! 不然是沒辦法避免這個錯誤的!
make clean
make # or make all