4

コンパイルにかなりの時間がかかる (独立した) ファイルがいくつかあるので、Don Stewart の回答hereに従って、並列コンパイルを試してみようと思いました。

ここの指示に従ったので、メイクファイルは次のようになります

quickbuild:
    ghc --make MyProg.hs -o MyProg

depend:
    ghc -M -dep-makefile makefile MyProg

# DO NOT DELETE: Beginning of Haskell dependencies
...
MyProg.o : MyProg.hs
MyProg.o : B.hi
MyProg.o : C.hi
...
# DO NOT DELETE: End of Haskell dependenciesghc

(注: docsに反して、GHC は "makefile" が存在する場合でも、"makefile" ではなく "Makefile" にデフォルト設定されているようです。)

私の質問は次のとおりです。quickbuild を auto-gen の依存関係のいずれかに依存させるにはどうすればよいですか (make が実際に並行して実行されるようにするため)。'quickbuild' の依存リストに 'MyProg.o' を追加しようとしましたが、'make' は (当然のことながら) 'B.hi' をビルドするルールがないと文句を言いました。

4

1 に答える 1

1

makeこのような目的には使用しないことをお勧めします。

ghc-parmakeとその問題、特にこれを見てください。GHCには非常に洗練された再コンパイル チェッカーがあり、Makefile で複製することはできません (たとえば、自分のプロジェクトの外部のパッケージ ファイルが変更されたかどうかを検出できます)。

また、複数の GHC を並列に実行する場合、並列から大きなスピードアップ (実際には > 2 ではない) は得られません。make -jこれは、複数の GHC を起動すると起動時のオーバーヘッドが大きくなり、 によって回避されるためghc --makeです。.hi特に、新しい GHC 呼び出しのたびに、コンパイルしているモジュールのすべての依存関係に含まれるすべてのインターフェース ファイルを解析して型チェックする必要があります。ghc --makeそれらをキャッシュします。

代わりに、ghc --make -jGHC 7.8 の新しいものを使用してください。これは真に並列です。

手動で作成した Makefile よりも信頼性が高く、手間がかからず、ファイルのタイム スタンプを使用して Make よりも再コンパイルを回避できます。


一見、これは Haskell の欠点のように思えますが、実際にはそうではありません。ビルドに使用するのが好きな他の言語make(C++ など) では、プロジェクト外のファイルがいつ変更されたかに気付くことは不可能です。コンパイラ自体にビルドシステムがあると、ghc --makeこれに気付くことができます。

于 2014-02-28T10:56:05.527 に答える