Funciones en Makefile
Pregunta
Estoy escribiendo un Makefile con un montón de cosas repetitivas, por ejemplo.
debug_ifort_Linux:
if [ $(UNAME) = Linux ]; then \
$(MAKE) FC=ifort FFLAGS=$(difort) PETSC_FFLAGS="..." \
TARGET=$@ LEXT="ifort_$(UNAME)" -e syst; \
else \
echo $(err_arch); \
exit 1; \
fi
donde se define el destino 'Syst', se define la variable 'UNAME' (y es por lo general Linux, pero podría también por Cygwin o OSF1) y las variables 'difort' y 'err_arch' también se definen. Este bloque de código se utiliza muy muchas veces para diferentes objetivos del compilador (utilizando una convención de nombre ' '). Dado que esta es una enorme cantidad de código redundante, me gustaría ser capaz de escribir de una manera más sencilla. Por ejemplo, me gustaría hacer algo como esto:
debug_ifort_Linux:
compile(uname,compiler,flags,petsc_flags,target,lext)
donde compilación podría ser una función que hace el código anterior en base a los argumentos. ¿Alguien tiene alguna idea de cómo podría lograr esto?
Solución
Hay 3 conceptos relacionados:
El resultado refactorizado podría tener este aspecto:
ifeq ($(UNAME),Linux)
compile = $(MAKE) FC=$(1) FFLAGS=$(2) PETSC_FFLAGS=$(3) \
TARGET=$@ LEXT="$(1)_$(UNAME)" -e syst
else
define compile =
echo $(err_arch)
exit 1
endef
endif
debug_ifort:
$(call compile,ifort,$(difort),"...")
Que uno \
lo que queda es para continuar la línea $(MAKE)
para la cáscara.
Ninguna variable multilínea es necesario en este caso, ya que es sólo una línea de código shell.
las variables multilínea sólo se utilizan en el bloque más.
Si usted no necesita parámetros que se pueden utilizar: = misiones y acaba de ampliar el método con $(compile)
(ver enlatados recetas )
[Editar] Nota: Uso hacen antes de la versión 3.82, los = no se reconoció al final de la instrucción define para mí. He arreglado esto mediante el uso define compile
lugar.
Otros consejos
Usted está buscando el call
función .
compile = \
if [ $(UNAME) = $(1) ]; then \
$(MAKE) FC=$(2) FFLAGS=$(3) PETSC_FFLAGS="..." \
TARGET=$@ LEXT="$(4)_$(UNAME)" -e syst; \
else \
echo $(err_arch); \
exit 1; \
fi
debug_ifort_Linux:
$(call compile,Linux,ifort,$(difort),ifort)
Si se puede reestructurar su Makefile
un poco, sin embargo, usted debe ver si se puede usar make
's condicionales en lugar de sh
's.