あなたはそうすることができます。これが、変数を定義解除するために使用するターゲットの名前であると仮定して、その方法を次に示しundef
ます。
FOO:=foo
ifeq (undef,$(filter undef,$(MAKECMDGOALS)))
override undefine FOO
endif
.PHONY: all
all:
echo $(FOO) '($(origin FOO))'
.PHONY: undef
undef: $(if $(filter-out undef,$(MAKECMDGOALS)),,$(.DEFAULT_GOAL)))
make
使用される要素の説明:
MAKECMDGOALS
make
が呼び出されたゴールを含む定義済みの読み取り専用変数です。これを使用して、make
が で呼び出されたかどうかを確認しundef
ます。
.DEFAULT_GOAL
デフォルトの目標を含む事前定義された変数です。明示的に設定されていない場合は、最初の目標 (この場合は ) に設定されall
ます。
ifeq
...endif
で条件付き部分を許可しますMakefile
。
- この
$(filter pattern,list)
関数は、list
と一致するすべての要素を返しますpattern
。したがって、がその目標の 1 つとしてmake
呼び出された場合はになり、それ以外の場合は空の文字列になります。undef
$(filter undef,$(MAKECMDGOALS))
undef
$(filter-out pattern,list)
関数は の反対です$(filter key,list)
。list
に一致しないすべての要素を返しますpattern
。そのため、 only でmake
呼び出された場合は空の文字列になります。それ以外の場合は、コマンド ラインで指定されたすべてのゴールのリストになります。undef
$(filter-out undef,$(MAKECMDGOALS))
undef
undefine
変数を未定義にします。
override
コマンドラインで渡された場合でも、変数を変更します。override
使用する意味があるかどうかは、ユース ケースに応じて決定する必要があります。
- が true の場合、関数は
$(if cond,then[,else])
戻ります。それ以外の場合(または が存在しない場合は空の文字列)。空でない文字列は true、空の文字列は false です。then
cond
else
else
そのため、コマンドラインで指定されたFOO
場合、Makefile は未定義になります。undef
の「魔法の」依存関係により、 がコマンド ラインで指定された唯一のゴールでundef
ある場合、デフォルトのゴール (この例では ) に依存して実行されるようになります。これは、変数を未定義にすることを除いて、が同様に動作することを確認するためです。undef
all
make undef
make
警告: このようなMakefile
の動作は混乱を招く可能性があります。CPPFLAGS+=-DNDEBUG
このメカニズムを使用して、指定された場合に除外する Makefile を想像してくださいdebug
。と が に対して異なる出力をmake debug all
作成make all
するのは予想外です。と比較して追加の出力が作成されることが期待されます。主な期待は、コマンドラインに他の目標が追加されていても、常に同じように動作することです。スタイルのメカニズムを使用してそのようなメカニズムを実装することをお勧めします。make all
make debug all
make all
make all
configure
(出典: GNU make に関する私の未発表の本から。)