簡單Makefile編寫教程
阿新 • • 發佈:2018-12-25
Makefile編寫
1. make和Makefile的介紹
1.1 make工具
利用make
工具可以自動完成編譯工作。這些工作包括:
- 如果僅僅修改了某幾個原始檔,則只重新編譯這幾個原始檔;
- 如果某個標頭檔案被修改,則重新編譯所有包含該標頭檔案的原始檔。
利用這種自動編譯可大大簡化開發工作,避免不必要的重新編譯。
1.2 Makefile
make
工具通過一個稱為Makefile
的檔案來完成並自動維護編譯工作。Makefile
檔案描述了整個工程的編譯、連結等規則。
2. Makefile基本規則
TARGET ...:DEPENDENCIES ...
COMMAND
...
- 目標(TARGET)程式產生的檔案,如可執行檔案和目標檔案;目標也可以是要執行的動作,如
clean
,也稱偽目標。 - 依賴(DEPENDENCIES)是用來產生目標的輸入檔案列表,一個目標通常依賴於多個檔案。
- 命令(COMMAND)是
make
執行的動作(命令是shell命令或者是可在shell下執行的程式)。注意:每個命令列的起始字元必須為TAB
字元。 - 如果
DEPENDENCIES
中有一個或多個檔案更新的話,COMMAND
就要執行,這就是Makefile
最核心的內容。
接下來就根據這個Makefile
基本規則來編寫一個最基本的Makefile
檔案
.PHONY: clean
main:main.o sub.o add.o print.o
gcc -Wall -g main.o add.o sub.o print.o -o main
main.o:main.c
gcc -Wall -g -c main.c -o main.o
add.o:add.c add.h
gcc -Wall -g -c add.c -o add.o
sub.o:sub.c sub.h
gcc -Wall -g -c sub.c -o sub.o
print.o:print.c print.h
gcc -Wall -g -c print.c -o print.o
clean:
rm -f *.o main
我們可以看到,main
是我們最終想要生成的目標檔案,它依賴main.o sub.o add.o print.o
這四個.o
檔案。因此要執行gcc -Wall -g main.o add.o sub.o print.o -o main
命令來生成目標檔案,但是當前沒有這些.o
檔案,因此就要先生成這些.o
檔案。我們寫了四條xxx.o:xxx.c
然後執行gcc -Wall -g -c xxx.c -o xxx.o
,這些語句就會生成目標檔案的依賴項。
clean
是一個偽目標檔案,因為它沒有依賴項。我們只是想通過make clean
來將.o
檔案刪除,但是我們通常要指定.PHONY:clean
這條語句,用來顯式的指定clean
是偽目標,來防止當前目錄下有一個同名的clean
檔案。這樣,一個簡單呢的Makefile
檔案就寫好了。
3. Makefile自動化變數
雖然像上述那樣可以完成編譯,但是明顯非常麻煩,接下來介紹Makefile
的自動化變數。
選項名 | 作用 |
---|---|
[email protected] | 規則的目標檔名 |
$< | 規則的第一個依賴檔名 |
$^ | 規則的所有依賴檔案列表 |
我們使用這些自動化變數來嘗試從寫剛才的Makefile
.PHONY:clean
OBJ=main.o sub.o add.o print.o
main:$(OBJ)
gcc -Wall -g $^ -o [email protected]
main.o:main.c
gcc -Wall -g -c $< -o [email protected]
add.o:add.c add.h
gcc -Wall -g -c $< -o [email protected]
sub.o:sub.c sub.h
gcc -Wall -g -c $< -o [email protected]
print.o:print.c print.h
gcc -Wall -g -c $< -o [email protected]
clean:
rm -f *.o main
我們定義了一個變數叫OBJ
,他是我們的依賴項列表。然後使用自動化變數來代替對應的檔案,如上所示。
但是,我們這些.c
檔案都要生成.o
檔案,這樣寫也非常麻煩,我們介紹另一些規則。
- 模式規則
%.o:%.c
- 字尾規則
.c:.o
我們來使用這兩種規則:
.PHONY:clean
CC = gcc
CFLAGS = -Wall -g
OBJ = main.o sub.o add.o print.o
main:$(OBJ)
$(CC) $(CFLAGS) $^ -o [email protected]
#%.o:%.c
.c.o:
$(CC) $(CFLAGS) -c $< -o [email protected]
clean:
rm -f *.o main
使用這兩個規則,就會將所有.c
檔案生成同名的.o
檔案,這樣,Makefile
就更加簡潔。
4. make常用的內嵌函式
- 函式呼叫
$(function arguments)
- $(wildcard PATTERN)
- 當前目錄寫的匹配模式的檔案
- 例如:src=$(wildcard *.c)
- $(patsubst PATTERN,REPLACEMENT,TEXT)
- 模式替換函式
- 例如:$(patsubst %.c, %.o, \$src)
- 等價於$(src:.c=.o)
- shell函式
- 執行shell命令
- 例如:$(shell ls -d */)