有没有办法为多项目构建的不同部分获得不同的跨 scala 版本? 这样做的动机是我将客户端和服务器库捆绑在一个构建中。 客户端库需要同时支持 2.9 和 2.10,但我想在服务器中使用 2.10 特定的库和功能。
我们有一个黑客解决方法:
def forkSrcDirs(srcDirectory: File, scalaVer: String) = {
val ver = scalaVer.split("\.").take(2).mkString(".")
Seq(srcDirectory / "scala-%s".format(ver), srcDirectory / "java-%s".format(ver))
}
lazy val forkSourceSettings = {
seq(
unmanagedSourceDirectories in Compile <++= (sourceDirectory in Compile, scalaVersion) apply forkSrcDirs,
unmanagedSourceDirectories in Test <++= (sourceDirectory in Test, scalaVersion) apply forkSrcDirs
)
}
这让我们可以通过将所有代码放在 server/src/main/scala-2.10 中来实现目标,但这似乎是我们可以直接使用 SBT 设置来完成的事情。
看起来 sbt-cross 插件提供了您需要的东西。它从单个项目定义中为每个您需要的 scala 版本生成一个 sbt 项目。
在project/plugins.sbt中,添加
resolvers += Resolver.sonatypeRepo("releases")
addSbtPlugin("com.lucidchart" % "sbt-cross" % "1.1")
对于给定的结构,您的build.sbt应该看起来像
lazy val root = (project in file("."))
.aggregate(server, client_2_9, client_2_10)
lazy val server = (project in file("server"))
.settings(
scalaVersion := "2.10.6"
)
lazy val client = (project in file("client"))
.cross
lazy val client_2_9 = client("2.9.3")
lazy val client_2_10 = client("2.10.6")
Build.scala中:
//maybe you need to set your preferred scalaVersion
import sbt._
import Keys._
object HelloBuild extends Build {
lazy val root = Project(id = "main",
base = file(".")) aggregate(client, server)
lazy val client = Project(id = "client", base = file("client")).settings(crossScalaVersions := Seq("2.9.2", "2.10.0"))
lazy val server = Project(id = "server", base = file("server"))
}
要发布本地(删除"-local"以实际发布"):
sbt "server/publish-local" "project client" "+ publish-local"
文件夹结构如下所示:
.
├── client
│ └── src
│ └── main
│ └── scala
│ └── Client.scala
├── project
│ └── Build.scala
└── server
└── src
└── main
└── scala
└── Server.scala
链接:
- http://www.scala-sbt.org/0.12.2/docs/Detailed-Topics/Cross-Build.html
- http://www.scala-sbt.org/0.12.3/docs/Getting-Started/Multi-Project.html