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
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".
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
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