it-swarm.dev

¿Cómo pasar el argumento a Makefile desde la línea de comandos?

¿Cómo pasar el argumento a Makefile desde la línea de comandos?

Entiendo que puedo hacer

$ make action VAR="value"
$ value

con Makefile

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

¿Cómo obtengo el siguiente comportamiento?

$ make action value
value

?

Qué tal si

$make action value1 value2
value1 value2
84
Meng Lu

Probablemente no deberías hacer esto; Estás rompiendo el patrón básico de cómo funciona Make. Pero aquí está:

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

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

EDITAR:
Para explicar el primer comando,

$(MAKECMDGOALS) es la lista de "objetivos" enunciados en la línea de comandos, por ejemplo, "action value1 value2".

$@ es una variable automática para el nombre del objetivo de la regla, en este caso "acción".

filter-out es una función que elimina algunos elementos de una lista. Entonces $(filter-out bar, foo bar baz) devuelve foo baz (puede ser más sutil, pero aquí no necesitamos sutileza).

Póngalos juntos y $(filter-out $@,$(MAKECMDGOALS)) devuelve la lista de objetivos especificados en la línea de comandos que no sea "action", que podría ser "value1 value2".

170
Beta

Aquí hay una solución de trabajo genérica basada en @ Beta's.

Estoy usando GNU Make 4.1 con Shell=/bin/bash encima de mi Makefile, así que YMMV!

Esto nos permite aceptar argumentos adicionales (al no hacer nada cuando obtenemos un trabajo que no coincide, en lugar de lanzar un error).

%:
    @:

Y esta es una macro que obtiene los argumentos para nosotros:

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

Aquí hay un trabajo que podría llamar este:

test:
    @echo $(call args,defaultstring)

El resultado sería:

$ make test
defaultstring
$ make test hi
hi

¡Nota! Es posible que sea mejor usar un "Archivo de tareas", que es un patrón de bash que funciona de manera similar, pero sin los matices de Maketools. Ver https://github.com/adriancooney/Taskfile

8
M3D

Desde mi perspectiva es mucho más fácil hacer algo como una muestra a continuación. Considera una tarea:

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

Ahora cuando quiero llamarlo simplemente ejecuto algo como:

AT="build assets" make provision

o solo:

make provision en este caso AT es una cadena vacía

7
kharandziuk