首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何防止SBT重新编译修改的.class文件?

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

Stack Overflow用户
提问于 2014-09-23 09:55:36
回答 3查看 536关注 0票数 5

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

代码语言:javascript
复制
enhance <<= enhance triggeredBy (compile in Compile)

问题是sbt有一种叫做增量重新编译的机制。它监视生成的.class文件。每次增强器重写生成的.class文件时,sbt都会识别这些修改,并在下一个编译命令中重新编译相关的源代码。

对我们来说,重新编译是一项耗费时间的工作。我们希望停止sbt重新编译修改后的.class文件。这可能意味着使sbt只监视源更改,而不是输出更改。

我对此做了些调查。但我在这件事上发现了一些小事。现在,我知道一个名为Analysis的特性可能负责从源到输出.class文件的映射。所以我向你们求助。

Ps:我们可以通过将增强的输出放到另一个文件夹来解决这个问题,但是它不是首选的。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-09-24 18:45:57

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

经过一定的研究,我们发现sbt注意到了文件修改的时间。也就是说,我们可以通过回滚修改后的最后修改时间来欺骗sbt,这样sbt就不会注意到任何更改。

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

  1. 查找所有.class文件
  2. 记下他们上次修改的时间
  3. 做增强
  4. 把前一次修改的时间放回去

这是个小把戏。我们仍然期望有更有力的解决办法。

票数 2
EN

Stack Overflow用户

发布于 2014-09-23 20:15:00

sbt 强烈阻止文件的突变。.您应该生成不同的文件。通过这样做,您将解决问题,因为sbt的增量编译器仍将查看未修改的.class文件。您将需要重新布线:

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

代码语言:javascript
复制
classDirectory in Compile := crossTarget.value / "classes-orig"

使用工具处理这些.class文件,并将它们发送到crossTarget.value / "classes" (原始classDirectory )

代码语言:javascript
复制
enhance <<= enhance triggeredBy (compile in Compile)

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

重新连接productDirectories以使用crossTarget.value / "classes" (否则它将在修改后的classDirectory中查找

代码语言:javascript
复制
productDirectories in Compile := Seq(crossTarget.value / "classes")

确保products依赖于您的enhance任务:

代码语言:javascript
复制
products in Compile <<= (products in Compile) dependsOn enhance

如果您有资源,您可能需要更多的重新布线(请参阅copyResources)。但基本上你应该能到那里。

票数 4
EN

Stack Overflow用户

发布于 2018-08-31 13:19:21

描述:

有点像Chenyu,我不得不为SBT 1.x编写一个插件,它将增强编译后的类,后来我想确保这些增强类用于构建 jar

我不想黑这个解决方案,所以陈宇的回答对我来说是不可接受的,sjrd的回答非常有用,但适应了SBT 0.13

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

代码:

代码语言:javascript
复制
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
)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25992100

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档