如何制作Makefile目标取决于仅可能存在的文件?

时间:2013-07-10 07:07:57

标签: language-agnostic makefile dependencies wildcard gnu-make

我有一组[name] .c格式的文件,其中一些#include一个关联的[name] .h文件。我想要一个makefile目标重新构建[name] .o如果[name] .c或[name] .h被修改。我试过了:

$(OBJDIR)/%.o : $(SRCDIR)/%.c $(SRCDIR)/%.h
        #Implementation of target omitted

但是,对于没有关联的.h文件的.c文件,请对上述规则进行投诉。我试过了:

$(OBJDIR)/%.o : $(SRCDIR)/%.c $(wildcard $(SRCDIR)/%.h)
        #Implementation of target omitted

这构建,但修改.h文件不会触发重建。有什么理由我不能以这种方式使用%吗?

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

1 个答案:

答案 0 :(得分:1)

您的尝试将无效,因为当读入makefile时,会立即展开作为目标或先决条件列表一部分出现的变量和函数。此时,显然,无法知道%可能会扩展到以后,当make试图弄清楚如何构建目标时,实际上它正在扩展文字字符串<srcdir>/%.h,其中可能没有。{/ p>

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

$(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

(注意额外的$转义通配符函数。)