我有一堆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
方法。
好的,让我们检查the migration guide。
许多案例类被替换为使用Contraband生成的伪案例类。将
.copy(foo = xxx)
迁移到withFoo(xxx)
。
很酷,我们来试试吧。
build.sbt:100: error: value withId is not a member of sbt.Project
.jvmConfigure(_.withId("core"))
^
所以我asked on Gitter并得到了蟋蟀。
1.0 API文档的链接现在实际上指向某个东西,这很好,但它们在this case中没有用,并且尝试阅读SBT源让我头疼。我并不急于更新到1.0,但我想在某些时候我不得不这样做,也许有些有帮助的人会在那时回答这个问题。
答案 0 :(得分:15)
(这个答案已经编辑了有关sbt 1.1.0+和sbt-crossproject 0.3.1+的信息,这显着简化了整个事情。)
使用sbt 1.1.0及更高版本,您可以使用.withId("core")
。但是对于sbt-crossproject 0.3.1+,情况会更好,见下文。
我不知道如何更改这里也是解决原始问题的完全不同的方式,即{{1} } / Project
的ID,但core
代替coreJS
。我们的想法是自定义coreJVM/coreJS
以使用您想要开头的ID。
首先,您需要使用sbt-crossproject。这是新的标准"用于跨多个平台的编译,由来自Scala Native和我自己(来自Scala.js)的@densh共同设计。 Scala.js 1.x将始终使用sbt-crossproject,但也可以将sbt-crossproject与Scala.js 0.6.x一起使用。为此,请关注the instructions in the readme。特别是,不要忘记"阴影"部分:
crossProject
sbt-crossproject比Scala.js更灵活。硬编码// Shadow sbt-scalajs' crossProject and CrossType from Scala.js 0.6.x
import sbtcrossproject.{crossProject, CrossType}
。这意味着您可以更轻松地自定义它。特别是,它具有crossProject
的通用概念,定义了任何给定平台的行为方式。
对于跨JVM / JS项目,新式Platform
调用将是
crossProject
从sbt-crossproject 0.3.1开始,您可以简单地告诉它不要为您的某个平台添加平台后缀。在您的情况下,您希望避免使用JVM平台的后缀,因此您可以编写:
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.0及之前
lazy val coreBase = crossProject(JVMPlatform, JSPlatform)
.withoutSuffixFor(JVMPlatform)
.crossType(CrossType.Pure)
...
lazy val core = coreBase.jvm
lazy val coreJS = coreBase.js
和JVMPlatform
不是ADT;它们采用OO风格设计。这意味着您可以创建自己的。特别是,您可以创建自己的JSPlatform
,其作用与JVMPlatform
相同,但不会在项目ID中添加后缀:
JVMPlatformNoSuffix
现在还不够,因为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
无需明确修补项目ID。