Pregunta

Estoy tratando de crear una plantilla genérica para construir mis Makefile, algo así como discuten en el documentación eval .

Parece que no puedo conseguir la función de comodín para trabajar dentro de un eval. El código básico estoy teniendo problemas con este aspecto.

SRC_DIR = ./src/

PROG_NAME = test

define PROGRAM_template
  $(1)_SRC_DIR = $(join $(SRC_DIR), $(1)/)
  $(1)_SRC_FILES = $(wildcard $$($(1)_SRC_DIR)*.c)
endef

$(eval $(call PROGRAM_template, $(PROG_NAME)))

all:
    @echo $(test_SRC_DIR)
    @echo $(test_SRC_FILES)
    @echo $(wildcard $(wildcard $(test_SRC_DIR)*.c)

Cuando corro hacer con esto, la salida es

./src/test

[correct list of all .c files in ./src/test/]

Básicamente, la llamada comodín dentro PROGRAM_template no está siendo eval'd como yo esperaba. Los resultados de llamadas en una lista vacía.
La llamada está siendo unirse a eval'd correctamente sin embargo.

Entonces, ¿qué estoy haciendo mal? Mi conjetura es que

$$($(1)_SRC_DIR) 

No es correcto, pero no puedo averiguar la forma correcta de hacerlo.

Editar Una vez que esto se resolvió, no pasó mucho tiempo para mí para golpear a otro problema con eval. He publicado como una nueva cuestión en para GNU Make 3.80 fallo eval

¿Fue útil?

Solución

Es necesario duplicar escapar prácticamente todas las funciones y variables cuando se utiliza eval. En la mayoría de los casos, las únicas cosas que No tienen que ser argumentos de doble escape son de función (porque la función call se expandirá completamente ellos). En este caso, técnicamente no es necesario join de doble escape o SRC_DIR bien, pero va a simplificar su vida si lo que siempre doble escapar de todas las variables y funciones cuando se utiliza eval.

La razón por la que necesita el doble escapa es que la expansión ocurre dos veces cuando se utiliza eval. La función eval sí mismo lleva a cabo la expansión, y luego la expansión se realiza nuevo cuando el bloque es finalmente analiza como sintaxis makefile (es decir, cuando en realidad es evaluada).

La forma en que lo tienes escrito, wildcard se invoca en el $( test_SRC_DIR)*.c literal de cadena. Si lo desea, puede ver esto por sí mismo mediante la sustitución de wildcard con info en su versión y ver qué pasa.

Es necesario esperar antes de invocar realmente wildcard hasta la segunda expansión, por lo que es argumento es el resultado de la expansión de $(test_SRC_DIR).

Prueba esto:

SRC_DIR = ./src/

PROG_NAME = test

define PROGRAM_template
  $(1)_SRC_DIR = $$(join $$(SRC_DIR),$(1)/)
  $(1)_SRC_FILES = $$(wildcard $$($(1)_SRC_DIR)*.c)
endef

$(eval $(call PROGRAM_template,$(PROG_NAME)))

all:
    @echo $(test_SRC_DIR)
    @echo $(test_SRC_FILES)
    @echo $(wildcard $(test_SRC_DIR)*.c)

Editar : Después de publicar esto, pensé que sería mejor probarlo para asegurarse de que realmente funciona. Al hacerlo, descubrí otro problema. Debe evitar poner espacios entre la coma y el argumento al llamar funciones. Esto causa un carácter de espacio literal que se antepone al argumento que se pasa a la función y conduce a resultados no deseados. He quitado los espacios después de las comas en la función de llamadas en mi versión (si bien esto no es un problema para la llamada a join, quité el espacio allí también sólo porque es un buen hábito para entrar).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top