前言
本文通过简略的几个示例,以及对同一个 Makefile 进行几个版本的迭代,帮忙疾速的了解变量和模式规定的应用。
1、回顾
在上一篇文章中,咱们应用 Makefile 编译 fun.c 和 main.c 这两个文件,最终生成名为 app 的可执行文件。
fun.c 的内容
#include <stdio.h>
void fun()
{printf("This is fun()!\n");
}
main.c 的内容
extern void fun();
int main()
{fun();
return 0;
}
第一版 Makefile
.PHONY:clean
all: main.o fun.o
gcc -o app main.o fun.o
main.o : main.c
gcc -o main.o -c main.c
fun.o : fun.c
gcc -o fun.o -c fun.c
clean:
rm app main.o fun.o
能够发现,Makefile 外面有很多反复的内容,咱们能够利用变量和模式规定对其进行优化。
2、主动变量
$@:用于示意一个规定中的指标。当有多个指标时,$@指的是其中任何导致规定命令被运行的自标。
$^:示意的是规定中的所有先决条件。
$<:示意的是规定中的第一个先决条件。
是不是看得有点晕?没关系,咱们基于下面的 Makefile,做一点点批改,把这些货色都打印进去看一下,就很分明了。
.PHONY:clean
all: main.o fun.o
gcc -o app main.o fun.o
@echo "\$$@ = $@"
@echo "$$^ = $^"
@echo "$$< = $<"
main.o : main.c
gcc -o main.o -c main.c
fun.o : fun.c
gcc -o fun.o -c fun.c
clean:
rm app main.o fun.o
运行 make,终端打印如下内容
gcc -o app main.o fun.o
$@ = all
$^ = main.o fun.o
$< = main.o
理解到这些之后,咱们再次批改
第二版 Makefile
.PHONY:clean
all: main.o fun.o
gcc -o app $^
main.o : main.c
gcc -o $@ -c $^
fun.o : fun.c
gcc -o $@ -c $^
clean:
rm app main.o fun.o
3、变量的类别与赋值
变量的类别有 <font color=’red’> 递归扩大变量 </font> 和 <font color=’green’> 简略扩大变量 </font>
3.1 递归扩大变量
这种只用一个“=”符号定义的变量被称为递归扩大变量
.PHONY:all
goal = $(mid)
mid = $(fun)
fun = test
all:
@echo "goal = $(goal)"
运行 make 命令,打印如下
goal = test
3.2 简略扩大变量
用“:=”操作符来定义的,make 只对其进行一次开展。
.PHONY:all
goal_A = hello
mid_A = $(goal_A) world
goal_A = test
goal_B := hello
mid_B := $(goal_B) world
goal_B := test
all:
@echo "mid_A = $(mid_A),mid_B= $(mid_B)"
运行 make 命令,打印如下
mid_A = test world,mid_B= hello world
3.3 变量条件赋值
用“?=”操作符来定义,如果变量没有被定义,将左边的值赋值给它,如果变量曾经定义了,则不扭转其原值。
.PHONY:all
funA = original
funA ?= replacement
funB ?= replacement
all:
@echo "funA = $(funA),funB = $(funB)"
运行 make 命令,打印如下
funA = original,funB = replacement
3.4 变量追加赋值
通过“+=”实现追加赋值
.PHONY:all
objects = main.o fun.o
objects += append.o
all:
@echo "objects = $(objects)"
运行 make 命令,打印如下
objects = main.o fun.o append.o
3.5 高级变量援用性能
在赋值的同时,实现文件名后缀替换操作
.PHONY:all
src = a.c b.c c.c
objs := $(src:.c=.o)
all:
@echo "objs = $(objs)"
运行 make 命令,打印如下
objs = a.o b.o c.o
留神 ,src:.c=.o 冒号前面不能有空格,如果加了空格变成 src: .c=.o,运行 make,打印的后果如下
objs = a.c b.c c.c
4、模式规定
一个模式规定的格局为:
%.o : %.c
command...
咱们利用模式规定对第二版的 Makefile 进行优化
第三版 Makefile
#替换掉这部分
#main.o : main.c
# gcc -o $@ -c $^
#fun.o : fun.c
# gcc -o $@ -c $^
.PHONY:clean
all: main.o fun.o
gcc -o app $^
%.o : %.c
gcc -o $@ -c $^
clean:
rm app main.o fun.o
这里将两条构建指标文件的规定变成了一条
” % ” 相似于通配符,%.c 匹配所有以 ”.c “ 结尾的文件,采纳了模式当前,不论有多少个源文件,都能够用同一条规定,能够极大的简化 Makefile
5、利用变量和模式规定优化 Makefile
咱们再对第三版的 Makefile 进行优化,将编译器,指标等都用变量代替,这样当前批改只须要改变变量局部就好了
第四版 Makefile
.PHONY:clean
CC = gcc
RM = rm
TARGET = app
OBJS = main.o fun.o
$(TARGET) : $(OBJS)
$(CC) -o $@ $^
%.o : %.c
$(CC) -o $@ -c $^
clean:
$(RM) $(TARGET) $(OBJS)
到这里,Makefile 曾经失去了很大的改善,然而咱们能够看到 OBJS = xxxx 这里,如果文件数量多,得一个个书写,还是不够智能。
下一篇文章,将介绍 Makefile 函数的应用,利用函数能够轻松治理好源文件和指标文件。
———————————————————————————————
码字不易,点个赞再走吧!
欢送关注我的同名公众号,这里有更多好料等着你哦!