0

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

$(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 文件)。

4

1 回答 1

1

您的尝试不会奏效,因为在读入 makefile 时,作为目标或先决条件列表的一部分出现的变量和函数会立即展开。显然%,当 make 是试图弄清楚如何构建目标,所以它实际上是在扩展<srcdir>/%.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

(注意额外$转义通配符功能)。

于 2013-07-10T12:37:49.027 回答