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

时间:2016-11-09 02:26:39

标签: gradle kotlin protocol-buffers

我尝试使用Gradle构建一个同时使用Google协议缓冲区和Kotlin的项目。我希望将proto文件编译成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代码?

3 个答案:

答案 0 :(得分:13)

我能够通过在build.gradle中添加两行来实现这一点。

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

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

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

compileKotlin.dependsOn ':generateProto'

答案 1 :(得分:5)

对于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,它不需要操作任务顺序。

答案 2 :(得分:1)

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

例如,我有debugrelease版本,其demoprod版本会创建demoDebugdemoRelease和{{1} }和prodDebug变体。

然后使用

`

prodRelease

`

将不同的compileKotlin与generateProto

联系起来
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'
      }
    }