makefile--隱式規則
阿新 • • 發佈:2018-12-14
1、makefile中出現同名目標時
- 同名依賴:所有的依賴將合併在一起,成為目標的最終依賴
- 同名命令:當多處出現同一目標的命令時,make發出警告;所有之前定義的命令被最後定義的命令取代 示例1–makefile中出現同名依賴
.PHONY : all
all : a.txt
all : b.txt
a.txt :
@echo "this is [email protected]"
b.txt :
@echo "this is [email protected]"
示例2–makefile中出現同名命令
.PHONY : all
all :
@echo "command-1"
all :
@echo "command-2"
all :
@echo "this is [email protected]"
注意事項
- 當使用include關鍵字包含其它檔案時,需要確保被包含檔案中的同名目標只有依賴,沒有命令;否則,同名目標的命令將會被最後定義的命令取代。
示例3–使用include關鍵字時,出現同名命令 makefile檔案與1.mk檔案位於同一個目錄下
makefile
.PHONY : all
all :
@echo "this is [email protected]"
include 1.mk
all :
@echo "this command from 1.mk"
2、隱式規則(build-in rules)
- make提供了一些常用的,例行的規則實現
- 當相應目標的規則未提供時,make嘗試使用隱式規則 示例4–目標的規則未提供,make使用隱式規則 func.h
#ifndef FUNC_H
#define FUNC_H
#define HELLO "hello world"
void foo();
#endif
func.c
#include "stdio.h"
#include "func.h"
void foo()
{
printf("void foo():%s\n",HELLO);
}
main.c
#include "stdio.h" #include "func.h" extern void foo(); int main() { foo(); return 0; }
makefile
SRCS := $(wildcard *.c)
OBJS := $(SRCS:.c=.o)
app.out : $(OBJS)
$(CC) -o [email protected] $^
$(RM)
@echo "Target ===> [email protected]"
makefile等價於下面的檔案
SRCS := $(wildcard *.c)
OBJS := $(SRCS:.c=.o)
app.out : $(OBJS)
$(CC) -o [email protected] $^
$(RM)
@echo "Target ===> [email protected]"
%.o : %.c
@echo "rule"
$(CC) -c -o [email protected] $^
從以上makefile執行結果可以看到,CC、RM、以及%.o : %.c 呼叫的$(CC) -c -o [email protected] $^,都是make中預設的隱式規則。
通過使用$(.VARIABLES)可以檢視make中所有預定義的變數
隱式規則小結一
- 當make發現目標的依賴不存在時,
- 嘗試通過依賴名逐一查詢隱式規則;
- 並且通過依賴名推匯出可能需要的原始檔。
示例5–獲取makefile中的預定義變數
all :
@echo "$(.VARIABLES)"
示例6–改變預定義變數將改變隱式規則的行為
SRCS := $(wildcard *.c)
OBJS := $(SRCS:.c=.o)
CC := gcc
RM := rm -rf *.o
app.out : $(OBJS)
$(CC) -o [email protected] $^
$(RM)
@echo "Target ===> [email protected]"
%.o : %.c
$(CC) -o [email protected] -c $^
隱式規則小結二
- make提供了生成目標檔案的隱式規則
- 隱式規則會使用預定義變數完成編譯工作
- 改變預定義變數將部分改變隱式規則的行為
- 當存在自定義規則時,不再使用隱式規則
隱式規則副作用
- 編譯行為難以控制
- 大量使用隱式規則可能產生意想不到的編譯行為
- 編譯效率低下
- make從隱式規則和自定義規則中選擇最終使用的規則
- 隱式規則鏈
- 當依賴的目標不存在時,make會極力組合各種隱式規則對目標進行建立,進而產生意料之外的編譯行為。例如:需要名為N.o的目標,隱式規則建立過程為:N.y=>N.c=>N.o
檢視make的隱式規則
- 檢視所有隱式規則:make -p
- 檢視具體隱式規則:make -p | grep “XXX” 示例7,命令列輸入檢視%.o預設的所有隱式規則make -p | grep “%.o”,隱式規則的查詢從上往下依次進行匹配
3、隱式規則的禁用
- 區域性禁用(用於makefile檔案內部)
- 在makefile中自定義規則
%.o : %.c
$(CC) -o [email protected] -c $^
- 在makefile中定義模式為空(如:%.o:%c)
%.o : %.p
- 全域性禁用(用於命令列編譯)
- make -r
小結
- 隱式規則可能造成意想不到的編譯行為
- 在實際工程專案中儘量不使用隱式規則