2011-06-29 25 views
14

¿Cuál es el problema con la función dep2 en el código de ejemplo siguiente?Definición de funciones de creación de GNU personalizadas

dep1 = $(eval makefile_list_$1 := $(MAKEFILE_LIST))$(eval -include $1.mk)$(eval MAKEFILE_LIST := $(makefile_list_$1)) 

define dep2 
$(eval makefile_list_$1 := $(MAKEFILE_LIST)) 
$(eval -include $1.mk) 
$(eval MAKEFILE_LIST := $(makefile_list_$1)) 
endef 

$(call dep1,test) 
$(call dep2,test) 

.DEFAULT_TARGET: all 
.PHONY: all 
all: 
    @echo [email protected] 

GNU make 3,81 y 3,82 producir Makefile:10: *** missing separator. Stop. que apunta a la llamada DEP2, DEP1 se ejecuta sin errores. La única diferencia entre las dos variantes son las nuevas líneas en dep2 (y todo el punto por el que me gustaría usar define).

Respuesta

6

se le olvidó la =:
definen DEP2 =

EDIT:
Deja un punto y coma al final de cada línea. He probado esto y funciona (en GNUMake 3.81).

define dep2 
$(eval makefile_list_$1 := $(MAKEFILE_LIST)); 
$(eval -include $1.mk); 
$(eval MAKEFILE_LIST := $(makefile_list_$1)); 
endef 

Por qué estos puntos y comas son necesarios no sé, pero en la documentación define parece ser utilizado para múltiples líneas "variables" sólo cuando la definición de secuencias de comandos shell para ser utilizado en las recetas, no Haz comandos, así que tal vez las reglas son un poco diferentes.

+0

No, el '=' es opcional (y solo se introdujo con GNU make 3.82). Agregarlo no hace la diferencia. –

+0

@ g.b .: ¿Realmente lo has intentado? Lo hice (con GNU make 3.81), y sí marcó la diferencia. Funciona según lo esperado para mí, si agrego el '='. – eriktous

+4

@eriktous: Sí, lo intenté con 3.82. Las versiones anteriores simplemente ignorarán por completo la declaración de definición si está seguida por un '=', que es la razón por la cual no aparece el mensaje de error. –

-1

Hay mucho que se puede mejorar en lo que está haciendo. Por un lado, realmente desea factorizar las llamadas eval a una sola llamada en la parte superior.

Su problema particular, sin embargo, proviene de no entender que la cadena recursiva multilínea que el comando make define nunca incluye la nueva línea lady. La convención más natural para escribir funciones evalable es

definen Foo Línea 1 Línea 2

ENDEF

Usted puede mirar en el eval cadena es de ver y ver lo que esto hace a través del comando de información, por ejemplo, $ (info $ (llamar a Foo, x) $ (llamar a Foo, y)).

1

Movería las llamadas $(eval ...) fuera de dep2. Al hacerlo de esta manera, no hay necesidad de punto y coma en dep2. Esto significa duplicar los signos $ de algunas expansiones para evitar que la expansión se realice demasiado pronto. Entonces:

define dep2 
makefile_list_$1 := $$(MAKEFILE_LIST) 
-include $1.mk 
MAKEFILE_LIST := $$(makefile_list_$1) 
endef 

$(eval $(call dep2,test)) 

# Quick checks for testing, to be removed from the final code... 
$(info $(makefile_list_test)) 
$(info $(MAKEFILE_LIST)) 

.DEFAULT_TARGET: all 
.PHONY: all 
all: 
    @echo [email protected] 

He probado el código anterior y funciona con Gnu Make 4.0. Esperaría que funcione para Gnu Make 3.8x. El patrón $(eval $(call ...)) es lo que siempre hago para ejecutar mis funciones personalizadas, y lo he usado desde hace bastante tiempo.

Cuestiones relacionadas