Make 快速入門

1. Make

make 是 linux 系統的實用程序。它用於管理對於大型程序的自動編譯任務,自動決定程序某一部分須要從新編譯,併發出編譯指令。雖然,咱們最多見於 C 語言程序的編譯。可是,make 不限於某一特定語言,凡是能夠經過 shell 命令來運行編譯器的語言均可以使用 make 。除此以外,你甚至能夠用 make 描述任何構建任務,這些任務中,文件須要在其依賴的文件發生變更後自動更新。html

2. Makefile

在使用 make 以前,你必須在當前目錄下添加一個 Makefile 文件,它描述了文件之間的依賴(輸入輸出)關係,並提供更新文件的 Shell 命令。Makefile 文件名能夠是 Makefile 也能夠是 makefile ,推薦使用 Makefile前端

2.1 構成

簡單的 Makefile 文件由若干以下格式的規則(rule)組成:node

target: prerequisites
        recipe
複製代碼
  • target : 一般是程序生成(輸出)的一個或多個文件名,例如:可執行文件或目標文件;它也能夠是要執行任務的名稱,例如用於清理生成文件的 clean 任務。
  • prerequisites: 先決條件是用於生成 target 文件的輸入文件或是完成 target 任務前須要先執行的任務 。一個 target 能夠沒有先決條件,也能夠有一個或多個先決條件。
  • recipe: 中文翻譯爲菜譜,它是 make 用於生成 target 文件或完成 target 任務而執行一系列 shell 命令。這些命令能夠放在同一行裏,也能夠每一個命令佔一行。值得注意的是,recipe 默認以製表符開頭,而不是空格。

2.2 運行 make

在當前目錄下建立一個 Makefile 文件, 命名爲 Makefile 。將如下內容複製到新建的 Makefile 文件中。linux

注意: recipe 默認是以製表符開頭,不是空格。若是複製到文件是空格,須要手動將空格改爲製表符,即按鍵盤 tab 鍵。shell

.PHONY: help clean mk

help :
	@echo "help info"

dist :
	@mkdir dist

clean :
	@rm -rf dist

複製代碼

.PHONY: help clean mk 用於告訴 make 指定 target 列表不是文件名。能夠理解是純粹的任務,而不生成文件。npm

在 Makefile 所在目錄運行不帶參數的 make 命令:json

make
複製代碼

會啓動 Makefile 文件中第一個 target ,本例是 help , make 將 Makefile 中第一個出現的 target 做爲默認目標 。微信

要啓動其餘 target,須要在 make 命令後指定 target 名稱。以下分別啓動目標 dist 和 clean 。併發

make dist
make clean
複製代碼

*2.3 擴展:對比 npm scripts

對於前端的同窗,最熟悉的構建方式莫過於 npm package.json 中 scripts 構建命令。在不使用項目中安裝的包的狀況下,即項目目錄下 node_modules 裏的包,徹底可使用 Makefile 來完成一些構建任務,make 的優點在於更好管理相互依賴的構建任務。app

3. 變量

make 中的變量本質是一種宏替換,用於簡化和維護重複出現的字符串和字符串列表。既能夠出如今目標,先決條件,也能夠出如今「菜譜」的 shell 命令中;能夠是命令自己,也能夠是命令的選項,或者輸入輸出文件;甚至也能夠出如今另外一個變量的引用中(計算變量)。

3.1 定義變量

make 變量定義和 shell 變量的定義很是類似。不一樣的是 make 變量的名稱能夠是任何不包含 :, #, = 和空字符的字符序列,而且等號兩邊能夠有空格(shell 定義變量的等號兩個不容許出現空格)。

以下定義一個變量 objs ,用於表示 c 語言編譯器輸出的一系列目標文件。

objs = main.o model.o view.o controller.o
複製代碼

3.2 使用變量

make 變量支持和 shell 變量同樣,在變量標識符前加美圓符 $ 來引用,所以,若是在"菜譜"中使用 shell 變量,須要使用雙美圓符 $$ 做爲前綴加以區分;但更推薦的使用方式是使用美圓符後跟一對圓括號的方式,例如使用上文建立的變量 objs ,能夠這樣 $(objs)

build: $(objs)
    cc -o app $(objs)
複製代碼

4. 函數

make 中的函數用於處理 Makefile 文件中的文本,例如:計算操做的文件列表,「菜譜」中使用的命令等。

4.1 函數調用

函數調用相似於變量引用,它能夠出如今任何變量引用能夠出現的地方。調用方式以下:

$(function arguments)
複製代碼

或者:

${function arguments}
複製代碼

其中,function 是函數名稱,arguments 是函數的參數。函數名與參數之間用空格或製表符隔開,多個參數之間用逗號 , 隔開。

4.2 用於字符串替換和分析的函數

4.2.1 $(subst from,to,text)

text 上執行文本替換,將出現的全部 from 替換成 to

Makefile:

subst:
	@echo $(subst o,O,hello world)
複製代碼

make:

$ make subst
hellO wOrld
複製代碼

4.2.2 $(patsubst pattern,replacement,text)

text 中尋找空格分隔的單詞,若是單詞匹配 pattern , 就將匹配的單詞替換成 replacementpatternreplacement 均可以包含通配符 %,匹配任意數量的任意字符。當 patternreplacement 同時包含通配符 %,則將 replacement% 替換成與 pattern% 匹配的文本。

Makefile:

patsubst:
	@echo $(patsubst %.c,%.o,hello.c.c world.c)
複製代碼

make:

$ make patsubst
hello.c.o world.o
複製代碼

4.2.3 $(strip string)

移除字符串 string 首尾空格,而且將字符串中的多個空格替換成一個空格。

Makefile:

strip:
	@echo $(strip hello world ! )
複製代碼

make:

$ make strip
hello world !
複製代碼

4.2.4 $(sort list)

按英文字母表順序對列表 list 中的單詞進行排序,刪除重複的單詞。輸出是由單個空格分隔的單詞列表。

Makefile:

sort:
	@echo $(sort dog cat animal fox bear fox elephant)
複製代碼

make:

$ make sort
animal bear cat dog elephant fox
複製代碼

4.2.5 $(words text)

返回 text 中單詞數量。

Makefile:

words:
	@echo $(words dog cat animal fox bear fox elephant)
複製代碼

make:

$ make words
7
複製代碼

4.2.6 $(word n,text)

返回 text 中第 n 個單詞,n 從 1 開始計數。

Makefile:

animals = bear cat dog elephant fox
word:
	@echo $(word $(words $(animals)), $(animals))
複製代碼

make:

$ make word
fox
複製代碼

5. 隱式規則

某些從新生成目標文件的方式很是經常使用。例如,使用 C 編譯器 cc.c 源文件編譯生成 .o 目標文件。 隱式規則將告訴 make 如何使用經常使用的技術,讓你在使用時沒必要給出所有細節,簡化書寫。例如,make 爲 C 語言編譯提供一個隱式規則。文件名決定將應用哪一個隱式規則。好比,C 編譯一般輸入 .c 文件,輸出 .o 文件。 所以,當看到文件名結尾符合這種組合時,make 將隱式規則應用於 C 編譯。

Makefile:

app : main.o utils.o
	cc -o app main.o utils.o

main.o : main.c utils.h
	cc -c main.c

utils.o : utils.c
	cc -c utils.c
複製代碼

能夠去掉編譯命令,簡寫爲:

app : main.o utils.o
	cc -o app main.o utils.o

main.o : main.c utils.h

utils.o : utils.c
複製代碼

make:

$ make
cc    -c -o main.o main.c
cc    -c -o utils.o utils.c
cc -o app main.o utils.o
複製代碼

參考


微信掃描二維碼 獲取最新技術原創

相關文章
相關標籤/搜索