[ < ] [ > ]   [ << ] [] [ >> ]         [冒頭] [目次] [見出し] [ ? ]

6. 変数の使用法

変数は、makefileのなかで文字列の代理となるための名前の定義です。 それらのは明確な要求によってターゲット、必要条件、コマンドあるいは makefileの一部で代用されます。(makeのバージョンによっては変数は マクロと呼ばれます。)

makefile中の変数とファンクションは読み込みの際に展開されます。ただし、 ルールにおけるシェルコマンドは例外で、‘=’を使った変数定義の右側と defineディレクティブを使用した変数定義の本体は展開されません。

変数はいろいろなものを代用することができ、それらは、ファイル名のリスト、 コンパイラに渡すオプション、実行するプログラム、ソースファイルを探す ディレクトリ、出力するディレクトリなどです。

変数は、‘:’、‘#’、‘=’と空白を含まない文字列で表わされます。 しかし、変数はまた、文字以外の数字、アンダースコアは使用を避けるべきでしょう。 なぜなら、それらは将来特別な意味を持つからです。また、シェルによっては 環境変数を通してサブのmakeに渡せない場合もあります (see section サブのmakeへの変数の伝達.)。

また、変数名は大文字小文字を区別し、‘foo’と‘FOO’と‘Foo’は すべて異なるものとして参照されます。

伝統的には大文字を使いますが、makefileにおいては目的にかなうように小文字の 使用を推奨します。大文字は明示的なルールのコントロールのためのパラメータや コマンドのオプションのオーバーライドのためのパラメータに使用することを 推奨します(see section 変数のオーバーライド.)。

いくつかの変数は単一の文字またはごく少ない文字列になっていて、 それらは自動変数と呼ばれ特別な用途に用いられます。 See section 自動変数.。


[ < ] [ > ]   [ << ] [] [ >> ]         [冒頭] [目次] [見出し] [ ? ]

6.1 変数参照の基礎

変数の値を代用するには、括弧または中括弧のなかにドル記号に続いて変数名を 書きます。たとえば、‘$(foo)’や‘${foo}’は変数fooの正しい 参照例です。また、‘$’の特別な点は、ファイル名やコマンドにおいて1個の ドル記号を表わす際は、‘$$’と記述しなければならないことです。

変数参照は文脈のどこからでも行なわれます。たとえば、ターゲット、必要条件、 コマンド、大部分のディレクトリ、そして新たな変数などからです。ここに 一般的な例がありますが、プログラムのすべてのオブジェクトの名前を変数が 保持しています。

 
objects = program.o foo.o utils.o
program : $(objects)
        cc -o program $(objects)

$(objects) : defs.h

変数は、テキストの正確な代用により、動作を参照します。したがって、ルール、

 
foo = c
prog.o : prog.$(foo)
        $(foo)$(foo) -$(foo) prog.$(foo)

は、C言語のプログラムの‘prog.c’をコンパイルします。変数のまえの スペースは無視されるため、fooの値は正確に‘c’です。(ただし、 実際のmakefileにはこのように記述しないでください。)

ドル記号以外の文字、開いている括弧または中括弧がドル記号に続く場合は それを変数名として扱います。したがって、変数xは‘$x’で参照できます。 しかし、この方法は自動変数以外ではうまくいきません (see section 自動変数.)。


[ < ] [ > ]   [ << ] [] [ >> ]         [冒頭] [目次] [見出し] [ ? ]

6.2 変数の2つのフレーバー

GNUのmakeにおいて変数が値を持つには2つの方法があります。 それを変数の2つのフレーバーと呼びます。このフレーバーは、定義のされ方と 展開されるときのタイミングによって区別されます。

1つめのフレーバーは、再帰的に展開された変数で、‘=’( see section 変数の設定.)あるいはdefineディレクティブ( see section 変数のまったく同一の定義.)を使って定義されたものです。 指定する値はまったく同一にインストールされ、ほかの変数への参照を含む場合でも 代用されるときにはいつでも展開されます。このような展開を再帰的な展開 と呼びます。

たとえば、

 
foo = $(bar)
bar = $(ugh)
ugh = Huh?

all:;echo $(foo)

は、‘Huh?’というエコーを表示します。‘$(fo)’は‘$(bar)’に 展開され、さらに‘$(ugh)’に展開され、最終的に‘Huh?’になります。

この変数のフレーバーは別のバージョンのmakeだけでサポートされています。 その利点としては、

 
CFLAGS = $(include_dirs) -O
include_dirs = -Ifoo -Ibar

の例で意図されていることは、‘CFLAGS’がコマンドに展開されるとき、 ‘-Ifoo -Ibar -O’と展開されます。ここで不便なことは、変数の最後に 何かを付加できないことです。

 
CFLAGS = $(CFLAGS) -O

なぜなら、これは変数の展開において無限ループを引き起こしてしまうから です。(実際には、makeはそれと検知し、通知してくれます。)

別の不便な点は変数が展開されるときはつねに定義におけるファンクション (see section テキスト変換のためのファンクション.)への参照が 行なわれることです。これによってmakeは動作が遅くなり、さらに、 wildcardshellファンクションに対して予測不可能で コントロールできない結果をもたらします。

再帰的な変数の展開による問題と不便さを回避するには、もう1つのフレーバー、 すなわち単純な変数の展開というものがあります。

変数の単純な展開は、‘:=’(see section 変数の設定.)を 使用して定義します。単純に展開される変数の値は一度すべてに対して行なわれ、 ほかの変数とファンクションへの参照も定義された時点で行なわれます。 そして、その実際の値は記述したテキストの展開結果となります。 ほかの変数への参照は何も含まないため、

 
x := foo
y := $(x) bar
x := later

は、以下と同じになります。

 
y := foo bar
x := later

単純に展開された変数が参照されたとき、その値はまったく同じに代用されます。

ここには多少複雑な例があり、shellファンクションと連携した‘:=’の 使用について説明します(See section shellファンクション.)。 この例では、変数MAKELEVELの使用について示していて、下のレベルに値が 渡される際の変更について示しています。MAKELEVELについては、 See section サブのmakeへの変数の伝達.。

 
ifeq (0,${MAKELEVEL})
cur-dir   := $(shell pwd)
whoami    := $(shell whoami)
host-type := $(shell arch)
MAKE := ${MAKE} host-type=${host-type} whoami=${whoami}
endif

:=’の使用による利便性は、典型的なディレクトリを下るコマンドにおいて 以下のようになることです。

 
${subdirs}:
      ${MAKE} cur-dir=${cur-dir}/$@ -C $@ all

一般的に単純に展開される変数は、多くのプログラミング言語の変数のように 働くため、複雑なmakefileのプログラミングをより予測可能なものにします。 また、その変数の値自体(あるいは展開機能を使った値の処理によって)を使って 再定義を可能にしたり、展開機能をより効果的にすることが可能です( see section テキスト変換のためのファンクション.)。

変数の値に空白を使用することもできます。しかし、その空白は 変数参照の代用とファンクションコールのまえに破棄されます。このことは、 変数の参照によって保護される変数の値にスペースを含むことができる ということを示し、以下のように表わせます。

 
nullstring :=
space := $(nullstring) # end of the line

ここで、変数spaceの値はまさに1個のスペースです。コメントの ‘# end of the line’はたんにわかりやすくするためのものです。後続の 空白文字が変数の値と切り離せないために、行の終わりの1個の空白は 同じ効果を持ちます(読み取ることは困難ですが)。変数の値の終わりに スペースを置く場合は、意図を明らかにするという目的でコメントを 行の終わりに置くのがよいでしょう。反対に、変数の値の最後にスペースを 置きたくない場合には、以下のように、行の終わりに適当なコメントを 複数のスペースに続いて置いてはなりません。

 
dir := /foo/bar    # directory to put the frobs in

ここで、変数dirの値は‘/foo/bar ’(4つのスペースが 続いています)で、意図とは異なるでしょう。ここでは、‘$(dir)/file’ としたいはずです。

変数に対する別の割り当てを行なう演算子‘?=’があります。 これは条件変数割り当て演算子と呼ばれます。その理由は、変数が 定義されていない場合にだけ効果を持つからで、ステートメントは 以下のようになります。

 
FOO ?= bar

は以下と同じです (see section originファンクション.)。

 
ifeq ($(origin FOO), undefined)
  FOO = bar
endif

空の値をセットされた変数がすでに定義されていて、‘?=’は変数に セットされていないことに注意してください。


[ < ] [ > ]   [ << ] [] [ >> ]         [冒頭] [目次] [見出し] [ ? ]

6.3 変数参照の進んだ機能

この節では、より柔軟な変数の参照法のいくつかの方法について記述します。


[ < ] [ > ]   [ << ] [] [ >> ]         [冒頭] [目次] [見出し] [ ? ]

6.3.1 代用の参照

代用参照は、指定した変更による変数の値の代用を行ないます。この場合、 ‘$(var:a=b)’ (あるいは ‘${var:a=b}’)の書式を持ち、変数varの値を とり、すべての語の終わりのabの値で置き換えられ、文字列が 代用されます。

語の終わりという意味は、空白が続くかあるいは置き換えられる値の終わりの どちらかにaが現われることを意味しています。aが値に現われる ほかの場合は変更できません。たとえば、

 
foo := a.o b.o c.o
bar := $(foo:.o=.c)

のように、‘bar’を‘a.c b.c c.c’とセットします。 See section 変数の設定.。

代用参照は、実際にはpatsubst展開機能 (see section 文字列の代用と分析のファンクション.)の 短縮です。したがって、代用参照はほかのmakeのインプリメンテーションに 対する互換性のためにpatsubstと同じく提供されます。

別のタイプの代用参照はpatsubst機能のすべてを利用することができます。 書式は前と同じで、‘$(var:a=b)’ですが、aは 1個の‘%’文字を含まなければなりません。このケースは、 ‘$(patsubst a,b,$(var))’と同じです。 patsubstファンクションの説明については、 See section 文字列の代用と分析のファンクション.。

 
たとえば、

foo := a.o b.o c.o
bar := $(foo:%.o=%.c)

のように、‘bar’を‘a.c b.c c.c’とセットします。


[ < ] [ > ]   [ << ] [] [ >> ]         [冒頭] [目次] [見出し] [ ? ]

6.3.2 計算された変数名

計算された変数名は洗練されたmakefileプログラミングのためだけに必要な 複雑な概念です。ほとんどの場合これを用いる必要はなく、例外は名前に ドル記号を用いた変数を作る際に奇妙な結果を得る場合です。しかし、 すべてを理解したい、あるいは興味があるならば読み進んでください。

変数は、内部的に名前のなかで参照されます。これは計算された変数名、 あるいはネストされた変数の参照と呼ばれます。たとえば、

 
x = y
y = z
a := $($(x))

において、aは‘z’として定義され、‘$($(x))’の内部の ‘$(x)’は‘y’に展開されます。したがって‘$(y)’に展開される ‘$($(x))’は反対に‘z’に展開されます。ここで参照される変数の名前は 明示的ではありません。それは‘$(x)’の展開から計算されたものです。また ‘$(x)’の参照は外部からの参照においてネストしています。

前記の例では、2つのレベルのネストでした。しかし、どんな数のレベルでも 可能です。3つのレベルの場合の例を示します。

 
x = y
y = z
z = u
a := $($($(x)))

もっとも奥のレベルの‘$(x)’は‘y’に展開され、したがって、 ‘$($(x))’は‘$(y)’に展開され、反対に‘z’に展開されます。 そして、‘$(z)’は‘u’となります。

変数名による変数の再帰的展開に対する参照は通常の方式で再展開されます。 たとえば、

 
x = $(y)
y = z
z = Hello
a := $($(x))

この場合、aを‘Hello’として定義しています。したがって ‘$($(x))’は‘$($(y))’となり、‘$(z)’となって最後には ‘Hello’となります。

ネストされた変数の参照はほかの参照と同様に (see section テキスト変換のためのファンクション.)、修正された参照や 呼び出されたファンクションをも含んでいる場合があります。たとえば、 substファンクション (see section 文字列の代用と分析のファンクション.)を 使用する例として、

 
x = variable1
variable2 := Hello
y = $(subst 1,2,$(x))
z = y
a := $($($(z)))

は、aを‘Hello’として定義しています。このネストの記述の仕方は 複雑で、誰でもこう記述したいかどうかは疑問としても、これはきちんと 動作します。‘$($($(z)))’が‘$($(y))’に展開され、 ‘$($(subst 1,2,$(x)))’に展開されます。xからの値 ‘variable1’を得て、‘variable2’への代用によって変更が 加えられます。結果的に‘$(variable2)’となり、値が‘Hello’である 変数の参照となります。

計算された変数名は単一の変数の参照からなっているわけではありません。 複数の変数の参照からなることもできますし、ある不変のテキストである場合も あります。たとえば、

 
a_dirs := dira dirb
1_dirs := dir1 dir2
a_files := filea fileb
1_files := file1 file2
ifeq "$(use_a)" "yes"
a1 := a
else
a1 := 1
endif
ifeq "$(use_dirs)" "yes"
df := dirs
else
df := files
endif

dirs := $($(a1)_$(df))

の場合は、dirsに同じ値としてuse_ause_dirsのセットに 応じて、a_dirs1_dirsa_filesあるいは 1_filesを与えます。

また、計算された変数名は代用参照においても使用されます。

 
a_objects := a.o b.o c.o
1_objects := 1.o 2.o 3.o

sources := $($(a1)_objects:.o=.c)

は、sourcesa1の値に応じて、‘a.c b.c c.c’あるいは ‘1.c 2.c 3.c’として定義します。

ネストされた変数の参照の利用における唯一の制限は、呼び出される ファンクションの名前の一部を指定できないことです。これは、 ネストされた参照の展開が行なわれるまえに、認知されているファンクションの 名前に対するテストが行なわれるためです。

 
ifdef do_sort
func := sort
else
func := strip
endif
bar := a d b g q c
foo := $($(func) $(bar))

の場合は、‘foo’に対してsortあるいはstripファンクションの 引数として‘a d b g q c’が与えられるのではなく、変数 ‘sort a d b g q c’あるいは‘strip a d b g q c’の値が 与えられようとします。この制限は、よいアイデアがあれば将来的に なくすることができるでしょう。

また、変数割り当ての左側あるいはdefineディレクティブにおいて、 この計算された変数名を使用することができます。

 
dir = foo
$(dir)_sources := $(wildcard $(dir)/*.c)
define $(dir)_print
lpr $($(dir)_sources)
endef

この例では、変数‘dir’、‘foo_sources’と‘foo_print’を 定義しています。

ここで注意してほしいのは、ネストされた変数参照再帰的に 展開された変数(see section 変数の2つのフレーバー.)はmakefileの プログラミングでは複雑な方法で同時に使用される場合があるものの、 両者はまったく異なるということです。


[ < ] [ > ]   [ << ] [] [ >> ]         [冒頭] [目次] [見出し] [ ? ]

6.4 変数の値の取得の仕方

変数はいくつかの異なる方法で値を取得できます。


[ < ] [ > ]   [ << ] [] [ >> ]         [冒頭] [目次] [見出し] [ ? ]

6.5 変数の設定

makefileから変数をセットするには、行の先頭から変数名に続いて‘=’ あるいは‘:=’を記述します。‘=’あるいは‘:=’のあとは変数の 値となります。たとえば、

 
objects = main.o foo.o bar.o utils.o

では、変数名objectsを定義しています。変数名の隣のスペースと ‘=’のあとのスペースは無視されます。

=’で定義された変数は再帰的に展開される変数です。また‘:=’で 定義された変数は単純に展開される変数です。これらの定義はその定義が 作られるまえに展開される変数の参照を含んでいます。 See section 変数の2つのフレーバー.。

変数名はファンクションと変数の参照を含んでいます。そしてそれらは使用される 実際の変数名をみつけるための行が読み込まれるときに展開されます。

変数の値の長さは、コンピュータのスワップ領域の量を除けば制限はありません。 変数の定義が長い場合にはバックスラッシュを適当な位置に置くことにより複数の 行に分割することが賢明です。このことはmakeの機能に影響を与えず、 可読性のよさにつながります。

設定を行なわない限り、ほとんどの変数名は空の文字列を値として持っていると みなされますが、いくつかの変数はあらかじめ組み込まれた空でない初期値を 持っていて、その変更もできます (see section 暗黙のルールで使用される変数.)。 いくつかの特別な変数は、自動的にそれぞれのルールに従って新しい値に セットされます。これらを自動変数と呼びます (see section 自動変数.)。

すでに設定されていない場合にだけ値をセットしようとする場合、‘=’の かわりに略式演算子‘?=’を使用することができます。変数‘FOO’の2つの 設定は同じものです(see section originファンクション.)。

 
FOO ?= bar

は、以下と同じです。

 
ifeq ($(origin FOO), undefined)
FOO = bar
endif

[ < ] [ > ]   [ << ] [] [ >> ]         [冒頭] [目次] [見出し] [ ? ]

6.6 変数へのテキストの追加

すでに定義されている変数の値にさらにテキストを追加することが有益な場合が しばしばあります。その場合、例のように‘+=’を含む行を使用します。

 
objects += another.o

この場合、変数objectsの値を取得していて、テキスト‘another.o’を 追加しています。したがって、

 
objects = main.o foo.o bar.o utils.o
objects += another.o

は、objectsを‘main.o foo.o bar.o utils.o another.o’に セットしています。

+=’を使用するのは、

 
objects = main.o foo.o bar.o utils.o
objects := $(objects) another.o

に似ていますが、より複雑な値を用いる場合には重要となります。

事前に定義されていない変数が問題になる場合、‘+=’は通常の‘=’ のように働きます。つまり、再帰的な展開を行なう変数を定義します。 しかしながら、事前に定義がある場合は、‘+=’の動作は最初に どのフレーバーで定義されているかに依存します。 2つの変数のフレーバーについての説明は、 See section 変数の2つのフレーバー.。

+=’によって変数の値に追加する場合、変数の初期定義のテキストを 含むかのようにmakeは働きます。最初に‘+=’で定義を行なう場合、 ‘+=’は単純展開の変数にテキストを追加し、‘:=’のように古い値に 追加をするまえに新しいテキストを展開します(‘:=’の説明については、 see section 変数の設定.)。実際には以下のようになります。

 
variable := value
variable += more

はまったく以下と同じです。

 
variable := value
variable := $(variable) more

一方では、最初に‘=’を使用して再帰的展開をするように定義した変数に ‘+=’を使用する場合、makeは少しだけ違う動作をします。 再帰的展開を定義する場合を思い出してください。変数やファンクションの 参照に対してセットした値をmakeはただちに展開はしません。 新しい変数(see section 変数の2つのフレーバー.)に参照を 行なう際に、テキストをまったく同じ状態で格納するかわりに、 あとで展開するために変数とファンクションの参照を保存します。再帰的展開を させる変数について‘+=’を使用する場合は、指定したテキストを makeが追加する未展開のテキストに対して行なうことになります。

 
variable = value
variable += more

は、ほぼ以下と同じです。

 
temp = value
variable = $(temp) more

ここでは、tempと呼ばれる変数は例外的に定義していません。 ここで重要となるのは、変数の古い値が参照を含む場合に問題になることです。 共通の例として以下をあげます。

 
CFLAGS = $(includes) -O
…
CFLAGS += -pg # enable profiling

最初の行では、別の変数includeへの参照に用いられるCFLAGSを 定義しています。(CFLAGSはCのコンパイルの際のルールに使用されます。 see section 暗黙のルールのカタログ.。) 定義に対する‘=’の使用はCFLAGSを再帰的展開変数にします。 ‘$(includes) -O’はmakeCFLAGSの定義を処理する際に 展開しないことを意味しています。したがってincludesはその値が 有効になるまで、定義の必要はなく、CLAGSに参照が 及ぶ直前にだけ定義されればよいのです。‘+=’を使用せずに、 CFLAGSの値に追加するには、以下のように記述してしまいます。

 
CFLAGS := $(CFLAGS) -pg # enable profiling

しかし、この方法は望むものに近いのですが、完全ではありません。‘:=’を 使用することはCFLAGSを単純展開の変数として再定義します。つまり、 makeはテキスト‘$(CFLAGS) -pg’をその変数をセットするまえに 展開します。もし、includesがまだ定義されていない場合、 ‘ -O -pg’を得るため、includesの定義は効果を 持たなくなります。反対に、‘+=’の使用によってCFLAGS未展開の値‘$(includes) -O -pg’にセットします。したがって、 includesに対する参照を保存するため、あとの時点で定義を得られるならば、 ‘$(CFLAGS)’はその値をまだ使い続けます。


[ < ] [ > ]   [ << ] [] [ >> ]         [冒頭] [目次] [見出し] [ ? ]

6.7 overrideディレクティブ

コマンドの引数で変数がセットされた場合、makefileのなかでの通常の割り当ては 無視されます(see section 変数のオーバーライド.)。しかし、コマンドの 引数でセットされたにもかかわらずmakefileのなかに変数をセットしたい場合には、 overrideディレクティブを使用することができ、 以下のような行となります。

 
override variable = value

あるいは、

 
override variable := value

コマンド行で定義された変数にさらにテキストを追加するには、以下の例を使います。

 
override variable += more text

See section 変数へのテキストの追加.。

overrideディレクティブはmakefileとコマンド引数のあいだの論争が エスカレートしているあいだは使用されませんでした。コマンド引数によって ユーザーの指定した値に変更と追加が可能なようにされたのです。

たとえば、Cコンパイラを実行する際に‘-g’スイッチをつねに使用するとします。 しかしユーザーがコマンド引数としてほかのスイッチを指定するのを許可したいと 思う場合、このoverrideディレクティブを使用します。

 
override CFLAGS += -g

また、overrideディレクティブをdefineディレクティブとともに 使用することもできます。

 
override define foo
bar
endef

[ < ] [ > ]   [ << ] [] [ >> ]         [冒頭] [目次] [見出し] [ ? ]

6.8 変数のまったく同一の定義

変数の値のセットのもう1つ別の方法は、defineディレクティブを 使用する方法です。このディレクティブは通常のシンタックスとは異なり、 改行文字を値に含みます。これはコマンドのシーケンスの定義をするのに便利です (see section コマンドの組み合わせの定義.)。

defineディレクティブは同じ行で変数名だけがそのあとに続きます。そして 変数の値は次の行に現われます。値の終わりには、endefという語だけの行が 置かれます。シンタックスの違いは別として、defineは‘:=’ とよく似た働き、すなわち再帰的展開の変数を作成します (see section 変数の2つのフレーバー.)。 変数名はファンクションと変数への参照を含み、使用される実際の変数名を 発見するためにディレクティブが読み込まれる際に展開されます。

 
define two-lines
echo foo
echo $(bar)
endef

通常の割り当てにおける変数の値は改行文字を含みませんが、define における値の行は改行文字で区切られ、変数の値になります(ただし、 endefよりもまえで、値の一部とみなされない最後の改行文字を除きます)。

前記の例は機能的には以下と同一です。

 
two-lines = echo foo; echo $(bar)

セミコロンで区切られた2つのコマンドは2つの別のシェルコマンドのようにふるまい ます。しかしながら、気をつけなければならないのは、2つに別れた行を使う場合は makeはシェルを2回呼び出し、それぞれ独立したサブシェルを個々の行で 実行するということです。See section コマンド実行.。

また、コマンド行での変数定義よりもdefineによる変数定義を 優先したい場合は、defineとともにoverrideディレクティブを 使用することができます。

 
override define two-lines
foo
$(bar)
endef

See section overrideディレクティブ.。


[ < ] [ > ]   [ << ] [] [ >> ]         [冒頭] [目次] [見出し] [ ? ]

6.9 環境(変数)からの変数の取得

makeのなかの変数はmakeが動作している環境変数から取得することも できます。makeがその起動を監視している環境変数は、その同じ名前と値で makeの変数になります。ただし、makefileで明示的に割り当てられたものや コマンドの引数として与えられたものは環境変数からの値をオーバーライドします。 (‘-e’フラグが指定されている場合、環境変数がmakefileのなかの変数を オーバーライドしますが、実際には推奨しません。 See section オプションのサマリー.。 しかし、この手法はあまりすすめられるものではありません。)

したがって、環境設定でCFLAGS変数をセットしている場合、C言語の コンパイルにおいて希望するコンパイラのスイッチを使用することができます。 このことは、標準あるいは従来の意味付けを持つ変数に対しては安全な方法です。 なぜならば、makefileがそれらをほかのことに使うことはないことが わかっているからです。(しかし、実はこのことは信頼できないことです。 makefileによってはCFLAGSを明示的に設定するため、環境変数の影響が まったくないこともあるからです。)

makeが再帰的に呼び出される場合、外部の呼び出しで定義された変数は 環境を通して内部の呼び出しに渡されます( see section makeの再帰的用法.)。デフォルトでは、 環境変数またはコマンド行からもたらされた変数のみが再帰的な呼び出しにおいて 渡されます。また、exportディレクティブを使用してほかの変数を 渡すこともできます。詳細については、 See section サブのmakeへの変数の伝達.。

環境からの変数のほかの使用は推奨されません。その理由は、外部から設定された makefileの環境変数に対するファンクションに依存することは、同一の makefileでも異なったユーザーに異なった結果をもたらすため賢明とは いえないからです。このことはmakefileの目的に反することといえます。

そのような問題はとくに変数SHELLについて見受けられます。それは通常、 対話型のシェルがユーザーの選択で決められ環境変数に設定されているからです。 このことがmakeに対しては非常に望ましくないことになります。したがって、 makeSHELLの環境変数を無視するようになっています(ただし、 MS-DOSとMS-Windowsでは通常SHELLがセットされていません。 See section コマンド実行.)。


[ < ] [ > ]   [ << ] [] [ >> ]         [冒頭] [目次] [見出し] [ ? ]

6.10 ターゲット固有の変数の値

makeのなかの変数の値は通常はグローバルです。すなわち(無論、リセットさ れない限り)評価される位置を問わず同じです。ただし、自動変数だけは例外です (see section 自動変数.)。

ほかの例外は、ターゲット固有の変数の値です。この機能を使用すると makeが現在ビルドをしているターゲットの同じ変数に異なった値を 定義することができます。自動変数の場合は、ターゲットのコマンドスクリプトの 文脈の中だけでそれらの値は有効です(ほかのターゲット固有の割り当てにおいて)。

ターゲット固有の変数の値のセットは以下のようにします。

 
target … : variable-assignment

あるいは以下のようになります。

 
target … : override variable-assignment

複数のターゲットの値は、ターゲットリストの個々のメンバーに対する変数の値を 作成します。

変数割り当てはいろいろな割り当ての有効な書式を取ることができます。再帰的 (‘=’)、静的(‘:=’)、追加(‘+=’)あるいは条件(‘?=’) といったものです。変数割り当てに現われるすべての変数はターゲットの 文脈のなかで評価されます。したがって、事前に定義されたターゲット固有の 変数の値はすべて有効となります。注意しなければならないのは、この変数の 値はいかなるグローバルな変数の値とも実際には別個のものであることで、 同一のフレーバーである必要はありません。

ターゲット固有の変数はmakefileのほかの変数と同じプライオリティを持ちますが、 コマンド行で提供される変数(そして、‘-e’オプションのある場合の環境に おいて)は優先します。overrideディレクティブの指定はターゲット固有の 変数の値を優先します。

ターゲット固有の変数にはもう1つ特別な特徴があります。ターゲット固有の 変数を定義する際、この変数の値はこのターゲットのすべての必要条件で有効 となります(その必要条件が自身のターゲット固有の変数の値をオーバーライド しない限り)。したがって、ステートメントの例は以下のようになります。

 
prog : CFLAGS = -g
prog : prog.o foo.o bar.o

上記の例では、‘prog’に対するコマンドスクリプトにおいて‘-g’の CFLAGSをセットしています。しかし、それによって‘prog.o’、 ‘foo.o’と‘bar.o’とそれらの必要条件のすべてを作成しようとします。


[ < ] [ > ]   [ << ] [] [ >> ]         [冒頭] [目次] [見出し] [ ? ]

6.11 パターン固有の変数の値

ターゲット固有の変数の値 (see section ターゲット固有の変数の値.)だけでなく、 GNUのmakeはパターン固有の変数の値もサポートします。この場合、 指定されたパターンにマッチするいかなるターゲットに対しても変数の 定義がされます。この方法で定義された変数は、ターゲット固有の変数が 明示的に定義されたあとで、かつ親のターゲットに対してターゲット固有の 変数が定義されるまえにサーチされます。

パターン固有の変数の値のセットは以下のようになります。

 
pattern … : variable-assignment

あるいは、以下のようになります。

 
pattern … : override variable-assignment

上記の例ではパターンは%-patternです。ターゲット固有の変数の値があるため、 複数のパターンの値が個々のパターンに対してのパターン固有の変数の値を 作成します。また変数の割り当てはいろいろな割り当ての書式を取ることが 可能です。ただし、overrideが指定されていない限り、コマンド行での 変数のセットが優先されます。

たとえば、

 
%.o : CFLAGS = -O

は、CFLAGSを‘-o’の値をパターン%.oにマッチするすべての ターゲットに対して割り当てます。


[ << ] [ >> ]           [冒頭] [目次] [見出し] [ ? ]

この文書は新堂 安孝によって2009年9月22日texi2html 1.82を用いて生成されました。