9

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
4

2 に答える 2

15

以下のような課題に応募evalすれば問題は解決しますか?

$(eval PHP_OUT_FILE := $(call GENERATED_FILE,$(1),$(2),php))
$(eval JS_OUT_FILE := $(call GENERATED_FILE,$(1),$(3),js))

お役に立てれば

于 2011-04-22T01:21:54.953 に答える
5

私はこれを少し実験してきましたが、評価の順序が次のようになったことを理解したと思いmakeます。
伊勢藤はあなたの問題に対する一つの解決策を提供しました、それは私がうまくいくと思います。$もう1つは、次のように、変数を参照するときに1秒を追加するだけです$$(PHP_OUT_FILE)

于 2011-04-22T13:38:47.953 に答える