在Makefile中使用变量有点类似与C语言中的宏定义,使用该变量相当于内容替换,使用变量可以使Makefile易于维护,修改内容变得简单。

1 Makefile变量

1.1自定义变量

1)定义变量方法:
变量名=变量值
2)引用变量:
$(变量名)或 ${变量名}
3) makefile的变量名:
》makefile变量名可以以数字开头
》变量是大小写敏感的
》变量一般都在makefile的头部定义
》变量几乎可在makefile的任何地方使用
示例
#变量
OBJS=ADD.o SUB.o main.o
TARGET=main
( T A R G E T ) : (TARGET): (TARGET):(OBJS)
gcc $(OBJS) -o $(TARGET)
ADD.o:ADD.c
gcc -c ADD.c -o ADD.o
SUB.o:SUB.c
gcc -c SUB.c -o SUB.o
main.o:mian.c
gcc -c main.c -o main.o

clean:
rm -rf $(OBJS) $(TARGET)

除了使用用户自定义变量,makefile中也提供了一些变量(变量名大写)供用户使用,我们可以直接对其进行赋值。
CC=gcc #arm-linux-gcc
CPPFLAGS: C预处理的选项 如:-I
CFLAGS:C编译器的选项 -Wall -g -c
LDFLAGS:链接器选项 -L -I

1.2 自动变量

$@:表示规则中的目标
$<:表示规则中的第一个条件
$^:表示规则中的所有条件,组成一个列表,以空格隔开,如果这个列表中有重复的项,则消除重复项。
注意:自动变量只能在规则中的命令中使用

参考示例

#变量
OBJS=ADD.o SUB.o main.o
TARGET=main
#$@:表示目标
#$<:表示第一个依赖
#$^:表示所有的依赖

$(TARGET):$(OBJS)
	#$(CC) $(OBJS) -o $(TARGET)
	$(CC) $^ -o $@
	echo $@
	echo $<
	echo $^
ADD.o:ADD.c
	$(CC) -c $< -o $@
SUB.o:SUB.o
	$(CC) -c $< -o $@
main.o:main.c
	$(CC) -c $< -o $@
clean:
	rm -rf $(TARGET) $(OBJS)

1.3 模式规则

模式规则示例:
%.o:%.c
$(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@

OBJS=main.o ADD.o SUB.o
TARGET=main
$(TAGET):$(OBJS)
	$(CC) $(OBJS) -o $(TARGET)
%.o:%.c
	gcc -c $< -o $@

2 Makefile中的函数

makefile中的函数有很多,本文主要介绍两个比较常用的函数。

  1. wildcard - 查找指定目录下的指定类型的文件
    src=$(wildcard *.c)//找到当前目录下所有后缀为.c的文件,赋值给src。
  2. patsubst - 匹配替换
    obj= ( p a t s u b s t (patsubst %.c,%.o, (patsubst(src))//把src变量里所有后缀为.c的文件替换成.o
    在makefile中所有的函数都是有返回值的。
SRC=$(wildcard *.c)
OBJS=$(patsubst %.c, %.o, $(SRC))
TARGET=main
$(TARGET):$(OBJS)
	$(CC) $(OBJS) -o $(TARGET)
%.o:%.c
	$(CC) -c $< -o $@

2.1 Makefile中的伪目标

clean用途:清除编译生成的中间.o文件和最终目标文件
make clean: 如果当前目录下有同名clean文件,则不执行clean对应的命令,解决方案:
利用伪目标声明:.PHONY:clean
声明目标为伪目标之后,makefile将不会判断该目标是否存在或者该目标是否需要更新

clean命令中的特殊符号
**“-”**此条命令出错,make也会继续执行后续的命令。如:“-rm main.o”
**“@”**不显示命令本身,只显示结果。如:“@echo clean done”

SRC=$(wildcard *.c)
OBJS=$(patsubst %.c,%.o,$(SRC))
TARGET=main
$(TARGET):$(OBJS)
	$(CC) $(OBJS) -o $(TARGET)
%.o:%.c
	$(CC) -c $< -o $@
.PHONY:clean
clean:
	rm -rf $(OBJS) $(TARGET)

总结:一条规则,两个函数三个变量

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐