Як передати аргумент Makefile з командного рядка?


109

Як передати аргумент Makefile з командного рядка?

Я розумію, що можу зробити

$ make action VAR="value"
$ value

з Makefile

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

Як отримати таку поведінку?

$ make action value
value

?

Як щодо

$make action value1 value2
value1 value2


3
Можливий дублікат аргументів Passing для "make run"
lesmana

Відповіді:


212

Ви, мабуть, не повинні цього робити; ви порушуєте основну схему того, як працює Make. Але ось це:

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

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

EDIT:
Щоб пояснити першу команду,

$(MAKECMDGOALS) - це список "цілей", написаний у командному рядку, наприклад, "value 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
Євгеній Генералов

1
Пробачте моє незнання. Я спробував googling %:і @:не можу знайти інформацію про те, що роблять ті "директиви" (або як вони називають). Не могли б ви пояснити?
Jon

15
@Jon: Посібник тут . Частина, що складається %:і @:є правилом . Назва цілі %означає, що це правило, яке відповідає будь-якому ; тобто, якщо Make не зможе знайти іншого способу побудувати те, про що ти йому кажеш, побудувати, воно виконає це правило. @:Є рецепт ; що :означає нічого не робити, а @значить робити це мовчки.
Бета

Дякую. Я читав цей посібник, і спочатку не розглядав, це %:насправді % :цільове ім'я типу підстановки. Я не бачу нічого на цій сторінці посібника, що стосується, @:хоча ... це говорить про те, що правило "робити нічого" буде просто ;після специфікації цілі, тож, чи не було б точніше писати % : ;як "макіяж" -нещо »правило?
Jon

1
filter-outне працює, коли дія є залежністю від цілі, вказаної в командному рядку, оскільки $@буде встановлено ім'я залежності, а не оригінальний аргумент, викликаний у командному рядку. Натомість я призначаю MAKECMDGOALSмасив оболонки, а потім @ args=($(MAKECMDGOALS)); args=("$${args[@]:1}")
видаляю

18

Ось загальне робоче рішення, засноване на @ 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

Примітка! Можливо, вам буде краще скористатися "Заданим файлом", який є базовим шаблоном, який працює аналогічно, лише без нюансів Макетолів. Дивіться https://github.com/adriancooney/Taskfile


Це спрацювало!! ДЛЯ інших людей, які пробують це, переконайтеся, що є tabраніше @echo, ні space.
Абдулла Аль Маруф - Тухін

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 читайте мою відповідь на ще одне дуже схоже, але, здавалося б, не повторне питання: передача аргументів для "примусового запуску"

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.