プロジェクト内のすべての「Makefile」を検索し、それらに基づいてルールを生成したいと考えています。ただし、(意図的に) Action から逃れることはできないように見えます。そのため、代わりに「Makefile」スキャナーをシェイク機能の前の IO 操作に持ち上げました。
main = do
makefiles <- findMakefiles
shake skakeOptions $ generate_rules makefiles
より良い方法はありますか?
プロジェクト内のすべての「Makefile」を検索し、それらに基づいてルールを生成したいと考えています。ただし、(意図的に) Action から逃れることはできないように見えます。そのため、代わりに「Makefile」スキャナーをシェイク機能の前の IO 操作に持ち上げました。
main = do
makefiles <- findMakefiles
shake skakeOptions $ generate_rules makefiles
より良い方法はありますか?
まず、現在のアプローチに問題はないと思います。Shake パッケージ自体は、組み込みの Ninja および Makefile インタープリターに対して同様のアプローチを使用します。 Makefile インタープリター またはSake インタープリターの詳細を参照してください。Makefile の処理が問題にならないほど高速である限り (通常は問題ありません)、基本的に Shake を使用してカスタム ビルド構文のインタープリターを作成していることになり、うまく機能します。
Makefile の処理にコストがかかる場合や、Makefile 自体に他の依存関係がある場合など、このアプローチを避けるべきいくつかの理由があります。そのような状況では、 の組み合わせを使用しnewCache
て Makefile を 1 回解析するaddOracle
ことができるため、ルールは必要な Makefile のサブセットに依存することができます。ただし、このアプローチは基本的に間接的なレイヤーを強制するため、うまくいくにはトリッキーですgenerate_rules
。ghc-makeパッケージはこの手法を使用し (「makefile」ルールと への呼び出しをnewCache
参照)、usingConfigFile
Shake パッケージの関数は同じnewCache
/addOracle
パターンを使用します。
元のアプローチに固執すると、一歩を踏み出すことができる少し異なる場所がありますfindMakefiles
。できるよ:
main = shakeArgsWith shakeOptions [] $ \_ -> xs -> do
makefiles <- findMakefiles
let rules = generate_rules makefiles
if null xs then rules else withoutActions rules >> want xs
これには、コマンド ライン フラグを簡単に追加して、Makefile の場所やそれを処理するためのオプションを見つけられるという利点があります。Shake の Ninja システムと Makefile システムの両方がそれをサポートし、--makefile=FILE
デフォルトをオーバーライドするために使用します。を移動したくない場合でも、コマンド ライン処理を提供する元の例でにgenerate_rules
置き換えることができます。shake
shakeArgs