2

プロジェクト内のすべての「Makefile」を検索し、それらに基づいてルールを生成したいと考えています。ただし、(意図的に) Action から逃れることはできないように見えます。そのため、代わりに「Makefile」スキャナーをシェイク機能の前の IO 操作に持ち上げました。

main = do
  makefiles <- findMakefiles
  shake skakeOptions $ generate_rules makefiles

より良い方法はありますか?

4

1 に答える 1

1

まず、現在のアプローチに問題はないと思います。Shake パッケージ自体は、組み込みの Ninja および Makefile インタープリターに対して同様のアプローチを使用します。 Makefile インタープリター またはSake インタープリターの詳細を参照してください。Makefile の処理が問題にならないほど高速である限り (通常は問題ありません)、基本的に Shake を使用してカスタム ビルド構文のインタープリターを作成していることになり、うまく機能します。

Makefile の処理にコストがかかる場合や、Makefile 自体に他の依存関係がある場合など、このアプローチを避けるべきいくつかの理由があります。そのような状況では、 の組み合わせを使用しnewCacheて Makefile を 1 回解析するaddOracleことができるため、ルールは必要な Makefile のサブセットに依存することができます。ただし、このアプローチは基本的に間接的なレイヤーを強制するため、うまくいくにはトリッキーですgenerate_rulesghc-makeパッケージはこの手法を使用し (「makefile」ルールと への呼び出しをnewCache参照)、usingConfigFileShake パッケージの関数は同じ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置き換えることができます。shakeshakeArgs

于 2014-08-18T07:00:13.627 に答える