如何使用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' } }
每个构建类型都必须添加一个额外的源代码目录。 在这个示例中有两种构建类型: debug
和release
。
如果您使用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。
例如我有debug
和release
版本与demo
和prod
口味,它将创建demoDebug
, demoRelease
和prodDebug
和prodRelease
变种。
然后使用
`
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') }