How to build Google protocol buffers and Kotlin using Gradle?

南笙酒味 提交于 2020-12-29 05:29:19

问题


I'm trying to build a project that uses both Google protocol buffers and Kotlin using Gradle. I want the proto files to compile into Java source, which is then called from my Kotlin code.

My source files are arranged like this:

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

Here's my build.gradle file:

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'
}

When I run ./gradlew assemble I get a bunch of "Unresolved reference" errors during :compileKotlin. Afterwards I can see that there are no Java source files generated, so it appears that the proto compiler is not being invoked at all.

If I remove the apply plugin: 'kotlin' line, then ./gradlew assemble successfully generates the Java source, but of course my Kotlin source is never compiled.

How do I fix my build.gradle so that I can call my protobuf code from Kotlin?


回答1:


I was able to get this to work by adding two lines to my build.gradle.

The first line adds the directory in which the proto compiler generates Java code to the directories the :compileKotlin looks for Java source:

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

The second ensures that the Java code is (re)generated before invoking :compileKotlin:

compileKotlin.dependsOn ':generateProto'



回答2:


For Kotlin and Android:

android {

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

An additional source directory has to be added for every build type. In this sample there are two build types: debug and release.

If you're using grpc, another line has to be added per build type:

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'
    }
}

At least with Kotlin 1.0.6, protobuf-gradle-plugin 0.8.0, protobuf 3.2.x and grpc 1.x it's not required to fiddle with the task order.




回答3:


if you are working with multiple build types and flavors in android and with protobuf-lite use below with kotlin.

for example I have debug and release builds with demo and prod flavors it will create demoDebug, demoRelease and prodDebug and prodRelease variants.

then use

`

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'
      }
    }

`

tie the different compileKotlin with generateProto

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')
}


来源:https://stackoverflow.com/questions/40499452/how-to-build-google-protocol-buffers-and-kotlin-using-gradle

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!