【问题标题】:How do I make a Makefile target depend on a file that only possibly exists?如何使 Makefile 目标依赖于仅可能存在的文件?
【发布时间】:2013-07-08 00:23:00
【问题描述】:

我有一组格式为 [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 文件)。

【问题讨论】:

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


    【解决方案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
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-24
      • 1970-01-01
      • 2011-03-23
      • 2018-02-08
      • 1970-01-01
      • 2011-08-05
      相关资源
      最近更新 更多