最近编译源文件发现当修改头文件后,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?

make自动生成依赖文件的两种形式的更多相关文章

  1. spring4笔记----依赖注入的两种形式

    设值注入:通过<property.../>元素驱动Spring执行setter的方法 构造注入:通过<constructor-arg.../>元素驱动Spring执行带有参数的 ...

  2. Makefile 自动生成依赖

    虽然以前对Makefile有个基本概念,但是真正到自己去写一个哪怕是简单的Makefile时也会遇到不少的麻烦.    现在我有如下文件 dList.h dList.c memory.c debug. ...

  3. Makeflie自动生成依赖,自动化编译

    在netbeans里开发,有一个重要文件makefile,是用来编译所有的文件. 项目的目录结构如下,扁平的目录结构,如何实现自动化编译,写makefile呢? 第一版 基础版: CC = g++ C ...

  4. Makefile中自动生成头文件依赖

    为什么需要自动生成头文件依赖? 编译单个源文件时,需要获取文件中包含的头文件的信息,但是一般的Makefile不会在规则中明确写明文件依赖的头文件,所以单独修改头文件后,不会导致包含头文件的源文件重新 ...

  5. Makefile自动生成头文件依赖

    前言 Makefile自动生成头文件依赖是很常用的功能,本文的目的是想尽量详细说明其中的原理和过程. Makefile模板 首先给出一个本人在小项目中常用的Makefile模板,支持自动生成头文件依赖 ...

  6. Wix 安装部署(一)同MSBuild 自动生成打包文件

    因为项目需要,最近在研究Wix打包部署,园子里也有一些关于wix的博客,方方面面,讲的点各不同.我自己也在测试过程中,写下过程,以供参考.最新版本WiX Toolset v3.7,如何安装的就不说了, ...

  7. Eclipse将引用了第三方jar包的Java项目打包成jar文件的两种方法

    方案一:用Eclipse自带的Export功能 步骤1:准备主清单文件 “MANIFEST.MF”, 由于是打包引用了第三方jar包的Java项目,故需要自定义配置文件MANIFEST.MF,在该项目 ...

  8. makefile自动生成依赖关系

    手工编写依赖关系不仅工作量大而且极易出现遗漏,更新也很难及时,修改源或头文件后makefile可能忘记修改.为了解决这个问题,可以用gcc的-M选项自动生成目标文件和源文件的依赖关系.-M选项会把包含 ...

  9. php中soap的使用实例以及生成WSDL文件,提供自动生成WSDL文件的类库——SoapDiscovery.class.php类

    1. web service普及: Webservice soap wsdl区别之个人见解 Web Service实现业务诉求:  Web Service是真正“办事”的那个,提供一种办事接口的统称. ...

随机推荐

  1. no leveldbjni64-1.8 in java.library.path

    在抽取以太坊Java版本的Trie树部分时,遇到了一个问题: Exception in thread "main" java.lang.UnsatisfiedLinkError: ...

  2. 51nod 1158 全是1的最大子矩阵

    题目链接:51nod 1158 全是1的最大子矩阵 题目分类是单调栈,我这里直接用与解最大子矩阵类似的办法水过了... #include<cstdio> #include<cstri ...

  3. 坑爹的属性,android:descendantFocusability用法简析

    开发中很常见的一个问题,项目中的listview不仅仅是简单的文字,常常需要自己定义listview,自己的Adapter去继承 BaseAdapter,在adapter中按照需求进行编写,问题就出现 ...

  4. 读<jQuery 权威指南>[6]--实用工具函数

    官方地址:http://api.jquery.com/category/utilities/ 一.数组和对象操作 1. $.each——遍历 $.each(obj,function(param1,pa ...

  5. investopedia level 2

    Mispricing can be explained by the sum of the two components: true mispricing and estimation errorVe ...

  6. java 代理的三种实现方式

    Java 代理模式有如下几种实现方式: 1.静态代理. 2.JDK动态代理. 3.CGLIB动态代理. 示例,有一个打招呼的接口.分别有两个实现,说hello,和握手.代码如下. 接口: public ...

  7. Windows下Apache的优化

    (1)首选查看apache的工作模式 windows下的查看apache的工作模式命令: httpd -l 如果列出mod_win32.c,则表示是 win32.c 工作方式. 列出的全部内容如下所示 ...

  8. 建筑行业如何用BPM替换OA?

    2015年4月,K2正式与上海水石建筑规划设计有限公司签约. 为提高公司运作流程的效率,有效的对各流程的运作管理和优化,降低成本,同时提高公司的资金管理水平,水石公司利用K2系统作为整个公司流程的管理 ...

  9. loadrunner (一)如何查看分析、报告结果

  10. Javascript实现CheckBox的全选与取消全选的代码(转)

    js函数 复制代码 代码如下: <script type="text/javascript"> function checkAll(name) { var el = d ...