Jua*_*des 8 makefile local-variables
我define
用来创建一个宏.但是,在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
Run Code Online (Sandbox Code Playgroud)
您可以从上面的代码中看到我正在重复这些行
$(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)
Run Code Online (Sandbox Code Playgroud)
但是如果我稍后尝试使用它们(仍然在定义中),比如$(PHP_OUT_FILE)
或者$(JS_OUT_FILE)
,变量是空的.我希望能够从我的宏中删除重复.我做错了吗?这不可能吗?还有另一种方法吗?
测试两种答案
我尝试了eriktous和Ise Wisteria的方法,他们都"工作"了.没有人创建私有变量,只是全局变量,我可以使用,我只需要小心碰撞变量,我不能进行任何递归调用(我没有计划).
eriktous方法的问题在于,添加$$使得变量在外部进行求值,也就是说,$$作为单个$输出,并且仅在调用目标时进行求值.因此,调用宏两次将覆盖它.
Ise Wisteria的方法尽我所能.调用eval可以确保变量立即被声明,因此宏可以在宏被渲染时由宏可用和扩展.它确实意味着我无法在宏中将它设置为两个不同的值,但我也可以.
这是我用来测试它的makefile
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)
Run Code Online (Sandbox Code Playgroud)
这是输出:我已经省略了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
Run Code Online (Sandbox Code Playgroud)
Ise*_*ria 14
是否适用eval
于以下任务解决问题?
$(eval PHP_OUT_FILE := $(call GENERATED_FILE,$(1),$(2),php))
$(eval JS_OUT_FILE := $(call GENERATED_FILE,$(1),$(3),js))
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助
我一直在试验这一点,我想我现在明白评估的顺序make
如下.
Ise Wisteria为您的问题提供了一个解决方案,我认为应该可行.另一个是$
在引用变量时简单地添加一个,如下所示:$$(PHP_OUT_FILE)
.