Makefile 语法学习

Makefile 语法学习

① 为什么需要 Makefile
高效地编译程序
修改源文件或头文件,只需要重新编译牵涉到的文件,就可以重新生成 APP

②Makefile语法
一个简单的 Makefile 文件包含一系列的“规则”,其样式如下:

目标(target)…: 依赖(prerequiries)…
命令(command)

`
如果“依赖文件”比“目标文件”更加新,那么执行“命令”来重新生成“目标文件”。

命令被执行的 2 个条件:依赖文件比目标文件新,或是 目标文件还没生成。

先介绍 Makefile 的 2 个函数:
A. $(foreach var,list,text)
简单地说,就是 for each var in list, change it to text。 对 list 中的每一个元素,取出来赋给 var,然后把 var 改为 text 所描述的形式。
在这里插入图片描述
B. $(wildcard pattern)
pattern 所列出的文件是否存在,把存在的文件都列出来。
在这里插入图片描述

objs := main.o sub.o

test : $(objs)
	gcc -o test $^

#需要判定是否存在依赖文件
#.main.o.d  .sub.o.d
dep_files := $(foreach f,$(objs),.$(f).d)
dep_files := $(wildcard $(dep_files))

#把依赖的文件包含起来
ifneq ($(dep_files),)
	include $(dep_files)
endif

%.o : $.c
	gcc -Wp,-MD,.$@.d -c -o $@ $^

clean:
	rm *.o test -f
distclean:
	rm $(dep_files) *.o test -f

知识点
A. make 命令的使用:
执行 make 命令时,它会去当前目录下查找名为“Makefile”的文件,并根据它的指示去执行操作,生成第一个目标。
我们可以使用“-f”选项指定文件,不再使用名为“Makefile”的文件,比如:
make -f Makefile.build

我们可以使用“-C”选项指定目录,切换到其他目录里去,比如:
make -C a/ -f Makefile.build

B. 即时变量、延时变量:
A = xxx // 延时变量
B ?= xxx // 延时变量,只有第一次定义时赋值才成功;如果曾定义过,此赋值无效
C := xxx // 立即变量
D += yyy // 如果 D 在前面是延时变量,那么现在它还是延时变量;
// 如果 D 在前面是立即变量,那么现在它还是立即变量

例如:
A = $@
test:
@echo $A

变量 A 是延时变量,它的值在使用时才展开、才确定。

上述 Makefile 中,变量 A 的值在执行时才确定,它等于 test,是延时变量。

如果使用“A := @ ” , 这 是 立 即 变 量 , 这 时 @”,这是立即变量,这时 @@为空,所以 A 的值就是空

C. 变量的导出(export):

D. Makefile 中可以使用 shell 命令:
比如:
TOPDIR := $(shell pwd)

E. 在 Makefile 中怎么放置第 1 个目标:
执行 make 命令时如果不指定目标,那么它默认是去生成第 1 个目标。
所以“第 1 个目标”,位置很重要。有时候不太方便把第 1 个目标完整地放在文件前面,这时可以在文
件的前面直接放置目标,在后面再完善它的依赖与命令。比如:
First_target: // 这句话放在前面

F. 假想目标:
我们的 Makefile 中有这样的目标:
clean:
rm -f $(shell find -name “*.o”)
rm -f $(TARGET)
如果当前目录下恰好有名为“clean”的文件,那么执行“make clean”时它就不会执行那些删除命令。
这时我们需要把“clean”这个目标,设置为“假想目标”,这样可以确保执行“make clean”时那些删
除命令肯定可以得到执行。
使用下面的语句把“clean”设置为假想目标:
.PHONY : clean

G. 常用的函数:
i. $(foreach var,list,text)
简单地说,就是 for each var in list, change it to text。 对 list 中的每一个元素,取出来赋给 var,然后把 var 改为 text 所描述的形式。
例子:
objs := a.o b.o
dep_files := $(foreach f, ( o b j s ) , . (objs), . (objs),.(f).d) // 最终 dep_files := .a.o.d .b.o.d

ii. $(wildcard pattern)
pattern 所列出的文件是否存在,把存在的文件都列出来。
例子:
src_files := $( wildcard *.c) // 最终 src_files 中列出了当前目录下的所有.c 文件

iii. $(filter pattern…,text)
把 text 中符合 pattern 格式的内容,filter(过滤)出来、留下来。
例子:
obj-y := a.o b.o c/ d/
DIR := $(filter %/, $(obj-y)) //结果为:c/ d/

iv. $(filter-out pattern…,text)
把 text 中符合 pattern 格式的内容,filter-out(过滤)出来、扔掉。
例子:
obj-y := a.o b.o c/ d/
DIR := $(filter-out %/, $(obj-y)) //结果为:a.o b.o

vi. $(patsubst pattern,replacement,text)
寻找text’中符合格式pattern’的字,用replacement’替换它们。pattern’和`replacement’
中可以使用通配符。
比如:
subdir-y := c/ d/
subdir-y := $(patsubst %/, %, $(subdir-y)) // 结果为:c d

H
$@ 表示目标文件
$^ 表示所有的依赖文件
$< 表示第一个依赖文件
$? 表示比目标还要新的依赖文件列表

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值