1. 配置 Scala

配置 Scala 

sbt 需要为项目获取 Scala,它可以自动执行此操作,也可以显式配置。为项目配置的 Scala 版本将编译、运行、文档化并为项目代码提供 REPL。编译项目时,sbt 需要运行 Scala 编译器,并为编译器提供类路径,这可能包括多个 Scala jar,例如反射 jar。

自动管理的 Scala 

最常见的情况是,您想使用仓库中可用的 Scala 版本。唯一需要的配置是您要使用的 Scala 版本。例如,

scalaVersion := "2.10.0"

这将从通过 resolvers 设置配置的仓库中检索 Scala。它将使用此版本构建您的项目:编译、运行、scaladoc 和 REPL。

配置 scala-library 依赖项 

默认情况下,标准 Scala 库会自动添加为依赖项。如果您想将其配置为与默认值不同,或者您的项目只有 Java 源代码,请设置

autoScalaLibrary := false

为了编译 Scala 源代码,Scala 库需要位于类路径上。当 autoScalaLibrary 为 true 时,Scala 库将位于所有类路径上:测试、运行时和编译。否则,您需要像添加任何其他依赖项一样添加它。例如,以下依赖项定义仅在测试中使用 Scala

autoScalaLibrary := false

libraryDependencies += "org.scala-lang" % "scala-library" % scalaVersion.value % "test"

配置其他 Scala 依赖项 

当使用标准库以外的 Scala 依赖项时,将其添加为正常的托管依赖项。例如,要依赖于 Scala 编译器,

libraryDependencies += "org.scala-lang" % "scala-compiler" % scalaVersion.value

请注意,无论上一节中描述的 autoScalaLibrary 设置的值如何,这都是必需的。

配置 Scala 工具依赖项 

为了编译 Scala 代码、运行 scaladoc 并提供 Scala REPL,sbt 需要 scala-compiler jar。这应该不是项目的正常依赖项,因此 sbt 在特殊的私有 scala-tool 配置中添加了对 scala-compiler 的依赖项。在某些情况下,您可能希望对此进行更多控制。使用 managedScalaInstance 键禁用此自动行为

managedScalaInstance := false

这也会禁用对 scala-library 的自动依赖。如果您不需要 Scala 编译器执行任何操作(编译、REPL、scaladoc 等),则可以到此为止。在这种情况下,sbt 不需要您的项目中的 Scala 实例。否则,sbt 仍然需要访问 Scala 编译器的 jar 文件,用于编译和其他任务。您可以通过在 scala-tool 配置中声明依赖项或通过显式定义 scalaInstance 来提供它们。

在第一种情况下,添加 scala-tool 配置并在该配置中添加对 scala-compiler 的依赖项。组织并不重要,但 sbt 需要模块名称为 scala-compilerscala-library,以便适当地处理这些 jar 文件。例如,

managedScalaInstance := false

// Add the configuration for the dependencies on Scala tool jars
// You can also use a manually constructed configuration like:
//   config("scala-tool").hide
ivyConfigurations += Configurations.ScalaTool

// Add the usual dependency on the library as well on the compiler in the
//  'scala-tool' configuration
libraryDependencies ++= Seq(
   "org.scala-lang" % "scala-library" % scalaVersion.value,
   "org.scala-lang" % "scala-compiler" % scalaVersion.value % "scala-tool"
)

在第二种情况下,直接构造类型为 ScalaInstance 的值,通常使用 伴生对象 中的方法,并将其分配给 scalaInstance。您还需要将 scala-library jar 添加到类路径中,以编译和运行 Scala 源代码。例如,

managedScalaInstance := false
scalaInstance := ...
Compile / unmanagedJars += scalaInstance.value.libraryJar

切换到本地 Scala 版本 

要使用本地构建的 Scala 版本,请按照下一节中的说明配置 Scala 主目录。Scala 仍然会像以前一样解析,但 jar 文件将来自配置的 Scala 主目录。

使用来自本地目录的 Scala 

从源代码构建 Scala 的结果是 Scala 主目录 <base>/build/pack/,其中包含一个子目录 lib/,其中包含 Scala 库、编译器和其他 jar 文件。通过下载和解压缩 Scala 分发版可以获得相同的目录布局。此类 Scala 主目录可以通过设置 scalaHome 来用作 jar 文件的源代码。例如,

scalaHome := Some(file("/home/user/scala-2.10/"))

默认情况下,lib/scala-library.jar 将被添加到非托管类路径中,lib/scala-compiler.jar 将被用于编译 Scala 源代码并提供 Scala REPL。不会在 scala-library 上记录托管依赖项。这意味着 Scala 只有在您显式定义对 Scala 的依赖项或 Scala 通过依赖项间接依赖的情况下才会从仓库中解析。在这些情况下,解析的依赖项的工件将被 Scala 主目录 lib/ 目录中的 jar 文件替换。

与托管依赖项混合 

例如,考虑在配置 scalaHome 时添加对 scala-reflect 的依赖项

scalaHome := Some(file("/home/user/scala-2.10/"))

libraryDependencies += "org.scala-lang" % "scala-reflect" % scalaVersion.value

这将像往常一样解析,只是 sbt 会查看 /home/user/scala-2.10/lib/scala-reflect.jar 是否存在。如果存在,该文件将用于替换托管依赖项中的工件。

仅使用非托管依赖项 

您可以直接添加 Scala jar 文件,而不是添加对它们的托管依赖项。scalaInstance 任务提供了对 Scala 分发版的结构化访问。例如,要添加 Scala 主目录 lib/ 目录中的所有 jar 文件,

scalaHome := Some(file("/home/user/scala-2.10/"))

Compile / unmanagedJars ++= scalaInstance.value.jars

要仅添加一些 jar 文件,请在添加它们之前从 scalaInstance 中过滤掉 jar 文件。

sbt 的 Scala 版本 

sbt 需要 Scala jar 文件才能运行自身,因为它是用 Scala 编写的。sbt 使用相同的 Scala 版本编译您为项目编写的构建定义,因为它们使用 sbt API。此 Scala 版本在特定 sbt 版本中固定,无法更改。对于 sbt 1.9.8,此版本为 Scala 2.12.18。由于此 Scala 版本在 sbt 运行之前是必需的,因此用于检索此版本的仓库是在 sbt 启动器 中配置的。