Я использую 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
Из приведенного выше кода видно, что я дублирую строки
$ (вызов GENERATED_FILE, $ (1), $ (2), php)
и $ (вызов 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 заключается в том, что добавление $$ делает так, чтобы переменная оценивалась извне, то есть $$ выводится как один $ и оценивается только при вызове цели. Следовательно, вызов макроса дважды отменяет его.
Подход Исэ Глицинии делает то, что мне нужно. Вызов eval гарантирует, что переменная будет объявлена немедленно и, следовательно, доступна и расширена макросом во время обработки макроса. Это означает, что я не мог установить для него два разных значения в макросе, но меня это тоже устраивает.
Вот ' s 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