makefileの単一の論理行にあるDefineキーワード内のSwitch-caseブロック

makefileの単一の論理行にあるDefineキーワード内のSwitch-caseブロック

ghc.mkこれはHaskellソースコンパイルの一部から抜粋したコードです。著者が一行にファンクションブロックを作成することにしたので、違うことがわかりました。これはmakefileの作成に関する一般的な慣行ですか?

デバッグのために各ケースハンドルにステートメントを入れるのが好きですechoが、現在の設定ではechoステートメントをシェルコマンドとして解釈することはできません。

define installLibsTo
        $(call INSTALL_DIR,$2)
        for i in $1; do \
                case $$i in \
                  *.a) \
                    $(call INSTALL_DATA,$(INSTALL_OPTS),$$i,$2); \
                    $(RANLIB_CMD) $2/`basename $$i` ;; \
                  *.dll) \
                    $(call INSTALL_PROGRAM,$(INSTALL_OPTS),$$i,$2) ; \
                    $(STRIP_CMD) $2/`basename $$i` ;; \
                  *) \
                  $(call INSTALL_DATA,$(INSTALL_OPTS),$$i,$2); \
                  esac; \
    done
endef

ベストアンサー1

makefileの構文でこれを要求するため、完全なシェルコマンドは単一の論理行にあります。 makefile ルールでは、各レシピ行は別々のシェルインスタンスで実行されます。パーサーがこのポイントに達する前にバックスラッシュ改行シーケンスが削除されるため、直後のバックスラッシュ改行文字は改行文字として扱われません。つまり、次のように書くことができます(1つのタブに8つのスペースを使用しました)。

target:
        for x in $^; do \
          somecommand $$x; \
        done

次のシェルコマンドを実行してビルドしますtarget

for x in dependency1 dependency2 dependency3; do           somecommand $x;         done

シェルはここで改行文字を受け取りません(したがって、;beforeは必須ですdone)。

このメイクファイルを作成した場合:

target:
        for x in $^; do
          somecommand $$x;
        done

その後、各for x in …; dosomecommand $x;およびはdone別々のシェルで実行されますが、機能しません。

表示される変数は、installLibsTo同じ制約を持つより大きな例です。使用すると、2つの論理レシピラインに展開されます。 1つは関数を呼び出して設定されたコマンドを実行しINSTALL_DIR、もう1つはforループを実行します。

おすすめ記事