Cross-compiling aggregate projects with different

2020-02-14 05:57发布

问题:

We have a project with several subprojects which can compile under both Scala 2.10 and 2.11, one subproject which only compiles under 2.10 (actually, Scala-Virtualized 2.10.2) and one subproject which only compiles under 2.11. Is there a simple way to create an aggregate project which cross-builds all possible subprojects for both 2.10 and 2.11? Or, alternately, to have different default projects for 2.10 and 2.11?

In particular, here is current Build.scala. If I add lmsBackend to root, I get

> show scalaVersion
[info] common/*:scalaVersion
[info]  2.10.4
[info] lms-backend/*:scalaVersion
[info]  2.10.2
[info] meta/*:scalaVersion
[info]  2.10.4
[info] community-edition/*:scalaVersion
[info]  2.10.4
[info] core/*:scalaVersion
[info]  2.10.4
[info] scalan/*:scalaVersion
[info]  2.10.4
> show crossScalaVersions
[info] common/*:crossScalaVersions
[info]  List(2.10.4, 2.11.5)
[info] lms-backend/*:crossScalaVersions
[info]  List(2.10.2)
[info] meta/*:crossScalaVersions
[info]  List(2.10.4, 2.11.5)
[info] community-edition/*:crossScalaVersions
[info]  List(2.10.4, 2.11.5)
[info] core/*:crossScalaVersions
[info]  List(2.10.4, 2.11.5)
[info] scalan/*:crossScalaVersions
[info]  List(2.10.4, 2.11.5)

SBT is able to run update, compile, etc. fine on this aggregate project. However, once I try any cross-building, things break:

> +update
[info] Setting version to 2.10.4
[info] Reapplying settings...
[info] Set current project to scalan (in build file:/home/aromanov/IdeaProjects/scalan-lite/)
...
[info] Updating {file:/home/aromanov/IdeaProjects/scalan-lite/}lms-backend...
[info] Resolving org.scala-lang.virtualized#scala-library;2.10.4 ...
[warn]  module not found: org.scala-lang.virtualized#scala-library;2.10.4
...
[info] Resolving org.scala-lang.virtualized#scala-compiler;2.10.4 ...
[warn]  module not found: org.scala-lang.virtualized#scala-compiler;2.10.4
...
[warn]  ::::::::::::::::::::::::::::::::::::::::::::::
[warn]  ::          UNRESOLVED DEPENDENCIES         ::
[warn]  ::::::::::::::::::::::::::::::::::::::::::::::
[warn]  :: org.scala-lang.virtualized#scala-library;2.10.4: not found
[warn]  :: org.scala-lang.virtualized#scala-compiler;2.10.4: not found
[warn]  ::::::::::::::::::::::::::::::::::::::::::::::
[warn] 
[warn]  Note: Unresolved dependencies path:
[warn]      org.scala-lang.virtualized:scala-library:2.10.4 ((sbt.Classpaths) Defaults.scala#L1169)
[warn]        +- com.huawei.scalan:lms-backend_2.10:0.2.6-SNAPSHOT
[warn]      org.scala-lang.virtualized:scala-compiler:2.10.4
[warn]        +- com.huawei.scalan:lms-backend_2.10:0.2.6-SNAPSHOT
[trace] Stack trace suppressed: run last lms-backend/*:update for the full output.
[error] (lms-backend/*:update) sbt.ResolveException: unresolved dependency: org.scala-lang.virtualized#scala-library;2.10.4: not found
[error] unresolved dependency: org.scala-lang.virtualized#scala-compiler;2.10.4: not found
[error] Total time: 2 s, completed Jan 28, 2015 1:33:49 PM

show scalaVersion now shows 2.10.4 for all subprojects. Is there any way to include lms-backend in the aggregate project and still avoid this problem?

回答1:

I had a similar question. My question had an additional complication of classpath dependencies (dependsOn), rather than just aggregation, but one solution for my problem fixes this one quite well.

sbt-doge, a deceptively cutesy GitHub project, replaces the implementation of + with one of its interchangeable prefixes: much, so, such, very.

Current implementation of + cross building operator does not take in account for the crossScalaVersions of the sub projects. Until that's fixed, here's an alternative implementation of it.

The creator of the project is one of the main contributors to SBT.


Add

addSbtPlugin("com.eed3si9n" % "sbt-doge" % "0.1.3")

to project/plugins.sbt.

Then

> very compile


回答2:

I believe sbt-doge might not be enough for your requirements as mine were not met by this plugin as well.

I would recommend sbt-cross

This plugin allows you for much more flexibility among your modules, as well as, it provides a way to aggregate modules of different Scala versions, without the need to have any version in common!

Example:

lazy val common = (project in file("common")).cross

lazy val common_2_11 = common("2.11.8")
lazy val common_2_10 = common("2.10.6")

lazy val A = (project in file("A"))
             .settings(scalaVersion := "2.10.6")
             .dependsOn(common_2_10)

lazy val B = (project in file("B"))
             .settings(scalaVersion := "2.11.8")
             .dependsOn(common_2_11)

lazy val root = (project in file("."))
                .aggregate(common, A, B)

I have already posted a similar answer.

Enjoy!



标签: scala sbt