одноуровневое расширение макроса makefile, в то же время его можно использовать как макрос - PullRequest
0 голосов
/ 22 октября 2018

Я пытаюсь создать макрос в Makefile, который я могу развернуть один раз, но все еще могу работать как макрос после раскрытия.Это полезно для меня, так как расширение первого уровня заполнит рекурсивные параметры, которые не будут длиться долго.Вот пример:

all: aperiod

TGT = hello
hello.TGT = world
world.TGT = period
define CREATE_TARGET
.SECONDARY: $(1)
$(3)$(1): $(4)$(2)
    @echo $$$$(@)
$(foreach t,$($(1).TGT),$(call CREATE_TARGET,$(t),$(1),$$(1),$$(1)))
endef
define CREATE
$(call CREATE_TARGET,$(TGT),,$$(1),)
endef

CREATE_EXP := $(call CREATE)
TGT :=
$(eval $(call CREATE_EXP,a))

Ошибка при запуске make: make: *** Нет правила для создания цели aperiod', needed by all '.Стоп.

TGT содержит изменяющийся набор значений.Я хочу, чтобы CREATE_EXP содержал полностью расширенный метод создания, который принимает параметр для назначения префиксов целевым объектам.

Таким образом, оптимально, я могу вызвать make aperiod и получить hello world period, или вызвать make bperiod после $(eval $(call CREATE_EXP,b)) и получите то же самое

Это очень сокращенный тестовый пример!

Значение CREATE_EXP правильное, но больше не будет работать для меня как макрос.

$(info $(value CREATE_EXP))

.SECONDARY: hello
$(1)hello: 
    @echo $$(@)
.SECONDARY: world
$(1)world: $(1)hello
    @echo $$(@)
.SECONDARY: period
$(1)period: $(1)world
    @echo $$(@)

Я хотел бы знать, почему Make ведет себя таким образом, а также есть ли лучший способ достичь общего смысла того, что я пытаюсь сделать.

РЕДАКТИРОВАТЬ: я нашел решение длясделать это, хотя мне все еще интересно, может ли вызов $ (call) создать макрос, который все еще нуждается в расширении.

define CREATE
define CREATE_EXP
$(call CREATE_TARGET,$(TGT),,$$(1),)
endef
endef

Использование $(eval $(call CREATE))

Первый раз через, make расширит переменные внутри.Это учитывает рекурсивное расширение, а также создание макроса функции.

1 Ответ

0 голосов
/ 22 октября 2018

Мне бы пришлось более глубоко задуматься о «лучшем способе» и действительно понять, что вы пытаетесь сделать, но ответить «почему make ведет себя так»: вы присваиваете CREATE_EXP как просто расширенную переменную, с :=:

CREATE_EXP := $(call CREATE)

Эта информация хранится вместе с переменной, и когда make расширяет что-то вроде $(CREATE_EXP), она знает, что значение CREATE_EXP уже было расширено, и не должнобыть расширенным снова.В этом-то и заключается весь смысл использования :=.

Вот альтернативная модель, которая может работать для вас:

$(foreach 1,a,$(eval $(CREATE_EXP)))

(я не пробовал это).Разница здесь в том, что сначала мы устанавливаем переменную 1 в качестве переменной foreach, затем мы вызываем eval в этом контексте.Хотя $(CREATE_EXP) расширяется до значения без дальнейшего расширения, eval будет анализировать его как make-файл и снова расширять его с установленным 1=a.

Просто примечание: this:

CREATE_EXP := $(call CREATE)

Абсолютно идентичен этому:

CREATE_EXP := $(CREATE)

Если вы не передаете аргументы call, это то же самое, что простое расширение макроса.

Возможно, вам будет интересно прочитатьнабор сообщений в блоге здесь: http://make.mad -scientist.net / category / metaprogramming / (начните с самого старого сначала).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...