Language agnostic 如何使Makefile目标依赖于仅可能存在的文件?

Language agnostic 如何使Makefile目标依赖于仅可能存在的文件?,language-agnostic,makefile,dependencies,wildcard,gnu-make,Language Agnostic,Makefile,Dependencies,Wildcard,Gnu Make,我有一组格式为[name].c的文件,其中一些#包括关联的[name].h文件。如果修改了[name].c或[name].h,我需要重新生成[name].o的生成文件目标。我试过: $(OBJDIR)/%.o : $(SRCDIR)/%.c $(SRCDIR)/%.h #Implementation of target omitted $(OBJDIR)/%.o : $(SRCDIR)/%.c $(wildcard $(SRCDIR)/%.h) #Impleme

我有一组格式为[name].c的文件,其中一些#包括关联的[name].h文件。如果修改了[name].c或[name].h,我需要重新生成[name].o的生成文件目标。我试过:

$(OBJDIR)/%.o : $(SRCDIR)/%.c $(SRCDIR)/%.h
        #Implementation of target omitted
$(OBJDIR)/%.o : $(SRCDIR)/%.c $(wildcard $(SRCDIR)/%.h)
        #Implementation of target omitted
但是,对于没有关联的.h文件的.c文件,请根据上述规则进行投诉。我试过:

$(OBJDIR)/%.o : $(SRCDIR)/%.c $(SRCDIR)/%.h
        #Implementation of target omitted
$(OBJDIR)/%.o : $(SRCDIR)/%.c $(wildcard $(SRCDIR)/%.h)
        #Implementation of target omitted
这将生成,但修改.h文件不会触发重建。有什么原因不能这样使用%吗


注意:我试图避免使用makedeps.pl或makefile生成的解决方案(因为我实际上没有使用.c或.h文件)。

您的尝试不会起作用,因为在读入makefile时,作为目标或先决条件列表一部分出现的变量和函数会立即展开。显然,在这一点上,当make试图找出如何构建目标时,无法知道
%
以后可能会扩展到什么,因此它实际上是在扩展文本字符串
/%.h
,而这个字符串大概没有

一个答案是将先决条件移动到单独的规则:

$(OBJDIR)/foo.o : $(wildcard $(SRCDIR)/foo.h)
$(OBJDIR)/bar.o : $(wildcard $(SRCDIR)/bar.h)
$(OBJDIR)/baz.o : $(wildcard $(SRCDIR)/baz.h)
如果您不想写出来,可以使用eval来完成:假设您有一个变量列出了对象文件:

OBJECTS = foo.o bar.o baz.o

$(foreach O,$(OBJECTS),$(eval $(OBJDIR)/$O : $(wildcard $(SRCDIR)/$(O:.o=.h))))
(这可能并不完全正确)

或者,您可以启用
.SECONDEXPANSION
并写入:

.SECONDEXPANSION:
$(OBJDIR)/%.o : $(SRCDIR)/%.c $$(wildcard $(SRCDIR)/%.h)
        #Implementation of target omitted
(注意额外的
$
转义通配符函数)