【问题标题】:Second Expansion: Evaluate pattern rule before GNU function call第二次扩展:在 GNU 函数调用之前评估模式规则
【发布时间】:2020-06-19 12:19:29
【问题描述】:

在我的makefile 中有一个针对每个目标文件的规则。对应的源文件和隐藏的依赖文件是前提条件。

示例: obj/test/bar.o : src/test/bar.c src/test/.bar.d

由于可能有大量的目标文件,我想概括一下这个规则。我的第一次尝试如下:

$(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(SRCEXT)  $(dir $(SRCDIR)/%.$(DEPSEXT)).$(notdir $(SRCDIR)/%.$(DEPSEXT))

$(BUILDDIR):=obj
$(SRCDIR):=src
$(OBJEXT):=o
$(SRCEXT):=c
$(DEPXEXT):=d

问题在于第二个先决条件中的模式规则评估 dirnotdir 已被应用。因此,上述示例的第二个先决条件是/src/.test/bar.d,而不是/src/test/.bar.d

作为替代方案,我尝试使用以下 shell 命令生成正确的先决条件:

%.$(OBJEXT): $(shell echo %.$(SRCEXT) | sed -e 's/^[^\/]*/src/') $(shell echo %.$(SRCEXT) |  sed -e 's/^[^\/]*/src/;s/^\(.*\/\)/\1./')

我正在使用sed 对目标文件执行字符串替换。正则表达式经过测试并且正确。虽然通配符%echo 可见,但我无法将它通过管道传输到sed。因此,sed 接收到一个空字符串并输出一个“错误”的结果。

问题:

  1. 如何调整规则以使其正常工作?
  2. 为什么echo 会看到%,但为什么无法通过管道将其导入sed

【问题讨论】:

    标签: makefile gnu


    【解决方案1】:

    使用shell 函数不起作用的原因与使用dir 等不起作用的原因完全相同。它们都是 make 函数,并且都以相同的方式扩展,那么为什么其中一个可以工作而另一个不工作呢?

    你遇到的问题是规则介绍行在解析makefile时被make扩展了。但是模式规则直到很久以后才会应用,当 make 尝试实际构建规则时。当 make 解析 makefile 时,它​​完全不知道 % 将扩展成什么:直到应用规则才完成扩展。

    因此,在所有情况下,make 函数(包括 shell)都在文字字符 % 上运行。

    通常,依赖文件被放到不同的目录中,而不是操纵文件名,例如.deps/foo.d,以避免这些类型的问题。

    但是,您可以使用secondary expansion 做您想做的事情,如下所示:

    .SECONDEXPANSION:
    
    $(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(SRCEXT) $$(dir $(SRCDIR)/$$*.$(DEPSEXT)).$$(notdir $(SRCDIR)/$$*.$(DEPSEXT))
    

    【讨论】:

    • 这就是我要找的。谢谢你。如果您将依赖文件存储在专用(隐藏)文件夹中,您是否还会重建源文件夹的目录结构?否则,.deps 文件夹中可能会出现两个同名的 .d 文件。示例:src/foo.c 和 src/test/foo.c
    • 是的,完全正确:您将拥有相同的结构。无论如何你都必须这样做,因为先决条件必须是 $(DEPDIR)/%.$(DEPSEXT)
    • 您不应该使用 shell 表达式,因为它效率低下。但是如果你出于某种原因想使用它,你必须将它放入像DEPNAME = $$(shell ...) 这样的变量中(注意不要使用:=),然后添加$(DEPNAME) 作为先决条件。或者,您可以创建一个像 MAKEDEP = $(shell echo $1.$(SRCEXT) ...) 这样的宏,然后添加 $$(call MAKEDEP,$$*) 作为先决条件。
    • 我已将我的案例移至一个新问题。
    猜你喜欢
    • 2017-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-01
    • 2020-03-23
    相关资源
    最近更新 更多