5

私たちのプロジェクトでは、コンパイルによって生成された .class ファイルへの強化された後処理があります。この拡張ステップでは、生成された .class ファイルが実際に変更され、上書きされます。

enhance <<= enhance triggeredBy (compile in Compile)

問題は、sbt には増分再コンパイルと呼ばれるメカニズムがあることです。生成された .class ファイルを監視します。エンハンサーが生成された .class ファイルをオーバーライドするたびに、sbt はこれらの変更を認識し、次のコンパイル コマンドで関連するソースを再コンパイルします。

私たちにとって、再コンパイルは非常に時間のかかる作業です。sbt が変更された .class ファイルを再コンパイルするのを止めたい。これは、sbt が出力の変更ではなく、ソースの変更のみを監視するようにすることを意味する場合があります。

私はこれについていくつかの検索を行いました。しかし、私はこれについて小さなことを見つけました。これで、Analysis と呼ばれる特性が、ソースから出力 .class ファイルへのマッピングに関与している可能性が高いことがわかりました。だから私はあなたたちに助けを求めます。

追伸: この問題は、enhance の出力を別のフォルダーに置くことで解決できるかもしれませんが、それは好ましくありません。

4

3 に答える 3

4

sbtは、ファイルへの変更を強く思いとどまらせます代わりに別のファイルを生成する必要があります。そうすることで、sbt のインクリメンタル コンパイラはまだ変更されていない .class ファイルを参照するため、問題は解決します。再配線を行う必要があります。

compileタスクの出力を別の場所に送信します。

classDirectory in Compile := crossTarget.value / "classes-orig"

これらの .class ファイルをツールで処理し、crossTarget.value / "classes"(元のclassDirectory:

enhance <<= enhance triggeredBy (compile in Compile)

enhance := {
  val fromDir := (classesDirectory in Compile).value
  val toDir := crossTarget.value / "classes"
  ...
}

とにかくproductDirectories使用するように再配線しますcrossTarget.value / "classes"(そうしないと、変更されたclassDirectory:

productDirectories in Compile := Seq(crossTarget.value / "classes")

あなたのタスクproductsに依存していることを確認してください:enhance

products in Compile <<= (products in Compile) dependsOn enhance

リソースがある場合は、さらに再配線が必要になる場合があります (「 」を参照copyResources)。しかし、基本的にはそこに到達できるはずです。

于 2014-09-23T20:15:00.720 に答える
2

sbt が出力 .class ファイルを監視することについて述べました。.class ファイルが変更されると、.class ファイルのソースが再コンパイルされます。

いくつかの調査の結果、sbt はファイルの変更を最終変更時刻までに通知することがわかりました。つまり、変更後に最後に変更された時刻をロールバックすることで sbt をだますことができるので、sbt は変更に気付かないようにすることができます。

したがって、私たちのソリューションはシンプルですが効果的です。

  1. すべての .class ファイルを見つける
  2. 最終更新時刻を書き留めます
  3. エンハンスをする
  4. 以前の最終更新時刻を戻す

これは小さなトリックです。より堅牢なソリューションを引き続き期待しています。

于 2014-09-24T18:45:57.023 に答える