我有一条来自 OP-TEE 的规则(使用大型 makefile 包含并生成调用树来编译两个操作系统内核和应用程序),其中包含一些立即展开的变量——据我所知,这里没有第二次展开相关,因为double double Dollar 在规则中,因此不受第二次扩展的影响。它应该始终在第二阶段进行扩展:
$(link-out-dir$(sm))/$(user-ta-uuid).elf: $(objs) $(libdeps) \
$(link-script-pp$(sm))
@$(cmd-echo-silent) ' LD $$@'
echo Target '$@', '$$@', "$@", "$$@"
在输出中,可以看到所有出现的$@
and$$@
都由 make 扩展,而不是 sh,但是单美元的没有填充正确的值,双美元的也没有自行转义:
echo Target '', 'out/someuuid.elf', "", "out/someuuid.elf"
Target , out/someuuid.elf, , out/someuuid.elf
我所期待的是:
echo Target 'out/someuuid.elf', '$@', "out/someuuid.elf", "$@"
Target out/someuuid.elf, $@, out/someuuid.elf,
哪种 make 机制可能是扩展在这里以不同方式工作的原因?
这个目标在其他 makefile 中嵌套了两层,并且有四个 make 调用,因此很难找出 buildchain 在这里配置的不同之处。
我无法使用最小的 makefile 重现此行为:
all: target1 target2 target3
.PHONY: target1 target2 target3 all
.SUFFIXES:
target1:
echo Target1 '$@', '$$@', "$@", "$$@"
# should make no difference, since used in immediate context on rule specification
TARGET2 := target2
TARGET3 = target3
$(TARGET2):
echo Target2 '$@', '$$@', "$@", "$$@"
$(TARGET3):
echo Target3 '$@', '$$@', "$@", "$$@"
通过 $@ 扩展为目标名称和 $$@ 扩展为字符串或位置 shell 参数的空列表,产生预期的输出:
echo Target1 'target1', '$@', "target1", "$@"
Target1 target1, $@, target1,
echo Target2 'target2', '$@', "target2", "$@"
Target2 target2, $@, target2,
echo Target3 'target3', '$@', "target3", "$@"
Target3 target3, $@, target3,
正如预期的那样,指定 .SECONDEXPANSION 不会更改结果。