Yo uso Makefiles.
Tengo un objetivo llamado run
que ejecuta el objetivo de compilación. Simplificado, se parece a lo siguiente:
prog: ....
...
run: prog
./prog
¿Hay alguna forma de pasar argumentos? Así que eso
make run asdf --> ./prog asdf
make run the dog kicked the cat --> ./prog the dog kicked the cat
¡Gracias!
Respuestas:
No sé cómo hacer exactamente lo que quieres, pero una solución podría ser:
Entonces:
fuente
$(foo)' or
$ {foo} 'es una referencia válida para la variable 'foo' ". y procede a dar ejemplos donde solo se usa $ (). Ah bueno.Esta pregunta tiene casi tres años, pero de todos modos ...
Si está utilizando GNU make, esto es fácil de hacer. El único problema es que
make
interpretará los argumentos no opcionales en la línea de comandos como objetivos. La solución es convertirlos en objetivos de no hacer nada, pormake
lo que no se quejará:Ejecutar esto da:
fuente
prog foo bar --baz
make
que no interpreten--baz
como una opción de línea de comandos:make -- prog foo bar --baz
. El--
significa "todo después de esto es un argumento, no una opción".RUN_ARGS
usar esto?else
rama a laifeq
y establecerRUN_ARGS
allí?$(eval $(RUN_ARGS):dummy;@:)
, sin un objetivo ficticio definido.para el estándar, puede pasar argumentos definiendo macros como este
luego úsalos así
Referencias para hacer NMake de Microsoft
fuente
Puede pasar la variable al Makefile como se muestra a continuación:
Uso:
o:
Alternativamente, use la solución provista por Beta :
Uso:
fuente
TL; DR no intentes hacer esto
en su lugar crea script:
y haz esto:
Responda a la pregunta planteada:
puedes usar una variable en la receta
luego pasa una asignación variable como argumento para hacer
Esto se ejecutará
./prog arg
.pero cuidado con las trampas. Voy a elaborar sobre las trampas de este método y otros métodos más adelante.
Responda a la intención asumida detrás de la pregunta:
la suposición: desea ejecutar
prog
con algunos argumentos pero debe reconstruir antes de ejecutar si es necesario.la respuesta: cree un script que se reconstruya si es necesario y luego ejecute prog con args
Este guión deja muy clara la intención. utiliza make para hacer lo que es bueno: construir. utiliza un script de shell para hacer lo que es bueno: procesamiento por lotes.
Además, puede hacer cualquier otra cosa que necesite con la total flexibilidad y expresividad de un script de shell sin todas las advertencias de un archivo MAKE.
También la sintaxis de llamada ahora es prácticamente idéntica:
comparar con:
contraste con
antecedentes:
make no está diseñado para pasar argumentos a un objetivo. Todos los argumentos en la línea de comando se interpretan como un objetivo (también conocido como objetivo), como una opción o como una asignación variable.
así que si ejecutas esto:
make interpretará
run
yfoo
como objetivos (objetivos) actualizar según sus recetas.--wat
como una opción para hacer. yvar=arg
como una asignación variable.Para obtener más detalles, consulte: https://www.gnu.org/software/make/manual/html_node/Goals.html#Goals
para ver la terminología, consulte: https://www.gnu.org/software/make/manual/html_node/Rule-Introduction.html#Rule-Introduction
sobre el método de asignación de variables y por qué lo recomiendo
y la variable en la receta
Esta es la forma más "correcta" y directa de pasar argumentos a una receta. pero aunque puede usarse para ejecutar un programa con argumentos, ciertamente no está diseñado para usarse de esa manera. ver https://www.gnu.org/software/make/manual/html_node/Overriding.html#Overriding
En mi opinión, esto tiene una gran desventaja: lo que quieres hacer es correr
prog
con argumentosarg
. pero en lugar de escribir:estas escribiendo:
esto se vuelve aún más incómodo cuando se intenta pasar múltiples argumentos o argumentos que contienen espacios:
comparar con:
para que conste, así es
prog
como se ve mi :También tenga en cuenta que no debe poner
$(var)
comillas en el archivo MAKE:porque entonces
prog
siempre obtendremos un solo argumento:Todo esto es por lo que recomiendo contra esta ruta.
para completar aquí hay algunos otros métodos para "pasar argumentos para hacer correr".
Método 1:
explicación súper corta: filtrar el objetivo actual de la lista de objetivos. create catch all target (
%
) que no hace nada para ignorar silenciosamente los otros objetivos.método 2:
explicación súper corta: si el objetivo es
run
eliminar el primer objetivo y crear objetivos de no hacer nada para los objetivos restantes usandoeval
.ambos te permitirán escribir algo como esto
Para una explicación más profunda, estudie el manual de make: https://www.gnu.org/software/make/manual/html_node/index.html
problemas del método 1:
Los argumentos que comienzan con un guión serán interpretados por make y no se pasarán como un objetivo.
solución alterna
los argumentos con un signo igual se interpretarán por make y no se pasarán
sin solución
argumentos con espacios es incómodo
sin solución
si resulta que un argumento es
run
(igual al objetivo), también se eliminarácorrerá en
./prog foo bar
lugar de./prog foo bar run
posible solución alternativa con el método 2
Si un argumento es un objetivo legítimo, también se ejecutará.
correrá
./prog foo bar clean
pero también la receta para el objetivoclean
(suponiendo que exista).posible solución alternativa con el método 2
cuando escribes mal un objetivo legítimo, se ignorará en silencio debido a la captura de todos los objetivos.
simplemente ignorará en silencio
celan
.La solución es hacer que todo sea detallado. para que veas lo que pasa. pero eso crea mucho ruido para la salida legítima.
problemas del método 2:
si un argumento tiene el mismo nombre que un objetivo existente, make imprimirá una advertencia de que se está sobrescribiendo.
no hay solución que yo sepa
los argumentos con un signo igual seguirán siendo interpretados por make y no se pasarán
sin solución
argumentos con espacios sigue siendo incómodo
sin solución
Los argumentos con saltos de espacio que
eval
intentan crear no hacen nada.solución alternativa: cree el objetivo global de capturar todo sin hacer nada como se indicó anteriormente. con el problema anterior, que nuevamente ignorará silenciosamente los objetivos legítimos mal escritos.
Se utiliza
eval
para modificar el archivo MAKE en tiempo de ejecución. cuánto peor puede ir en términos de legibilidad y debugabilidad y el Principio de menor asombro .solución alternativa: ¡no hagas esto! 1 en su lugar, escribe un script de shell que ejecute make y luego se ejecute
prog
.Solo he probado usando gnu make. otras marcas pueden tener un comportamiento diferente.
TL; DR no intentes hacer esto
en su lugar crea script:
y haz esto:
fuente
Aquí hay otra solución que podría ayudar con algunos de estos casos de uso:
En otras palabras, elija algún prefijo (
test-
en este caso) y luego pase el nombre del objetivo directamente al programa / corredor. Supongo que esto es principalmente útil si hay algún script de corredor involucrado que pueda desenvolver el nombre del objetivo en algo útil para el programa subyacente.fuente
$*
para pasar solo la parte del objetivo que coincide con el%
.No. Mirando la sintaxis de la página del manual para GNU make
puede especificar múltiples objetivos, por lo tanto, 'no' (al menos no de la manera exacta que especificó).
fuente
Puede extraer explícitamente cada enésimo argumento en la línea de comando. Para hacer esto, puede usar la variable MAKECMDGOALS, contiene la lista de argumentos de la línea de comando dada a 'make', que interpreta como una lista de objetivos. Si desea extraer el enésimo argumento, puede usar esa variable combinada con la función "palabra", por ejemplo, si desea el segundo argumento, puede almacenarlo en una variable de la siguiente manera:
fuente
make: *** No rule to make target 'arg'. Stop.
anon , se
run: ./prog
ve un poco extraño, ya que la parte derecha debe ser un objetivo, por lo que serun: prog
ve mejor.Sugeriría simplemente:
y me gustaría agregar que se pueden pasar argumentos:
make arg1="asdf" run
arg1="asdf" make run
fuente
Aquí está mi ejemplo. Tenga en cuenta que estoy escribiendo en Windows 7, usando mingw32-make.exe que viene con Dev-Cpp. (Tengo c: \ Windows \ System32 \ make.bat, por lo que el comando todavía se llama "make").
Uso para limpieza regular:
Uso para limpiar y crear una copia de seguridad en mydir /:
fuente
No estoy muy orgulloso de esto, pero no quería pasar variables de entorno, así que invertí la forma de ejecutar un comando fijo:
esto imprimirá el comando que desea ejecutar, así que simplemente evalúelo en una subshell:
fuente
¡Encontré una manera de obtener los argumentos con un signo igual (=)! La respuesta es especialmente una adición a la respuesta de @lesmana (ya que es la más completa y explicada aquí), pero sería demasiado grande para escribirla como comentario. Nuevamente, repito su mensaje: TL; ¡DR no intente hacer esto!
Necesitaba una forma de tratar mi argumento
--xyz-enabled=false
(ya que el valor predeterminado es verdadero), que todos sabemos ahora que este no es un objetivo de creación y, por lo tanto, no forma parte de él$(MAKECMDGOALS)
.Mientras miraba todas las variables de make haciendo eco,
$(.VARIABLES)
obtuve estos resultados interesantes:Esto nos permite ir de dos maneras: ya sea comenzando con una
--
(si eso se aplica a su caso) o analizando la variable específica de GNU (probablemente no está destinada a que la usemos)-*-command-variables-*-
. ** Ver pie de página para opciones adicionales ** En mi caso, esta variable contenía:Con esta variable podemos combinarla con la solución ya existente
$(MAKECMDGOALS)
y, por lo tanto, definiendo:y usarlo con (mezclar explícitamente el orden de los argumentos):
devuelto:
Como puede ver, perdemos el orden total de los args. La parte con los "args" de asignación parece haber sido revertida, el orden de los "args" de destino se mantiene. Coloqué las "asignaciones" -args al principio, espero que a su programa no le importe dónde se coloca el argumento.
Actualización: a continuación, las variables también parecen prometedoras:
fuente
Otro truco que uso es la
-n
bandera, que dicemake
que haga una carrera en seco. Por ejemplo,fuente