作用域基础

本页介绍作用域。

关于键的完整说明

前面我们假设像 name 这样的键对应 sbt 键值对映射中的一个条目。这是一种简化。在实际构建中,每个键可以在多个上下文中各自关联一个值,这些上下文称为作用域。

一些具体示例:

  • 如果构建定义中有多个子项目,同一个键在每个子项目中可以有不同的值。
  • 如果您希望以不同方式编译主源代码和测试源代码,compile 键可以为两者分别设置不同的值。
  • scalacOptions 键(包含 Scala 编译器选项)在编译类文件(compile)和运行 REPL(console)时可以有不同的值。

统一斜杠语法

sbt 中完整的作用域使用统一斜杠语法来描述:

projA / Compile / console / scalacOptions

它们表示三个层级的作用域划分:

  • 子项目作用域
  • 依赖配置作用域
  • 任务作用域

Note

统一斜杠语法于 sbt 1.1 引入,可同时用于 sbt shell 和 build.sbt。

按子项目划分作用域

如果您在一个构建中放置多个子项目,每个子项目都需要各自的设置。在 sbt shell 中,可以按如下方式编译特定的子项目:

sbt> projA/compile

按依赖配置划分作用域

依赖配置(简称配置)定义了一个库依赖图,并可能拥有自己的类路径、源代码、生成的包等。

sbt 中常见的一些配置:

  • Compile:定义主代码(src/main/scala)。
  • Test:定义如何编译测试(src/test/scala)。
  • Runtime:定义 run 任务的类路径。

在 sbt shell 中,可以按如下方式编译测试代码,这同时也会编译主代码:

sbt> Test/compile

在 build.sbt 中,可以按如下方式指定以 fork 方式运行测试:

Test / fork := true

按任务划分作用域

设置可以影响任务的工作方式。例如,compile 任务会受到 scalacOptions 设置的影响。

为此,任务键(如 compile)可以作为另一个键(如 scalacOptions)的作用域。调用 Scala 编译器的各种任务(compile、console、doc)可以共享 scalacOptions 等与编译相关的键,并且这些键在各任务中可以有不同的值。

scalaVersion := "3.9.0"
Compile / scalacOptions ++= List("-deprecation", "-Werror", "-Wunused:imports")
Compile / console / scalacOptions --= List("-Werror", "-Wunused:imports")

检查作用域

在 sbt shell 中,可以使用 inspect 命令来了解键及其作用域。试试 inspect Test / fullClasspath:

sbt:Hello> inspect Test / fullClasspath
[info] Task: Seq[class sbt.internal.util.Attributed]
[info] Description:
[info] 	The exported classpath, consisting of build products and unmanaged and
        managed, internal and external dependencies.
[info] Provided by:
[info] 	Test / fullClasspath
[info] Defined at:
[info] 	Defaults.scala:2823
[info] Dependencies:
[info] 	Test / fullClasspath / streams
[info] 	Test / exportedProducts
[info] 	Test / dependencyClasspath
[info] Reverse dependencies:
[info] 	Test / fgRun
[info] 	Test / run / bspBuildTargetJvmEnvironmentItem
[info] 	Test / console
[info] 	Test / fgRunMain
[info] 	Test / testLoader
[info] 	Test / bspBuildTargetJvmEnvironmentItem
....

更多详情,请参阅 sbt inspect 参考指南。