How to force sbt to resolve dependencies with scalaVersion compatible with the dependent project

999 views Asked by At

Consider the following contents of some build.sbt and no source code in particular:

lazy val y = (project in file("y"))
  .settings(
    scalaVersion := "2.11.8",
  )
  .dependsOn(x)

lazy val x = (project in file("x"))
  .settings(
    crossScalaVersions := Seq("2.11.8", "2.12.6")
  )

Here, sbt y/compile, fails with

sbt.librarymanagement.ResolveException: unresolved dependency: x#x_2.11;0.1.0-SNAPSHOT: not found

which is explained by sbt "show y/fullResolvers" referring to

Raw(ProjectResolver(inter-project, mapped: x#x_2.12;0.1.0-SNAPSHOT))

Why does it refer to _2.12? I suppose that since sbt "show y/allDependencies" lists

x:x:0.1.0-SNAPSHOT

as the dependency, which misses the scalaVersion and the _2.12, the sbt does not understand (unlike with external library dependencies) what scala version to look for. The _2.12 seems to be derived from the ThisBuild or Global value of scalaVersion which defaults to some 2.12.x, changing the scalaVersion at one of the scopes fixes the problem for the simplified example above, but if we add

lazy val z = (project in file("z"))
  .settings(
    scalaVersion := "2.12.6",
  )
  .dependsOn(x)

then what ever value we choose for scalaVersion in the Global / ThisBuild scope, either y or z will fail to build.

I am aware of sbt "+ y/compile" but why doesn't sbt y/compile correctly defaults to matching scalaVersion between the dependent project and the dependency? Or can it be made to pick the right scalaVersion when resolving dependencies?


sbt "show sbtVersion" gives me 1.2.1 but I have seen the same problem across different versions, no previous explanation online helped me understand / circumvent the problem.

1

There are 1 answers

0
Tomer Shetah On

You need to define a Scala version for the project. And it should be the most common version. You can see a general example at Cross building a project statefully. In your example you can do:

ThisBuild / scalaVersion := "2.11.8"

lazy val y = (project in file("y"))
  .settings(
    scalaVersion := "2.11.8"
  )
  .dependsOn(x)

lazy val x = (project in file("x"))
  .settings(
    crossScalaVersions := Seq("2.11.8", "2.12.6")
  )

Or if for example you go with Scala 2.12 as the default, you can do:

ThisBuild / scalaVersion := "2.12.6"

lazy val y = (project in file("y"))
  .settings(
    scalaVersion := "2.12.6"
  )
  .dependsOn(x)

lazy val x = (project in file("x"))
  .settings(
    crossScalaVersions := Seq("2.11.8", "2.12.6")
  )

Regarding the z requirement, I don't think it is possible. I think all subprojects should support the Scala version of the project.