本文並不是Makefile的教程,僅是本人學習時的感悟。
Makefile的基本格式
目標:依賴文件(or 目標)
[tab]命令
目標: 是要生成的或操作的命令的索引
依賴: 是生成目標依賴的文件或目標
命令: 是爲了生成目標需要執行的shell語句
任意一個依賴文件被改動,將導致已存在的目標文件過期,簡單來說,依賴的作用就是決定目標是否過期,是否需要重新編譯。
舉個例子,
#include <stdio.h>
#include "mylib1.h"
#include "mylib2.h"
int main(int argc, char argv[]){
printf("hello world!\n");
}
對應的Makefile可以是
helloworld: stdio.h mylib1.h mylib2.h other.o
gcc -o helloworld helloworld.c
也可以是
helloworld: other.o
gcc -o helloworld helloworld.c
前者希望在stdio.h、mylib1.h、mylib2.h、other.o被修改時重新執行helloworld目標,而後者僅僅希望檢查other.o的修改。
目標依賴往往還有另外一種用法,用於執行其他目標。例如
.PHONY: all clean target
all: target clean
target: helloworld.o
gcc helloworld.o -o helloworld
helloworld.o:
gcc -c helloworld.c
clean:
rm helloworld.o
執行all
目標的時候,依賴另外兩個目標target
和clean
。在執行all
目標前,會優先執行目標target
和clean
。
怎麼判斷all
依賴的是目標還是文件?
.PHONY: all
all: test
@echo in all
test:
@echo in test
執行這個Makefile時,當前目錄下有無test文件會有兩個不同的執行結果
[GMPY@11:24 tmp]$ll
總用量 4.0K
1186807 -rw-r--r-- 1 gmpy gmpy 57 4月 5 11:20 Makefile
[GMPY@11:24 tmp]$make
echo in test
in test
echo in all
in all
[GMPY@11:24 tmp]$touch test #創建test文件
[GMPY@11:24 tmp]$make
echo in all
in all
[GMPY@11:24 tmp]$
總結來說,判斷依賴是目標還是文件,有以下兩個規則:
- 優先檢查當前目錄下是否有同名文件,有則文件,無則目標
- .PHONY 標識的都是(僞)目標,不再檢查文件是否存在