我有一堆SBT 0.13项目定义,如下所示:
lazy val coreBase = crossProject.crossType(CrossType.Pure).in(file("core"))
.settings(...)
.jvmConfigure(_.copy(id = "core"))
.jsConfigure(_.copy(id = "coreJS"))
lazy val core = coreBase.jvm
lazy val coreJS = coreBase.js
(主要是因为我对于必须维护Scala.js构建并且不想输入它感到不满 JVM
每当我改变项目时后缀等等)
这不能在SBT 1.0中编译,因为 Project
没有 copy
方法吧。
好的,我们来检查一下 迁移指南。
许多案例类被替换为使用Contraband生成的伪案例类。迁移 .copy(foo = xxx)
至 withFoo(xxx)
。
很酷,我们来试试吧。
build.sbt:100: error: value withId is not a member of sbt.Project
.jvmConfigure(_.withId("core"))
^
所以我 在吉特问道 并得到了蟋蟀。
1.0 API文档的链接现在实际上指向了某些东西,这很好,但它们并没有很大帮助 这个案例,并试图阅读SBT来源让我头疼。我并不急于更新到1.0,但我想在某些时候,我想,也许有些有帮助的人会在那时回答这个问题。
(这个答案已经编辑了有关sbt 1.1.0+和sbt-crossproject 0.3.1+的信息,这显着简化了整个事情。)
使用sbt 1.1.0及更高版本,您可以使用 .withId("core")
。但是对于sbt-crossproject 0.3.1+更好,见下文。
我不知道改变一个的ID Project
但是 这也是一种完全不同的解决原始问题的方法,即有 core
/coreJS
代替 coreJVM/coreJS
。想法是定制 crossProject
使用您想要开始的ID。
首先,你需要使用 SBT-crossproject。它是跨多个平台进行编译的新“标准”,由Scala Native和我自己(来自Scala.js)的@densh共同设计。 Scala.js 1.x将始终使用sbt-crossproject,但也可以将sbt-crossproject与Scala.js 0.6.x一起使用。为此,请关注 自述文件中的说明。特别是,不要忘记“阴影”部分:
// Shadow sbt-scalajs' crossProject and CrossType from Scala.js 0.6.x
import sbtcrossproject.{crossProject, CrossType}
sbt-crossproject比Scala.js的硬编码更灵活 crossProject
。这意味着您可以更轻松地自定义它。特别是,它有一个通用的概念 Platform
,定义任何给定平台的行为方式。
对于跨JVM / JS项目,新风格 crossProject
调用将是
lazy val coreBase = crossProject(JVMPlatform, JSPlatform)
.crossType(CrossType.Pure)
.in(file("core"))
.settings(...)
.jvmConfigure(_.copy(id = "core"))
.jsConfigure(_.copy(id = "coreJS"))
lazy val core = coreBase.jvm
lazy val coreJS = coreBase.js
从sbt-crossproject 0.3.1开始,您可以简单地告诉它不要为您的某个平台添加平台后缀。在您的情况下,您希望避免JVM平台的后缀,因此您可以编写:
lazy val coreBase = crossProject(JVMPlatform, JSPlatform)
.withoutSuffixFor(JVMPlatform)
.crossType(CrossType.Pure)
...
lazy val core = coreBase.jvm
lazy val coreJS = coreBase.js
这就是你需要做的一切!
旧答案,适用于sbt-crossproject 0.3.0及之前
JVMPlatform
和 JSPlatform
不是ADT;它们采用OO风格设计。这意味着您可以创建自己的。特别是,您可以创建自己的 JVMPlatformNoSuffix
这将做同样的事情 JVMPlatform
但是没有为项目ID添加后缀:
import sbt._
import sbtcrossproject._
case object JVMPlatformNoSuffix extends Platform {
def identifier: String = "jvm"
def sbtSuffix: String = "" // <-- here is the magical empty string
def enable(project: Project): Project = project
val crossBinary: CrossVersion = CrossVersion.binary
val crossFull: CrossVersion = CrossVersion.full
}
现在还不够,因为 .jvmSettings(...)
和朋友被定义为采取行动 JVMPlatform
,而不是任何其他 Platform
如 JVMPlatformNoSuffix
。因此,你必须重新定义它:
implicit def JVMNoSuffixCrossProjectBuilderOps(
builder: CrossProject.Builder): JVMNoSuffixCrossProjectOps =
new JVMNoSuffixCrossProjectOps(builder)
implicit class JVMNoSuffixCrossProjectOps(project: CrossProject) {
def jvm: Project = project.projects(JVMPlatformNoSuffix)
def jvmSettings(ss: Def.SettingsDefinition*): CrossProject =
jvmConfigure(_.settings(ss: _*))
def jvmConfigure(transformer: Project => Project): CrossProject =
project.configurePlatform(JVMPlatformNoSuffix)(transformer)
}
一旦你在你的构建中拥有所有这些(隐藏在一个 project/JVMPlatformNoSuffix.scala
为了不污染 .sbt
文件),您可以将上面的跨项目定义为:
lazy val coreBase = crossProject(JVMPlatformNoSuffix, JSPlatform)
.crossType(CrossType.Pure)
.in(file("core"))
.settings(...)
lazy val core = coreBase.jvm
lazy val coreJS = coreBase.js
无需明确修补项目ID。
(这个答案已经编辑了有关sbt 1.1.0+和sbt-crossproject 0.3.1+的信息,这显着简化了整个事情。)
使用sbt 1.1.0及更高版本,您可以使用 .withId("core")
。但是对于sbt-crossproject 0.3.1+更好,见下文。
我不知道改变一个的ID Project
但是 这也是一种完全不同的解决原始问题的方法,即有 core
/coreJS
代替 coreJVM/coreJS
。想法是定制 crossProject
使用您想要开始的ID。
首先,你需要使用 SBT-crossproject。它是跨多个平台进行编译的新“标准”,由Scala Native和我自己(来自Scala.js)的@densh共同设计。 Scala.js 1.x将始终使用sbt-crossproject,但也可以将sbt-crossproject与Scala.js 0.6.x一起使用。为此,请关注 自述文件中的说明。特别是,不要忘记“阴影”部分:
// Shadow sbt-scalajs' crossProject and CrossType from Scala.js 0.6.x
import sbtcrossproject.{crossProject, CrossType}
sbt-crossproject比Scala.js的硬编码更灵活 crossProject
。这意味着您可以更轻松地自定义它。特别是,它有一个通用的概念 Platform
,定义任何给定平台的行为方式。
对于跨JVM / JS项目,新风格 crossProject
调用将是
lazy val coreBase = crossProject(JVMPlatform, JSPlatform)
.crossType(CrossType.Pure)
.in(file("core"))
.settings(...)
.jvmConfigure(_.copy(id = "core"))
.jsConfigure(_.copy(id = "coreJS"))
lazy val core = coreBase.jvm
lazy val coreJS = coreBase.js
从sbt-crossproject 0.3.1开始,您可以简单地告诉它不要为您的某个平台添加平台后缀。在您的情况下,您希望避免JVM平台的后缀,因此您可以编写:
lazy val coreBase = crossProject(JVMPlatform, JSPlatform)
.withoutSuffixFor(JVMPlatform)
.crossType(CrossType.Pure)
...
lazy val core = coreBase.jvm
lazy val coreJS = coreBase.js
这就是你需要做的一切!
旧答案,适用于sbt-crossproject 0.3.0及之前
JVMPlatform
和 JSPlatform
不是ADT;它们采用OO风格设计。这意味着您可以创建自己的。特别是,您可以创建自己的 JVMPlatformNoSuffix
这将做同样的事情 JVMPlatform
但是没有为项目ID添加后缀:
import sbt._
import sbtcrossproject._
case object JVMPlatformNoSuffix extends Platform {
def identifier: String = "jvm"
def sbtSuffix: String = "" // <-- here is the magical empty string
def enable(project: Project): Project = project
val crossBinary: CrossVersion = CrossVersion.binary
val crossFull: CrossVersion = CrossVersion.full
}
现在还不够,因为 .jvmSettings(...)
和朋友被定义为采取行动 JVMPlatform
,而不是任何其他 Platform
如 JVMPlatformNoSuffix
。因此,你必须重新定义它:
implicit def JVMNoSuffixCrossProjectBuilderOps(
builder: CrossProject.Builder): JVMNoSuffixCrossProjectOps =
new JVMNoSuffixCrossProjectOps(builder)
implicit class JVMNoSuffixCrossProjectOps(project: CrossProject) {
def jvm: Project = project.projects(JVMPlatformNoSuffix)
def jvmSettings(ss: Def.SettingsDefinition*): CrossProject =
jvmConfigure(_.settings(ss: _*))
def jvmConfigure(transformer: Project => Project): CrossProject =
project.configurePlatform(JVMPlatformNoSuffix)(transformer)
}
一旦你在你的构建中拥有所有这些(隐藏在一个 project/JVMPlatformNoSuffix.scala
为了不污染 .sbt
文件),您可以将上面的跨项目定义为:
lazy val coreBase = crossProject(JVMPlatformNoSuffix, JSPlatform)
.crossType(CrossType.Pure)
.in(file("core"))
.settings(...)
lazy val core = coreBase.jvm
lazy val coreJS = coreBase.js
无需明确修补项目ID。