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?

¿Fue útil?

Solución

Hay 3 conceptos relacionados:

  1. call función
  2. variables de multilínea
  3. condicionales

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.

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