どのようにして変数代入がMakefileで実際に機能するのかについて、誰でも明確な説明を与えることができます。
違いは何ですか :
VARIABLE = value
VARIABLE ?= value
VARIABLE := value
VARIABLE += value
GNU Makeのマニュアルの セクション を読みましたが、それでも私には意味がありません。
VARIABLE = value
変数の通常の設定 - その中の値は宣言された時ではなく、使われた時に再帰的に展開されます
VARIABLE := value
内部の値を単純に展開した変数の設定 - その中の値は宣言時に展開されます。
VARIABLE ?= value
値を持たない場合にのみ変数を設定する
VARIABLE += value
指定された値を既存の値に追加します(または変数が存在しない場合はその値に設定します)。
=
を使用すると、変数に値が割り当てられます。変数にすでに値がある場合は、それが置き換えられます。この値は使用時に拡張されます。例えば:
HELLO = world
HELLO_WORLD = $(HELLO) world!
# This echoes "world world!"
echo $(HELLO_WORLD)
HELLO = hello
# This echoes "hello world!"
echo $(HELLO_WORLD)
:=
の使用は、=
の使用と似ています。ただし、値が使用時に拡張されるのではなく、代入中に拡張されます。例えば:
HELLO = world
HELLO_WORLD := $(HELLO) world!
# This echoes "world world!"
echo $(HELLO_WORLD)
HELLO = hello
# Still echoes "world world!"
echo $(HELLO_WORLD)
HELLO_WORLD := $(HELLO) world!
# This echoes "hello world!"
echo $(HELLO_WORLD)
?=
を使用すると、変数に値 iff が割り当てられていません。変数に以前空の値(VAR=
)が割り当てられていた場合、それはまだ設定されていると見なされますと思います。それ以外の場合、=
とまったく同じように機能します。
+=
を使用するのは=
を使用するのと似ていますが、値を置き換えるのではなく、値が現在の値に追加され、その間にスペースが入ります。変数が以前に:=
で設定されていた場合、それは展開されますと思います。結果の値は使用時に展開されますと思います。例えば:
HELLO_WORLD = hello
HELLO_WORLD += world!
# This echoes "hello world!"
echo $(HELLO_WORLD)
HELLO_WORLD = $(HELLO_WORLD) world!
のようなものが使われた場合、再帰が起こり、それがあなたのMakefileの実行を終わらせるでしょう。 A := $(A) $(B)
が使用された場合、B
は+=
で拡張されるのに対して:=
はB
が拡張されないため、結果は+=
を使用する場合とまったく同じにはなりません。
私はあなたが "make"を使っていくつかの実験をすることを勧めます。これは=
と:=
の違いを示す簡単なデモです。
/* Filename: Makefile*/
x := foo
y := $(x) bar
x := later
a = foo
b = $(a) bar
a = later
test:
@echo x - $(x)
@echo y - $(y)
@echo a - $(a)
@echo b - $(b)
make test
が出力します。
x - later
y - foo bar
a - later
b - later bar
VARIABLE = value
を使用するとき、value
が実際に別の変数への参照である場合、その値はVARIABLE
が使用されているときにのみ決定されます。これは例で最もよく説明されています。
VAL = foo
VARIABLE = $(VAL)
VAL = bar
# VARIABLE and VAL will both evaluate to "bar"
VARIABLE := value
を使用すると、value
の値が になります。例えば:
VAL = foo
VARIABLE := $(VAL)
VAL = bar
# VAL will evaluate to "bar", but VARIABLE will evaluate to "foo"
VARIABLE ?= val
を使用するということは、VARIABLE
の値のみを設定することを意味します VARIABLE
がまだ設定されていない場合。まだ設定されていない場合、値の設定はVARIABLE
が使用されるまで延期されます(例1のように)。
VARIABLE += value
はvalue
をVARIABLE
に追加するだけです。 value
の実際の値は、=
または:=
を使用して、最初に設定されたときの値として決定されます。
上記の答えでは、「値は宣言時または使用時に拡張される」という意味を理解することが重要です。 *.c
のような値を与えても、何も展開されません。この文字列がコマンドによって使用される場合にのみ、それが何らかのグロビングを引き起こす可能性があります。同様に、$(wildcard *.c)
や$(Shell ls *.c)
のような値は展開を必要とせず、変数の定義で:=
を使用していても定義時に完全に評価されます。
いくつかのCファイルがあるディレクトリで次のMakefileを試してください。
VAR1 = *.c
VAR2 := *.c
VAR3 = $(wildcard *.c)
VAR4 := $(wildcard *.c)
VAR5 = $(Shell ls *.c)
VAR6 := $(Shell ls *.c)
all :
touch foo.c
@echo "now VAR1 = \"$(VAR1)\"" ; ls $(VAR1)
@echo "now VAR2 = \"$(VAR2)\"" ; ls $(VAR2)
@echo "now VAR3 = \"$(VAR3)\"" ; ls $(VAR3)
@echo "now VAR4 = \"$(VAR4)\"" ; ls $(VAR4)
@echo "now VAR5 = \"$(VAR5)\"" ; ls $(VAR5)
@echo "now VAR6 = \"$(VAR6)\"" ; ls $(VAR6)
rm -v foo.c
make
を実行すると、foo.c
という名前の余分な(空の)Cファイルを作成するルールがトリガーされますが、6つの変数のどれにもその値にfoo.c
がありません。