Как передать аргумент в Makefile из командной строки? - PullRequest
89 голосов
/ 08 июня 2011

Как передать аргумент в Makefile из командной строки?

Я понимаю, что могу сделать

$ make action VAR="value"
$ value

с Makefile

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

Как мне получитьследующее поведение?

$ make action value
value

?

Как насчет

$make action value1 value2
value1 value2

Ответы [ 3 ]

176 голосов
/ 08 июня 2011

Вы, вероятно, не должны этого делать; вы нарушаете основную схему того, как работает Make. Но вот оно:

action:
        @echo action $(filter-out $@,$(MAKECMDGOALS))

%:      # thanks to chakrit
    @:    # thanks to William Pursell

EDIT:
Чтобы объяснить первую команду,

$(MAKECMDGOALS) - это список «целей», указанных в командной строке, например, "действие значение1 значение2".

$@ является автоматической переменной для имени цели правила, в данном случае «действие».

filter-out - это функция, которая удаляет некоторые элементы из списка. Так что $(filter-out bar, foo bar baz) возвращает foo baz (это может быть более тонким, но нам здесь не нужна тонкость).

Соедините их вместе и $(filter-out $@,$(MAKECMDGOALS)) вернет список целей, указанных в командной строке, кроме «action», который может быть «value1 value2».

9 голосов
/ 30 октября 2017

Вот общее рабочее решение на основе @ Beta's

Я использую GNU Make 4.1 с SHELL=/bin/bash поверх моего Makefile, поэтому YMMV!

Это позволяет нам принимать дополнительные аргументы(ничего не делая, когда мы получаем работу, которая не соответствует, вместо того, чтобы выдавать ошибку).

%:
    @:

И это макрос, который получает аргументы для нас:

args = `arg="$(filter-out $@,$(MAKECMDGOALS))" && echo $${arg:-${1}}`

Вот работа, которая может вызывать эту:

test:
    @echo $(call args,defaultstring)

Результат будет:

$ make test
defaultstring
$ make test hi
hi

Примечание!Возможно, вам лучше использовать «Taskfile», который представляет собой шаблон bash, который работает аналогично созданию, только без нюансов Maketools.Смотри https://github.com/adriancooney/Taskfile

7 голосов
/ 17 февраля 2016

С моей точки зрения гораздо проще сделать что-то вроде примера ниже. Рассмотрим задачу:

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 - пустая строка

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...