Makefile

Makefile是构建项目的关键,它包含命令、依赖和目标。文章详细介绍了Makefile的语法,如目标定义、变量使用(包括自动变量和特殊变量)以及变量赋值的不同方式。此外,还讲解了预定义变量、模式规则和函数的应用,如wildcard、patsubst等,帮助读者更好地理解和编写Makefile。
摘要由CSDN通过智能技术生成

初识makefile

Makefile具有三个要素:命令依赖目标

Makefile并不会关心命令是如何执行的,仅仅只是会去执行所有定义的命令,输入命令的一个集合。

同时一条命令中的目标可能是另一条命令中的依赖,因此形成了一层一层的依赖关系。

在这里插入图片描述

make编译过程

更新过程

Makefile语法

  • ⽬标放在‘:’的前⾯,其名字可以是由字⺟和下划线‘_’组成 。
  • 执行时,用 make 目标 方式运行,当没有指明具体的⽬标是什么时,那么 make 以 Makefile ⽂件中定义的第⼀个⽬标作为这次运⾏的⽬标。
  • 目标 all: Makefile文件默认只生成第一个目标文件即完成编译,但是我们可以通过all 指定所需要生成的目标文件。
  • 注意 tab

在这里插入图片描述

变量

变量的使用可以提高makefile的可维护性。⼀个变量的定义很简单,就是⼀个名字(变量名)后⾯跟上⼀个等号,然后在等号的后⾯放这个变量所期望的值。对于变量的引⽤,则需要采⽤ ( 变量名 ) 或者 (变量名)或者 (变量名)或者{变量名}这种模式。

1.自动变量(☆☆☆☆☆)

对于每⼀个规则,⽬标和先决条件的名字会在规则的命令中多次出现,每⼀次出现都是⼀种麻烦,更为麻烦的是,如果改变了⽬标或是依赖的名,那得在命令中全部跟着改。有没有简化这种更改的⽅法呢?这我们需要⽤到 Makefile 中的⾃动变量,最常用包括:

  • $@⽤于表示⼀个规则中的⽬标。当我们的⼀个规则中有多个⽬标时,$@所指的是其中任何造成命令被运行的目标。
  • $^则表示的是规则中的所有先决(依赖)条件。
  • $<表示的是规则中的第⼀个先决(依赖)条件。
.PHONY:all
all:first second third
	@echo "\$$@ = $@"
	@echo "\$$^ = $^"
	@echo "\$$< = $<"
 
first second third:

运行结果

在这里插入图片描述

需要注意的是,在 Makefile 中‘ $ ’具有特殊的意思,因此,如果想采⽤ echo 输出‘$’,则必需⽤两个连着的‘$’。还有就是,$@对于 Shell 也有特殊的意思,我们需要在“$$@”之前再加⼀个脱字符‘\’。

修改simple的makefile

.PHONY: clean
CC = gcc
RM = rm
EXE = simple
OBJS = main.o foo.o
$(EXE): $(OBJS)
	$(CC) -o $@ $^
main.o: main.c
	$(CC) -o $@ -c $^
foo.o: foo.c
	$(CC) -o $@ -c $^
clean:
	$(RM) $(EXE) $(OBJS)

运行结果:

在这里插入图片描述

2.特殊变量

(1)MAKE变量

它表示的是make 命令名是什么。当我们需要在 Makefile 中调⽤另⼀个 Makefile 时需要⽤到这个变量,采⽤这种⽅式,有利于写⼀个容易移植的 Makefile。

.PHONY: clean
all:	@echo "MAKE = $(MAKE)"

运行结果:

(2)MAKECMDGOALS变量

它表示的是当前⽤户所输⼊的 make ⽬标是什么。

.PHONY: all clean
all clean:
	@echo "\$$@ = $@"
	@echo "MAKECMDGOALS = $(MAKECMDGOALS)"

在这里插入图片描述

MAKECMDGOALS 指的是⽤户输⼊的⽬标,当我们只运⾏ make 命令时,虽然根据Makefile 的语法,第⼀个⽬标将成为缺省⽬标,即 all ⽬标,但 MAKECMDGOALS 仍然是空,⽽不是all,这⼀点需要注意。

3.变量赋值

1、"="是最普通的等号,在Makefile中容易搞错赋值等号,使用 “=”进行赋值,变量的值是整个Makefile中最后被指定的值。

VIR_A = A
VIR_B = $(VIR_A) B
VIR_A = AA

经过上面的赋值后,最后VIR_B的值是AA B,而不是A B,在make时,会把整个Makefile展开,来决定变量的值

2、“:=” 表示直接赋值,赋予当前位置的值。

VIR_A := A
VIR_B := $(VIR_A) B
VIR_A := AA

最后BIR_B的值是A B,即根据当前位置进行赋值。因此相当于“=”,“:=”才是真正意义上的直接赋值

3、“?=” 表示如果该变量没有被赋值,赋值予等号后面的值。

VIR ?= new_value

如果VIR在之前没有被赋值,那么VIR的值就为new_value。

VIR := old_value
VIR ?= new_value

这种情况下,VIR的值就是old_value

4、"+="和平时写代码的理解是一样的,表示将符号后面的值添加到前面的变量上

4.预定义变量

CC:c编译器的名称,默认值为cc。cpp c预编译器的名称默认值为$(CC) -E

CC = gcc

回显问题,Makefile中的命令都会被打印出来。如果不想打印命令部分 可以使用@去除回显

@echo "clean done!"

5.override指令

override 指令避免定义的变量被覆盖

.PHONY: all
override foo = x
all:
	@echo "foo = $(foo)"

函数

1.wildcard函数(☆☆☆)

wildcard 是通配符函数,通过它可以得到我们所需的⽂件,这个函数类似我们在 Windows 或Linux 命令⾏中的“*”。其形式是:$(wildcard pattern)

.PHONY:all
SRC=$(wildcard *.c)
all:
	@echo "SRC = $(SRC)"

2.patsubst函数(☆☆☆)

patsubst 函数是⽤来进⾏字符串替换的,其形式是:$(patsubst pattern, replacement, text)

.PHONY:all
mixed=foo.c bar.c main.o
objects:=$(patsubst %.c, %.o, $(mixed))
all:
	@echo $(objects)

在这里插入图片描述

3.addprefix函数

addprefix 函数是⽤来在给字符串中的每个⼦串前加上⼀个前缀,其形式是:$(addprefix prefix, names…)

4.filter函数

filter 函数⽤于从⼀个字符串中,根据模式得到满⾜模式的字符串,其形式是:$(filter pattern…, text)

5.filter-out函数

filter-out 函数⽤于从⼀个字符串中根据模式滤除⼀部分字符串,其形式是:$(filter-out pattern…, text)

6.strip

strip 函数⽤于去除变量中的多余的空格,其形式是:$(strip string)

模式

.PHONY: clean
CC = gcc
RM = rm
EXE = simple
OBJS = main.o foo.o
$(EXE): $(OBJS)
	$(CC) -o $@ $^
%.o: %.c   //模式应用
	$(CC) -o $@ -c $^
clean:
	$(RM) $(EXE) $(OBJS)

模式类似于 Windows 操作系统中所使⽤的通配符,当然是⽤“%”⽽不是“*”。采⽤了模式以后,不论有多少个源⽂件要编译,都应⽤同⼀个模式规则。

其他

注释符

# 字符是注释符,makefile 把 # 字符后面的内容作为注释内容处理(shell、perl 脚本也是使用 # 字符作为注释符)。

如果某行的第一个非空字符为 #,则此行会被 make 解释为注释行(命令行除外,如果 Tab 字符之后使用 # 字符,则会被 make 解释为命令行)。

注释行的结尾如果存在反斜线(\),那么下一行也被作为注释行,可以进行多行注释。

建议在书写 makefile 时将注释作为一个独立的行,而不要和 makefile 的有效行放在同一行中书写。

make 有时候会把 # 字符之前的内容作为有效行的内容(如定义变量的时候)。

当在 makefile 中需要使用字符 # 时,可以使用 \ 加 #**(#)**来实现,表示将 # 字符作为一个普通字符而不是注释符。

清除

和all类似,编写用于清除编译生成的文件

假目标

假目标用于避免所定义的目标和已经存在的文件是重名的情况,使⽤**.PHONY** 关键字来定义

多用来定义 all , clean

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值