Типичная ошибка при попытке использовать $(eval ...)
для сгенерированных правил: ваш генератор не генерирует окончательный конец строки, и поэтому make
не анализирует сгенерированные правила, так как вы думаете, что они должны быть проанализированы.
Решение: Всегда конец многострочных макросов, определяющих правило (я) пустой строкой.Это гарантирует, что правила $(eval)
будут правильными.
variable.mk:
echo $@
echo 'test $@' > $@
FILES := cpf dma
# the empty line at the end of the macro is on purpose
define generate_template
$(warning input is $(1) end)
$(1): variable.mk
echo [CC] $$@
echo 'test $$@' > $$@
endef
$(foreach module,$(FILES),$(eval $(call generate_template,$(module))))
run.sh: cpf dma
echo [CC] $@
echo 'TEST $@' >$@
Тестовый прогон:
$ make run.sh
Makefile:14: input is cpf end
Makefile:14: input is dma end
echo variable.mk
variable.mk
echo 'test variable.mk' > variable.mk
echo [CC] cpf
[CC] cpf
echo 'test cpf' > cpf
echo [CC] dma
[CC] dma
echo 'test dma' > dma
echo [CC] run.sh
[CC] run.sh
echo 'TEST run.sh' >run.sh
$ cat variable.mk cpf dma run.sh
test variable.mk
test cpf
test dma
TEST run.sh
Я бы также предложил переписать ваш макрос, чтобы выполнить толькооднократная оценка, т. е.
$(eval $(foreach module,$(FILES),$(call generate_template,$(module))))
СОВЕТ: в случае, если $(eval ...)
не работает должным образом, я всегда изменяю его на $(info eval ...)
, чтобы точно узнать, что оценивается.Обычно это позволяет легко определять ошибки и опечатки в макросах генерации кода.