SBT Scala交叉版本,具有聚合和依赖性

Pau*_*per 4 scala sbt sbt-0.13 cross-build

我正在努力crossScalaVersions解决子项目的工作原理.

我有一个用2.10(foo)编译的项目和一个用2.11(bar)编译的项目.他们共享一个交叉编译的项目(常见).

如何编译项目foo和bar?


build.sbt

lazy val root = (project in file(".")).aggregate(foo, bar).settings(
  crossScalaVersions := Seq("2.10.4", "2.11.4")
)

lazy val foo = (project in file("foo")).dependsOn(common).settings(
  crossScalaVersions := Seq("2.10.4"),
  scalaVersion := "2.10.4"
)

lazy val bar = (project in file("bar")).dependsOn(common).settings(
  crossScalaVersions := Seq("2.11.4"),
  scalaVersion := "2.11.4"
)

lazy val common = (project in file("common")).settings(
  crossScalaVersions := Seq("2.10.4", "2.11.4")
)
Run Code Online (Sandbox Code Playgroud)

项目/ build.properties

sbt.version=0.13.7
Run Code Online (Sandbox Code Playgroud)

富/ SRC /主/阶/ Foo.scala

object Foo {
  <xml>{new C}</xml>
}
Run Code Online (Sandbox Code Playgroud)

酒吧/ SRC /主/阶/ Bar.scala

case class Bar(a: C, b: C, c: C, d: C, e: C, f: C, g: C,
  h: C, i: C, j: C, k: C, l: C, m: C, n: C, o: C, p: C,
  q: C, r: C, s: C, t: C, u: C, v: C, w: C, x: C, y: C,
  z: C)
Run Code Online (Sandbox Code Playgroud)

公共/ SRC /主/阶/ Common.scala

class C {}
Run Code Online (Sandbox Code Playgroud)

尝试1

$ sbt compile
[info] Resolving jline#jline;2.12 ...
[warn]  ::::::::::::::::::::::::::::::::::::::::::::::
[warn]  ::          UNRESOLVED DEPENDENCIES         ::
[warn]  ::::::::::::::::::::::::::::::::::::::::::::::
[warn]  :: common#common_2.11;0.1-SNAPSHOT: not found
[warn]  ::::::::::::::::::::::::::::::::::::::::::::::
[warn] 
[warn]  Note: Unresolved dependencies path:
[warn]      common:common_2.11:0.1-SNAPSHOT
[warn]        +- bar:bar_2.11:0.1-SNAPSHOT
sbt.ResolveException: unresolved dependency: common#common_2.11;0.1-SNAPSHOT: not found
Run Code Online (Sandbox Code Playgroud)

尝试2

$ sbt +compile
[error] /home/paul/test/bar/src/main/scala/Bar.scala:1: Implementation restriction: case classes cannot have more than 22 parameters.
[error] case class Bar(a: C, b: C, c: C, d: C, e: C, f: C, g: C,
[error]            ^
[error] one error found
[error] (bar/compile:compile) Compilation failed
Run Code Online (Sandbox Code Playgroud)

尝试3

$ sbt foo/compile bar/compile
[warn]  ::::::::::::::::::::::::::::::::::::::::::::::
[warn]  ::          UNRESOLVED DEPENDENCIES         ::
[warn]  ::::::::::::::::::::::::::::::::::::::::::::::
[warn]  :: common#common_2.11;0.1-SNAPSHOT: not found
[warn]  ::::::::::::::::::::::::::::::::::::::::::::::
[warn] 
[warn]  Note: Unresolved dependencies path:
[warn]      common:common_2.11:0.1-SNAPSHOT
[warn]        +- bar:bar_2.11:0.1-SNAPSHOT
sbt.ResolveException: unresolved dependency: common#common_2.11;0.1-SNAPSHOT: not found
Run Code Online (Sandbox Code Playgroud)

尝试4

$ sbt +foo/compile +bar/compile
[error] /home/paul/test3/foo/src/main/scala/Foo.scala:2: To compile XML syntax, the scala.xml package must be on the classpath.
[error] Please see http://docs.scala-lang.org/overviews/core/scala-2.11.html#scala-xml.
[error]   <xml>{new C}</xml>
[error]   ^
[error] one error found
[error] (foo/compile:compile) Compilation failed
Run Code Online (Sandbox Code Playgroud)

尝试5

我甚至尝试使用相同的基本目录定义common_2_10common_2_11项目,但不同的scala版本.我记得读过目标是Scala版本的命名空间,但SBT说存在冲突.

$ sbt
[error] Overlapping output directories:/home/paul/test3/common/target:
[error]     ProjectRef(file:/home/paul/test3/,common_2_10)
[error]     ProjectRef(file:/home/paul/test3/,common_2_11)
Run Code Online (Sandbox Code Playgroud)

我唯一能做的就是手动指定版本:

$ sbt ++2.10.4 foo/compile ++2.11.4 bar/compile
Run Code Online (Sandbox Code Playgroud)

但这是很多命令,永远不能使用并行性,并且避免了(1)项目聚合和(2)交叉构建的整个使用.

我错过了关于意图的基本内容crossScalaVersions吗?或者有没有办法让它与SBT的其余部分很好地合作,并且我可以编译我的异构项目?

Pau*_*per 5

我结束了两次声明,每个版本一次.

lazy val root = (project in file(".")).aggregate(foo, bar)

lazy val foo = (project in file("foo")).dependsOn(common_2_10).settings(
  scalaVersion := "2.10.4"
)

lazy val bar = (project in file("bar")).dependsOn(common_2_11).settings(
  scalaVersion := "2.11.4"
)

def commonProject = (project in file("common")).settings(
  target := baseDirectory.value / s"target-${scalaVersion.value}"
)

lazy val common_2_10 = commonProject.settings(
  scalaVersion := "2.10.4"
)

lazy val common_2_11 = commonProject.settings(
  scalaVersion := "2.11.4"
)
Run Code Online (Sandbox Code Playgroud)

请注意,我必须使目标目录不同,否则SBT会拒绝它,因为它们重叠.

还要注意的是def使得commonProject未包含项目定义SBT的魔法(基于反射的)搜索.


这不是最漂亮的,但它健壮,可读且合理.所有命令/任务都可以按预期工作.

在某种程度上,这甚至crossScalaVersions2.10和2.11项目现在可以并行编译更好,这不会发生在crossScalaVersions:)


编辑:我创建了一个SBT插件,sbt-cross,以帮助解决这个问题.