Я использую define
для создания макроса. Тем не менее, в рамках определенной конструкции я не могу создать переменную. Присвоение переменной не приводит к ошибке, но когда я пытаюсь использовать ее чуть позже, ее значение становится пустым.
Например
#######################################################
## JIDL_RULE
## Macro to build and install PHP and JS files
## from idl.json files
#######################################################
## param $(1) Full path to idl.json file
## param $(2) Path to directory to copy PHP file into (relative to where make is run from)
## param $(3) Path to directory to copy JS file into (relative to where make is run from)
##########################################################
define JIDL_RULE
# Create the output directory if it doesn't exist
$(2):
mkdir -p $(2)
$(3):
mkdir -p $(3)
# Rule to generate a PHP file. Notice that we have to prepend `pwd`
$(call GENERATED_FILE,$(1),$(2),php): $(1)
$(PHPHOME)/bin/php -f $(JIDL2PHP) -- `pwd`/$$< $(DATADEF_HOME) > $$@
# Rule to generate a JS file
$(call GENERATED_FILE,$(1),$(3),js): $(1)
$(PHPHOME)/bin/php -f $(JIDL2JS) -- `pwd`/$$< $(DATADEF_HOME) > $$@
# Add those generated files to the all target
all:: $(call GENERATED_FILE,$(1),$(2),php) $(call GENERATED_FILE,$(1),$(3),js) $(2) $(3)
# Remove generated files on clean:
clean::
-$(RM) -f $(call GENERATED_FILE,$(1),$(2),php) $(call GENERATED_FILE,$(1),$(3),js)
# Rules to install generated files
$(call PHP_RULE, $(call GENERATED_FILE,$(1),$(2),php))
$(call JS_RULE, $(call GENERATED_FILE,$(1),$(3),js))
endef
Вы можете видеть из кода выше, что я дублирую строки
$(call GENERATED_FILE,$(1),$(2),php)
и $(call GENERATED_FILE,$(1),$(3),js)
из нескольких мест. Поэтому я попытался создать две переменные в качестве первых двух операторов в макросе, например:
PHP_OUT_FILE := $(call GENERATED_FILE,$(1),$(2),php)
JS_OUT_FILE := $(call GENERATED_FILE,$(1),$(3),js)
Но если я попытаюсь использовать их позже (все еще в пределах определения), например $(PHP_OUT_FILE)
или $(JS_OUT_FILE)
, переменные будут пустыми. Я хотел бы иметь возможность удалить это дублирование из моего макроса. Я делаю это неправильно? Разве это не возможно? Есть ли другой способ сделать это?
ИСПЫТАНИЕ ОБА ОТВЕТОВ
Я попробовал подход Эриктуса и Исе Глицинии, и они оба "сработали". Ни один из них не создает приватные переменные, только глобальные переменные, с которыми у меня все в порядке, мне просто нужно быть осторожным с конфликтующими переменными, и я не могу совершать рекурсивные вызовы (которые я не планировал).
Проблема с подходом eriktous заключается в том, что добавление $$ делает его таким образом, что переменная оценивается снаружи, то есть $$ выводится как один $ и вычисляется только при вызове target. Поэтому повторный вызов макроса переопределит его.
Подход Исе Глицинии делает то, что мне нужно. Вызов eval гарантирует, что переменная будет объявлена немедленно, и, следовательно, она доступна и расширяется макросом во время удаления макроса. Это означает, что я не могу установить для него два разных значения в макросе, но я тоже согласен с этим.
Вот make-файл, который я использовал для проверки
define TEST
$(eval INNERVAR := Blah $(1))
inner::
echo Using EVAL: INNERVAR = $(INNERVAR)
echo
endef
define TEST2
INNERVAR2 := Blah $(1)
inner::
echo Using double dollar sign: INNERVAR2 = $$(INNERVAR2)
echo
endef
$(eval $(call TEST,TEST_1_A))
$(eval $(call TEST,TEST_1_B))
$(eval $(call TEST2,TEST_2_A))
$(eval $(call TEST2,TEST_2_B))
inner::
echo is that var really private? $(INNERVAR)
echo is that var really private? $(INNERVAR2)
А вот и вывод: я пропустил повторение команды make, которая должна быть выполнена, чтобы ее было легче увидеть.
Using EVAL: INNERVAR = Blah TEST_1_A
Using EVAL: INNERVAR = Blah TEST_1_B
# Calling the macro twice overwrites the global variable and since
# it's not expanded immediately, calling the macro with different params
# will output the last value that we set the variable to
Using double dollar sign: INNERVAR2 = Blah TEST_2_B
Using double dollar sign: INNERVAR2 = Blah TEST_2_B
# As expected, the variables are not private to the macro.
is that var really private? Blah TEST_1_B
is that var really private? Blah TEST_2_B