Makefile GNU make的自动依赖性

Makefile GNU make的自动依赖性,makefile,Makefile,这是我的文件夹视图: -> tree . ├── Makefile └── src ├── a10.c ├── a11.c ├── a12.c ├── a13.c ├── a14.c ├── a15.c ├── a16.c ├── a1.c ├── a2.c ├── a3.c ├── a4.c ├── a5.c ├── a6.c ├── a7.c ├── a8.c

这是我的文件夹视图:

-> tree
.
├── Makefile
└── src
    ├── a10.c
    ├── a11.c
    ├── a12.c
    ├── a13.c
    ├── a14.c
    ├── a15.c
    ├── a16.c
    ├── a1.c
    ├── a2.c
    ├── a3.c
    ├── a4.c
    ├── a5.c
    ├── a6.c
    ├── a7.c
    ├── a8.c
    ├── a9.c
    ├── a.c
    └── test.h
a1.c
a10.c
都是空的,只需测试,只有
a.c
test.h
有代码:

-> cat src/a.c
#include "test.h"

int main(void)
{
    printf("VAR = %d\n", VAR);
    printf("VAR1 = %d\n", VAR1);

    return 0;
}

-> cat src/test.h
#include <stdio.h>
可以生成AutoDependencies:

-> cat src/a.d
a.o: /home/haochen/Work/test_code/test_make/src/a.c \
 /home/haochen/Work/test_code/test_make/src/test.h
问题: 我修改了test.h,添加了一个错误:

-> vim src/test.h
-> cat src/test.h
#include <stdio.h>
#error here

更新:

我补充说:

DEP := $(patsubst %.c,%.d,$(SRC))

同时,我在make文件的最后一行添加了
-include

-include $(DEP)

我没有看到任何改进

.d
文件是表示头依赖关系的makefile。因此,您需要
-包括

makefile中的
.d
文件,例如

OBJ := $(patsubst %.c,%.o,$(SRC))
DEP := $(patsubst %.c,%.d,$(SRC))

...

-include $(DEP)

依赖项文件已正确生成,但您从未使用过它们:对于
@$(CC)-MM$(CFLAGS)$(INCLUDES)$$<>$1/$$*.d
,请发出生成依赖项文件的命令,但不使用它


依赖项文件是它们自己的小makefile,注定要由make读取。因此,您需要告诉make读取它们以及主Makefile。 对于这一点,您有,它暂停读取当前makefile,并在恢复读取当前makefile之前将所有列出的文件作为makefile读取(我在这里引用手册…)

由于依赖项文件在第一次生成时不存在,因此您可能需要在其前面添加
-
,以消除警告,即
没有此类文件

作为旁注,请确保在默认目标之后包含依赖项文件(或使用.default\u目标),因为如果不这样做,默认目标将成为包含文件中的第一个目标。 此外,您可能希望添加依赖项文件作为对象文件的先决条件,因为缺少依赖项文件会使某些先决条件丢失

所有这些都来自make maintainer的博客,您可以在那里找到更多信息

编辑: 对不起,我上次错过了。如果我没有错,
a.o
$1/%.o
不能匹配相同的目标。即使Makefile包含子目录中的文件,它也不会自动知道,对他来说,
a.o
src/a.o
是不一样的(事实上)。因此有两个独立的规则,一个是空的,没有配方(依赖文件中的一个) 一种解决方案可能是在依赖项生成中使用-MT标志(它将目标设置为您指定的字符串,例如$@)


您可能希望使用make的--debug选项来捕获此类错误;到目前为止,我发现跟踪不正确的依赖关系非常有用。

我发现了问题,我应该:

  • 写DEP

    DPES=…

  • 使用
    -MMD
    选项编译c文件:

    -MMD-c$<-o$@

  • 然后,添加:

    -包括$(DPE)


  • 据我所知,你的Makefile不使用*.d文件。@melpomene,那么你的意思是我需要在Makefile中使用(编写一些代码)生成的*.d文件?make怎么知道如何处理*.d文件?您需要在Makefile中包含或不包含*.d文件。我做了这些,但仍然没有改进。在最后一行添加
    -include
    ,似乎没有改进
    DEP := $(patsubst %.c,%.d,$(SRC))
    
    -include $(DEP)
    
    OBJ := $(patsubst %.c,%.o,$(SRC))
    DEP := $(patsubst %.c,%.d,$(SRC))
    
    ...
    
    -include $(DEP)