Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Functions in Makefile

I am writing a Makefile with a lot of repetitive stuff, e.g.

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 is usually Linux, but might also by Cygwin or OSF1) and the variables 'difort' and 'err_arch' are also defined. This block of code is used very many times for different compiler targets (using a name convention of ''). Since this is a huge amount of redundant code, I would like to be able to write it in a more simple manner. E.g., I would like to do something like this:

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

where compile could be a function doing the code above based on the arguments. Does anyone have any idea how I could accomplish this?

like image 363
Karl Yngve Lervåg Avatar asked Feb 03 '09 15:02

Karl Yngve Lervåg


People also ask

How do you call a function in makefile?

The call function is unique in that it can be used to create new parameterized functions. You can write a complex expression as the value of a variable, then use call to expand it with different values. The syntax of the call function is: $(call variable , param , param ,…)

What is $$ in makefile?

$$ means be interpreted as a $ by the shell. the $(UNZIP_PATH) gets expanded by make before being interpreted by the shell.

What does Patsubst do in makefile?

Finds whitespace-separated words in TEXT that match PATTERN and replaces them with REPLACEMENT. Here PATTERN may contain a % which acts as a wildcard, matching any number of any characters within a word.

What is f flag in makefile?

The -f flag in make is defined as follows, make -f makefile Specifies a different makefile . The argument makefile is a pathname of a description file, which is also referred to as the makefile. A pathname of '-' shall denote the standard input.


2 Answers

There are 3 related concepts:

  1. call function
  2. multi-line variables
  3. conditionals

The refactored result could 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),"...") 

That one \ that is left is to continue the $(MAKE) line for the shell. No multi-line variable is necessary here, because it is just one line of shell code. Multi-line variables are only used in the else block.

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

Note: Using make prior to version 3.82, the = was not recognized at the end of the define statement for me. I fixed this by using define compile instead.

like image 66
JonnyJD Avatar answered Oct 08 '22 14:10

JonnyJD


You're 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 restructure your Makefile a bit, though, you should see if you can use make's conditionals instead of sh's.

like image 40
ephemient Avatar answered Oct 08 '22 13:10

ephemient