最近编译源文件发现当修改头文件后,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. windows docker测试

    最近测试环节要求比较多,笔记本上虚拟机越来越多,试验一下docker,随笔如下. 一.安装docker 主机windows 10 专业版 网上在windows10上安装docker有两种方法 一个是使 ...

  2. CentOS7下安装Tomcat

    1.下载tomcat. 测试tomcat版本为:apache-tomcat-8.5.6.tar.gz.下载地址:http://tomcat.apache.org/download-80.cgi. 2. ...

  3. java_easyui体系之DataGrid(4)[转]

    一:简介 在前面DataGrid(3)的基础上添加后台的实现.本来是想只搭建前台页面的.后台不写.现在觉得还是都实现好点.从真实情况出发.后台用的ssh. 1. 新增冻结列功能. 2. 实现界面的添加 ...

  4. java_easyui体系之DataGrid(1)[转]

    一:简介 以表格的形式展示数据.项目中式很常见的一个使用.table展示数据.牵扯到分页.上一页下一页.首页.尾页.翻页.选中展示的记录用于操作.总记录数等等.使用DataGrid很容易实现这一点. ...

  5. linux 的 磁盘操作

    //显示目录和文件 以kb m g为单位 du -ah //总大小 du -sh /etc //查看分区 fdisk -l //对磁盘进行分区 fdisk /dev/sdb //格式化分区 mkfs ...

  6. iOS开发Swift篇—(八)函数(2)

    iOS开发Swift篇—(八)函数(2) 一.函数类型 函数类型也是数据类型的一种,它由形参类型和返回值类型组成,格式是 (形参类型列表) -> 返回值类型 func sum(num1: Int ...

  7. MSSQL CharIndex()用法

    CHARINDEX函数返回字符或者字符串在另一个字符串中的起始位置. CHARINDEX ( expression1 , expression2 [ , start_location ] ) expr ...

  8. 尾递归(Tail Recursion)和Continuation

    递归: 就是函数调用自己. func() { foo(); func(); bar(); } 尾调用:就是在函数的最后,调用函数(包括自己). foo(){ return bar(); } 尾递归:就 ...

  9. 通过WebViewJavascriptBridge实现OC与JS交互

      在.m方法当中,申明一个WebViewJavascriptBridge属性: @interface ExampleAppViewController () @property WebViewJav ...

  10. 跑马灯标记marquee

    常见属性: direction:滚动方向(left默)/right/up/down; behavior:滚动方式(scroll默)/slide/alternate来回弹动: width.height. ...