Целевое имя Double $ Dollar "$$@" в GNU Make
У меня есть правило из OP-TEE (использует большие make-файлы для включения и создания деревьев вызовов для компиляции двух ядер операционной системы и приложений) с некоторыми сразу развернутыми переменными - насколько я могу судить, здесь нет второго релевантного расширения, так как двойной двойной доллар является правилом и, следовательно, не подлежит второму расширению. Это всегда должно быть расширено на втором этапе:
$(link-out-dir$(sm))/$(user-ta-uuid).elf: $(objs) $(libdeps) \
$(link-script-pp$(sm))
@$(cmd-echo-silent) ' LD $$@'
echo Target '$@', '$$@', "$@", "$$@"
В выводе видно, что все вхождения $@
а также $$@
расширяются по 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-файлы и четыре делает вызовы, поэтому немного сложно выяснить, что buildhain настроил здесь по-другому.
Я не могу воспроизвести это поведение с минимальным make-файлом:
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 '$@', '$$@', "$@", "$$@"
получая ожидаемый результат с расширением $@ до целевого имени и расширением $$@ до строки или пустого списка позиционных параметров оболочки:
echo Target1 'target1', '$@', "target1", "$@"
Target1 target1, $@, target1,
echo Target2 'target2', '$@', "target2", "$@"
Target2 target2, $@, target2,
echo Target3 'target3', '$@', "target3", "$@"
Target3 target3, $@, target3,
Указание.SECONDEXPANSION не меняет результаты, как ожидалось.
1 ответ
Подсветка синтаксиса может быть хитрой - я не знал, что целевая цель является содержимым самой переменной - некоторые цели выше были define gen-link-t
начиная многострочную переменную, заканчивая некоторые цели ниже.
Цель была фактически вызвана после генерации с использованием $(eval $(call gen-link-t))
в конце файла, вместо того, чтобы читать его построчно - в результате происходит первое раскрытие $$ в $ при раскрытии переменной внутри $(call), в результате чего вызов возвращает $ как обычный текст, Вторая оценка произошла, когда make снова читал эту цель через $(eval)