Fonctions dans le fichier Makefile

J’écris un Makefile avec beaucoup de choses répétitives, par exemple

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 

où la cible ‘syst’ est définie, la variable ‘UNAME’ est définie (et est généralement Linux, mais pourrait aussi être par Cygwin ou OSF1) et les variables ‘difort’ et ‘err_arch’ sont également définies. Ce bloc de code est utilisé très souvent pour différentes cibles de compilation (en utilisant une convention de nom de ‘ ‘). Comme il s’agit d’une énorme quantité de code redondant, je voudrais pouvoir l’écrire de manière plus simple. Par exemple, j’aimerais faire quelque chose comme ceci:

 debug_ifort_Linux: comstack(uname,comstackr,flags,petsc_flags,target,lext) 

où comstack pourrait être une fonction faisant le code ci-dessus en fonction des arguments. Est-ce que quelqu’un a une idée de ce que je pourrais accomplir?

Il y a 3 concepts liés:

  1. fonction d’ call
  2. variables multilignes
  3. les conditionnels

Le résultat refactorisé pourrait ressembler à ceci:

 ifeq ($(UNAME),Linux) comstack = $(MAKE) FC=$(1) FFLAGS=$(2) PETSC_FFLAGS=$(3) \ TARGET=$@ LEXT="$(1)_$(UNAME)" -e syst else define comstack = echo $(err_arch) exit 1 endef endif debug_ifort: $(call comstack,ifort,$(difort),"...") 

Celui qui rest est de continuer la ligne $(MAKE) pour le shell. Aucune variable multi-lignes n’est nécessaire ici, car il ne s’agit que d’une seule ligne de code shell. Les variables multilignes ne sont utilisées que dans le bloc else.

Si vous n’avez pas besoin de parameters, vous pouvez utiliser: = assignation et simplement développer la méthode avec $(comstack) (voir les recettes prédéfinies )

[Edit] Note: En utilisant make avant la version 3.82, le = n’a pas été reconnu à la fin de l’instruction define pour moi. J’ai résolu ce problème en utilisant define comstack place.

Vous recherchez la fonction d’ call .

 comstack = \ 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 comstack,Linux,ifort,$(difort),ifort) 

Si vous pouvez restructurer un peu votre Makefile , cependant, vous devriez voir si vous pouvez utiliser les conditionnels de make au lieu de sh .