Gradle Protobuf模块频繁重复构建问题排查
解决Gradle Protobuf插件无变更重复构建问题
我使用0.9.1版本的protobuf Gradle插件配置模块生成gRPC代码,配置代码如下:
protobuf { protoc { artifact = "com.google.protobuf:protoc:$protobufVersion" } plugins { id("grpc") { artifact = "io.grpc:protoc-gen-grpc-java:$grpcVersion" } id("grpckt") { artifact = "io.grpc:protoc-gen-grpc-kotlin:$grpcKotlinVersion:jdk8@jar" } } generateProtoTasks { ofSourceSet("main").forEach { task -> task.plugins { id("grpc") id("grpckt") } task.builtins { id("kotlin") } } } }
代码生成功能正常,但模块会在无任何代码变更的情况下重复执行构建,导致构建速度大幅下降。通过--scan参数分析构建过程,得到如下提示:
The task was not up-to-date because of the following reasons:
Output property 'destDir' file xxx/build/extracted-protos/main has been removed.
问题原因及解决方案
这个问题是0.9.1版本protobuf插件的已知增量构建缺陷:插件默认使用的build/extracted-protos/main目录可能被其他任务(如自定义清理任务、资源同步任务)意外删除,或者插件自身对该目录的输入输出追踪逻辑存在漏洞,导致Gradle判定生成proto的任务输出变更,从而重复执行。
方案1:升级protobuf插件版本(推荐)
0.9.1版本较老旧,后续发布的版本(如0.9.4及以上)修复了这类增量构建问题。直接升级插件版本到最新稳定版,通常就能解决重复构建的问题。
方案2:自定义提取proto目录(无法升级时使用)
手动指定自定义的proto提取目录,避免和默认目录冲突,同时强化任务的输入输出追踪:
protobuf { protoc { artifact = "com.google.protobuf:protoc:$protobufVersion" } // 自定义提取proto的目录,避开默认的易冲突路径 extractProtos { destinationDir = file("$buildDir/custom-extracted-protos") } plugins { id("grpc") { artifact = "io.grpc:protoc-gen-grpc-java:$grpcVersion" } id("grpckt") { artifact = "io.grpc:protoc-gen-grpc-kotlin:$grpcKotlinVersion:jdk8@jar" } } generateProtoTasks { ofSourceSet("main").forEach { task -> task.plugins { id("grpc") id("grpckt") } task.builtins { id("kotlin") } // 显式标记任务输出目录,帮助Gradle正确追踪增量变更 task.outputs.dir(task.outputs.files.singleFile) } } }
额外检查
排查模块中是否存在自定义的清理、资源处理任务,确认这些任务是否会删除build/extracted-protos或自定义的提取目录。如果有,需要调整任务逻辑,排除该目录,或者调整任务执行顺序,确保生成proto的任务在删除类任务之后运行。
内容的提问来源于stack exchange,提问作者Kimble
相关产品推荐
相关产品推荐

