歡迎光臨
每天分享高質量文章

重新發現 make: 規則背後的力量 | Linux 中國

我過去認為 makefile 只是一種將一組組的 shell 命令列出來的簡便方法;過了一段時間我瞭解到它們是有多麼的強大、靈活以及功能齊全。這篇文章帶你領略其中一些有關規則的特性。

— Roberto Dip

 

備註:這些全是針對 GNU Makefile 的,如果你希望支援 BSD Makefile ,你會發現有些新的功能缺失。感謝 zge[1] 指出這點。

規則

規則rule是指示 make 應該如何並且何時構建一個被稱作為標的target的檔案的指令。標的可以依賴於其它被稱作為前提prerequisite的檔案。

你會指示 make 如何按步驟recipe構建標的,那就是一套按照出現順序一次執行一個的 shell 命令。語法像這樣:

  1. target_name : prerequisites
  2. recipe

一但你定義好了規則,你就可以透過從命令列執行以下命令構建標的:

  1. $ make target_name

標的一經構建,除非前提改變,否則 make 會足夠聰明地不再去執行該步驟。

關於前提的更多資訊

前提表明瞭兩件事情:

◈ 當標的應當被構建時:如果其中一個前提比標的更新,make 假定目的應當被構建。
◈ 執行的順序:鑒於前提可以反過來在 makefile 中由另一套規則所構建,它們同樣暗示了一個執行規則的順序。

如果你想要定義一個順序但是你不想在前提改變的時候重新構建標的,你可以使用一種特別的叫做“唯順序order only”的前提。這種前提可以被放在普通的前提之後,用管道符(|)進行分隔。

樣式

為了便利,make 接受標的和前提的樣式。透過包含 % 符號可以定義一種樣式。這個符號是一個可以匹配任何長度的文字元號或者空隔的萬用字元。以下有一些示例:

◈ %:匹配任何檔案
◈ %.md:匹配所有 .md 結尾的檔案
◈ prefix%.go:匹配所有以 prefix 開頭以 .go 結尾的檔案

特殊標的

有一系列標的名字,它們對於 make 來說有特殊的意義,被稱作特殊標的special target

你可以在這個檔案[2]發現全套特殊標的。作為一種經驗法則,特殊標的以點開始後面跟著大寫字母。

以下是幾個有用的特殊標的:

◈ .PHONY:向 make 表明此標的的前提可以被當成偽標的。這意味著 make 將總是執行,無論有那個名字的檔案是否存在或者上次被修改的時間是什麼。
◈ .DEFAULT:被用於任何沒有指定規則的標的。
◈ .IGNORE:如果你指定 .IGNORE 為前提,make 將忽略執行步驟中的錯誤。

替代

當你需要以你指定的改動方式改變一個變數的值,替代substitution就十分有用了。

替代的格式是 $(var:a=b),它的意思是獲取變數 var 的值,用值裡面的 b 替代詞末尾的每個 a 以代替最終的字串。例如:

  1. foo := a.o
  2. bar : = $(foo:.o=.c) # sets bar to a.c

註意:特別感謝 Luis Lavena[3] 讓我們知道替代的存在。

檔案檔案

檔案檔案是用來一起將多個資料檔案(類似於壓縮檔案的概念)收整合一個檔案。它們由 ar Unix 工具所構建。ar 可以用於為任何目的建立檔案,但除了靜態庫[4],它已經被 tar 大量替代。

在 make 中,你可以使用一個檔案檔案中的單獨一個成員作為標的或者前提,就像這樣:

  1. archive(member) : prerequisite
  2. recipe

最後的想法

關於 make 還有更多可探索的,但是至少這是一個起點,我強烈鼓勵你去檢視檔案[5],建立一個笨拙的 makefile 然後就可以探索它了。

 

贊(0)

分享創造快樂