Makefile的简单语法学习

通配符

假如一个目标文件所依赖的依赖文件很多,那样岂不是我们要写很多规则,这显然是不合乎常理的,我们可以使用通配符,来解决这些问题。
我们对上节程序进行修改,代码如下:

test : a.o b.o
	gcc -o test $^

%.o : %.c
	gcc -c -o $@ $<
  • %.o表示所有的.o文件
  • %.c表示所有的.c文件
  • $@:表示目标文件
  • $<:表示第一个依赖文件
  • $^:表示所有依赖文件

假想目标:.PHONY

我们想清除文件,在Makefile的结尾处添加如下代码就可以了:

clean:
	rm *.o test
  1. 执行make,生成第一个目标文件
  2. 执行make clean:清除所有文件

make后面可以带上目标名,也可以不带,如果不带目标名的话就会生成第一个规则里面的第一个目标。

make [目标]也可以不跟目标名,若无目标默认第一个目标。我们直接执行make的时候,会在makefile里面找到第一个目标然后执行下面的指令生成第一个目标。

当我们执行make clean的时候,就会在Makefile里面找到clean这个目标,然后执行下面的命令。

这个写法有些问题,原因是我们的目录里面没有clean这个文件
如果该目录下面有名为clean文件怎么办?

我们在该目录下创建一个名为clean的文件,然后重新执行make clean,结果显示

make: \`clean' is up to date.

一个规则能够执行的条件:

  1. 目标文件不存在
  2. 依赖比目标新

现在目标文件有,但是没有依赖文件,就无法判断文件的时间。
有同名的“clean”文件时,就没有办法执行make clean操作。解决办法:我们需要把目标定义为假象目标,用关键字PHONY

.PHONY:clean

重定向输出

在Linux命令行中,>符号通常用于重定向输出。
当输入> newfile时,它的作用是将命令的输出重定向到一个名为newfile的文件。
如果newfile文件不存在,则它会被创建;如果已经存在,则文件的内容会被覆盖。

如果希望输出追加到文件而不是覆盖文件内容,则可以使用>>符号。

command >> newfile

这样command的输出追加到newfile文件的末尾。

变量

在makefile中有两种变量:

  1. 简单变量(即时变量)
A := xxx #A的值在定义时就确定了
  1. 延时变量
B = xxx #B的值在使用时才确定

想使用变量的时候使用$来引用,如果不想看到命令输出时,在前面加上@符号。

:= # 即时变量
= # 延时变量
?= # 延时变量, 如果是第1次定义才起效, 如果在前面该变量已定义则忽略这句
+= # 附加, 它是即时变量还是延时变量取决于前面的定义
?=: 如果这个变量在前面已经被定义了,这句话就会不会起效果

A := $(C)
B = $(C)
C = abc

#D = 100ask
D ?= weidongshan

all:
	@echo A = $(A)
	@echo B = $(B)
	@echo D = $(D)

C += 123

输出
A =
B = abc 123
D = weidongshan

  1. A:=$©
    A为即时变量,在定义时就确定,由于刚开始时C值为空,所以A的值也为空。
  2. B=$©
    B为延时变量,只有使用到它的时候值才确定,当执行make时,会解析里面所有的变量,所以先解析C= abc,然后解析C += 123,此时,C = abc 123,当执行:@echo B = $(B) B的值为 abc 123。
  3. D?=weidongshan
    D变量在前面没有定义,所以D的值为weidongshan,如果在前面添加D = 100ask,最后D的值为100ask。

我们还可以通过命令行存入变量的值 例如:

执行:make D=123456 里面的 D ?= weidongshan 这句话就不起作用了。

函数foreach

$(foreach var,list,text)
A = a b c
B = (foreach f, $(A), $(f).o)

all:
	@echo B = $(B)

Makefile的简单语法学习_第1张图片

函数filter/filter-out

C = a b c d/

D = $(filter %/, $(C))
E = $(filter-out %/, $(C))

all:
        @echo D = $(D)
        @echo E = $(E)

Makefile的简单语法学习_第2张图片

wildcard

$(wildcard pattern)

这个函数会以pattern这个格式,去寻找存在的文件,返回存在文件的名字

files = $(wildcard *.c)

all:
	@echo files = $(files)

Makefile的简单语法学习_第3张图片
我们也可以用wildcard函数来判断,真实存在的文件

files2 = a.c b.c c.c d.c e.c abc
files3 = $(wildcard $(files2))

all:
        @echo files3 = $(files3)

在这里插入图片描述

patsubst函数

files2 = a.c b.c c.c d.c e.c abc

dep_files = $(patsubst %.c, %.d, $(files2))

all:
        @echo dep_files = $(dep_files)

Makefile的简单语法学习_第4张图片

你可能感兴趣的:(stm32,学习,Makefile)