Scala 如何防止SBT重新编译修改过的.class文件?

Scala 如何防止SBT重新编译修改过的.class文件?,scala,sbt,incremental-compiler,Scala,Sbt,Incremental Compiler,在我们的项目中,我们对编译生成的.class文件进行了增强后处理。此增强步骤实际上修改生成的.class文件,然后覆盖它 enhance <<= enhance triggeredBy (compile in Compile) 增强sbt。您应该生成不同的文件。通过这样做,您将解决您的问题,因为sbt的增量编译器仍将查看未更改的.class文件。您将需要重新布线: 将编译任务的输出发送到其他地方: classDirectory in Compile := crossTarget.v

在我们的项目中,我们对编译生成的.class文件进行了增强后处理。此增强步骤实际上修改生成的.class文件,然后覆盖它

enhance <<= enhance triggeredBy (compile in Compile)
增强sbt。您应该生成不同的文件。通过这样做,您将解决您的问题,因为sbt的增量编译器仍将查看未更改的.class文件。您将需要重新布线:

编译任务的输出发送到其他地方:

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 in Compile := Seq(crossTarget.value / "classes")
确保
产品
取决于您的
增强
任务:

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

products in Compile我说过sbt监视输出的.class文件。当修改.class文件时,它会重新编译.class文件的源代码

经过一些研究,我们发现sbt通过上次修改的时间来通知文件的修改。也就是说,我们可以通过在修改后回滚上次修改的时间来愚弄sbt,这样sbt就不会注意到任何更改

因此,我们的解决方案简单但有效:

  • 查找所有.class文件
  • 记下他们最后修改的时间
  • 你觉得这有什么好处
  • 把上次修改的时间放回去
  • 这是一个小技巧。我们仍然希望得到更可靠的解决方案。

    说明: 有点像Chenyu,我必须为SBT1.x写一个插件,它将增强编译类,后来我想确保那些增强类被用于构建jar

    我不想破解这个解决方案,所以我不能接受,而且非常有帮助,但调整为
    sbt0.13

    下面是我的工作解决方案,没有什么评论:

    代码:
    使用已编译的类创建单独的项目,并将其添加为依赖项(库)到您的play项目。@AndrzejJozwik感谢您的评论。您建议的方式不是首选方式,因为它距离我们的目标还有很长的路要走。由于我们的项目是一个非常大的项目,增加的复杂性可能会导致更多的问题。我们希望找到一种直接解决问题的方法。
    object autoImport {
      val enhancedDest = settingKey[File]("Output dir for enhanced sources")
    }
    
    def enhanceTask: Def.Initialize[Task[Unit]] = Def.task {
      val inputDir = (classDirectory in Compile).value
      val outputDir = enhancedDest.value
      enhance(inputDir, outputDir)
      ...
    }
    
    override def projectSettings: Seq[Def.Setting[_]] = Seq(
      enhancedDest := crossTarget.value / "classes-enhanced",
      products in Compile := Seq(enhancedDest.value), // mark enhanced folder to use for packaging
    
      // https://www.scala-sbt.org/1.0/docs/Howto-Dynamic-Task.html#build.sbt+v2
      compile in Compile := Def.taskDyn {
        val c = (compile in Compile).value // compile 1st.
        Def.task {
          (copyResources in Compile).value // copy resources before enhance        
          enhanceTask.value                // enhance
          c
        }
      }.value
    )