sbt集成ScalaPB编译提示PB.targets为空、proto路径不识别修复
问题核心原因
两个问题的本质都是sbt配置未正确生效:
- 你单独定义了
commonSettings、scalaGrpcSettings两个配置集合,但没有将这两个集合挂载到根项目上,sbt-protoc插件读取不到你配置的PB.targets规则,因此抛出Protobufs files found, but PB.targets is empty.错误。 - 你使用
:=操作符全量覆盖PB.protoSources配置时,要么自定义路径和实际proto存放位置不匹配,要么覆盖后丢失了默认的proto扫描路径,导致proto文件识别失败。
具体修复方案
- 第一步:将自定义配置关联到根项目
修改build.sbt中根项目的定义,把你写的通用配置、scalapb配置都加入项目的settings列表,修正后核心代码如下:ThisBuild / version := "0.1.0-SNAPSHOT" lazy val root = (project in file(".")) .settings( name := "proto-path-error", commonSettings, scalaGrpcSettings ) val openRtbCoreVersion = "1.5.5" val googleCommonProtosVersion = "1.12.0" val commonSettings: Seq[Def.Setting[_]] = Seq[Def.Setting[_]]( scalaVersion := "2.12.14", organization := "com.td", ) def scalaGrpcSettings: Seq[Def.Setting[_]] = Seq[Def.Setting[_]]( libraryDependencies += "com.thesamet.scalapb" %% "scalapb-runtime-grpc" % scalapb.compiler.Version.scalapbVersion, libraryDependencies += "com.thesamet.scalapb" %% "scalapb-runtime" % scalapb.compiler.Version.scalapbVersion % "protobuf", libraryDependencies += "com.google.api.grpc" % "proto-google-common-protos" % googleCommonProtosVersion % "protobuf", libraryDependencies += "com.google.openrtb" % "openrtb-core" % openRtbCoreVersion, libraryDependencies += "com.google.openrtb" % "openrtb-core" % openRtbCoreVersion % "protobuf", PB.targets in Compile := Seq( PB.gens.java -> (sourceManaged in Compile).value, scalapb.gen(javaConversions = true) -> (sourceManaged in Compile).value ), PB.includePaths in Compile ++= Seq( target.value / "protobuf_external", new File("definitions/common") ), PB.protoSources in Compile ++= Seq( PB.externalIncludePath.value / "google" / "api", new File("definitions/common"), target.value / "protobuf_external" ), excludeFilter in PB.generate := new SimpleFileFilter(file => file.getCanonicalPath.contains("google/protobuf")), PB.additionalDependencies := Nil ) - 第二步:按需选择proto存放路径
两种方案二选一即可:- 方案A:使用sbt-protoc默认扫描路径,把你的
common.proto放在src/main/protobuf目录下(可保留子目录结构),删除手动写的PB.protoSources、PB.includePaths全量覆盖配置,插件会自动扫描该路径下所有proto文件,无需额外配置。 - 方案B:保留自定义路径,把proto放在项目根目录的
definitions/common路径下,使用++=操作符把该路径追加到PB.protoSources列表中,不要用:=全量覆盖默认配置,避免默认路径失效。
- 方案A:使用sbt-protoc默认扫描路径,把你的
- 第三步:验证编译结果
配置修改完成后,执行sbt clean compile命令,编译完成后可在target/scala-2.12/src_managed/main目录下找到生成的Scala样例类,对应包路径com/td/protobuf/下会存在CMap.scala、Assets.scala两个文件,即为预期生成的case class。
注意事项
- sbt中
:=操作符是全量覆盖配置项,++=是在原有默认配置基础上追加内容,修改插件配置时优先用追加操作,避免默认规则被清空导致异常。 PB.protoSources用于指定业务proto文件的存放根目录,PB.includePaths用于指定编译proto时依赖的外部proto搜索路径,两者不要混淆配置。
内容的提问来源于stack exchange,提问作者user51
相关产品推荐
相关产品推荐

