используя eval внутри функции make - PullRequest
0 голосов
/ 30 сентября 2019

(Примечание. Это похоже на мой предыдущий вопрос, но, похоже, причина в другом, поэтому я публикую новый вопрос здесь).

Я отлаживаю некоторые make-файлы, которые усеяны очень запутанными eval-файлами. Я хотел бы быть в состоянии точно сбросить то, к чему расширяются eval, и затем назвать evals. Мне нужно сделать это так, чтобы я мог легко включить / выключить отладку, но я обнаружил странное поведение с eval внутри функции. У меня есть:

FOO := a:=foo
$(eval $(FOO))
$(info a=$(a))   #a=foo -- OK

define eval_dbg
$(info eval_dbg: running [$1]) # $1 is "a:=bar"
$(eval $(1))                   # fails - missing seperator...
endef

$(call eval_dbg,a:=bar)    #causes error...
$(info a=$a)

Но я получаю:

a=foo
eval_dbg: running [a:=bar]
test2.mk:17: *** missing separator.  Stop.

Возможно ли оценить параметр вызова?


** минимальный воспроизводимый пример:**

tmp> more test3.mk
FOO := a:=foo
$(eval $(FOO))
$(info a=$(a))

define eval_dbg
$(info eval_dbg: running [$1])
$(eval $(1))
endef

$(call eval_dbg,a:=bar)
$(info a=$a)

all:
        @echo running $@

tmp> make -f test3.mk
a=foo
eval_dbg: running [a:=bar]
test3.mk:10: *** missing separator.  Stop.

tmp> make --version
GNU Make 3.81
Copyright (C) 2006  Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.

This program built for x86_64-unknown-linux-gnu

Ответы [ 2 ]

1 голос
/ 01 октября 2019

Проблема связана с комментариями внутри "define".

По сути, "define" - это то же самое, что и присвоение переменной (кроме символов новой строки). «Call» делает расширение, но не оценку. Следовательно, комментарии попадают в поток без оценки -> возникает ошибка!

Итак, мораль:

  1. Определение - это не макрос;это строка
  2. Вызов не является оценкой;это расширение
  3. Комментарии не являются пробелами;они оцениваются

UPD. Как оказалось, другая проблема - старая версия make. Похоже, что v3.81 не может просто игнорировать пробелы, как это делают современные версии make.

Дополнительный eval исправляет эту проблему:

$(eval $(call eval_dbg,a:=bar))
0 голосов
/ 01 октября 2019

Проблема заключается в том, что результатом вызова eval(...) является пустая строка, поэтому в действительности вы передаете call аргумент - определенную функцию eval_dbg - которая содержит пробелы, и callне любит пробелы.

define func_1
$(info hello)
endef

$(call func_1) # this works                                                     

define func_2
$(info hello)

endef

$(call func_2) # this fails 

define func_3
$(info hello)
$(eval a:=b)
endef

$(call func_3) # this also fails

Но нет причины вызывать eval из функции. Как вы показали, вы можете распечатать заявление, а затем вызвать eval. Или вы можете передать eval результат вызова на call:

define foo_double
$(1):=foo_$(1)$(1)
endef

$(info $(call foo_double,a))
$(eval $(call foo_double,a))

$(info a is $a)
...