2016-12-13 2 views
0

これはおもちゃのMakefileです。 ファイル "a"、 "b"、 "c"、 "a.out"、 "b.out"、 "c.out"を作成したいと思います。makefile関数内の変数が正しく展開されていませんか?

LIST=a b c 
all: $(addsuffix .out,$(LIST)) 

define FUN 
    in := $(1) 
    out := $(1).out 
    $$(in) : 
     echo $(1) > $$(in) 
    $$(out) : $$(in) 
     echo $$(in) > $$(out) 
endef 
$(foreach p,$(LIST),\ 
    $(eval $(call FUN,$(p)))) 

私は "-n作る" を使用して、それを実行し、バージョンGNUは4.1を作成し、 実行本当のコマンドがあるテスト:

echo a > c 
echo c > c.out 
echo b > c 
echo c > c.out 
echo c > c 
echo c > c.out 

しかし、期待される結果は次のとおりです。

echo a > a 
echo a > a.out 
echo b > b 
echo b > b.out 
echo c > c 
echo c > c.out 

誰かがMakefileの動作やこのスクリプトを修正する方法を説明できますか?ありがとう。

答えて

0

これは私のこの試みに答える試みであり、コードには面倒な修正が付いています。私がここに投稿した理由は、より良い答えを待つことです。

GNU Makeマニュアル(https://www.gnu.org/software/make/manual/make.html#Reading-Makefiles)から、ターゲットと前提条件が直ちに評価され、レシピ部品が延期されます。

私の例では、$$(out) : $$(in)が直ちに評価されます。それは私が期待したものです。しかしecho $$(in) > $$(out)は後で拡張されます。このとき、$$(in)cとなり、$$(out)c.outとなります。しかし、それは私が望むものではありません。

私の視点では、ターゲット固有の変数(https://www.gnu.org/software/make/manual/make.html#Target_002dspecific)を使用するのが厄介な問題です。今、Makefileは以下のようなものです:

LIST=a b c 
all: $(addsuffix .out,$(LIST)) 

define FUN 
    in := $(1) 
    out := $(1).out 
    $$(in) : in=$(1) 
    $$(in) : 
    echo $(1) > $$(in) 
    $$(out) : $$(in) 
    echo $$(in) > $$(out) 
endef 
$(foreach p,$(LIST),\ 
    $(eval $(call FUN,$(p)))) 

ターゲット固有の変数が$$(in) : in=$(1)に指定されています。 しかし、レシピ部分に複数の変数がある場合は、複数のターゲット固有の変数を追加する必要があります。

2

新しい変数を作成する代わりに$1変数をどこでも使用してみませんか?展開で変数を使用する必要があるというルールはありません。のいくつかの並べ替えを見ず

define FUN 
    $1 : 
     echo [email protected] > [email protected] 
    $1.out : $1 
     echo $$< > [email protected] 
endef 

EDIT

:あなたはこのようなautomatic variablesを使用することができることをしたくない場合は

define FUN 
    $1 : 
     echo $1 > $1 
    $1.out : $1 
     echo $1 > $1.out 
endef 

:あなたはちょうどとしてそれを書くことができます現実的な例では判断が難しい。あなたの質問への短い答えはいいえ、makefileの中に "可変スコープ"を作成する魔法の方法はありません。

常に[email protected],$<などの自動変数を使用する必要があります。それが彼らのためのものです。必要な他の変数代入があり、呼び出しパラメータを直接使用するのではなく変数として設定する場合は、ターゲット固有の変数またはconstructed macro namesという2つの選択肢しかありません。

しかし、「ターゲット固有の変数の長いリスト」の問題は実際には分かりません。なぜ変数をグローバルに設定してから、ターゲット固有のものとして再度設定するのですか?それらをターゲット固有の変数として直接設定した場合は、それらを一度しか書き込まなくてはなりません。あなたの使い方が「厄介な」ものであることは明らかではありませんので、十分かどうかはわかりません。

また、ターゲット固有の変数は、前提条件リストで「継承」されているため、前提条件ではなく、主ターゲットでターゲット固有の変数を設定する必要があります。このようなので、

、この単純化した例では

define FUN 
    $1.out : FOO = $(some complex thing) 

    $1 : 
     echo $$(FOO) > [email protected] 
    $1.out : $1 
     echo $$(FOO) from $$< > [email protected] 
endef 
+0

は、あなたの答えは素晴らしい作品。実際の問題では、ターゲット固有の変数の長いリストなしで 'define ... endef'の中で変数を使用する方法を見つけることを望んでいます。あなたは解決策を知っていますか?ありがとう。 – zhanxw

関連する問題