2016-11-09 21 views
10

Tôi đang cố gắng xây dựng một dự án sử dụng cả bộ đệm giao thức của Google và Kotlin bằng Gradle. Tôi muốn các tệp proto để biên dịch thành nguồn Java, sau đó được gọi từ mã Kotlin của tôi.Làm cách nào để tạo bộ đệm giao thức của Google và Kotlin bằng Gradle?

file nguồn của tôi được sắp xếp như thế này:

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

Dưới đây là build.gradle tập tin của tôi:

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

Khi tôi chạy ./gradlew assemble tôi nhận được một loạt các sai sót "tài liệu tham khảo không được giải quyết" trong :compileKotlin. Sau đó tôi có thể thấy rằng không có tệp nguồn Java nào được tạo ra, do đó, có vẻ như trình biên dịch proto không được viện dẫn chút nào.

Nếu tôi xóa dòng apply plugin: 'kotlin', thì ./gradlew assemble tạo thành công nguồn Java, nhưng tất nhiên nguồn Kotlin của tôi không bao giờ được biên dịch.

Làm cách nào để sửa lỗi build.gradle để tôi có thể gọi mã protobuf của mình từ Kotlin?

Trả lời

10

Tôi có thể làm việc này bằng cách thêm hai dòng vào build.gradle của tôi.

Dòng đầu tiên cho biết thêm các thư mục trong đó trình biên dịch proto tạo ra mã Java để các thư mục các :compileKotlin tìm kiếm nguồn Java:

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

Thứ hai, đảm bảo rằng mã Java là (lại) được tạo ra trước khi gọi :compileKotlin :

compileKotlin.dependsOn ':generateProto' 
+2

Một lưu ý nhỏ: Bạn có thể thay đổi đường dẫn trong bước đầu tiên cho ' "$ {protobuf.generatedFilesBaseDir}/main/java" 'để tự động nhận thư mục thay đổi. –

5

Đối Kotlin và Android:

android { 

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

Một thư mục nguồn bổ sung phải được thêm vào cho mọi loại xây dựng. Trong mẫu này có hai loại bản dựng: debugrelease.

Nếu bạn đang sử dụng grpc, dòng khác đã được thêm vào mỗi build loại:

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

Ít nhất với Kotlin 1.0.6, protobuf-gradle-plugin 0.8.0, protobuf 3.2.x và grpc 1.x nó không cần thiết để fiddle với thứ tự nhiệm vụ.

0

nếu bạn đang làm việc với nhiều loại xây dựng và hương vị trong android và với việc sử dụng protobuf-lite dưới đây với kotlin.

ví dụ tôi có debugrelease xây dựng với demoprod hương vị nó sẽ tạo ra demoDebug, demoReleaseprodDebugprodRelease biến thể.

sau đó sử dụng

'

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

'

buộc các compileKotlin khác nhau với 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') 
} 
Các vấn đề liên quan