SBT `CrossProject` 构建破坏了自定义编译目标
SBT `CrossProject` build broken with custom compile target
为基于 Scala.js CrossProject
的构建定义的自定义编译目标(/tmp/sbt/
上的 ramdisk)出现 "Overlapping output directories" sbt 错误。
FWIW,已在 SBT 项目中无缝使用上述编译目标 3 年 运行。使用 sbt 默认编译目标(即构建项目根)时,错误 而不是 发生。由于我的工具是围绕 ramdisk 设置而设计的,所以有点阻碍。
这是实际错误:
Overlapping output directories:/tmp/sbt/foo:
[error] ProjectRef(file:/home/me/path/to/project/,fooJS)
[error] ProjectRef(file:/home/me/path/to/project/,fooJVM)
已尝试子类化 CrossType
as suggested in the docs, overriding projectDir
and sharedSrcDir
to no avail, same error. Here's SBT source location,其中检查重叠目标。
我想知道为什么自定义编译目标而不是默认目标会出现这种情况?更重要的是,如何获得使用 Scala.js' crossProject
?
的自定义编译目标
根据评论,您正在像这样自定义目标目录:
target <<= (name) { (name) => file("/tmp/sbt") / name }
在 0.13 表示法中,这意味着:
target := file("/tmp/sbt") / name.value
这会导致跨项目出现问题,因为 crossProject
的 JVM 和 JS 变体默认情况下具有相同的 name
,因此这两个项目确实会以相同的目标结束导致冲突的目录。
您有两种可能来解决这个问题。您要么更改 name
设置,使它们不相同(但随后您需要重新自定义 normalizedName
以使它们再次相同),或者您更改计算方式target
这样它就不同了。
第一个解决方案:
lazy val foo = crossProject.in(...).
jvmSettings(name := name.value + "-jvm").
jsSettings(name := name.value + "-js").
settings(
normalizedName := normalizedName.value.stripSuffix("-jvm").stripSuffix("-js")
).
// other settings
这不是很优雅。我建议另一种方法,例如:
target := {
/* Hacky way to detect whether this is a Scala.js project
* without pulling the Scala.js sbt plugin on the classpath.
*/
val isScalaJS = libraryDependencies.value.exists { dep =>
dep.name.startsWith("scalajs-library") // not tested
}
file("/tmp/sbt") / (name.value + (if (isScalaJS) "-js" else ""))
}
也不是很优雅,因为 hack,但至少你只需要在你的全局配置中使用一次。
为基于 Scala.js CrossProject
的构建定义的自定义编译目标(/tmp/sbt/
上的 ramdisk)出现 "Overlapping output directories" sbt 错误。
FWIW,已在 SBT 项目中无缝使用上述编译目标 3 年 运行。使用 sbt 默认编译目标(即构建项目根)时,错误 而不是 发生。由于我的工具是围绕 ramdisk 设置而设计的,所以有点阻碍。
这是实际错误:
Overlapping output directories:/tmp/sbt/foo:
[error] ProjectRef(file:/home/me/path/to/project/,fooJS)
[error] ProjectRef(file:/home/me/path/to/project/,fooJVM)
已尝试子类化 CrossType
as suggested in the docs, overriding projectDir
and sharedSrcDir
to no avail, same error. Here's SBT source location,其中检查重叠目标。
我想知道为什么自定义编译目标而不是默认目标会出现这种情况?更重要的是,如何获得使用 Scala.js' crossProject
?
根据评论,您正在像这样自定义目标目录:
target <<= (name) { (name) => file("/tmp/sbt") / name }
在 0.13 表示法中,这意味着:
target := file("/tmp/sbt") / name.value
这会导致跨项目出现问题,因为 crossProject
的 JVM 和 JS 变体默认情况下具有相同的 name
,因此这两个项目确实会以相同的目标结束导致冲突的目录。
您有两种可能来解决这个问题。您要么更改 name
设置,使它们不相同(但随后您需要重新自定义 normalizedName
以使它们再次相同),或者您更改计算方式target
这样它就不同了。
第一个解决方案:
lazy val foo = crossProject.in(...).
jvmSettings(name := name.value + "-jvm").
jsSettings(name := name.value + "-js").
settings(
normalizedName := normalizedName.value.stripSuffix("-jvm").stripSuffix("-js")
).
// other settings
这不是很优雅。我建议另一种方法,例如:
target := {
/* Hacky way to detect whether this is a Scala.js project
* without pulling the Scala.js sbt plugin on the classpath.
*/
val isScalaJS = libraryDependencies.value.exists { dep =>
dep.name.startsWith("scalajs-library") // not tested
}
file("/tmp/sbt") / (name.value + (if (isScalaJS) "-js" else ""))
}
也不是很优雅,因为 hack,但至少你只需要在你的全局配置中使用一次。