コマンドラインからMakefileに引数を渡す方法は?


109

コマンドラインからMakefileに引数を渡す方法は?

私ができることを理解しています

$ make action VAR="value"
$ value

Makefile

VAR = "default"
action:
    @echo $(VAR)

次の動作を取得するにはどうすればよいですか?

$ make action value
value

いかがですか

$make action value1 value2
value1 value2


回答:


212

おそらくこれを行うべきではありません。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」の場合もあります。


1
$(shell echo $(MAKECMDGOALS) | sed 's!^.* $@ !!')前にすべてのターゲットを省略し、単に引数として以下の点を考慮しますmake target1 target2 action value1 value2
Evgeniy Generalov

1
私の無知を許してください。私はグーグル%:を試してみまし@:たが、それらの「ディレクティブ」(またはそれらが呼び出されたもの)の機能に関する情報を見つけることができません。説明していただけますか?
Jon

15
@ジョン:マニュアルはこちらです。%:とからなる部分@:ルールです。ターゲット名%は、それがすべてに一致するルールであることを意味します。つまり、Makeは、ビルドするように指示したものをビルドする他の方法を見つけることができない場合、そのルールを実行します。これ@:レシピです。:手段は何もしない、と@手段が黙ってそれを行います。
2014

ありがとう。私はそのマニュアルを読んでいて、最初は考慮していません%:でした。実際に% :は、ワイルドカードタイプのターゲット名でした。@:しかし、そのマニュアルページには何も表示されていません...「何もしない」ルールは単に;ターゲット指定の後にあることを示唆しているので、% : ;「ワイルドカードは-なし」ルール?
Jon

1
filter-outアクションがコマンドラインで指定されたターゲットの依存関係である場合、コマンドラインで$@呼び出された元の引数ではなく、依存関係の名前に設定されるため、機能しません。その代わりに、私が割り当てMAKECMDGOALSシェル配列に、次いで、最初の要素削除:@ args=($(MAKECMDGOALS)); args=("$${args[@]:1}")
Gingi

18

@Betaに基づく一般的な作業ソリューションは次のとおりです

私はSHELL=/bin/bashMakefileの上で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
アブドラアルマルフ-Tuhin

11

はるかに簡単なアプローチ。タスクを考えてみましょう:

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は空の文字列です


-2

これをしようとしないでください

$ make action value1 value2

代わりにスクリプトを作成します。

#! /bin/sh
# rebuild if necessary
make
# do action with arguments
action "$@"

これを行います:

$ ./buildthenaction.sh value1 value2

より多くの説明については、なぜこれを行うのか、makefileハッカーの警告は、非常に類似しているが重複していないように見える別の質問への私の回答を読む理由です:"make run"に引数を渡す

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.