Итак, я понятия не имею, что это было задумано сделать в GNU Make 3.81. Как Этан указывает, когда я запускаю свой Makefile с GNU Make 3.81 я получаю эту ошибку:
make: *** No rule to make target `=', needed by `p'. Stop.
Это потому, что call
функция не может расширяться до присваивания значения переменной, так что интерпретирует p :=
как будто это было p: =
(что является целью p
с обязательным условием =
). Я не вижу, как это на самом деле то, что вы хотите. Если вы не видите эту ошибку, я могу предположить, что где-то в вашем makefile кто-то объявил рецепт с целью =
(ugh !!)
В GNU make 3.82 Я вижу сообщение empty variable name
. Причина этого в том, что GNU делает 3,82 введенных улучшений парсера, что вызвало некоторую отсталость-несовместимость. Файл NEWS дает следующее предупреждение:
As a result of parser enhancements, three backward-compatibility issues exist: first, a prerequisite containing an "=" cannot be escaped with a backslash any longer. You must create a variable containing an "=" and use that variable in the prerequisite.
незамеченный побочным эффектом этого является то, что знак равенства без значения перед ним в списке предпосылок теперь считается переменной целевой конкретной, где имя переменной пусто, тогда как раньше предполагалось, что он является целью, поскольку он не отвечает требованиям для присвоения переменной. Я не уверен, что это ошибка ... в общем, я не поклонник «обманывания» парсера с нечетными угловыми случаями, поэтому я предпочитаю более новое поведение.
Это всего определить довольно поддельным:
define CheckDir
p := $(foreach d,$1,$(call CheckIt,$d))
endef
Почему? Поскольку пользовательская функция CheckIt
содержит только инструкцию eval
. Но операторы eval
разворачиваются и результаты анализируются make, поэтому они всегда расширяются до пустой строки. Поэтому весь цикл foreach
расширяется до пустой строки. Поэтому, даже если бы это было истолковано как вы (видимо), предназначенные по маркам, он всегда будет просто расширяться:
p :=
, который, кажется, не очень полезно.Если вы измените приведенное выше определение на простое:
define CheckDir
$(foreach d,$1,$(call CheckIt,$d))
endef
тогда он всегда будет работать, и вы не увидите этих странных проблем.
Я не буду комментировать, как фиктивный это Makefile в общем ... :)
Вы уверены, что работает так, как вы думаете, что делает для 3.81? Вот выглядит так: '' 'задавать в качестве цели с' = 'в качестве предпосылки. (Вы не используете 'eval' в результате вызова' SomeCheck'. Добавление 'eval' также делает работу 3.82 в make-файле для любого определения работы, которое я могу назвать этим беспорядком.) Это кажется довольно ужасным способом сделать вещи (вы насильно обстреливаете многократно * во время * время разбора, это будет дорогостоящим). Какова цель всего этого? –
Привет, Этан, это выдержка из Большого беспорядка, с которым я имею дело, а не сделанный мной. Дело в том, что после обновления, чтобы сделать 3,82, существует множество ошибок в именах пустых переменных, и это просто доказательство концепции этой проблемы. Похоже, что eval выполняет работу, но не уверен, почему eval делает разные версии в 3,82? спасибо большое – brbzull
Теперь подумайте, должен ли eval warp вызвать SomeChek, или это можно сделать в определении SomeCheck? Спасибо – brbzull