如何使用Gradle建立Google协议缓冲区和Kotlin?

我正在尝试使用Gradle构建一个同时使用Google协议缓冲区和Kotlin的项目。 我想要原始文件编译成Java源代码,然后从我的Kotlin代码中调用。

我的源文件是这样排列的:

src/main/proto/*.proto src/main/kotlin/*.kt src/test/kotlin/*.kt 

这是我的build.gradle文件:

 version '1.0-SNAPSHOT' apply plugin: 'kotlin' apply plugin: 'java' apply plugin: 'com.google.protobuf' repositories { mavenCentral() maven { url "http://dl.bintray.com/kotlin/kotlin-eap-1.1" } } buildscript { ext.kotlin_version = '1.1-M02' repositories { mavenCentral() maven { url "http://dl.bintray.com/kotlin/kotlin-eap-1.1" } } dependencies { classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } protobuf { protoc { artifact = 'com.google.protobuf:protoc:3.0.0' } } dependencies { compile 'com.google.protobuf:protobuf-java:3.0.0' compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" testCompile 'junit:junit:4.12' } 

当我运行./gradlew assemble我得到了一堆“未解决的参考”错误:compileKotlin 。 之后我可以看到没有生成Java源文件,所以似乎根本没有调用proto编译器。

如果我删除apply plugin: 'kotlin'行,那么./gradlew assemble成功生成了Java源代码,但是我的Kotlin源代码当然不会被编译。

如何修复我的build.gradle以便我可以从Kotlin调用我的protobuf代码?

我能够通过添加两行到我的build.gradle得到这个工作。

第一行将proto编译器生成Java代码的目录添加到:compileKotlin寻找Java源代码的目录中:

 sourceSets.main.java.srcDirs += 'build/generated/source/proto/main/java' 

第二个确保在调用之前(重新)生成Java代码:compileKotlin

 compileKotlin.dependsOn ':generateProto' 

对于Kotlin和Android:

 android { sourceSets { debug.java.srcDirs += 'build/generated/source/proto/debug/java' release.java.srcDirs += 'build/generated/source/proto/release/java' } } 

每个构建类型都必须添加一个额外的源代码目录。 在这个示例中有两种构建类型: debugrelease

如果您使用grpc,则必须为每个构建类型添加另一行:

 android { sourceSets { debug.java.srcDirs += 'build/generated/source/proto/debug/java' debug.java.srcDirs += 'build/generated/source/proto/debug/grpc' release.java.srcDirs += 'build/generated/source/proto/release/java' release.java.srcDirs += 'build/generated/source/proto/release/grpc' } } 

至少在Kotlin 1.0.6中,protobuf-gradle-plugin 0.8.0,protobuf 3.2.x和grpc 1.x并不需要摆弄任务顺序。

如果你正在使用Android中的多种构建类型和风格,并使用下面的kotlin来使用protobuf-lite。

例如我有debugrelease版本与demoprod口味,它将创建demoDebugdemoReleaseprodDebugprodRelease变种。

然后使用

`

 android{ sourceSets { debug.java.srcDirs += 'build/generated/source/proto/demoDebug/javalite' debug.java.srcDirs += 'build/generated/source/proto/prodDebug/javalite' release.java.srcDirs += 'build/generated/source/proto/demoRelease/javalite' release.java.srcDirs += 'build/generated/source/proto/prodRelease/javalite' } } 

`

用generateProto绑定不同的compileKotlin

 tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all { if (getName() == 'compileDemoDebugKotlin') dependsOn(':app:generateDemoDebugProto') if (getName() == 'compileDemoReleaseKotlin') dependsOn(':app:generateDemoReleaseProto') if (getName() == 'compileProdDebugKotlin') dependsOn(':app:generateProdDebugProto') if (getName() == 'compileProdReleaseKotlin') dependsOn(':app:generateProdReleaseProto') }