gpt4 book ai didi

makefile - 为什么在使用 $$* 的二次扩展时 patsubst 停止工作?

转载 作者:行者123 更新时间:2023-12-02 21:49:31 24 4
gpt4 key购买 nike

这是来自 GNU Make manual section on Secondary Expansion 的示例(稍微简化):

foo_SRCS := bar.c baz.c

.SECONDEXPANSION:
# $$@ expands to the target ("foo" in this case)
foo: $$(patsubst %.c,%.o,$$($$@_SRCS))

这很好用;它构建 bar.obaz.o:

cc    -c -o bar.o bar.c
cc -c -o baz.o baz.c

但是如果我稍微调整一下这个例子,patsubst就会停止工作:

all: foo.a

foo_SRCS := bar.c baz.c

.SECONDEXPANSION:
# $$* expands to the stem of the match ("foo" in this case).
%.a: $$(patsubst %.c,%.o,$$($$*_SRCS))
ar rcs $@ $^

它不再构建 bar.obaz.o,而是直接使用 *.c 文件作为先决条件!

ar rcs foo.a bar.c baz.c

请注意,$$($$*_SRCS) 部分显然正在工作,它找到 foo_SRCS 并将其用作先决条件这一事实就证明了这一点。但由于某种原因,patsubst 部分已变成无操作!它没有将 %.c 替换为 %.o,而是直接使用 foo_SRCS

这是怎么回事?我怎样才能让我的例子工作?

编辑:我有一个理论,即 patsubst 中的 % 字符会使用词干匹配 (foo) 进行早期评估,因此 patsubst 本身看起来像是像这样的东西:

$(patsubst foo.c,foo.o,bar.c baz.c)

为了测试这个理论,我向 foo_SRCS 添加了一个名为 foo.c 的文件:

all: foo.a

foo_SRCS := foo.c bar.c baz.c

.SECONDEXPANSION:
# $$* expands to the stem of the match ("foo" in this case).
%.a: $$(patsubst %.c,%.o,$$($$*_SRCS))
ar rcs $@ $^

这导致了更奇怪的事情:

make: *** No rule to make target `foo.a', needed by `all'.  Stop.

最佳答案

百分比字符被 make 读取为与词干中的通配符匹配,并被替换为词干匹配。如果您检查示例的 make -p 输出,您将看到解析的目标行如下所示:

%.a: $(patsubst %.c,%.o,$($*_SRCS))

就 make 而言,这只是一组非常奇怪的模式目标(或类似的东西)。

如果您以与从 make 评估中转义 $ 类似的方式从 make 解析中转义百分比字符,您可以获得您想要的结果:

pc := %
$$(patsubst $$(pc).c,$$(pc).o,$$($$*_SRCS))

了解更多信息 substitution references (即 $(foo_SRCS:.c=.o))可用于此类转换,以代替对 patsubst 的较长调用。然而,在这种情况下,虽然它在这种情况下使用类似的 : 转义(通过 c := :),但它似乎并不作为唯一的先决条件至少在 GNU Make 3.81 中,目标(make 给出 Makefile:23: *** 命令在第一个目标之前开始。停止。 错误,我不太明白)。

关于makefile - 为什么在使用 $$* 的二次扩展时 patsubst 停止工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25589586/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com