在编译过程中处理依赖文件时遇到一个问题。我只是给您我在项目中遇到的情况。
我有两个名为a.c
,b.c
的C源文件,其中包括一个名为c.h
的头文件。我运行了makefile,其中包含编译两个文件的说明。我可以成功编译a.c
文件,但是在编译b.c
时遇到了一些失败,这需要对c.h
进行一些更改才能解决该问题。在c.h
中进行更改并触发构建(增量构建)之后,a.c
文件也应该再次编译,对吗?因为a.c
也依赖于c.h
文件。
我遵循了所有依赖机制(创建自动依赖文件,包括.d
文件等)
DEPSALL := $(wildcard $(patsubst %,%.d,$(basename $(TGTFILES)/*.c)))
-include $(DEPSALL)
$(TGTFILES)/%.o: $(TGTFILES)/%.c
mkdir -p $(@D)
$(CC64) -MT $@ -MMD -MP -MF $(patsubst %,%.d,$(basename $@)) -o $(@) -c $(CFLAGS64) $<
...
...
我在这里错过了什么吗?我想重建所有.c
文件,其中包括我更改过的特定头文件。
答案 0 :(得分:1)
您的问题是不完整的:您并未真正描述所面临的问题(但是我们可能会猜测目标文件并未按期重建),并且显示的Makefile部分不足以了解您的目标是。
首先,此表达式:
DEPSALL := $(wildcard $(patsubst %,%.d,$(basename $(TGTFILES)/*.c)))
毫无用处。等效于更简单易懂的内容:
DEPSALL := $(wildcard $(TGTFILES)/*.d))
类似地,在您的编译配方中,您可以替换:
$(patsubst %,%.d,$(basename $@))
作者:
$(TGTFILES)/$*.d
但是,让我们回到您的主要问题(至少我想这是您的主要问题):在修改头文件时,某些目标文件并没有得到应有的重建。
我的猜测是您认为:
DEPSALL := $(wildcard $(patsubst %,%.d,$(basename $(TGTFILES)/*.c)))
将为依赖性文件列表分配给DEPSALL
,每个源文件一个,就像其他形式一样:
DEPSALL := $(patsubst %.c,%.d,$(wildcard $(TGTFILES)/*.c))
如果这就是您的想法,那么您错了。您的版本将在调用make时为DEPSALL
中当前存在的依赖文件列表分配给$(TGTFILES)
。如果某些(或全部)丢失,则将不会重建某些目标文件...
我建议您仔细阅读this excellent post about Auto-Dependency Generation。如果您将其调整为适合您的设置,则应该以类似以下内容结束:
TGTFILES := tgtfiles
SRCS := $(wildcard $(TGTFILES)/*.c)
OBJS := $(patsubst %.c,%.o,$(SRCS))
DEPS := $(patsubst %.c,%.d,$(SRCS))
INCLUDES := include
CFLAGS += -I$(INCLUDES)
.PHONY: objs clean
objs: $(OBJS)
%.o: %.c
%.o: %.c %.d
$(CC) -MT $@ -MMD -MP -MF $*.Td $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
@mv -f $*.Td $*.d && touch $@
%.d: ;
.PRECIOUS: %.d
clean:
rm -f $(OBJS) $(DEPS)
include $(DEPS)
几个方面可能看起来很奇怪,毫无用处,甚至完全是错误的。但是,如果您仔细阅读上述文章,您会发现它完全有意义。演示:
$ tree
.
├── Makefile
├── include
│ └── c.h
└── tgtfiles
├── a.c
└── b.c
2 directories, 4 files
$ make
cc -MT tgtfiles/b.o -MMD -MP -MF tgtfiles/b.Td -Iinclude -c -o tgtfiles/b.o tgtfiles/b.c
cc -MT tgtfiles/a.o -MMD -MP -MF tgtfiles/a.Td -Iinclude -c -o tgtfiles/a.o tgtfiles/a.c
$ tree
.
├── Makefile
├── include
│ └── c.h
└── tgtfiles
├── a.c
├── a.d
├── a.o
├── b.c
├── b.d
└── b.o
2 directories, 8 files
$ cat tgtfiles/a.d
tgtfiles/a.o: tgtfiles/a.c include/c.h
include/c.h:
$ make
make: Nothing to be done for 'objs'.
$ touch include/c.h
$ make
cc -MT tgtfiles/b.o -MMD -MP -MF tgtfiles/b.Td -Iinclude -c -o tgtfiles/b.o tgtfiles/b.c
cc -MT tgtfiles/a.o -MMD -MP -MF tgtfiles/a.Td -Iinclude -c -o tgtfiles/a.o tgtfiles/a.c
答案 1 :(得分:0)
wildcard
函数应用程序看起来不正确。应该是:
DEPSALL := $(patsubst %,%.d,$(basename $(wildcard $(TGTFILES)/*.c)))