web-dev-qa-db-ja.com

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'が定義されている場合、変数 'UNAME'が定義され(通常はLinuxですが、CygwinまたはOSF1によっても可能です)、変数 'difort'および 'err_Arch'も定義されています。このコードブロックは、さまざまなコンパイラターゲットで非常に何度も使用されます( ''という命名規則を使用します)。これは膨大な量の冗長なコードであるため、より簡単な方法で記述できるようにしたいと思います。たとえば、私はこのようなことをしたいと思います:

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

compileは、引数に基づいて上記のコードを実行する関数である場合があります。誰かが私がこれをどのように達成できるか考えていますか?

48

3つの関連する概念があります。

  1. call関数
  2. 複数行変数
  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_を使用してこれを修正しました。

37
JonnyJD

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 を使用できるかどうかを確認してください。

38
ephemient