2013-06-25 14 views
11

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ベースのツールを試してみる理由です。

答えて

8

名前が静的に特定できない複数の出力を生成する書き込み規則は、少し複雑です。通常の方法は、名前が静的に知られている出力を見つけることです。常にneedが存在する場合、または存在しない場合は、静的出力として使用する偽ファイルを作成します(ghc-make, the .result file)。あなたのケースでは、究極の出力としてmodule.jarを持っているので、私は書くでしょう:

"module.jar" *> \out -> do 
    javas <- getDirectoryFiles "" ["src//*.java"] 
    need javas 
    liftIO $ removeFiles "" ["bin//*"] 
    liftIO $ createDirectory "bin" 
    () <- cmd "javac -d bin" javas 
    classes <- getDirectoryFiles "" ["bin//*.class"] 
    need classes 
    cmd "jar cf" [out] "-C bin ." 

あなたは.classファイルに依存しません(そして実際にすることはできませんので、二つの規則にそれを分割への利点は、ありませんが、それらが名前の中で予測できないので)、ソースファイルが変更された場合、常にmodule.jarを再構築します。このルールには、あなたが言及しているすべての依存関係があります。また、.javaまたは.classファイルを追加/名前変更/削除すると、getDirectoryFiles呼び出しが追跡されるため、自動的に再コンパイルされます。

+0

すばらしい、ありがとうNeil!これは基本的には動作しますが、いくつかの小さな変更が必要です。たとえば、src/bin接頭辞を含む.javaファイルと.classファイルの完全なパスを '必要 'する必要があります。また、javacを呼び出す前に 'bin'ディレクトリを明示的に作成する必要があります。私はあなたの答えを編集する必要がありますか? –

+0

はい!私はあなたが後でsrcを前置するよりも簡単なgetDirectoryFilesを "" [src // *。java "]に変更したと思われますが、どちらも同じように(しかも効率的​​に)動作するはずです。ディレクトリを作成するには、liftIO $ createDirectoryが必要です。通常は、shakeが知っている出力用のディレクトリをすべて作成しますが、ここではbinについてはわかりません。 –

+0

私は同様のことをしていますが、私は動的に生成されたFilePathを必要とするときに、「MVar操作で無期限にブロックされたスレッド」になるようです。 – user239558

関連する問題