我使用define
來創建一個宏。但是,在定義構造中,我無法創建變量。分配一個變量不會導致錯誤,但是當我稍後嘗試使用它時,它的值是空的。在makefile宏中定義變量(定義)
例如
#######################################################
## 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) > [email protected]
# Rule to generate a JS file
$(call GENERATED_FILE,$(1),$(3),js): $(1)
$(PHPHOME)/bin/php -f $(JIDL2JS) -- `pwd`/$$< $(DATADEF_HOME) > [email protected]
# 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的伊勢紫藤的做法,他們都「工作」。兩者都不會創建私有變量,只有全局變量,我可以,我只需要小心碰撞變量,我不能做任何遞歸調用(我沒有計劃)。
eriktous的方法存在的問題是,添加$$使得變量在外部被評估,也就是說,$$被輸出爲單個$並且只有在目標被調用時才被評估。因此,調用宏兩次將覆蓋它。
伊斯紫藤的方法確實做了我需要的。調用eval可以確保變量立即被聲明,因此在宏被撤銷時它是可用的並且被宏擴展。這確實意味着我無法在宏中將其設置爲兩個不同的值,但我也可以。
這是我用來測試它
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)
makefile文件而這裏的輸出:我ommitted是運行,以使其更容易看到報表作出的呼應。
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
爲什麼你不能使用更容易的模式規則來實現相同的任何特殊原因?好吧,這並不能回答這個問題,但我認爲你想找到一個解決方案來構建這些東西...... :) – 0xC0000022L 2011-04-22 00:15:28
要解釋爲什麼,它不會幫助回答問題。我不是在尋求解決實際問題的幫助。只是一種在定義中定義局部變量的方法:) – 2011-04-22 00:22:09
@STATUS_ACCESS_DENIED:讓我試着回答你的問題,也許不完全; idl.json文件位於多個文件夾中,不會複製到它們所在的文件夾中。每次對宏的調用都必須指定輸出目錄。請不要問我這是爲什麼:) – 2011-04-22 15:41:39