问题 如何拥有多个Scala版本的SBT子项目?


我有一个使用Scala 2.10的项目和一个使用Scala 2.11的项目。它们依赖于一个可以用两者编译的通用项目。

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

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

lazy val baz = (project in file("baz")).settings(
  crossScalaVersions := Seq("2.10.4", "2.11.4"),
  scalaVersion := "2.10.4"
)

接着

$ sbt bar/update
[info] Updating {file:/home/paul/Private/test/}bar...
[info] Resolving baz#baz_2.11;0.1-SNAPSHOT ...
[warn]  module not found: baz#baz_2.11;0.1-SNAPSHOT
[warn] ==== local: tried
[warn]   /home/paul/.ivy2/local/baz/baz_2.11/0.1-SNAPSHOT/ivys/ivy.xml
[warn] ==== public: tried
[warn]   http://repo1.maven.org/maven2/baz/baz_2.11/0.1-SNAPSHOT/baz_2.11-0.1-SNAPSHOT.pom
[info] Resolving jline#jline;2.12 ...
[warn]  ::::::::::::::::::::::::::::::::::::::::::::::
[warn]  ::          UNRESOLVED DEPENDENCIES         ::
[warn]  ::::::::::::::::::::::::::::::::::::::::::::::
[warn]  :: baz#baz_2.11;0.1-SNAPSHOT: not found
[warn]  ::::::::::::::::::::::::::::::::::::::::::::::
[trace] Stack trace suppressed: run last bar/*:update for the full output.
[error] (bar/*:update) sbt.ResolveException: unresolved dependency: baz#baz_2.11;0.1-SNAPSHOT: not found
[error] Total time: 1 s, completed Jan 13, 2015 11:42:51 AM

我怎么能 baz 这两个项目都可用吗?


7077
2018-01-13 18:45


起源

你试过吗? crossPaths := false 选项,完全忽略scala版本? - yevgeniy mordovkin
您可能会遇到一些可比性问题(不是100%),但说实话,您的情况无论如何都闻起来很糟糕;所以我建议这是一个临时修复,直到你做 FOO 和 巴兹 两者都使用2.11.4。 - yevgeniy mordovkin


答案:


Yevgeniy Mordovkin提出的解决方案,宣布 crossPaths := false 在baz项目中,作品。

你可能做的另一件事是先加一个 + 在命令之前: sbt '+ bar/update'。那将构建 巴兹 对于所有声明的Scala版本。


7
2018-01-26 09:13



谢谢。 (1) 将 crossPaths 导致问题,因为Scala次要版本不是二进制兼容的? (2) 似乎 + 工作,我还需要补充 crossVersions 至 bar,并切换项目 project bar 接着 +update (代替 +bar/update),否则使用2.10。 - Paul Draper
@PaulDraper无需添加 crossScalaVersions 至 bar。你要做的就是设置 settings 在宣布之前 dependsOn: lazy val bar = (project in file("bar")).settings(scalaVersion := "2.11.4").dependsOn(baz)。 - Ionuț G. Stan
你可以使用@PaulDraper update 没有前面的 + 内 bar 只要你已经编译过 baz 对于所有声明的版本。 - Ionuț G. Stan
@PaulDraper和是的,设置 crossPaths := false 可能会导致问题,所以你最好不要使用它。 - Ionuț G. Stan
@IonuţG.Stan不幸的是,推杆 settings 之前 aggregate 以同样的方式似乎不起作用。预计会吗?看到 stackoverflow.com/questions/27231293/... 和 github.com/scalan/scalan-ce/tree/include-lms-backend-in-root - Alexey Romanov


我创造了一个 SBT插件 为了这。

项目/ plugins.sbt

resolvers += Resolver.sonatypeRepo("releases")

addSbtPlugin("com.lucidchart" % "sbt-cross" % "1.0")

build.sbt

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

lazy val bar = (project in file("bar")).dependsOn(baz_2_11).settings(
  scalaVersion := "2.11.5"
)

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

lazy val baz_2_10 = baz("2.10.4")

lazy val baz_2_11 = baz("2.11.5")

它需要更多行,但现在一切都按预期编译: sbt foo/compile 工作,和 sbt bar/compile 作品。

您不必记住唯一命令,也没有错误 crossPath := false,而且不像 ++,这是可并行化的: sbt compile 将编译 foobar,和 baz 同时使用正确的Scala版本。


2
2017-11-26 23:14



不幸的是,它并没有与Intellij一起发挥出色,但是从sbt开始 - 快速且令人敬畏。 - Tvaroh
与IntellJ一起使用 2017.1.4 - Atais
@Tvaroh我认为它与Intellij一起使用或者比任何其他解决方案更好。如果您另外观察,请在Github项目中提交错误。 - Paul Draper
@PaulDraper仅在所有模块都设置为交叉构建时才有效。如果是一个子集 - 它没有。 - Tvaroh
它是否适合发布包的工作流程? - acjay


我有类似的设置,并让它像这样工作:

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

和建设

sbt '++ 2.10.4 baz/compile' 'bar/compile' '++ 2.11.4 baz/compile' 'foo/compile'

0
2017-11-26 21:51