多项目基础

虽然简单程序可以从单项目构建开始,但更常见的是将构建拆分为多个较小的子项目。

构建中的每个子项目都有自己的源目录,运行 packageBin 时会生成自己的 JAR 文件,总体上与其他项目的工作方式相同。

子项目通过声明类型为 Projectlazy val 来定义。例如:

scalaVersion := "3.8.1"
LocalRootProject / publish / skip := true

lazy val core = (project in file("core"))
  .settings(
    name := "core",
  )

lazy val util = (project in file("util"))
  .dependsOn(core)
  .settings(
    name := "util",
  )

val 的名称用作子项目的 ID,用于在 sbt shell 中引用该子项目。

sbt 始终会定义一个根项目,因此在上面的构建定义中,我们将共有三个子项目。

子项目依赖

子项目可以依赖另一个子项目的代码。通过声明 dependsOn(...) 实现。例如,如果 util 需要在其 classpath 上使用 core,您可以将 util 定义为:

lazy val util = (project in file("util"))
  .dependsOn(core)

根项目

构建根目录下的子项目称为 root project(根项目),通常在构建中扮演特殊角色。如果未在构建的根目录定义子项目,sbt 会自动创建一个默认的根项目,用于聚合构建中的所有其他子项目。

任务聚合

任务聚合是指在聚合子项目上运行任务时,也会在被聚合的子项目上运行。

scalaVersion := "3.8.1"

lazy val root = rootProject
  .autoAggregate
  .settings(
    publish / skip := true
  )

lazy val util = (project in file("util"))

lazy val core = (project in file("core"))

在上面的示例中,根子项目聚合了 utilcore。当您在 sbt shell 中输入 compile 时,所有三个子项目将并行编译。

通用设置

在 sbt 2.x 中,直接在 build.sbt 中编写且不带 settings(...) 的裸设置是 common settings(通用设置),会注入到所有子项目中。

scalaVersion := "3.8.1"

lazy val core = (project in file("core"))

lazy val app = (project in file("app"))
  .dependsOn(core)

在上面的示例中,scalaVersion 设置应用于默认根子项目、coreutil

此规则的一个例外是已经限定到子项目的设置。

scalaVersion := "3.8.1"

lazy val core = (project in file("core"))

lazy val app = (project in file("app"))
  .dependsOn(core)

// This is applied only to app
app / name := "app1"

我们可以利用此例外,添加仅适用于默认根项目的设置,如下所示:

scalaVersion := "3.8.1"

lazy val core = (project in file("core"))

lazy val app = (project in file("app"))
  .dependsOn(core)

// These are applied only to root
LocalRootProject / name := "root"
LocalRootProject / publish / skip := true