Shakeを使用してJavaコードを構築していますが、javacコンパイラの異常な性質のためにちょっと止まっています。一般に、大きなプロジェクトの各モジュールでは、コンパイラはすべてのモジュールのソースファイルのを入力として呼び出し、すべての出力ファイルを1回のパスで生成します。続いて、コンパイラで生成された.classファイルを通常はJAR(基本的にはZIP)にアセンブルします。次のようにShakeを使用した多入力多出力コンパイラ
は、例えば、一般的なJavaモジュールのプロジェクトが配置されている:
- 複数の.javaファイルが含まれている
src
ディレクトリ、そのうちのいくつかは、深い木に多くのレベルを入れ子になりました。 bin
ディレクトリには、コンパイラの出力が含まれています。通常、この出力は同じディレクトリ構造とファイル名に従います。.class
は各.javaファイルに置き換えられますが、マッピングはではありません。は必ずしも1対1ではありません。次のように私はシェイクで定義したい
ルールはそのためです。
1)src
の下で任意のファイルがbin
下どのファイルよりも新しい場合、bin
のすべての内容を消去し、再作成:
javac -d bin <recursive list of .java files under src>
私は、このルールが過剰と思われるが、コンパイラワットを起動せずに知っています単一の入力ファイルのわずかな変更に起因する出力の変化の程度を知ることはできません。
2)bin
の下で任意のファイルは、その後でmodule.jar
再作成module.jar
よりも新しい場合:
jar cf module.jar -C bin .
感謝を!
PS静脈の応答は「Ant/Maven/Gradle /を使用してください」とは思われません。私は、これらのツールがJavaコンパイルをすぐに提供していることは知っていますが、作成して集約するのがはるかに難しいです。これが私がHaskell/Shakeベースのツールを試してみる理由です。
すばらしい、ありがとうNeil!これは基本的には動作しますが、いくつかの小さな変更が必要です。たとえば、src/bin接頭辞を含む.javaファイルと.classファイルの完全なパスを '必要 'する必要があります。また、javacを呼び出す前に 'bin'ディレクトリを明示的に作成する必要があります。私はあなたの答えを編集する必要がありますか? –
はい!私はあなたが後でsrcを前置するよりも簡単なgetDirectoryFilesを "" [src // *。java "]に変更したと思われますが、どちらも同じように(しかも効率的に)動作するはずです。ディレクトリを作成するには、liftIO $ createDirectoryが必要です。通常は、shakeが知っている出力用のディレクトリをすべて作成しますが、ここではbinについてはわかりません。 –
私は同様のことをしていますが、私は動的に生成されたFilePathを必要とするときに、「MVar操作で無期限にブロックされたスレッド」になるようです。 – user239558