web-dev-qa-db-fra.com

Comment passer un argument à Makefile à partir de la ligne de commande?

Comment passer un argument à Makefile à partir de la ligne de commande?

Je comprends que je peux faire

$ make action VAR="value"
$ value

avec Makefile

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

Comment puis-je obtenir le comportement suivant?

$ make action value
value

?

Que diriez-vous

$make action value1 value2
value1 value2
93
Meng Lu

Vous ne devriez probablement pas faire ça; vous rompez le schéma de base de la façon dont Make fonctionne. Mais le voici:

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

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

MODIFIER:
Pour expliquer le premier commandement,

$(MAKECMDGOALS) est la liste des "cibles" épelée sur la ligne de commande, par exemple. "action valeur1 valeur2".

$@ Est un variable automatique pour le nom de la cible de la règle, dans ce cas "action".

filter-out Est une fonction qui supprime certains éléments d'une liste. Donc, $(filter-out bar, foo bar baz) renvoie foo baz (Cela peut être plus subtil, mais nous n’avons pas besoin de subtilité ici).

Rassemblez-les et $(filter-out $@,$(MAKECMDGOALS)) renvoie la liste des cibles spécifiées sur la ligne de commande autres que "action", qui peut être "valeur1 valeur2".

181
Beta

Voici une solution de travail générique basée sur @ Beta

J'utilise GNU Make 4.1 avec Shell=/bin/bash sur mon Makefile, alors YMMV!

Cela nous permet d’accepter des arguments supplémentaires (en ne faisant rien lorsque nous obtenons un travail qui ne correspond pas, au lieu de renvoyer une erreur).

%:
    @:

Et ceci est une macro qui obtient les arguments pour nous:

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

Voici un travail qui pourrait appeler celui-ci:

test:
    @echo $(call args,defaultstring)

Le résultat serait:

$ make test
defaultstring
$ make test hi
hi

Remarque! Vous feriez peut-être mieux d'utiliser un "Taskfile", qui est un modèle bash qui fonctionne de la même manière, mais sans les nuances de Maketools. Voir https://github.com/adriancooney/Taskfile

10
M3D

Beaucoup plus facile aproach. Considérons une tâche:

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

Maintenant, quand je veux l'appeler, je lance juste quelque chose comme:

AT="build assets" make provision

ou juste:

make provision dans ce cas AT est une chaîne vide

9
kharandziuk