害怕 Makefile?別怕!
來源:插圖由 Anindyanfitri 繪製 - Freepik.com
在過去幾年裡,我有幸與許多才華洋溢的軟體工程師共事。讓我印象深刻的一點是,他們之中有許多人對 Makefiles 缺乏實務上的了解,也不知道它們有什麼用處。
當需要自動化建置流程時,他們往往會自己寫 shell 腳本。常見的例子就是在專案資料夾中出現名為 build.sh、run.sh 或 doall.sh 的檔案。
他們一再重複實作相同的基本功能:
- 解析輸入參數與環境變數。
- 手動管理建置步驟之間的相依性。
- 錯誤處理(……也許有吧)。
在這個過程中,他們也不斷犯下相同的基本錯誤:
而這些正是 Makefile 當初被發明要解決的問題。
Makefile 很可怕!
如果你覺得 make 很可怕,你想到的可能是那些大型 軟體專案中複雜的建置機制。其實不必如此。來聽聽 make 的作者Stuart Feldman(史都華·費德曼)本人怎麼說:
一開始是一個精密的相依性分析器的構想,後來簡化成簡單得多的東西,並在那個週末變成了 Make。使用那些還很不成熟的工具是當時文化的一部分。Makefile 是文字檔,而不是經過神奇編碼的二進位檔,因為那正是 Unix 的精神:可列印、可除錯、可理解的東西。
Make 在一個週末內就被打造出來,用簡單的方式解決一個反覆出現的問題。
Makefile 很簡單!
出門前,我需要先穿好衣服。我每次都遵循同樣簡單的步驟:內褲、長褲、襯衫、套頭毛衣、襪子、鞋子、外套。你大概也有自己的穿衣順序,即使和我的不同。
其中有些步驟彼此之間存在相依關係。Make 很適合用來處理相依性。
讓我們試著把我的穿衣流程用 Makefile 來表示。
dress: trousers shoes jacket
@echo "All done. Let's go outside!"
jacket: pullover
@echo "Putting on jacket."
pullover: shirt
@echo "Putting on pullover."
shirt:
@echo "Putting on shirt."
trousers: underpants
@echo "Putting on trousers."
underpants:
@echo "Putting on underpants."
shoes: socks
@echo "Putting on shoes."
socks: pullover
@echo "Putting on socks."如果我們執行這個 Makefile,會得到以下輸出:
$ make dress
Putting on underpants.
Putting on trousers.
Putting on shirt.
Putting on pullover.
Putting on socks.
Putting on shoes.
Putting on jacket.
All done. Let's go outside!剛剛發生了什麼事?
有注意到這些步驟都按照正確的順序執行了嗎?只要清楚地寫下步驟之間的相依關係,make 就能幫我們正確地執行它們。
每個建置步驟都有以下結構:
target: [dependencies]
<shell command to execute>
<shell command to execute>
...當我們執行
make時,Makefile中的第一個目標會預設被執行。目標的順序並不重要。
Shell 指令必須以 tab 縮排。
在指令前加上
@符號,就可以隱藏執行時指令本身的輸出。如果
target並非你想要建置的檔案,請在建置步驟結尾加上.PHONY <target>。常見的 phony 目標有:clean、install、run……否則,如果有人建立了一個install目錄,make會靜默地失敗,因為建置目標已經存在。.PHONY: install install: npm install
恭喜!你已經學會了關於 make 需要知道的 90% 知識。
下一步
真正的 Makefiles 還能做更多!它們只會建置有變更的檔案,而不需要完整重建。而且它們會盡可能平行處理。只是,請盡量保持簡單。
隨機一篇部落格