¿Cómo pasar un argumento a Makefile desde la línea de comando?

Respuestas:

212

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

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" detallada en la línea de comando, por ejemplo, "acción valor1 valor2".

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

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

Ponlos juntos y $(filter-out $@,$(MAKECMDGOALS))devuelve la lista de objetivos especificados en la línea de comando que no sean "acción", que podría ser "valor1 valor2".

Beta
fuente
1
$(shell echo $(MAKECMDGOALS) | sed 's!^.* $@ !!')para omitir todos los objetivos antes y simplemente considerar los siguientes como argumentos:make target1 target2 action value1 value2
Evgeniy Generalov
1
Perdona mi ignorancia. He intentado buscar en Google %:y @:no puedo encontrar información sobre lo que hacen esas "directivas" (o como se llamen). ¿Podría explicar por favor?
Jon
15
@Jon: El manual está aquí . La parte que consta de %:y @:es una regla . El nombre del objetivo %significa que es una regla que coincide con cualquier cosa ; es decir, si Make no puede encontrar otra forma de construir lo que le dice que construya, ejecutará esa regla. El @:es una receta ; los :medios no hacen nada y los @medios lo hacen en silencio.
Beta
Gracias. Había estado leyendo ese manual y no consideré al principio, que %:era en realidad % :, un nombre de destino de tipo comodín. Sin @:embargo , no veo nada en esa página del manual con respecto a ... sí sugiere que una regla de "no hacer nada" simplemente tendría un ;después de la especificación de destino, por lo que, ¿no sería más preciso escribir % : ;como el "comodín hacer -¿Nada "regla?
Jon
1
filter-outno funciona cuando la acción es una dependencia del objetivo especificado en la línea de comando, porque $@se establecerá en el nombre de la dependencia, no en el argumento original llamado en la línea de comando. En cambio, lo asigno MAKECMDGOALSa una matriz de shell y luego elimino el primer elemento:@ args=($(MAKECMDGOALS)); args=("$${args[@]:1}")
Gingi
18

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

Estoy usando GNU Make 4.1 SHELL=/bin/bashencima 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 arrojar 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 a este:

test:
    @echo $(call args,defaultstring)

El resultado sería:

$ make test
defaultstring
$ make test hi
hi

¡Nota! Puede que sea mejor utilizar un "archivo de tareas", que es un patrón bash que funciona de manera similar, solo que sin los matices de Maketools. Ver https://github.com/adriancooney/Taskfile

M3D
fuente
¡¡Funcionó!! Para otras personas que lo prueben, asegúrese de que haya tabantes @echo, no space.
Abdullah Al Maruf - Tuhin
11

Enfoque mucho más sencillo. Considere 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 provisionen este caso ATes una cadena vacía

kharandziuk
fuente
-2

no intentes hacer esto

$ make action value1 value2

en su lugar, cree un script:

#! /bin/sh
# rebuild if necessary
make
# do action with arguments
action "$@"

y haz esto:

$ ./buildthenaction.sh value1 value2

para obtener más explicaciones de por qué hacer esto y las advertencias de la piratería de archivos Makefile, lea mi respuesta a otra pregunta muy similar pero aparentemente no duplicada: Pasar argumentos para "hacer correr"

lesmana
fuente