在 sbt 0.13 中使用 .sbt 文件编写多项目构建的惯用方式

Posted

技术标签:

【中文标题】在 sbt 0.13 中使用 .sbt 文件编写多项目构建的惯用方式【英文标题】:Idiomatic way to write multi-project builds with .sbt files in sbt 0.13 【发布时间】:2013-07-25 08:51:54 【问题描述】:

我听说 .sbt 文件在 0.13 中以各种方式进行了改进,现在我可以在其中指定多项目构建。

http://www.scala-sbt.org/0.13.0/docs/Community/ChangeSummary_0.13.0.html#sbt-format-enhancements 提到我们现在可以在 .sbt 文件中定义子项目。我也知道根目录下的多个 .sbt 文件会聚合成一个概念文件。

不过,我真正想要的是不要让十几个子项目 .sbt 文件污染我的根目录。有没有办法可以将子项目 build.sbt 文件放入它们各自的子目录中,在它们之间共享一些公共代码,然后为聚合子项目的整个项目创建一个根 build.sbt?我现在在 .scala 文件中有类似的设置,但如果可能的话,我更愿意使用 .sbt 文件。

如果不可能,用 .sbt 文件构建大型多项目构建的“正确”方法是什么?

【问题讨论】:

【参考方案1】:

在 0.12 中应该已经是这样了,您可以将 .sbt 文件放在子项目的基本目录中,并且那里的设置将包含在该项目的范围内。

通过在project/ 中创建一个普通的.scala 文件,可以在.sbt 文件之间重用代码。 project/ 中的代码可用于.sbt 文件。一个.sbt 中的定义对其他.sbt 文件不可见,至少在0.13 中是这样。这主要是一个实现限制,未来版本是否会取消,尚不确定。

默认根项目将聚合所有子项目,包括来自subProject/build.sbt 中定义的项目的子项目。

当前的困难在于明确。 例如,根目录中的以下build.sbt 将在sub/ 中定义一个子项目。 这是一个完整的定义,定义了项目的 ID、基目录等。

<root>/build.sbt

lazy val sub = project

但是,它不能引用<sub>/build.sbt 中定义的任何内容。 (sub/build.sbt 的存在直到 <root>/build.sbt 被编译和评估之后才知道。) 因此,要明确定义 sub 聚合的内容,您需要类似以下内容:

sub/build.sbt

lazy val sub = project.in(file(".")).aggregates(subSub)
//or: lazy val sub = project in file(".") aggregate subSub

lazy val subSub = project

但是,这重复了sub 的定义。

一个可能的解决方案是让根定义只是一个参考,例如:

<root>/build.sbt

lazy val sub = LocalProject("sub")

【讨论】:

从 0.13 开始,我可以在 .sbt 文件中添加项目定义。如果我将这样的项目值放在subproject1/build.sbt 中并想定义一个聚合子项目构建的根项目怎么办?如果 .sbt 文件之间的值不可见,聚合或创建跨子项目依赖项似乎很棘手。 澄清一下,我的最终目标是尽可能地划分子项目,并尽量减少需要放入通用 .scala 文件中的代码量。我肯定必须在子项目之间保留一些通用代码,但希望它们尽可能独立。 已更新以解决您的 cmets。指示的可能解决方案没有实施,只是一个概念解决方案。 这很有帮助,谢谢。我会看看我遇到了多少痛苦:) 最近的更新是否对这些指南进行了更改? AutoPlugins 等。我想知道写一个规范的“这就是你应该如何制作大型花哨的多项目构建”文档是否值得。我知道手册中有一个,但它告诉您比您应该如何做更多的事情。

以上是关于在 sbt 0.13 中使用 .sbt 文件编写多项目构建的惯用方式的主要内容,如果未能解决你的问题,请参考以下文章

未解决的依赖:org.scala-sbt#sbt; 0.13:运行sbt 0.13时找不到?

IntelliJ IDEA 12 与 sbt 0.13

SBT 打包本地文件

Windows上的sbt 0.13 - 无法访问存储库

测试 sbt 插件

Sbt 0.13 插件依赖和 scala-reflect.jar 版本冲突