あなたはそうすることができます。これが、変数を定義解除するために使用するターゲットの名前であると仮定して、その方法を次に示し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 です。thencondelseelse
そのため、コマンドラインで指定されたFOO場合、Makefile は未定義になります。undef
の「魔法の」依存関係により、 がコマンド ラインで指定された唯一のゴールでundefある場合、デフォルトのゴール (この例では ) に依存して実行されるようになります。これは、変数を未定義にすることを除いて、が同様に動作することを確認するためです。undefallmake undefmake
警告: このようなMakefileの動作は混乱を招く可能性があります。CPPFLAGS+=-DNDEBUGこのメカニズムを使用して、指定された場合に除外する Makefile を想像してくださいdebug。と が に対して異なる出力をmake debug all作成make allするのは予想外です。と比較して追加の出力が作成されることが期待されます。主な期待は、コマンドラインに他の目標が追加されていても、常に同じように動作することです。スタイルのメカニズムを使用してそのようなメカニズムを実装することをお勧めします。make allmake debug allmake allmake allconfigure
(出典: GNU make に関する私の未発表の本から。)