开发者社区> double2li> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

make自动生成依赖文件的两种形式

简介: 最近编译源文件发现当修改头文件后,make并不会自动把包含此头文件的所有源文件重新编译,而每次都是需要把对应的中间文件清除才能重新编译,非常的麻烦。因此需要make自动对源文件所依赖的头文件进行管理,即make自动生成依赖文件。
+关注继续查看
最近编译源文件发现当修改头文件后,make并不会自动把包含此头文件的所有源文件重新编译,而每次都是需要把对应的中间文件清除才能重新编译,非常的麻烦。因此需要make自动对源文件所依赖的头文件进行管理,即make自动生成依赖文件。鉴于本人的刚开始写的博客,很多方面经验不足,比如如何介绍我所用到的知识等,现在只是对我在过程中遇到的问题进行记录,相关的知识可以查看gnu make中文文档,上网等等。
遇到的问题记录如下:1、make在生成依赖文件后并不正确:原因是生成的依赖文件中的目标文件(.d与.o)并不与所要的编译的源文件对应(一个在当前目录,一个在子目录下),对makefile的依赖文件的生成规则进行了查看,发现是使用了gcc -MM默认的生成方式,于是想到看有没有指定的依赖目标的生成规则。于是在网上搜索看到了这么一个帖子(http://bbs.chinaunix.net/thread-930718-1-1.html):楼主的问题是:
gcc -M生成依赖关系的时候,默认的形式是:
xxx.o: xxx.c

但是如果我想生成
objs/xxx.o: xxx.c
的形式,用什么参数呢?
看到了四楼的回答发现可以使用gcc的-MT(或者-MQ)的参数来改变target.
 
看到了这里继续对-MT进行资料的搜索,看到这么一个博客(http://blog.sina.com.cn/s/blog_717794b70101gjca.html),里面就包含了利用gcc生成依赖文件的规则:
%.d : %.c
        $(CC) $(CCFLAGS) -MF"$@" -MG -MM -MP -MT"$@" -MT"$(<:.c=.o)" "$<".
其中-MF是输出依赖文件名,而-MT就是说在输出的依赖文件中的目标, 楼主的例子里为-MT"$@" -MT"$(<:.c=.o)"
就是说在输出的依赖文件中目标是 "$@" 和 "$(<:.c=.o)"。于是得出两种生成依赖文件的处理方式,以下便是我修改后的makefile文件:
SUBDIRS=$(shell ls -l |grep ^d | awk '{if($$9 == "uart") print $$9}')
SRC_FILE = $(wildcard avdecc/*.c) #编译子目录下的源文件使用的方法
DEPS = $(patsubst %.c, %.d, $(SRC_FILE))// 替换成.d文件
OBJS = $(patsubst %.c, %.o, $(SRC_FILE))
 
LIB=libavdecc-host.a
all:LIB
 
LIB:$(OBJS)
$(AR) rc $(LIB) $(OBJS)
 
$(OBJS):%.o:%.c
$(CC) -MM $(CFG_INC) -MT"$*.d" -MT"$(<:.c=.o)" $< > $*.d #生成对应的依赖文件,实际上是一个Makefile文件
$(CC) -c $(CFG_INC) $(CFLAGS) $< -o $@
 
sinclude $(DEPS) #包含依赖文件到当前Makefile文件,这是个关键的步骤。因为make会把DEPS文件都包含进本makefile文件中,把它当做目标,并且检查其的生成规则。
 
$(SUBDIRS):ECHO
make -C $@ #递归编译子目录
 
ECHO:
@echo $(SUBDIRS)
 
.PHONY:clean
clean:
@$(RM) $(OBJS) $(LIB) $(DEPS) .*.sw?
make -C $(SUBDIRS) clean
CUR_SOURCE = $(wildcard ./*.c) #编译当前的源文件,使用gnu make手册的依赖文件的生成方式
CUR_OBJS = $(patsubst %.c, %.o, $(CUR_SOURCE))
DEPS = $(patsubst %.c, %.d, $(CUR_SOURCE))
 
BIN=avdecc
 
all:$(CUR_OBJS) BIN
 
$(CUR_OBJS):%.o:%.c
$(CC) $(CFLAGS) $(CFG_INC) -c -o $@ $<
 
BIN:$(CUR_OBJS)
$(CC) -o $(BIN) $(CUR_OBJS) $(CFLAGS) $(CFG_INC)
 
sinclude $(CUR_OBJS:.o=.d) #包含依赖文件到当前makefile文件
%.d:%.c
@set -e; rm -f $@; \
$(CC) -MM $(CFG_INC) $< > $@.$$$$; \ #gcc-MM生成依赖的默认形式
sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
 
.PHONY:clean
clean:
@$(RM) $(CUR_OBJS) $(BIN) $(DEPS) .*.sw?

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Java中的自动装箱与拆箱
Java中的自动装箱与拆箱
32 0
Java装箱与自动拆箱
Java 编译器在`基本数据类型`和其对应的`对象封装类型`之间进行自动转换.例如将`int`转成`Integer`,将`char`转成包装类`Character`等等.其他基本数据类型的转换如下:
243 0
Spring-Boot + Swagger2 自动生成API接口文档
spring-boot作为当前最为流行的Java web开发脚手架,相信越来越多的开发者会使用其来构建企业级的RESTFul API接口。这些接口不但会服务于传统的web端(b/s),也会服务于移动端。
1751 0
在阿里云上进行Docker应用的自动弹性伸缩
简介 上次介绍了通过监控集成实现容器的自定义弹性伸缩。最近阿里云Docker容器服务发布了自动弹性伸缩的支持,可以非常方便的支持容器的自动弹性伸缩,从而更好的支持应用的弹性管理。能够自动的监控容器应用的指标,并根据配置的自动弹性伸缩的规则进行扩缩容。在业务增长超过监控指标阀值的时候自动增加容器应用
15964 0
Alluxio文件操作Java API示例
                 一、写文件 // 获取文件系统客户端FileSystem实例 FileSystem fs = FileSystem.Factory.get(); // 构造Alluxio路径AlluxioURI实例 AlluxioURI pat...
1494 0
Java自动装箱与拆箱
  自动装箱与拆箱机制在实际使用中非常常见,不过也特别容易出错,博主在面对下面一道题的时候自信满满,可还是没有能够全对,所以写下这篇博文,给自己对自动装箱与拆箱机制做一下知识巩固,也给各位朋友做一下参考。
1168 0
+关注
double2li
一个在IT行业摸爬滚打的老司机
2869
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载