[解決済み] 変数が設定されていない場合、makefileを中断させるには?
質問
makefile の変数が設定されていない、または値がないことに基づいて make/makefile の実行を中断するにはどうすればよいですか?
これを思いついたのですが、呼び出し側が明示的にターゲットを実行しない場合のみ動作します(つまり、呼び出し側で
make
のみ)。
ifeq ($(MY_FLAG),)
abort: ## This MUST be the first target :( ugly
@echo Variable MY_FLAG not set && false
endif
all:
@echo MY_FLAG=$(MY_FLAG)
このようなものがあればいいと思うのですが、makeのマニュアルには何も書いてありませんでした。
ifndef MY_FLAG
.ABORT
endif
解決方法は?
TL;DR
: を使用します。
error
機能
:
ifndef MY_FLAG
$(error MY_FLAG is not set)
endif
行はインデントされてはならないことに注意してください。より正確には、これらの行の前にタブを入れてはいけません。
一般的な解決策
多くの変数をテストする場合は、そのための補助関数を定義しておくとよいでしょう。
# Check that given variables are set and all have non-empty values,
# die with an error otherwise.
#
# Params:
# 1. Variable name(s) to test.
# 2. (optional) Error message to print.
check_defined = \
$(strip $(foreach 1,$1, \
$(call __check_defined,$1,$(strip $(value 2)))))
__check_defined = \
$(if $(value $1),, \
$(error Undefined $1$(if $2, ($2))))
そして、その使い方は以下の通りです。
$(call check_defined, MY_FLAG)
$(call check_defined, OUT_DIR, build directory)
$(call check_defined, BIN_DIR, where to put binary artifacts)
$(call check_defined, \
LIB_INCLUDE_DIR \
LIB_SOURCE_DIR, \
library path)
この場合、次のようなエラーが出力されます。
Makefile:17: *** Undefined OUT_DIR (build directory). Stop.
注意事項
実際のチェックはここで行われます。
$(if $(value $1),,$(error ...))
の挙動を反映しています。
ifndef
条件付きで、空の値に定義された変数も "undefined"と見なされるようになります。しかし、これは単純な変数と明示的に空の再帰的変数にのみ当てはまります。
# ifndef and check_defined consider these UNDEFINED:
explicitly_empty =
simple_empty := $(explicitly_empty)
# ifndef and check_defined consider it OK (defined):
recursive_empty = $(explicitly_empty)
コメントで @VictorSergienko が提案したように、少し異なる動作が望まれるかもしれません。
$(if $(value $1)
は、値が空でないかどうかをテストします。それは時々 変数が空の値で定義されていればOK . 私なら$(if $(filter undefined,$(origin $1)) ...
そして
さらに ディレクトリであり、それが存在しなければならない場合 チェックを実行するときに
$(if $(wildcard $1))
. しかし、別の関数になる。
ターゲット別チェック
また、特定のターゲットが呼び出された場合にのみ変数を要求できるように、解決策を拡張することも可能である。
$(call check_defined, ...)
レシピの中から
チェックをレシピに移動させるだけです。
foo :
@:$(call check_defined, BAR, baz value)
先頭の
@
記号はコマンドエコーをオフにし
:
は実際のコマンドで、シェルの
ノーオペレーションスタブ
.
ターゲット名の表示
は
check_defined
関数を改良して、ターゲット名 (
$@
という変数がある)。
check_defined = \
$(strip $(foreach 1,$1, \
$(call __check_defined,$1,$(strip $(value 2)))))
__check_defined = \
$(if $(value $1),, \
$(error Undefined $1$(if $2, ($2))$(if $(value @), \
required by target `$@')))
これで、チェックに失敗しても、きれいにフォーマットされた出力が得られるようになりました。
Makefile:7: *** Undefined BAR (baz value) required by target `foo'. Stop.
check-defined-MY_FLAG
特殊目標
個人的には、上記のようなシンプルでわかりやすい解決策を使いたいところです。しかし、例えば この答え は、実際のチェックを実行するために特別なターゲットを使用することを提案しています。これを一般化して、ターゲットを暗黙のパターンルールとして定義してみるのもよいでしょう。
# Check that a variable specified through the stem is defined and has
# a non-empty value, die with an error otherwise.
#
# %: The name of the variable to test.
#
check-defined-% : __check_defined_FORCE
@:$(call check_defined, $*, target-specific)
# Since pattern rules can't be listed as prerequisites of .PHONY,
# we use the old-school and hackish FORCE workaround.
# You could go without this, but otherwise a check can be missed
# in case a file named like `check-defined-...` exists in the root
# directory, e.g. left by an accidental `make -t` invocation.
.PHONY : __check_defined_FORCE
__check_defined_FORCE :
使用方法
foo :|check-defined-BAR
は
check-defined-BAR
がリストアップされます。
注文制
(
|...
) の前提条件となる。
長所
- (間違いなく)よりきれいな構文
短所
- カスタムエラーメッセージの指定ができない
-
実行中
make -t
(参照 レシピの実行に代えて ) は、ルートディレクトリをたくさんのcheck-defined-...
ファイルです。これは、パターン・ルールである を宣言することはできません。.PHONY
.
これらの制限は、いくつかの方法を用いて克服することができると思います。
eval
マジックと
二次展開
のハック、その価値があるかどうかはわからないけど。
関連
-
[解決済み】makefile:4。*** missing separator. 停止する
-
[解決済み】makeコマンドのエラー makefile:18: *** missing separator. 停止する [重複]。
-
[解決済み】Makefileの中の.PHONYの目的は何ですか?
-
[解決済み】Makeエラー:セパレータがない
-
[解決済み】なぜmakeはターゲットが最新だと思うのですか?
-
[解決済み] makefileの "all "は何の略ですか?
-
[解決済み] GNU Makefile の変数割り当て =, ?=, :=, += の違いは何ですか?
-
[解決済み] makefile の記号 $@ と $< はどういう意味ですか?
-
[解決済み】makefileに'cd'コマンドを記述するには?
-
[解決済み] 別のMakefileからMakefileを呼び出すには?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] ターゲットが指定されていない場合、「make」アプリはどのようにしてビルドするデフォルトターゲットを知るのですか?
-
[解決済み] make clean、make clobber、make distclean、make mrproper、make realcleanの違いは何ですか?
-
undefinedmakefile *** セパレータがありません。
-
[解決済み] makefile で条件規則を使用する
-
[解決済み] GNU Bashの組み込み関数 : (コロン) は何のためにあるのですか?
-
[解決済み] Makefile.amとMakefile.inとは何ですか?
-
[解決済み】OSがmakefileを検出する
-
[解決済み] ってなんですか?(アットマークコロン)はMakefileの中でどういう意味ですか?
-
[解決済み] Makefileの変数が前提条件として設定されていることを確認する方法は?
-
[解決済み] makefileで別のターゲットを実行する