scalapb 和自定义源代码生成器冲突

scalapb and custom source generator conflict

我希望向 sbt 添加自定义源代码生成器,并将其与 Scalapb(Scala 协议缓冲区生成器)一起使用。每个都自己工作。然而,当两者结合时,项目在清理后第一次编译失败。如果我运行再次编译,它会成功。

name := "Foo root project"

scalaVersion in ThisBuild:= "2.12.1"

sourceGenerators in Compile += Def.task {
  val file = (sourceManaged in Compile).value / "demo" / "Test.scala"
  IO.write(file, """object Test extends App { println("Hi") }""")
  Seq(file)
}.taskValue

PB.targets in Compile := Seq(
  scalapb.gen() -> (sourceManaged in Compile).value
)

错误信息:

[error] source file '/ ... /target/scala-2.12/src_managed/main/demo/Test.scala' could not be found
[error] one error found
[error] (compile:compileIncremental) Compilation failed

要重现此错误,您至少需要 src/main/protobuf 中的一个原型文件。

令我困惑的是,两个源代码生成器,我的自定义任务和 scalapb 会发生冲突。他们不应该都写入 src_managed 目录吗?我是否遗漏了一些基本的 sbt 概念?

sbt-protoc 存在一个已知问题,导致它删除 src 管理目录中的源。

选项 1:使 ScalaPB 生成到 srcManaged 的​​子目录,这样它只删除该目录:

PB.targets in Compile := Seq(
  scalapb.gen() -> (sourceManaged in Compile).value / "protobufs"
)

选项 2:使 ScalaPB 不删除子目录,但您必须时常自行清理它(例如当 protobuf 消息被重命名时):

PB.deleteTargetDirectory in Compile := false