#foreach #makefile #user-defined-functions
#заранее #makefile создать файл #определяемые пользователем функции #foreach #makefile
Вопрос:
У меня есть следующий Makefile:
X=a.jar b.jar c.jar
Y=/var/tmp/abc/a.jar /var/tmp/abc/b.jar /var/tmp/abc/c.jar
all: $(addprefix /var/tmp/abc/tmp/, $(X))
define AddRule
dst=$1
src=$2
/var/tmp/abc/tmp/$(dst): $(src)
@echo $$@
@echo $$^
@mkdir -p $$(dir $$@)
@cp $$^ $$@
endef
$(foreach jar, $(X), $(eval $(call AddRule, $(jar), $(filter %$(jar), $(Y)))))
(/var/tmp/abc/{a, b, c}.jar существует)
В принципе, для каждого имени файла в $ X я хочу найти полный путь в $ Y и создать правило, которое копирует этот файл в /var/tmp / abc / tmp (я знаю, что есть гораздо более простой способ сделать это, но мой фактический Makefile сложнее и нуждается в подобной конструкции).
Когда я запускаю этот Makefile, я получаю следующий вывод:
/var/tmp/abc/tmp/a.jar
/var/tmp/abc/a.jar
/var/tmp/abc/tmp/b.jar
/var/tmp/abc/b.jar
make: *** No rule to make target `/var/tmp/abc/tmp/c.jar', needed by `all'. Stop.
Теперь «забавная» часть: если я добавлю следующую строку после объявления правила «все»:
X =d
все три файла jar обработаны, ‘make’ ничего не упоминает о ‘d’ (даже если файл ‘d’ не существует), и запуск прошел успешно.
Таким образом, похоже, что цикл foreach не проходит последнюю итерацию (или, скорее всего, происходит что-то еще, что приводит к тем же результатам). Кто-нибудь знает, в чем проблема и как ее исправить?
Спасибо!
Ответ №1:
Плохая не только последняя итерация цикла. В основном call
расширяется $(dst)
до любого значения, которое оно имеет, при call
вызове, а не при вычислении нового кода. Затем вычисляется новый код, а затем на следующей итерации определение расширяется — со значениями, которые были установлены в предыдущем блоке нового кода. Итак, вместо {a, b, c} он выдает { , a, b} (вам придется некоторое время смотреть на это, прежде чем это обретет смысл).
Решение: добавьте пару дополнительных $
s:
define AddRule
dst=$1
src=$2
/var/tmp/abc/tmp/$$(dst): $$(src)
...
endef