Makefile中.PHONY伪目标的作用(完整)

第一种情况:避免命令与目录下的文件名重复

实际上这个情况很少发生,但网上大部分博客也仅介绍了这一种情况。这里以如下Makefile简单介绍一下:

clean:
	rm  -f *.o temp

如果当前目录下没有名为“clean”的文件,则rm指令会被执行。如果有的话,由于clean没有依赖文件,所以目标被认为是最新的而不去执行rm指令。
在Makefile中加入伪目标声明可防止这种情况发生

.PHONY : clean

第二种情况:make的并行和递归执行过程中

先看一个例子

SUBDIRS = foo bar baz
subdirs:
for dir in $(SUBDIRS); do \
$(MAKE) -C $$dir; \
done

如上用循环到所有子目录下执行make指令,有以下问题:
1.如果其中一个make指令执行失败(代码格式错误等),它不会停下来,而会继续执行其它目录的make指令,这样很难定位出错的位置。
2.没有用到make对目录的并行处理功能,而是按顺序执行。

  • 并行处理功能:如果两个目标有依赖关系,如a依赖于b,则执行顺序一定是先生成b再生成a。而不过没有依赖关系的话,不同目标是可以并行生成的。而上面的Makefile在循环中顺序执行一样会失去并行性。

而有了PHONY后,可以解决这些问题,修改Makefile如下:

SUBDIRS = foo bar baz
.PHONY: subdirs $(SUBDIRS)
subdirs: $(SUBDIRS)
$(SUBDIRS):
	$(MAKE) -C $@
#在并行Makefile中需要注意目录处理的顺序
foo: baz #没有命令行,限制子目录的make顺序,即先生成baz才能生成foo

当一个目标文件的依赖包含伪目标时,每一次在执行这个规则时伪目标所定义的命令都会被执行。所以subdirs: $(SUBDIRS)代表$(SUBDIRS)下定义的命令$(MAKE) -C $@每次都会无条件地被执行。
而伪目标不在任何目标文件的依赖中时,只能通过make来主动执行,如上面的make clean

  • Linux内核源码的/scripts/Makefile.build中就有这种伪目标出现:各个子目录并行递归生成其目录的.o文件,最终通过顶层目录的.o生成内核文件。

第三种情况:生成多个应用程序

在Makefile中第一个目标即最后要生成的文件,如果想在一个目录下创建多个可执行程序,可以用伪目标“all”作为第一个目标。

#sample Makefile
all : prog1 prog2 prog3
.PHONY : all
prog1 : prog1.o utils.o
	cc -o prog1 prog1.o utils.o
prog2 : prog2.o
	cc -o prog2 prog2.o
prog3 : prog3.o sort.o utils.o
	cc -o prog3 prog3.o sort.o utils.o 
  • make prog1/prog2/prog3可以单独生成其中一个可执行程序
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tilblackout

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值