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
¿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
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 :) –
@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í :) –