parallel cross building, part 3
This is part 3 of the post about sbt-projectmatrix, an experimental plugin that I’ve been working to improve the cross building in sbt. Here’s part 1 and part 2. I’ve just released 0.5.0.
recap: building against multiple Scala versions
After adding sbt-projectmatrix to your build, here’s how you can set up a matrix with two Scala versions.
ThisBuild / organization := "com.example"
ThisBuild / scalaVersion := "2.12.10"
ThisBuild / version := "0.1.0-SNAPSHOT"
lazy val core = (projectMatrix in file("core"))
.settings(
name := "core"
)
.jvmPlatform(scalaVersions = Seq("2.12.10", "2.11.12"))
This will create subprojects coreJVM2_11
and coreJVM2_12
. Unlike ++
style stateful cross building, these will build in parallel. This part has not changed.
Previous post also discussed the idea of VirtualAxis so a row can express multiple concepts.
what’s new in 0.5.0
0.4.0 came pretty close, but there are some issue I ran into when I tried to use it in a real project. First is the lack of %
syntax.
It’s fairly common for subprojects to depend only from Test
configuration, or depend on Compile
from Compile
, and Test
from Test
. 0.5.0 adds %
to make this possible.
lazy val app = (projectMatrix in file("app"))
.dependsOn(core % "compile->compile;test->test")
.settings(
name := "app"
)
.jvmPlatform(scalaVersions = Seq("2.12.10"))
lazy val core = (projectMatrix in file("core"))
.settings(
name := "core"
)
.jvmPlatform(scalaVersions = Seq("2.12.10", "2.13.1"))
Another feature that’s available to Project
is .configure(...)
method. It takes a vararg of Project => Project
functions, and applies them in order. Since some of the builds I deal with uses .configure(...)
this helps me migrate from Project
to ProjectMatrix
.
zincApiInfo example
Here’s from Zinc build I’m working:
lazy val compilerInterface = (projectMatrix in internalPath / "compiler-interface")
.enablePlugins(ContrabandPlugin)
.settings(
minimalSettings,
name := "Compiler Interface",
exportJars := true,
crossPaths := false,
)
.jvmPlatform(autoScalaLibrary = false)
.configure(addSbtUtilInterface)
lazy val zincApiInfo = (projectMatrix in internalPath / "zinc-apiinfo")
.dependsOn(compilerInterface, compilerBridge, zincClassfile % "compile;test->test")
.settings(
name := "zinc ApiInfo",
compilerVersionDependentScalacOptions,
mimaSettings,
)
.jvmPlatform(scalaVersions = List(scala212, scala213))
.configure(addBaseSettingsAndTestDeps)
In the above, both compilerInterface
and zincApiInfo
are project matrices. compilerInterface
is how a Java-only matrix looks like, and zincApiInfo
is a Scala project matrix with multiple Scala versions.
Unlike the traditional multi-project setup, this would create a subproject for each Scala version so a fairly complex web of projects can be set up without using ++
commands.
summary
- sbt-projectmatrix enables parallel building of multiple Scala versions and JVM/JS/Native cross building.
- sbt-projectmatrix 0.5.0 adds
%
support for inter-matrix dependencies.