【问题标题】:How can I change the compiler flags of an sbt project without causing recompilation?如何在不导致重新编译的情况下更改 sbt 项目的编译器标志?
【发布时间】:2018-05-25 13:12:44
【问题描述】:

在测试和调试使用 sbt 构建的 Scala 项目时经常出现,我需要为特定文件传递一些额外的编译器标志。例如-Xlog-implicits 来调试隐式解析问题。但是,在build.sbt 或控制台中更改scalacOptions 会使缓存无效并导致重新编译整个项目/测试套件。等待这么久除了烦人之外,这还意味着打印出大量来自不相关文件的噪音。相反,如果我可以从 sbt 控制台编译带有一些额外标志的特定文件会更好,但我没有找到这样做的方法。

【问题讨论】:

    标签: scala sbt


    【解决方案1】:

    问题

    更改scalac选项触发重新编译的原因是因为Scala的增量编译器Zinc现在不可能影响增量编译的语义,所以它是悲观的。我相信这可以改进,并且可以支持一些列入白名单的标志,这样下次像你这样的人就不必再问了。

    不过,这个问题有一个解决方案,而且比乍看之下更通用。

    解决方案

    您可以在您的 sbt 构建中创建一个子项目,它是您想要“记录隐含”的项目的副本,但默认启用 -Xlog-implicits。

    // Let's say foo is your project definition
    lazy val foo = project.settings(???)
    
    // You define the copy of your project like this
    lazy val foo-implicits = foo
      .copy(id = "foo-implicits")
      .settings(
        target := baseDirectory.value./("another-target"),
        scalacOptions += "-Xlog-implicits"
      )
    

    注意这段代码sn-p的以下属性:

    1. 我们重新定义了项目 ID,因为当我们重用项目定义时,该 ID 仍与前一个相同(在本例中为 foo)。当存在共享相同 id 的项目时,Sbt 会失败。
    2. 我们重新定义目标目录是因为我们想避免重新编译。如果我们保持和之前一样,那么重新编译foo-implicits会删除之前编译的编译产物(反之亦然)。这正是我们想要避免的。
    3. 根据您在此问题中的要求,我们将 -Xlog-implicits 添加到 Scalac 选项中。在通用解决方案中,这段代码应该消失。

    什么时候有用?

    这不仅对您的用例有用,而且当您希望在不同的 Scala 版本中拥有同一项目的不同模块时。以下有两个好处:

    1. 您没有在 sbt ++ 中使用交叉编译,这是已知的一些内存问题。
    2. 您可以添加仅适用于具体 Scala 版本的新库依赖项。

    它有更多的应用,但我希望这能解决你的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-01-28
      • 2012-03-15
      • 2012-07-05
      • 2010-09-07
      • 2012-12-13
      • 2013-06-06
      • 1970-01-01
      • 2013-01-21
      相关资源
      最近更新 更多