4

I need to cross-build a project with both Scala 2.10 and 2.11 (and ultimately 2.12 also). Some packages that were part of 2.10, for example parser-combinators, are packaged independently in 2.11. Thus they are not required to be mentioned in the 2.10 build but are required in 2.11. Furthermore, there may be more than one such package, which are required to use a common version.

I found the documentation re: cross-building on the SBT site to be somewhat lacking in helpfulness here. And, although, there are several StackOverflow Q&As which relate to this subject, I could not find one that addressed this specific point.

Phasmid
  • 923
  • 7
  • 19

1 Answers1

7

The solution is as follows (showing only the relevant part of build.sbt):

scalaVersion := "2.10.6"
crossScalaVersions := Seq("2.10.6","2.11.8")

val scalaModules = "org.scala-lang.modules"
val scalaModulesVersion = "1.0.4"

val akkaGroup = "com.typesafe.akka"
lazy val akkaVersion = SettingKey[String]("akkaVersion")
lazy val scalaTestVersion = SettingKey[String]("scalaTestVersion")

akkaVersion := (scalaBinaryVersion.value match {
  case "2.10" => "2.3.15"
  case "2.11" => "2.4.1"
})
scalaTestVersion := (scalaBinaryVersion.value match {
  case "2.10" => "2.2.6"
  case "2.11" => "3.0.1"
})

libraryDependencies ++= (scalaBinaryVersion.value match {
  case "2.11" => Seq(
    scalaModules %% "scala-parser-combinators" % scalaModulesVersion,
    scalaModules %% "scala-xml" % scalaModulesVersion,
    "com.typesafe.scala-logging" %% "scala-logging" % "3.4.0"
  )
  case _ => Seq()
}
)

libraryDependencies ++= Seq(
  akkaGroup %% "akka-actor" % akkaVersion.value % "test",
  "org.scalatest" %% "scalatest" % scalaTestVersion.value % "test"
)

Note that this solution also addresses the problem of how to set the version of a dependency(ies) according to the binary version. I think this may be addressed elsewhere in Stackoverflow but here it is all in the same place.

Seth Tisue
  • 29,985
  • 11
  • 82
  • 149
Phasmid
  • 923
  • 7
  • 19
  • 3
    Matching `scalaBinaryVersion` as a string is good enough for normal versions of Scala, but will break on milestones, release candidates, nightlies, and so forth. To be fully correct, use e.g. `CrossVersion.partialVersion(scalaBinaryVersion.value) match { case Some((2, 10)) => ...` – Seth Tisue Dec 31 '16 at 15:43
  • 1
    Also, the way you're handling the Scala modules here doesn't make sense. scala-xml 1.0.4 and scala-parser-combinators 1.0.4 have absolutely nothing to do with each other; these are completely separate libraries with separate release schedules and version numbering. Note for example that Scala 2.12.1 ships with scala-parser-combinators 1.0.4 and scala-xml 1.0.6. – Seth Tisue Dec 31 '16 at 15:46
  • Thanks, @SethTisue. I see what you're saying about scale-xml and scala-parser-combinators but I wanted to show an example of where two packages might be related (and didn't really have a proper one). I did put these at the same version, however, because otherwise I got warnings about evictions. I realize I could have fixed those another way. Anyway, thanks for your comment. – Phasmid Dec 31 '16 at 17:00