Functions in the Makefile

I am writing a Makefile with a lot of repetitive things, for example.

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 

where the target "syst" is defined, the variable "UNAME" is defined (and usually it is Linux, but can also be Cygwin or OSF1), and the "difort" and "err_arch" variables are defined. This block of code is used so many times for different purposes of the compiler (using the naming convention ''). Since this is a huge amount of redundant code, I would like to write it in a simpler way. For example, I would like to do something like this:

 debug_ifort_Linux: compile(uname,compiler,flags,petsc_flags,target,lext) 

where compilation can be a function that executes the code above based on the arguments. Does anyone know how I could do this?

+46
function bash makefile gnu-make
Feb 03 '09 at 15:47
source share
2 answers

There are 3 related concepts:

The reorganized result might look like this:

 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),"...") 

It remains \ to leave the string $(MAKE) for the shell. There is no multi-line variable here because it is just one line of shell code. Multiline variables are used only in the else block.

If you don't need parameters, you can use: = assignment and just extend the method with $(compile) (see canned recipes )

[Edit] Note. Using make before version 3.82, value = was not recognized at the end of the define statement for me. I fixed this using define compile instead.

+35
Dec 22 '12 at 2:17
source share

You are looking for the call function.

 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) 

If you can change the Makefile structure a bit, you should see if you can use make conditional expressions instead of sh 's.

+36
Feb 03 '09 at 15:59
source share



All Articles