• 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。

         Makefile中include的调用方式:

    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>>手册中说该方法过时了,原因描述如下:

     

         InGNU make, the feature of remaking makefiles makes this practice obsolete—you need nevertell make explicitly to regenerate the prerequisites, because it always regenerates any makefile that is out of date.

     

         这段话的关键句“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

  • 相关阅读:
    'jar' 不是内部或外部命令,也不是可运行的程序 或批处理文件。或批处理文件
    idea 集成 javap
    JVM_ 动态链接
    远程服务调用RMI框架 演示,和底层原理解析
    IO/NIO/AIO 解读
    JUC 并发编程--10, 阻塞队列之--LinkedBlockingDeque 工作窃取, 代码演示
    github,使用技巧, 让你的开发事半功倍
    JVM-相关,这里引用别人博客
    python开发学习day01 (编程; 计算机三大核心硬件 ; 操作系统与平台)
    webdriervAPI(多表单切换)
  • 原文地址:https://www.cnblogs.com/GoodGoodWorkDayDayUp/p/2602044.html
Copyright © 2020-2023  润新知