8

I want to implement the following build in SBT:

  • Having multiple scala version
  • Having multiple target version (because of a library dependency)

Let's take for example an external Lib, that exist in version 1.0, 2.0, 3.0, and Scala 2.92, 2.10.2, I would like to compile, assembly and publish:

  • MyProject_externalLib1.0_scala_2.9.2
  • MyProject_externalLib1.0_scala_2.10.2
  • MyProject_externalLib2.0_scala_2.9.2
  • MyProject_externalLib2.0_scala_2.10.2
  • MyProject_externalLib3.0_scala_2.9.2
  • MyProject_externalLib3.0_scala_2.10.2

By default, however, I would want to work in a single version. Only when I launch a release processes, all the versions should be compiled and tested and assembled.

Is there a simple way to implement this multiple-version build in Sbt?

Edmondo
  • 19,559
  • 13
  • 62
  • 115
  • is `externalLib` itself a scala library that is cross-published against 2.9.2 and 2.10.2? or is it a simple java library? – gourlaysama Aug 22 '13 at 13:05

1 Answers1

10

cross building

Having multiple Scala version in sbt is fairly common, and it's called cross building or cross publishing. See sbt's Cross-building page for details. All you have to do is:

scalaVersion := "2.10.2"

crossScalaVersions := Seq("2.10.2", "2.9.2")  

By sbt's naming convention, your published artifact will have binary version post fix, which is _2.10 for Scala 2.10.x, and _2.9.2 for Scala 2.9.2. This is to take advantage of the binary compatibility among the 2.10 series. You can use crossVersion to control that aspect.

cross building against an external library

Cross building against an external library is a bit more tricky. The closet situation I can think of is a plugin for Dispatch. In there, I created a custom setting called dispatchVersion:

lazy val dispatchVersion = SettingKey[String]("x-dispatch-version")

This is set in the buildSettings as

dispatchVersion := "0.10.1"

and my version prefixed with dispatch0.10.0_:

version <<= dispatchVersion { dv => "dispatch" + dv + "_0.1.0" }

Here's how to add dependencies using the key:

libraryDependencies <++= (dispatchVersion) { (dv) => Seq(
  "net.databinder.dispatch" %% "dispatch-core" % dv,
  "net.databinder.dispatch" %% "dispatch-json4s-native" % dv
)}

For Java libraries it should be % instead of %%:

libraryDependencies <++= (externalLibVersion) { (el) => Seq(
  "org.apache" % "foo" % el,
  "org.apache" % "foo-extention" % el
)}

Aside from making a custom plugin like sbt-cross-building, there's no easy way to iterate over a sequence of external versions. You can write a shell script like:

sbt "set externalLibVersion := \"1.0\"" +assembly "set externalLibVersion := \"2.0\"" +assembly "set externalLibVersion := \"3.0\"" +assembly
Eugene Yokota
  • 94,654
  • 45
  • 215
  • 319