当头文件更改时,GNU-Make不会重新编译

时间:2017-05-17 09:31:23

标签: header gnu-make recompile armcc

当hdr.h文件发生更改时,GNU-Make不会重新编译。 如下面的打印行,即使生成main.d文件也没有尝试重新编译。 你能指导我为什么会这样吗?

hdr.h

#ifndef __HDR_H__  

#define LOOP_CNT 1000  

#endif /* __HDR_H__ */  

的main.c

#include <stdio.h>  
#include "hdr.h"  

int main(void)  
{  
    int i, sum = 0;  
    for (i = 0; i < LOOP_CNT; i++) sum += i;  
    (void)printf("sum = %d\n", sum);  
    return 0;  
}  

生成文件

SUFFIXES += .d

.PHONY: clean  

OBJECTS = $(patsubst %.c,%.o,$(wildcard *.c))  
CC = armcc  
LD = armcc  
CFLAGS += 

# Default target  
all: sum  

sum : $(OBJECTS)  
    $(CC) $(CFLAGS) -o $@ $^  

$(OBJECTS) : %.o : %.c   
    $(CC) $(CFLAGS) -o $@ -c $<  

# Generating dependency files  
%.d : %.c  
    @$(CC) -M $< > $@  

# Include dependency file to have gcc recompile necessary sources  
include $(patsubst %.c,%.d,$(wildcard *.c))  
#$(info $(patsubst %.c,%.d,$(wildcard *.c)))

clean:  
    rm -f *.o *.d core $(EXEC_NAME)  

这是第二行打印的行。

C:\project\dep>make all
Makefile:24: main.d: No such file or directory
armcc    -o main.o -c main.c
armcc    -o sum main.o

C:\project\dep>make all
make: Nothing to be done for `all'. 

main.d文件生成如下。

__image.axf: main.c
__image.axf: C:\Program Files\ARM\RVCT\Data\4.1\713\include\windows\stdio.h
__image.axf: hdr.h

5 个答案:

答案 0 :(得分:1)

一般来说,如果需要编译源文件来创建目标文件,那么还需要重建其依赖文件。

因此,不是为.d文件设置单独的目标,而是在编译时简单地重新生成它。为实现这一目标,一种简单的方法是替换

$(OBJECTS) : %.o : %.c   
    $(CC) $(CFLAGS) -o $@ -c $<  

# Generating dependency files  
%.d : %.c  
    @$(CC) -M $< > $@  

$(OBJECTS) : %.o : %.c   
    $(CC) $(CFLAGS) -o $@ -c $<  
    @$(CC) -M $< > $@  

请注意,只有在编译成功时才会重新编写依赖项文件。如果编译失败,将删除目标文件,因此无论依赖文件是否是最新的,都将强制重新编译。

答案 1 :(得分:1)

作为一个快速而脏的Makefile修复程序,如果标题发生更改,我只需列出所有标题文件,然后在构成C src文件中的目标文件的部分中添加$(HEADERS)作为依赖项。它没有尽可能高效,但我发现它足够好,即

HEADERS = \
    my_header.h \
    my_other_header.h

$(BUILD_DIR)/%.o: %.c $(HEADERS)
    $(LINK.c) $< -c -o $@

答案 2 :(得分:0)

在构建之前,您是否尝试过清理。 清洁和构建应该工作

答案 3 :(得分:0)

如果头文件发生更改,要让它重建您的依赖项文件,您可以将它们的构建规则更改为:

%.d : %.c
        $(CC) -M $< > $@
        @$(CC) -M $< -MT $*.d >> $@  

因为它还附加依赖规则,表明.d文件是从.c和.h文件构建的。

至于如何让它们(重新)构建在第一位 - 如果你的make版本太旧而且没有(重新)自动构建它们你可能有这样的东西:

all: depend subs

depend: $(patsubst %.c,%.d,$(wildcard *.c))

(顺便说一句,我认为如果它在变量BTW中并且效率更高,它看起来更干净)

或者像这样添加依赖项到对象构建:

$(OBJECTS) : %.o : %.c %.d
    $(CC) $(CFLAGS) -o $@ -c $<  

但是这两个解决方案都要求你运行make两次,否则include这些更改

答案 4 :(得分:0)

Makefile的问题是这样的:

不正确:

tmplist=list()
for each in a:
    for obj in b:
        if each == obj.serial:
            tmplist.append(obj)

print(tmplist)

正确(请注意已添加的%.d依赖项,%。c不能为elimin):

$(OBJECTS) : %.o : %.c
    $(CC) $(CFLAGS) -o $@ -c $<

依赖链如下:

$(OBJECTS) : %.o : %.c %.d
    $(CC) $(CFLAGS) -o $@ -c $<

在原始版本中,确实触发了all +->sum +->x.o +->x.c --------------------------------- x.d +->x.c [generate rule: "x.d: x.c x.h"] after include: x.d +->x.c +->x.h 规则,我猜想%.d指令是负责任的(否则,将不会建立include -s)。但是,即使它们被触发,也没有任何东西将它们连接到%.d文件。因此,即使它们被重建,由于%.o文件已更改,对%.h文件也没有依赖链。

连接依赖链可以解决此问题。


请注意,在%.o之后运行更正的Makefile会生成如下错误消息:

clean

make docs中所述,当Makefile:123: x.d: No such file or directory 找不到include时,它会发出一条错误消息,但此时它并不认为这是致命的错误,而是试图找到会创建丢失文件的规则。

添加

Makefile

创建目标文件/链接配方可以确认当时确实存在这些规则。