打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Makefile自动依赖

Makefile自动依赖

 

Makefile生成自动依赖的方法有两种:

1.  将所有.o文件的依赖关系写入单独文件,然后在Makefile中调用该文件

2.  每个.c文件对应一个.d文件,将依赖关系写入.d文件中

 

 

一、对于第一种方法,Makefile的写法如下:

#file start

CC = gcc

SRCS := $(wildcard *.c)

OBJS := $(patsubst %.c,%.o, $(SRCS))

 

all: main

 

main: $(OBJS)

        $(CC) -o main $(OBJS)

 

.depend: $(SRCS)

        @$(CC) -MM $(SRCS) > $@

sinclude .depend

 

clean:

        rm -f  *.o .depend main

#file end

 

说明:

(1)       OBJS := $(patsubst %.c,%.o, $(SRCS))

     $(SRC)中的.c文件列表替换成对应的.o文件,在这里不能用“*.c”“*.o”来代替,试想在.o文件还不存在的情况下,规则语句“main: $(OBJS)”就会被解析成“main:*.o”,main依赖于“*.o”,“*.o”对应的规则又去哪找呢

(2)       .depend: $(SRCS)

     为的是.c文件更改时重新生成.depend文件

(3)       @$(CC) -MM $(SRCS) > $@

     行首的”@”符号表示在执行make时不显示该符号后的shell命令;

     $@:表示当前目标文件,即”.depend”

     假设main.c文件只引用了main.h头文件,那么这条命令的输出结果为:

         main.o: main.c main.h

(4)       sinclude .depend

     将生成的依赖关系文件引入到当前Makefile

     Makefileinclude的调用方式:

a)  首先在指定的目录下搜索被调用文件(该例没有加路径,则为当前目录)

b)  如果没有找到,则从-I所指定的include目录查找,如果还没找到,则从“/usr/gnu/include”“/usr/local/include”等目录查找

c)  最终结果还是没找到,则Makefile会试图寻找匹配规则来生成对应文件,例如本例中的规则为:

           .depend: $(SRCS)

          @$(CC) -MM $(SRCS) > $@

则根据该规则生成.depend文件。

程序首次编译时肯定不存在.depend文件,但这是makefile也不需要该文件,因为首次编译肯定连接的都是最新文件。也就是说首次编译时生成的.depend文件其实没用上,而是留作以后有了改动,比如更改了.h文件中的宏变量,则此时可根据.depend中的依赖关系只生成对应的.o文件了

d)  如果没有对应规则或其它原因导致生成文件失败,就要看你用的是include还是sinclude了,两者的区别:

 

异常

错误

include

输出异常信息(例如首次编译时找不到.depend文件)

Makefile终止执行(例如找不到匹配规则而无法生成文件)

cinclude

不输出异常信息

忽略该错误,makefile继续执行

 

(5)      此方法过时?

     很遗憾,在<< GNU make>>手册中说该方法过时了,原因描述如下:

 

     InGNUmake, the feature of remaking makefiles makes this practiceobsolete—you need nevertell make explicitly to regenerate theprerequisites, because it always regenerates any makefile that is out ofdate.

 

     这段话的关键句“because it always regenerates any makefile that is out of date”甚是无法理解,要的不就是这种效果么,有文件更新的话对其进行重新编译,对的啊,不懂!

     正是由于这个搞不懂的原因才有了第二种方法

 

二、为每个.c文件生成对应的.d文件,Makefile写法如下:

#file start

SOURCES = $(wildcard *.c)

OBJS := $(patsubst %.c,%.o, $(SOURCES))

 

all: main

 

%.d: %.c

        @set -e; rm -f $@; \

        $(CC) -MM  $< > $@.$$$$; \

        sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \

        rm -f $@.$$$$

 

sinclude $(SOURCES:.c=.d)

 

main:$(OBJS)

        $(CC) -o main $(OBJS)

 

clean:

        rm -f *.o test *.d

#file end

 

上面提到的原因中“you need nevertell make explicitly to regenerate the prerequisites”,其实在这里也是手动指定的啊:“$(CC) -MM  $< > $@.$$$$”,另外为每个.c文件都生成.d文件似乎还麻烦了些,没明白手册是什么意思。

贴上main.d文件中的内容:

main.o main.d : main.c main.h

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
比较好的makefile文件
简易Makefile
makefile .d的解释
makefile自动依赖和隐式规则测试,顺便探讨下通用的makefile的写法
makefile编译所有c文件
怎样编写Makefile文件 - Moose W. Oler的日志 - 网易博客
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服