sbt/README.markdown

200 lines
5.1 KiB
Markdown
Raw Normal View History

2018-06-24 04:35:09 +02:00
sbt-projectmatrix
=================
cross building using subprojects.
This is an experimental plugin that implements better cross building.
setup
-----
2019-05-10 20:01:30 +02:00
**Requirements**: Requires sbt 1.2.0 or above.
2018-06-24 04:35:09 +02:00
In `project/plugins.sbt`:
```scala
2021-05-17 17:20:07 +02:00
addSbtPlugin("com.eed3si9n" % "sbt-projectmatrix" % "0.8.0")
2019-05-10 20:01:30 +02:00
// add also the following for Scala.js support
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "0.6.27")
2018-06-24 04:35:09 +02:00
```
usage
-----
2019-05-10 20:01:30 +02:00
### 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.
```scala
ThisBuild / organization := "com.example"
2020-08-24 05:37:19 +02:00
ThisBuild / scalaVersion := "2.13.3"
2019-05-10 20:01:30 +02:00
ThisBuild / version := "0.1.0-SNAPSHOT"
lazy val core = (projectMatrix in file("core"))
.settings(
name := "core"
)
2020-08-24 05:37:19 +02:00
.jvmPlatform(scalaVersions = Seq("2.13.3", "2.12.12"))
2019-05-10 20:01:30 +02:00
```
2020-08-24 05:37:19 +02:00
This will create subprojects `core` and `core2_12`.
2019-05-10 20:01:30 +02:00
Unlike `++` style stateful cross building, these will build in parallel.
### two matrices
It gets more interesting if you have more than one matrix.
2018-06-24 04:35:09 +02:00
```scala
2019-05-10 20:01:30 +02:00
ThisBuild / organization := "com.example"
2020-08-24 05:37:19 +02:00
ThisBuild / scalaVersion := "2.13.3"
2019-05-10 20:01:30 +02:00
ThisBuild / version := "0.1.0-SNAPSHOT"
// uncomment if you want root
// lazy val root = (project in file("."))
// .aggregate(core.projectRefs ++ app.projectRefs: _*)
// .settings(
// )
2018-06-24 04:35:09 +02:00
lazy val core = (projectMatrix in file("core"))
.settings(
name := "core"
)
2020-08-24 05:37:19 +02:00
.jvmPlatform(scalaVersions = Seq("2.13.3", "2.12.12"))
2018-06-24 04:35:09 +02:00
lazy val app = (projectMatrix in file("app"))
.dependsOn(core)
.settings(
name := "app"
)
2020-08-24 05:37:19 +02:00
.jvmPlatform(scalaVersions = Seq("2.13.3"))
2019-05-10 20:01:30 +02:00
```
2020-08-24 05:37:19 +02:00
This is an example where `core` builds against Scala 2.12 and 2.13, but app only builds for one of them.
2019-05-10 20:01:30 +02:00
### Scala.js support
2019-05-12 15:30:21 +02:00
[Scala.js](http://scala-js.org/) support was added in sbt-projectmatrix 0.2.0.
2019-05-10 20:01:30 +02:00
To use this, you need to setup sbt-scalajs as well:
```scala
lazy val core = (projectMatrix in file("core"))
.settings(
name := "core"
)
2020-08-24 05:37:19 +02:00
.jsPlatform(scalaVersions = Seq("2.12.12", "2.11.12"))
2019-05-10 20:01:30 +02:00
```
This will create subprojects `coreJS2_11` and `coreJS2_12`.
2019-05-12 15:30:21 +02:00
### Scala Native support
[Scala Native](http://scala-native.org) support will be added in upcoming release.
To use this, you need to setup sbt-scala-native` as well:
```scala
lazy val core = (projectMatrix in file("core"))
.settings(
name := "core"
)
2019-06-27 01:57:50 +02:00
.nativePlatform(scalaVersions = Seq("2.11.12"))
2019-05-12 15:30:21 +02:00
```
2019-06-27 01:57:50 +02:00
This will create subproject `coreNative2_11`.
2019-05-12 15:30:21 +02:00
2019-05-10 20:01:30 +02:00
### parallel cross-library building
The rows can also be used for parallel cross-library building.
For example, if you want to build against Config 1.2 and Config 1.3, you can do something like this:
In `project/ConfigAxis.scala`:
```scala
import sbt._
case class ConfigAxis(idSuffix: String, directorySuffix: String) extends VirtualAxis.WeakAxis {
}
```
In `build.sbt`:
2019-05-10 20:01:30 +02:00
```scala
ThisBuild / organization := "com.example"
ThisBuild / version := "0.1.0-SNAPSHOT"
lazy val config12 = ConfigAxis("Config1_2", "config1.2")
lazy val config13 = ConfigAxis("Config1_3", "config1.3")
lazy val scala212 = "2.12.10"
lazy val scala211 = "2.11.12"
lazy val app = (projectMatrix in file("app"))
2019-05-10 20:01:30 +02:00
.settings(
name := "app"
2019-05-10 20:01:30 +02:00
)
.customRow(
scalaVersions = Seq(scala212, scala211),
axisValues = Seq(config12, VirtualAxis.jvm),
_.settings(
moduleName := name.value + "_config1.2",
2019-05-10 20:01:30 +02:00
libraryDependencies += "com.typesafe" % "config" % "1.2.1"
)
)
.customRow(
scalaVersions = Seq(scala212, scala211),
axisValues = Seq(config13, VirtualAxis.jvm),
_.settings(
moduleName := name.value + "_config1.3",
2019-05-10 20:01:30 +02:00
libraryDependencies += "com.typesafe" % "config" % "1.3.3"
)
)
```
This will create `appConfig1_22_11`, `appConfig1_22_12`, and `appConfig1_32_12` respectively producing `app_config1.3_2.12`, `app_config1.2_2.11`, and `app_config1.2_2.12` artifacts.
2019-05-10 20:01:30 +02:00
### referencing the generated subprojects
2019-05-10 20:01:30 +02:00
You might want to reference to one of the projects within `build.sbt`.
```scala
lazy val core12 = core.jvm("2.12.8")
lazy val appConfig12_212 = app.finder(config13, VirtualAxis.jvm)("2.12.8")
2018-06-24 04:35:09 +02:00
```
2019-05-10 20:01:30 +02:00
In the above `core12` returns `Project` type.
### accessing axes from subprojects
Each generated subproject can access the values for all the axes using `virtualAxes` key:
```scala
lazy val platformTest = settingKey[String]("")
lazy val core = (projectMatrix in file("core"))
.settings(
name := "core"
)
.jsPlatform(scalaVersions = Seq("2.12.12", "2.11.12"))
.jvmPlatform(scalaVersion = Seq("2.12.12", "2.13.3"))
.settings(
platformTest := {
if(virtualAxes.value.contains(VirtualAxis.jvm))
"JVM project"
else
"JS project"
}
)
```
2019-05-10 20:01:30 +02:00
credits
-------
- The idea of representing cross build using subproject was pionieered by Tobias Schlatter's work on Scala.js plugin, which was later expanded to [ sbt-crossproject](https://github.com/portable-scala/sbt-crossproject). However, this only addresses the platform (JVM, JS, Native) cross building.
- [sbt-cross](https://github.com/lucidsoftware/sbt-cross) written by Paul Draper in 2015 implements cross building across Scala versions.
2018-06-24 04:35:09 +02:00
license
-------
MIT License