Makefile

最近总是涉及Makefile,说说自己的感悟,现在大的工程Makefile都写好了,或者使用Cmake或者automake生成Makefile,如果要优化,也是看懂即可按自己的想法修改,但是如果需要自己写一个小的测试程序,还需自己懂如何写Makefile,从今天开始做一个Makefile总结,每有所学就记录在此。虽说网上多的是,但也不能全都照搬,我的目的是会用,而不是开培训班上课,但自己写下来带有自己思考的才能是自己的东西。
全程复制爱编程的大丙,大佬牛逼。

1. Makefile规则

 target1, target2 ... :  depend1, depend2, ...
	comand1
	comand2
  1. command:前面需要一个tab缩进
  2. target:执行command后可以生成一个和目标同名的文件(也可以不生成文件,因为command可能只是一个动作,这样的目标为伪目标)
    【注】target可以有多个,因为comand也可以有多个

例子

#多个目标,多个命令
app1,app2:a.c b.c c.c
	gcc -o app1 a.c b.c
	gcc -o app2 b.c c.c

2. Makefile工作原理

2.1 规则的执行

先从一个例子开始:

# makefile
# 规则之间的嵌套
# 规则1
app:a.o b.o c.o
	gcc a.o b.o c.o -o app
# 规则2
a.o:a.c
	gcc -c a.c
# 规则3
b.o:b.c
	gcc -c b.c
# 规则4
c.o:c.c
	gcc -c c.c

总结一下结论:

  1. 执行make后,makefile会去从Makefile中找到第一条规则,第一条规则中的命令执行的前提是依赖全都存在。
  2. 如果第一条规则中的依赖不存在,他就会去找哪条命令能生成需要的依赖,知道所有的依赖都有了。
  3. 如果要执行Makefile中非第一条规则,就要把要那条规则的目标写到make命令后面(比如make b.o)。

2.2 文件时间戳

还是看这个例子:

# makefile
# 规则之间的嵌套
# 规则1
app:a.o b.o c.o
	gcc app.o a.o b.o c.o -o app
# 规则2
a.o:a.c
	gcc -c a.c
# 规则3
b.o:b.c
	gcc -c b.c
# 规则4
c.o:c.c
	gcc -c c.c

如果先执行:
make
后修改了文件中的b.c,然后再执行
make
那么,这时候就会先执行规则3,然后再执行规则1。
问题:第二次执行make的时候,明明第一条规则的目标实现比依赖要新,按理说不应该去执行规则2了呀,自己写个小程序实验目标是实现以下效果,Makefile与上述例子相同。
在这里插入图片描述
在执行完一遍make后。我更改b.c,再次make,后执行结果如下:
在这里插入图片描述
可以验证,Make在检查第一条规则时,看当前的依赖是否有依赖,如果有,就会递归的检查生成第一条规则依赖的规则是否满足“目标比依赖新”的要求。

2.3 自动推导

Makefile会会使用默认的编译规则编译.c文件,所以在写依赖时只需要写*.o,Makefile就会为这个 .o 寻找合适的源文件。

3. 变量

Makefile中有三种,分别为自定义变量,预定义变量,自动变量。

3.1 自定义变量

使用方法:

  • 定义方法:变量名=变量值
  • 使用方法:$(变量名)

3.2 预定义变量

Makefile中有些变量是预定义的,一般都是大写的,用户可以直接使用,请参考爱编程的大丙博客。
下面是其中的一个例子:

obj=add.o  div.o  main.o  mult.o  sub.o
target=calc
CFLAGS=-O3 # 代码优化
$(target):$(obj)
        $(CC)  $(obj) -o $(target) $(CFLAGS)

上面说预定义代码不用定义,但上面的例子不也是定义了一遍CFLAGS嘛,因为Makefile中代码的定义和赋值是在一起的。

3.3 自动变量

自动变量很重要,用于表示规则中的目标和依赖文件,只能在某条规则的命令中使用。

variableimplication
$*表示目标文件的名称,不包含目标文件的扩展名
$+表示所有的依赖文件,这些依赖文件之间以空格分开,按照出现的先后为顺序,其中可能包含重复的依赖文件
$<表示依赖项中第一个依赖文件的名称
$?依赖项中,所有比目标文件时间戳晚的依赖文件,依赖文件之间以空格分开
$@表示目标文件的名称,包含文件扩展名
$^依赖项中,所有不重复的依赖文件,这些文件之间以空格分开

下面是一个小例子:

calc:add.o  div.o  main.o  mult.o  sub.o
	gcc $^ -o $@ 	

4. 模式匹配

在这只写一个例子,看懂了就行,用到了在研究,一般用到的不多。

# 模式匹配 -> 通过一个公式, 代表若干个满足条件的规则
# 依赖有一个, 后缀为.c, 生成的目标是一个 .o 的文件, % 是一个通配符, 匹配的是文件名
%.o:%.c
	gcc $< -c
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值