コマンドラインからMakefileに引数を渡す方法は?
私ができることを理解しています
$ make action VAR="value"
$ value
と Makefile
VAR = "default"
action:
@echo $(VAR)
次の動作を取得するにはどうすればよいですか?
$ make action value
value
?
いかがですか
$make action value1 value2
value1 value2
コマンドラインからMakefileに引数を渡す方法は?
私ができることを理解しています
$ make action VAR="value"
$ value
と Makefile
VAR = "default"
action:
@echo $(VAR)
次の動作を取得するにはどうすればよいですか?
$ make action value
value
?
いかがですか
$make action value1 value2
value1 value2
回答:
おそらくこれを行うべきではありません。Makeの動作の基本的なパターンを破っています。しかし、ここにあります:
action:
@echo action $(filter-out $@,$(MAKECMDGOALS))
%: # thanks to chakrit
@: # thanks to William Pursell
編集:
最初のコマンドを説明するには、
$(MAKECMDGOALS)
コマンドラインでスペルアウトされた「ターゲット」のリストです。たとえば、「action value1 value2」
$@
ルールのターゲットの名前(この場合は「アクション」)の自動変数です。
filter-out
リストからいくつかの要素を削除する関数です。したがって、$(filter-out bar, foo bar baz)
戻り値foo baz
(より微妙な場合がありますが、ここでは微妙な必要はありません)
これらをまとめて、$(filter-out $@,$(MAKECMDGOALS))
「action」以外のコマンドラインで指定されたターゲットのリストを返します。「value1 value2」の場合もあります。
$(shell echo $(MAKECMDGOALS) | sed 's!^.* $@ !!')
前にすべてのターゲットを省略し、単に引数として以下の点を考慮しますmake target1 target2 action value1 value2
%:
を試してみまし@:
たが、それらの「ディレクティブ」(またはそれらが呼び出されたもの)の機能に関する情報を見つけることができません。説明していただけますか?
%:
とからなる部分@:
がルールです。ターゲット名%
は、それがすべてに一致するルールであることを意味します。つまり、Makeは、ビルドするように指示したものをビルドする他の方法を見つけることができない場合、そのルールを実行します。これ@:
はレシピです。:
手段は何もしない、と@
手段が黙ってそれを行います。
%:
でした。実際に% :
は、ワイルドカードタイプのターゲット名でした。@:
しかし、そのマニュアルページには何も表示されていません...「何もしない」ルールは単に;
ターゲット指定の後にあることを示唆しているので、% : ;
「ワイルドカードは-なし」ルール?
filter-out
アクションがコマンドラインで指定されたターゲットの依存関係である場合、コマンドラインで$@
呼び出された元の引数ではなく、依存関係の名前に設定されるため、機能しません。その代わりに、私が割り当てMAKECMDGOALS
シェル配列に、次いで、最初の要素削除:@ args=($(MAKECMDGOALS)); args=("$${args[@]:1}")
@Betaに基づく一般的な作業ソリューションは次のとおりです
私はSHELL=/bin/bash
Makefileの上でGNU Make 4.1を使用しているので、YMMVです!
これにより、追加の引数を受け入れることができます(エラーをスローするのではなく、一致しないジョブを取得しても何もしません)。
%:
@:
そして、これは私たちのために引数を取得するマクロです:
args = `arg="$(filter-out $@,$(MAKECMDGOALS))" && echo $${arg:-${1}}`
これはこれを呼ぶかもしれない仕事です:
test:
@echo $(call args,defaultstring)
結果は次のようになります。
$ make test
defaultstring
$ make test hi
hi
注意!Maketoolsのニュアンスがなければ、makeと同様に機能するbashパターンである「タスクファイル」を使用した方がよい場合があります。https://github.com/adriancooney/Taskfileを参照してください
tab
に@echo
、ではなく、前にあることを確認してくださいspace
。
はるかに簡単なアプローチ。タスクを考えてみましょう:
provision:
ansible-playbook -vvvv \
-i .vagrant/provisioners/ansible/inventory/vagrant_ansible_inventory \
--private-key=.vagrant/machines/default/virtualbox/private_key \
--start-at-task="$(AT)" \
-u vagrant playbook.yml
これを呼び出したいときは、次のように実行します。
AT="build assets" make provision
あるいは単に:
make provision
この場合AT
は空の文字列です
これをしようとしないでください
$ make action value1 value2
代わりにスクリプトを作成します。
#! /bin/sh
# rebuild if necessary
make
# do action with arguments
action "$@"
これを行います:
$ ./buildthenaction.sh value1 value2
より多くの説明については、なぜこれを行うのか、makefileハッカーの警告は、非常に類似しているが重複していないように見える別の質問への私の回答を読む理由です:"make run"に引数を渡す