phony - makefile windows
¿Cómo puedo usar macros para generar múltiples objetivos/reglas de Makefile dentro de foreach? Comportamiento misterioso (3)
La respuesta de Beta es correcta, pero quería abordar el comentario: "No estoy seguro de por qué Hacer objetar las reglas no evaluables".
La razón por la que las reglas no evaluables no funcionan es que un makefile está en última instancia basado en líneas, y las líneas se cortan ANTES de que las variables se expandan. Entonces, simplemente no es posible que una expansión de una variable se convierta en un resultado multilínea: incluso si la expansión contiene nuevas líneas, todo se trata como una "línea". Cuando make finaliza la expansión del bucle foreach
y analiza los resultados, básicamente ve esto:
a1: b c touch a1 a2: b c touch a2 a3: b c touch b3
por lo que recibe el error "patrones de destino múltiples".
La evaluación causa que re-interprete el resultado de la expansión desde el principio como un fragmento completo de la sintaxis de makefile, incluyendo el corte de líneas, etc., y es por eso que una expansión de líneas múltiples funciona allí.
Estoy usando GNU make 3.81. Aquí hay un makefile de prueba que demuestra el problema:
define BOZO
a$(1): b c
touch a$(1)
endef
$(foreach i,1 2 3,$(call BOZO,$(i)))
La idea aquí es usar una plantilla de macro (BOZO) para generar reglas que sigan un patrón predecible.
Problema: cuando ejecuto make en este makefile recibo un error que dice:
Makefile.fake:10: *** multiple target patterns. Stop.
(donde la línea 10 es la línea con el foreach).
Ahora, sé lo que normalmente indica ese error. Veamos a qué se expande esa línea utilizando la función de info
para enviar la expansión a la salida estándar. Cambio de línea 10 para que sea:
$(info $(foreach i,1 2 3,$(call BOZO,$(i))))
y corro:
$ make -n
a1: b c
touch a1
a2: b c
touch a2
a3: b c
touch a3
make: *** No targets. Stop.
Tenga en cuenta que se espera el mensaje "sin objetivos", ya que la función $ (info ...) se vacía, pero hace que se impriman las reglas generadas.
Vamos a ejecutar esas reglas, ¿de acuerdo?
$make -n > out.txt
make: *** No targets. Stop.
$make -f out.txt a1 a2 a3
touch a1
touch a2
touch a3
$
¡AAARGH! Las reglas funcionan bien. Entonces ... ¿el error está en make, o en mi entendimiento?
Una pista final que podría ayudar a diagnosticar: si cambio la línea foreach a:
$(foreach i,1,$(call BOZO,$(i)))
(para que foreach tenga una sola iteración)
y luego hacer
$make a1
Me sale un error diferente:
make: *** No rule to make target `a1''. Stop.
No conozco ninguna forma de "ver" la expansión de $(foreach )
que hace see a excepción de $(info )
, y su salida es legal, por lo que estoy bastante perplejo.
Tal vez viejo, pero siempre relevante. No hay necesidad de hacer esta macro en absoluto.
La solución para su problema es simplemente definiendo esta regla:
a%: b c
touch a%
El porcentaje actúa como comodín. Ver más información aquí: https://.com/a/7406471/2522849
$(foreach i,1 2 3,$(eval $(call BOZO,$(i))))
La función eval le dice a Make que analice las estructuras como sintaxis de makefile, para "promulgarlas". No estoy seguro de por qué Make objetó las reglas no evaluadas de esta manera en particular, pero eso es algo académico.