在Makefile中的函数

我正在写一个有很多重复的东西的Makefile,例如

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 

在定义了目标'syst'的地方,定义了variables'UNAME'(通常是Linux,但也可能是Cygwin或OSF1),variables'difort'和'err_arch'也被定义。 这段代码被用于很多次,用于不同的编译目标(使用名称约定“ “)。 由于这是大量的冗余代码,我希望能够以更简单的方式编写它。 例如,我想要做这样的事情:

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

其中compile可以是一个基于参数执行上面的代码的函数。 有没有人有任何想法我可以做到这一点?

有三个相关的概念:

  1. callfunction
  2. 多线variables
  3. 条件语句

重构的结果可能如下所示:

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

那剩下的就是继续shell的$(MAKE)行。 这里不需要多行variables,因为它只是一行shell代码。 多行variables只在else块中使用。

如果你不需要参数,你可以使用:=赋值,只需要使用$(compile)展开方法(参见jar头食谱 )

[编辑] 注意:在3.82之前使用make,在我的定义语句的末尾没有识别出=。 我通过使用define compile来解决这个问题。

您正在寻找callfunction 。

 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) 

如果你可以稍微调整一下你的Makefile ,你应该看看是否可以使用make的条件而不是sh