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
上記のコードから、行を複製していることがわかります
$(call GENERATED_FILE,$(1),$(2),php)
と$(call GENERATED_FILE,$(1),$(3),js)
複数の場所から。そこで、次のように、マクロの最初の 2 つのステートメントとして 2 つの変数を作成してみました。
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 と Ise Wisteria のアプローチを試してみましたが、どちらも「うまくいきました」。どちらもプライベート変数を作成せず、グローバルだけで問題ありません。変数の衝突に注意する必要があり、再帰呼び出しを行うことはできません (これは計画していませんでした)。
eriktous のアプローチの問題は、$$ を追加すると、変数が外部で評価されるようになるという事実です。つまり、$$ は単一の $ として出力され、ターゲットが呼び出されたときにのみ評価されます。したがって、マクロを 2 回呼び出すとオーバーライドされます。
伊勢藤のアプローチは、私が必要とすることを行います。eval を呼び出すと、変数がすぐに宣言されるため、マクロが評価されている間、マクロによって使用および展開されます。これは、マクロ内で 2 つの異なる値を設定できなかったことを意味しますが、それでも問題ありません。
テストに使用したメイクファイルは次のとおりです
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