交叉构建

交叉构建(cross building)指从同一组源文件构建多个目标。这包括 Scala 交叉构建(针对多个 Scala 发布版本)、平台交叉构建(针对 JVM、Scala.JS 和 Scala Native)以及 Spark 版本等自定义虚拟轴。

使用交叉构建的库

要使用针对多个 Scala 版本构建的库,请将 ModuleID 中的第一个 % 改为 %%。这会告诉 sbt 将 Scala ABI(应用程序二进制接口)后缀附加到依赖名称。例如:

libraryDependencies += "org.typelevel" %% "cats-effect" % "3.5.4"

当当前 Scala 版本为 Scala 3.x 时,以上写法等价于以下:

libraryDependencies += "org.typelevel" % "cats-effect_3" % "3.5.4"

有关设置的更多详情,请参阅 cross building setup

历史背景

在 Scala 早期(Scala 2.9 之前),Scala 库即使在补丁级别也不保持二进制兼容性,因此每次发布新 Scala 版本时,库都必须针对新版本重新发布。这意味着库用户需要选择与其使用的 Scala 版本兼容的特定版本。

即使在 Scala 2.9.x 之后,Scala 库在次版本级别也不保持二进制兼容性,因此针对 Scala 2.10.x 编译的库与 2.11.x 不兼容。

为解决此问题,sbt 开发了交叉构建机制,使得:

  • 同一组源文件可以针对多个 Scala 版本编译
  • 定义将 ABI 版本(如 _2.12)附加到 Maven 构件的约定
  • 后来此机制扩展以支持 Scala.JS 和其他平台

项目矩阵

sbt 2.x 引入了项目矩阵,使交叉构建可以并行进行。

organization := "com.example"
scalaVersion := "3.8.1"
version      := "0.1.0-SNAPSHOT"

lazy val core = (projectMatrix in file("core"))
  .settings(
    name := "core"
  )
  .jvmPlatform(scalaVersions = Seq("3.8.1", "2.13.17"))

有关设置的更多详情,请参阅 cross building setup