2011-04-22 13 views
5

Estoy usando define para crear una macro. Sin embargo, dentro de una construcción definida, no puedo crear una variable. Asignar una variable no causa un error, pero cuando intento usarlo un poco más tarde, su valor está vacío.Definición de variables dentro de una macro makefile (definir)

Por ejemplo

####################################################### 
## JIDL_RULE 
## Macro to build and install PHP and JS files 
## from idl.json files 
####################################################### 
## param $(1) Full path to idl.json file 
## param $(2) Path to directory to copy PHP file into (relative to where make is run from) 
## param $(3) Path to directory to copy JS file into (relative to where make is run from) 
########################################################## 
define JIDL_RULE 
# Create the output directory if it doesn't exist 
$(2): 
    mkdir -p $(2) 

$(3): 
    mkdir -p $(3) 

# Rule to generate a PHP file. Notice that we have to prepend `pwd` 
$(call GENERATED_FILE,$(1),$(2),php): $(1) 
    $(PHPHOME)/bin/php -f $(JIDL2PHP) -- `pwd`/$$< $(DATADEF_HOME) > [email protected] 

# Rule to generate a JS file 
$(call GENERATED_FILE,$(1),$(3),js): $(1) 
    $(PHPHOME)/bin/php -f $(JIDL2JS) -- `pwd`/$$< $(DATADEF_HOME) > [email protected] 

# Add those generated files to the all target 
all:: $(call GENERATED_FILE,$(1),$(2),php) $(call GENERATED_FILE,$(1),$(3),js) $(2) $(3) 

# Remove generated files on clean: 
clean:: 
    -$(RM) -f $(call GENERATED_FILE,$(1),$(2),php) $(call GENERATED_FILE,$(1),$(3),js) 

# Rules to install generated files 
$(call PHP_RULE, $(call GENERATED_FILE,$(1),$(2),php)) 
$(call JS_RULE, $(call GENERATED_FILE,$(1),$(3),js)) 
endef 

Se puede ver en el código anterior que estoy duplicando las líneas

$(call GENERATED_FILE,$(1),$(2),php) y $(call GENERATED_FILE,$(1),$(3),js) desde múltiples lugares. Así que he intentado crear dos variables como los dos primeros estados en la macro, así:

PHP_OUT_FILE := $(call GENERATED_FILE,$(1),$(2),php) 
JS_OUT_FILE := $(call GENERATED_FILE,$(1),$(3),js) 

Pero si trato de usarlos más tarde (aún dentro de la definen), al igual que $(PHP_OUT_FILE) o $(JS_OUT_FILE), las variables se vacía . Me encantaría poder eliminar esa duplicación de mi macro. ¿Lo estoy haciendo mal? ¿No es posible? ¿Hay alguna otra forma de hacerlo?

pruebas de ambas respuestas

Probé el enfoque de eriktous y Ise Wisteria y ambos de "trabajado". Ninguno de los dos crea variables privadas, solo globales, con lo que estoy de acuerdo, solo tendré que tener cuidado con las variables colisionantes y no puedo hacer ninguna llamada recursiva (que no estaba planeando).

El problema con el enfoque de eriktous es el hecho de que al sumar $$ se hace que la variable se evalúe afuera, es decir, el $$ se emite como un solo $ y solo se evalúa cuando se llama al destino. Por lo tanto, llamar al macro dos veces lo anulará.

El enfoque de Ise Wisteria hace lo que necesito sin embargo. Llamar a eval hace que la variable se declare inmediatamente y, por lo tanto, está disponible y expandida por la macro mientras se evacua la macro. Significa que no pude establecerlo en dos valores diferentes dentro de la macro, pero estoy de acuerdo con eso también.

Aquí está el makefile que solía probarlo

define TEST 
$(eval INNERVAR := Blah $(1)) 
inner:: 
    echo Using EVAL: INNERVAR = $(INNERVAR) 
    echo 

endef 

define TEST2 
INNERVAR2 := Blah $(1) 
inner:: 
    echo Using double dollar sign: INNERVAR2 = $$(INNERVAR2) 
    echo 
endef 

$(eval $(call TEST,TEST_1_A)) 
$(eval $(call TEST,TEST_1_B)) 
$(eval $(call TEST2,TEST_2_A)) 
$(eval $(call TEST2,TEST_2_B)) 

inner:: 
    echo is that var really private? $(INNERVAR) 
    echo is that var really private? $(INNERVAR2) 

Y aquí está la salida: He omitido eco de maquillaje de la declaración que se va a ejecutar para que sea más fácil de ver.

Using EVAL: INNERVAR = Blah TEST_1_A 

Using EVAL: INNERVAR = Blah TEST_1_B 

# Calling the macro twice overwrites the global variable and since 
# it's not expanded immediately, calling the macro with different params 
# will output the last value that we set the variable to 
Using double dollar sign: INNERVAR2 = Blah TEST_2_B 
Using double dollar sign: INNERVAR2 = Blah TEST_2_B 

# As expected, the variables are not private to the macro. 
is that var really private? Blah TEST_1_B 
is that var really private? Blah TEST_2_B 
+0

¿Alguna razón especial por la que no pudo usar las reglas de patrones mucho más fáciles para lograr lo mismo? De acuerdo, eso no responde a esa pregunta en particular, pero creo que quieres encontrar una solución para construir el material ... :) – 0xC0000022L

+1

Llevaría demasiado tiempo explicar por qué y no ayudaría con responder la pregunta.No estoy buscando ayuda para resolver el problema real. Solo una forma de definir las variables locales dentro de una definición :) –

+0

@STATUS_ACCESS_DENIED: Permítame intentar responder a su pregunta, tal vez no del todo; Los archivos idl.json se encuentran en varias carpetas y no se copian en la misma carpeta en la que se encuentran. Cada llamada a la macro debe especificar el directorio de salida. Por favor, no me preguntes por qué es así :) –

Respuesta

9

¿Ayuda la aplicación eval a la asignación como la siguiente resolver el problema?

$(eval PHP_OUT_FILE := $(call GENERATED_FILE,$(1),$(2),php)) 
$(eval JS_OUT_FILE := $(call GENERATED_FILE,$(1),$(3),js)) 

Esperanza esto ayuda

+0

Funciona, increíble, gracias, ver mi edición para una comparación con el enfoque de eriktous. –

+0

Gracias, me alegro de que haya ayudado :-) La solución de _eriktous_ es interesante. Será útil en situaciones ligeramente diferentes. –

5

He estado experimentando con esto un poco, y creo que ahora entiendo el orden de evaluación make siguiente.
Ise Wisteria ha ofrecido una solución a su problema, que creo que debería funcionar. Otro es simplemente agregar un segundo $ al hacer referencia a las variables, como este: $$(PHP_OUT_FILE).

+0

Esto casi funciona ... Si solo llamo una vez al macro, veanme editar para obtener una explicación. Todavía estoy muy agradecido por la entrada. –

Cuestiones relacionadas