我正在编写一个包含很多重复内容的 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”的地方,定义了变量“UNAME”(通常是 Linux,但也可能是 Cygwin 或 OSF1),还定义了变量“difort”和“err_arch”。此代码块多次用于不同的编译器目标(使用“”的命名约定)。由于这是大量冗余代码,我希望能够以更简单的方式编写它。例如,我想做这样的事情:
debug_ifort_Linux:
compile(uname,compiler,flags,petsc_flags,target,lext)
其中 compile 可以是一个基于参数执行上述代码的函数。有谁知道我如何才能做到这一点?
最佳答案
有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)
行。
这里不需要多行变量,因为它只是一行 shell 代码。
多行变量只用在 else block 中。
如果您不需要参数,您可以使用 := assignment 并使用 $(compile)
扩展方法(参见 canned recipes )
注意:使用 3.82 版之前的 make,我无法识别定义语句末尾的 =。我改用 define compile
解决了这个问题。
关于bash - Makefile 中的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/507641/