我有一个 Scala.js 项目,想使用 SBT sourceGenerators 设置在编译时生成一些代码。在下面的 SBT 文件中,如果我对 sourceGenerators 部分中的字符串进行硬编码,或者如果我引用“project”目录中定义的 Scala 代码,一切都会正常。
然而,我想要做的是让我的 build.sbt 文件引用一个完全独立的“生成器”项目中的源代码。我已经尝试了各种依赖于 RootProject(file("path-to-generator-project")) 的方法,但似乎没有任何效果。谁能帮我弄清楚如何让 build.sbt 代码引用从另一个项目中的源代码构建的类?
编辑:编辑以添加我正在尝试做的示例。
如果我的文件夹结构如下所示:
MyScalaJSProject
build.sbt
client
server
shared
generator
src/main/scala/Generator.scala
(object with a generate: String method)
build.sbt (generator is its own root level project)
Run Code Online (Sandbox Code Playgroud)
使用该结构,我希望我的顶级 build.sbt 能够引用 Generator.generate 来生成用于 sourceGenerators 的字符串。但是如果我在下面的 build.sbt 中调用 Generator.generate ,我会得到一个构建错误,因为我的顶级项目 build.sbt 不知道生成器项目。
import sbt.Project.projectToRef
lazy val clients = Seq(client)
lazy val server = (project in file("server")).settings(
name := "ServerProject",
scalaVersion := "2.11.8",
scalaJSProjects := clients,
pipelineStages := Seq(scalaJSProd, gzip),
resolvers += ...some resolvers...,
libraryDependencies ++= Seq(...some dependencies...),
sourceGenerators in Compile += Def.task {
val file = (sourceManaged in Compile).value / "demo" / "Test.scala"
IO.write(file, Generator.generate) <-- build error here
Seq(file)
}.taskValue
).enablePlugins(PlayScala).
aggregate(clients.map(projectToRef): _*).
dependsOn(sharedJvm)
lazy val client = (project in file("client")).settings(
name := "ClientProject",
scalaVersion := "2.11.8",
persistLauncher := true,
persistLauncher in Test := false,
libraryDependencies ++= Seq(...client dependencies...),
addCompilerPlugin("org.scalamacros" % "paradise" % "2.1.0" cross CrossVersion.full)
).enablePlugins(ScalaJSPlugin, ScalaJSPlay).
dependsOn(sharedJs)
lazy val shared = (crossProject.crossType(CrossType.Pure) in file("shared")).
settings(
name := "SharedProject",
scalaVersion := scalaV,
libraryDependencies ++= Seq(...shared dependencies...)
).
jsConfigure(_ enablePlugins ScalaJSPlay)
lazy val sharedJvm = shared.jvm
lazy val sharedJs = shared.js
// loads the Play project at sbt startup
onLoad in Global := (Command.process("project server", _: State)) compose (onLoad in Global).value
// for Eclipse users
EclipseKeys.skipParents in ThisBuild := false
// Compile the project before generating Eclipse files, so that generated .scala or .class files for views and routes are present
EclipseKeys.preTasks := Seq(compile in (server, Compile))
Run Code Online (Sandbox Code Playgroud)
由于您想直接在 sbt 文件中使用生成器,因此您的Generator类是构建的一部分;因此应该在project文件夹中定义。有关更多信息,请参阅http://www.scala-sbt.org/0.13/docs/Organizing-Build.html
我很快写了一个简单的例子,在项目文件夹中定义了一个简单的生成器。
生成.sbt
name := "ServerProject"
scalaVersion := "2.11.8"
sourceGenerators in Compile += Def.task {
val file = (sourceManaged in Compile).value / "demo" / "Test.scala"
IO.write(file, Generator.generate)
Seq(file)
}.taskValue
Run Code Online (Sandbox Code Playgroud)
项目/Generator.scala
object Generator {
def generate = """
package demo
object Test{
def main(args: Array[String]): Unit = {
println("Hello, world!")
}
}
"""
}
Run Code Online (Sandbox Code Playgroud)
做一个sbt run会打印“你好,世界!” 正如预期的那样。
如果您的生成器更复杂;你有两个选择:
首先:将其提取为 sbt AutoPlugin;并使您的构建依赖于插件。(请参阅此处。)这很容易做到,您可以在其他项目中重用这些代码。
第二:build.sbt在项目文件夹中添加一个文件,这将使您的主构建依赖于生成器项目。使用相同的例子;这是要创建的文件夹结构:
生成.sbt
和上面一样
发电机/src/main/scala/Generator.scala
与上面的 project/Generator.scala 相同(我只是移动了文件)
项目/build.sbt
lazy val generator=RootProject(file("../generator"))
lazy val root=(project in file(".")).dependsOn(generator)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2047 次 |
| 最近记录: |