Makefile模式规则
Makefile规则:当依赖比目标文件新时,重新生成目标文件
target(目标):prerequiries(依赖)
command(命令)
简单例子,现在有三个文件a.c b.h b.c
内容为:
---------------------a.c--------------
#include <stdio.h>
#include <stdlib.h>
#include "b.h"
int main(int argc,char **argv)
{
int c;
c=add(1,2);
printf("c = %d\n",c);
return 0;
}
---------------------b.c-----------------
#include "b.h"
int add(int a,int b)
{
return a+b;
}
---------------------b.h------------------
#ifndef _B_H
#define _B_H
int add(int a,int b);
#endif
下面了解几个变量的含义:
符合|含义
–|:–😐–:
@
∣
规则中的目标集合,在模式规则中,如果有多个目标的话,“
@|规则中的目标集合,在模式规则中,如果有多个目标的话,“
@∣规则中的目标集合,在模式规则中,如果有多个目标的话,“@”表示匹配模式中定义的目标集合
<
∣
依赖文件集合中的第一个文件,如果依赖文件是以模式
(
即“
<|依赖文件集合中的第一个文件,如果依赖文件是以模式(即“%” )定义的,那么“
<∣依赖文件集合中的第一个文件,如果依赖文件是以模式(即“<”就是符合模式的一系列的文件集合
∣
所有依赖文件的集合,使用空格分开,如果在依赖文件中有多个重复的文件,“
^|所有依赖文件的集合,使用空格分开,如果在依赖文件中有多个重复的文件,“
∣所有依赖文件的集合,使用空格分开,如果在依赖文件中有多个重复的文件,“^”会去除重复的依赖文件,值保留一份。
简单Makefile编写:
test : a.c b.c b.h
gcc -o test a.c b.c
clean:
rm *.o test -f
改进:
#变量表示
objs = a.o b.o
#$^表示所有依赖
test:$(objs)
gcc -o test $^
#$@:目标集合 $<:依赖文件集合
%.o : %.c
gcc -c -o $@ $<
#.PHONY伪目标,这样子不会判断同一目录下是否有clean文件存在
.PHONY clean:
rm test *.o -rf
Makefile中的变量
Makefile中的变量分为三种:简单变量,延时变量,export变量
A := XXX
:A的值定义时就确定为XXXB = XXX
:XXX定义之后B的值才确定下来C ?= XXX
:第一次定义才起效,前面若已经定义,则忽略
示例:
A := 123
B = $(C)
C = abc
D = 100ASK
D ?= ASK
print:
@echo $(A)
@echo $(B)
@echo $(C)
@echo $(D)
结果:
Makefile的简单函数
- $(foreach var,list,test),遍历list,将list中的每个变量赋给var,再将var代入test中
示例:将A中的每个变量都添加.o后缀
A = a b c
B = $(foreach f,$(A),$(f).o)
print:
@echo B=$(B)
结果:
- $(filter pattern …,text):在text中取出符合pattern格式的值
- $(filter-out pattern …,text):在text中取出不符合pattern格式的值
示例:
C = a b c d/
D = $(filter %/,$(C))
E = $(filter-out %/,$(C))
print:
@echo D=$(D)
@echo E=$(E)
结果:
- $(wildcard pattern):取出符合pattern格式的文件
示例:取出真实存在的文件,我的某个目录下有a.c b.c c.c
三个文件
files = a.c b.c c.c d.c
files2 = $(wildcard $(files))
print:
@echo files2 = $(files2)
结果:
-
(
p
a
t
s
u
b
s
t
p
a
t
t
e
r
n
,
r
e
p
l
a
c
e
m
e
n
t
,
(patsubst pattern,replacement,
(patsubstpattern,replacement,(var)):将var所有满足pattern格式的文件全部替换为replacement格式
示例:将所有files中所有.c
文件替换为.d
文件
files = a.c b.c c.c d.c
files2 = $(patsubst %.c,%.d,$(files))
print:
@echo files2 = $(files2)
结果:
Makefile实例
gcc -M a.c
可以得到a.c
的依赖文件
gcc -M -MF a.d a.c
可以将a.c
的依赖文件全部写入a.d
文件中
示例:有三个文件a.c b.c b.h
objs = a.o b.o
#依赖,判断是否存在依赖a.d,b.d
dep_files :=$(patsubst %,%.d,$(objs))
dep_files :=$(wildcard $(dep_files))
#编译选项
CFLAGS = -Werror -Iinclude
test:$(objs)
gcc -o test $^
#判断是否存在,注意空格
ifneq ($(dep_files),)
include $(dep_files)
endif
%.o:%.c
gcc $(CFLAGS) -c -o $@ $< -MD -MF $@.d
clean:
rm test *.o -rf
distclean:
rm $(dep_files)
.PHONY: clean