当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
答案 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
创建目标文件/链接配方可以确认当时确实存在这些规则。