私は、多くの反復的なものを含む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),"...")
_
残されたその_\
_は、シェルの$(MAKE)
行を続けることです。シェルコードは1行なので、複数行の変数は必要ありません。複数行の変数は、elseブロックでのみ使用されます。
パラメータが必要ない場合は、:=割り当てを使用して、$(compile)
でメソッドを拡張するだけです( 缶詰レシピ を参照)。
[編集]注:バージョン3.82より前のmakeを使用すると、=が最後に認識されませんでした私のための定義ステートメントの。代わりに_define compile
_を使用してこれを修正しました。
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)
ただし、Makefile
を少し再構成できる場合は、make
の代わりにsh
の- conditionals を使用できるかどうかを確認してください。