make使用总结(7)-Makefile编写

make使用总结(7)-Makefile编写

上篇文章编写了最简单的Makefile文件。但它不够完美。首先当.h文件发生变化时,需要先make clean,再make.这种方式在编译大型项目时会变得很慢,因为它需要先删除之前生成的所有中间文件,再重新创建中间文件。而理论上make只需要重新编译此.h文件涉及到的相关源文件。然后链接程序就可以了。这节就是要解决这个问题。

优化make时的头文件依赖问题

例程源码链接:https://download.csdn.net/download/qq_23274715/13765780.

工程目录如下:
在这里插入图片描述

其中,文件common.c和main.c中引用了common.h文件。

Makefile文件如下:

# 文件说明
# 所有的文件都在同级目录下。包括`.h`文件,`.c`文件,以及生成的`.o`文件。
# 源文件需要手动的添加到Makefile文件中。


# 要生成的文件名
BIN := main

# 要编译的源文件
SRCS := main.c common.c

OBJS := $(SRCS:.c=.o)
DEPS := $(SRCS:.c=.d)


CC ?= gcc
INC_DIR ?= ./
WARNINGS ?= -Werror -Wall
CFLAGS ?= -O3 -g0 -I$(INC_DIR) $(WARNINGS)
LDFLAGS ?= 

$(BIN):$(OBJS)
	$(CC) -o $@ $^ $(LDFLAGS)

%.o:%.c
	$(CC) $(CFLAGS) -c -o $@ $<

%.d: %.c
	$(CC) -MM $(CFLAGS) $< | sed 's,\($*\)\.o[:]*,$(OBJPATH)/\1.o $@:,g' > $@

.PHONY:clean

clean:
	rm -f *.o *.d $(BIN)

-include $(DEPS)

与之前的Makefile文件不同之处有三点:

  1. 新添加了一个变量DEPS.
  2. 新添加了一个规则%.d: %.c
  3. 在文件末尾引用了-include $(DEPS).

我们现在的目标是当common.h文件发生变化时,make应该重新生成common.o.而要达到这一目的,我们就需要修改common.o的依赖。如下的代码。这样修改完成后,由于common.o依赖于common.h,所以当common.h发生变化,make就会重新生成common.o了。

common.o:common.c common.h
	$(CC) $(CFLAGS) -c -o $@ $<

一般我们都是使用gcc-MM选项自动化的实现这种依赖。如使用gcc -MM common.c命令得到的输出为common.o: common.c common.h

上面新添加的规则%.d: %.c就是使用上面的方式实现自动化依赖的。下面详细介绍这个规则

%.d: %.c
	$(CC) -MM $(CFLAGS) $< | sed 's,\($*\)\.o[:]*,$(OBJPATH)/\1.o $@:,g' > $@

这个规则中的shell命令可以分为三部分:

  1. $(CC) -MM $(CFLAGS) $<.将它简化并实例化后为gcc -MM common.c.就是用来输出common.o: common.c common.h的内容信息。然后将其信息通过管道传给sed命令。
  2. sed 's,\($*\)\.o[:]*,$(OBJPATH)/\1.o $@:,g'.这个sed命令作用是将内容common.o: common.c common.h转化成common.o common.d: common.c common.h。即添加common.d目标,让它也依赖于common.c和common.h。为什么要这样做了?因为当common.c和common.h发生变化时,common.d文件也要更新。
    1. 关于sed命令的使用详解man sed.
  3. > $@:将sed命令处理的结果common.o common.d: common.c common.h重定向到文件$@,即common.d文件中。

有了这个规则后,make就可以为每个c文件生成一个d文件,用来存放此c文件引用的头文件信息。最后使用-include $(DEPS)将所有的d文件加载到此Makefile.这样我们的目就实现了。


关于技术交流

此处后的文字已经和题目内容无关,可以不看。
qq群:825695030
微信公众号:嵌入式的日常
如果上面的文章对你有用,欢迎打赏、点赞、评论。二维码

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

theboynoName

感谢鼓励

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

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

打赏作者

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

抵扣说明:

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

余额充值