本页假设您已阅读了之前的入门页面,特别是构建定义、作用域和任务图。
库依赖可以以两种方式添加
lib
目录中的 jar 文件大多数人使用托管依赖而不是非托管依赖。但非托管依赖在开始时可能更简单。
非托管依赖的工作原理如下:将 jar 文件添加到 lib
中,它们将被放在项目类路径上。就这么简单!
您也可以将测试 jar 文件(例如 ScalaCheck、Specs2 和 ScalaTest)放在 lib
中。
lib
中的依赖项将被放在所有类路径上(对于 compile
、test
、run
和 console
)。如果您想更改其中一个的类路径,例如,您可以调整 Compile / dependencyClasspath
或 Runtime / dependencyClasspath
。
要使用非托管依赖,不需要在 build.sbt
中添加任何内容,尽管如果您想使用不同的目录而不是 lib
,可以更改 unmanagedBase
密钥。
要使用 custom_lib
而不是 lib
unmanagedBase := baseDirectory.value / "custom_lib"
baseDirectory
是项目的根目录,因此在这里您使用特殊方法 value
更改 unmanagedBase
,具体取决于 baseDirectory
,如 任务图 中所述。
还有一个 unmanagedJars
任务,它列出来自 unmanagedBase
目录的 jar 文件。如果您想使用多个目录或执行其他复杂的操作,则可能需要将整个 unmanagedJars
任务替换为执行其他操作的任务,例如,无论 lib
目录中的文件如何,都清空 Compile
配置的列表
Compile / unmanagedJars := Seq.empty[sbt.Attributed[java.io.File]]
sbt 使用 Coursier 来实现托管依赖,因此如果您熟悉 Coursier、Apache Ivy 或 Maven,您将不会遇到太多麻烦。
libraryDependencies
密钥 大多数情况下,您只需在设置 libraryDependencies
中列出您的依赖项。您也可以编写 Maven POM 文件或 Ivy 配置文件来外部配置您的依赖项,并让 sbt 使用这些外部配置文件。您可以了解有关此处的更多信息。
声明依赖项看起来像这样,其中 groupId
、artifactId
和 revision
是字符串
libraryDependencies += groupID % artifactID % revision
或者像这样,其中 configuration
可以是字符串或 Configuration
值(例如 Test
)
libraryDependencies += groupID % artifactID % revision % configuration
libraryDependencies
在 Keys 中声明如下
val libraryDependencies = settingKey[Seq[ModuleID]]("Declares managed dependencies.")
%
方法从字符串创建 ModuleID
对象,然后您将这些 ModuleID
添加到 libraryDependencies
中。
当然,sbt(通过 Coursier)必须知道从哪里下载模块。如果您的模块位于 sbt 附带的默认仓库之一,则这将正常工作。例如,Apache Derby 位于标准 Maven2 仓库中
libraryDependencies += "org.apache.derby" % "derby" % "10.4.1.3"
如果您在 build.sbt
中输入它,然后 update
,sbt 应该将 Derby 下载到 Coursier 缓存 中。(顺便说一句,update
是 compile
的依赖项,因此大多数情况下无需手动键入 update
。)
当然,您也可以使用 ++=
一次添加多个依赖项
libraryDependencies ++= Seq(
groupID % artifactID % revision,
groupID % otherID % otherRevision
)
在极少数情况下,您也可能发现使用 :=
与 libraryDependencies
的原因。
%%
获取正确的 Scala 版本 如果您使用 organization %% moduleName % version
而不是 organization % moduleName % version
(区别在于 organization
后的双 %%
),sbt 将将您的项目的二进制 Scala 版本添加到构件名称中。这只是一个快捷方式。您可以在没有 %%
的情况下编写它
libraryDependencies += "org.scala-stm" % "scala-stm_2.13" % "0.9.1"
假设您构建的 scalaVersion
为 2.13.12
,则以下内容是相同的(请注意 "org.scala-stm"
后的双 %%
)
libraryDependencies += "org.scala-stm" %% "scala-stm" % "0.9.1"
其想法是,许多依赖项都针对多个 Scala 版本进行了编译,您希望获取与您的项目匹配的版本以确保二进制兼容性。
有关这方面的更多详细信息,请参阅交叉构建。
organization % moduleName % version
中的 version
不一定是单个固定版本。Ivy 可以根据您指定的约束选择模块的最新修订版本。而不是像 "1.6.1"
这样的固定修订版本,您指定 "latest.integration"
、"2.9.+"
或 "[1.0,)"
。有关详细信息,请参阅Ivy 修订版本 文档。
有时使用 Maven “版本范围”来指定依赖项(传递或其他),例如 [1.3.0,)
。如果在构建中声明了依赖项的特定版本,并且它满足范围,则 sbt 将使用指定的版本。否则,Coursier 可以访问互联网以查找最新版本。这会导致令人惊讶的行为,即有效版本会随着时间的推移而不断变化,即使有一个满足范围条件的库的指定版本。
如果构建中找到了一个令人满意的版本,则 Maven 版本范围将被其下限替换,以便使用该版本。您可以使用 JVM 标志 -Dsbt.modversionrange=false
禁用此行为。
并非所有包都位于同一台服务器上;sbt 默认使用标准 Maven2 仓库。如果您的依赖项不在默认仓库之一中,则需要添加解析器以帮助 Ivy 找到它。
要添加额外的仓库,请使用
resolvers += name at location
使用两个字符串之间的特殊 at
。
例如
resolvers += "Sonatype OSS Snapshots" at "https://oss.sonatype.org/content/repositories/snapshots"
resolvers
密钥在 Keys 中定义如下
val resolvers = settingKey[Seq[Resolver]]("The user-defined additional resolvers for automatically managed dependencies.")
at
方法从两个字符串创建 Resolver
对象。
如果您将其添加为仓库,则 sbt 可以搜索您的本地 Maven 仓库
resolvers += "Local Maven Repository" at "file://"+Path.userHome.absolutePath+"/.m2/repository"
或者,为了方便起见
resolvers += Resolver.mavenLocal
有关定义其他类型仓库的详细信息,请参阅解析器。
resolvers
不包含默认解析器;它只包含构建定义添加的额外解析器。
sbt 将 resolvers
与一些默认仓库组合起来,形成 externalResolvers
。
因此,要更改或删除默认解析器,您需要覆盖 externalResolvers
而不是 resolvers
。
通常,依赖项由您的测试代码(在 src/test/scala
中,由 Test
配置编译)而不是您的主代码使用。
如果您希望依赖项仅显示在 Test
配置的类路径中,而不是 Compile
配置的类路径中,请添加 % "test"
,如下所示
libraryDependencies += "org.apache.derby" % "derby" % "10.4.1.3" % "test"
您也可以使用 Test
配置的类型安全版本,如下所示
libraryDependencies += "org.apache.derby" % "derby" % "10.4.1.3" % Test
现在,如果您在 sbt 交互式提示符中键入 show Compile/dependencyClasspath
,您应该看不到 derby jar 文件。但是,如果您键入 show Test/dependencyClasspath
,您应该在列表中看到 derby jar 文件。
通常,与测试相关的依赖项,例如 ScalaCheck、Specs2 和 ScalaTest 将使用 % "test"
定义。
有关库依赖项的更多详细信息和技巧,请参阅本页。