SBT Scala 跨版本,具有聚合和依赖关系
SBT Scala cross versions, with aggregation and dependencies
我正在为 crossScalaVersions
如何处理子项目而苦恼。
我有一个使用 2.10 (foo) 编译的项目和一个使用 2.11 (bar) 编译的项目。他们共享一个交叉编译的项目(common)。
如何编译项目 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")
)
project/build.properties
sbt.version=0.13.7
foo/src/main/scala/Foo.scala
object Foo {
<xml>{new C}</xml>
}
bar/src/main/scala/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)
common/src/main/scala/Common.scala
class C {}
尝试 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
尝试 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
尝试 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
尝试 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
尝试 5
我什至尝试使用相同的基本目录但不同的 scala 版本定义 common_2_10
和 common_2_11
项目。我记得读过目标是按 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)
我唯一要做的就是手动指定版本:
$ sbt ++2.10.4 foo/compile ++2.11.4 bar/compile
但这是很多命令,永远不能使用并行性,并且避免了整个使用(1)项目聚合和(2)交叉构建。
我是否遗漏了有关 crossScalaVersions
意图的一些基本内容?或者有没有办法让它与 SBT 的其余部分一起很好地运行,并让我编译我的异构项目?
看看我的 sbt-doge:
sbt plugin to aggregate tasks across subprojects and their crossScalaVersions
我最后声明了两次通用,每个版本一次。
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"
)
请注意,我必须使目标目录不同,否则 SBT 会拒绝它,因为它们重叠。
另请注意,def
使得 commonProject
不包括 SBT 的神奇(基于反射的)项目定义搜索。
这不是最漂亮的,但它是健壮的、可读的和合理的。所有 commands/tasks 都按预期工作。
在某种程度上,这 甚至比 crossScalaVersions
更好,因为 2.10 和 2.11 项目现在可以并行编译, 这不会发生在 crossScalaVersions
:)
编辑:我创建了一个 SBT 插件,sbt-cross,来帮助解决这个问题。
我正在为 crossScalaVersions
如何处理子项目而苦恼。
我有一个使用 2.10 (foo) 编译的项目和一个使用 2.11 (bar) 编译的项目。他们共享一个交叉编译的项目(common)。
如何编译项目 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")
)
project/build.properties
sbt.version=0.13.7
foo/src/main/scala/Foo.scala
object Foo {
<xml>{new C}</xml>
}
bar/src/main/scala/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)
common/src/main/scala/Common.scala
class C {}
尝试 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
尝试 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
尝试 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
尝试 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
尝试 5
我什至尝试使用相同的基本目录但不同的 scala 版本定义 common_2_10
和 common_2_11
项目。我记得读过目标是按 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)
我唯一要做的就是手动指定版本:
$ sbt ++2.10.4 foo/compile ++2.11.4 bar/compile
但这是很多命令,永远不能使用并行性,并且避免了整个使用(1)项目聚合和(2)交叉构建。
我是否遗漏了有关 crossScalaVersions
意图的一些基本内容?或者有没有办法让它与 SBT 的其余部分一起很好地运行,并让我编译我的异构项目?
看看我的 sbt-doge:
sbt plugin to aggregate tasks across subprojects and their crossScalaVersions
我最后声明了两次通用,每个版本一次。
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"
)
请注意,我必须使目标目录不同,否则 SBT 会拒绝它,因为它们重叠。
另请注意,def
使得 commonProject
不包括 SBT 的神奇(基于反射的)项目定义搜索。
这不是最漂亮的,但它是健壮的、可读的和合理的。所有 commands/tasks 都按预期工作。
在某种程度上,这 甚至比 crossScalaVersions
更好,因为 2.10 和 2.11 项目现在可以并行编译, 这不会发生在 crossScalaVersions
:)
编辑:我创建了一个 SBT 插件,sbt-cross,来帮助解决这个问题。