Gradle: Java / Kotlin, C ++, ProtoBuf в том же проекте - PullRequest
0 голосов
/ 20 марта 2019

У меня есть приложение Java + Kotlin, созданное с помощью Gradle.

Некоторые функции низкого уровня предоставляются отдельным приложением C ++.

Два приложения взаимодействуют через сокет илиpipe, используя Protocol Buffers и gRPC.

Изначально я надеялся собрать все три (сгенерированный ProtoBuf код, приложение Java, приложение C ++) в одном проекте, однако конфликт cpp-application и javaопределенные задачи (компиляция / реализация / тест?).

С тех пор я разбил это на три проекта:

/
 build.gradle
 settings.gradle
 cpp-app/
         build.gradle
         settings.gradle
         ...
 java-app/
          build.gradle
          settings.gradle
          ...
 protocol/
          build.gradle
          settings.gradle
          build/generated/source/proto/main/java/...   <-- Java generated code
          build/generated/source/proto/main/cpp/...    <-- C++ generated code
          ...

У меня есть проект protocol, успешно генерирующий реализации C ++ и Java.

Как заставить проекты приложений C ++ и Java разрешать и использовать эти выходные данные в своих сборках?

1 Ответ

0 голосов
/ 20 марта 2019

Я решил это, когда писал вопрос.

Файлы конфигурации Gradle показаны ниже. Есть несколько избыточных блоков, которые не нужны для этого примера (или вообще необходимы), однако они достигают цели.

/ build.gradle

subprojects {
        group = 'com.whatever.your.group'
        version = '0.0.0'
        repositories {
                mavenCentral()
        }
}

/ settings.gradle

rootProject.name = 'my-project'
include 'java-app'
include 'cpp-app'
include 'protocol'

/ Java-приложение / build.gradle

buildscript {
        repositories {
                mavenCentral()
        }
        dependencies {
                classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.20"
        }
}

plugins {
        // Java
        id 'maven'
        id 'idea'
        id 'application'
        id 'java'
        id 'org.jetbrains.kotlin.jvm' version '1.3.20'

        // ProtoBuf
        id 'com.google.protobuf' version '0.8.8'
}

description = """"""

sourceCompatibility = 8
targetCompatibility = 8

compileKotlin {
        kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
        kotlinOptions.jvmTarget = "1.8"
}

mainClassName = 'my.main.Class'

dependencies {
        protobuf project(':protocol') // <-- name of protobuf project
        compile project(':protocol')  // <-- name of protobuf project
        // We have "protobuf" and "compile", as "compile" brings in transitive dependencies

        testCompile 'junit:junit:4.12'

        implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.20"

        testImplementation "org.jetbrains.kotlin:kotlin-test:1.3.20"
        testImplementation "org.jetbrains.kotlin:kotlin-test-junit:1.3.20"
}

sourceSets {
        main {
                java {
                        srcDir "src/main/java"
                }
                kotlin {
                        srcDir "src/main/kotlin"
                }
        }
}

/ Java-приложение / settings.gradle

rootProject.name = 'java-app'

/ CPP-приложение / build.gradle

plugins {
        id 'maven'
        id 'cpp'
}

description = """"""

project.tasks.build.dependsOn 'protocol'  // <-- name of protobuf project

model {
        components {
                main(NativeExecutableSpec) {
                        ...
                }
        }
        ...
}

/ CPP-приложение / settings.gradle

rootProject.name = 'cpp-app'

/ протокол / build.gradle

plugins {
        id 'maven'
        id 'java'
        id 'com.google.protobuf' version '0.8.8'
}

repositories {
        mavenCentral()
}

description = """"""

sourceCompatibility = 8
targetCompatibility = 8

dependencies {
        compile 'com.google.protobuf:protobuf-java:3.7.0'
        compile 'io.grpc:grpc-stub:1.19.0'
        compile 'io.grpc:grpc-protobuf:1.19.0'
}

sourceSets {
        main {
                proto {
                        srcDir "src/main/proto"
                }
        }
}

protobuf {
        protoc {
                artifact = "com.google.protobuf:protoc:3.7.0"
        }
        plugins {
                grpc_java {
                        artifact = 'io.grpc:protoc-gen-grpc-java:1.19.0'
                }
                grpc_cpp {
                        path = getPluginPath('cpp')
                }
                grpc_python {
                        path = getPluginPath('python')
                }
        }
        generateProtoTasks {
                generatedFilesBaseDir = "${buildDir}/build/generated/src"
                all()*.builtins {
                        java { }
                        cpp { }
                        python { }
                }
                all()*.plugins {
                        grpc_java {
                                outputSubDir = 'java'
                        }
                        grpc_cpp {
                                outputSubDir = 'cpp'
                        }
                        grpc_python {
                                outputSubDir = 'python'
                        }
                }
        }
}

clean {
        delete protobuf.generatedFilesBaseDir
}

// Used to find executables for generating C++ and Java gRPC
static def getPluginPath(name) {
        def path = "which grpc_${name}_plugin".execute()
        path.waitFor()
        path = path.in.text.trim()
        if (!path) {
                println "Failed to locate GRPC plugin for ${name}"
        } else {
                println "Found GRPC plugin for ${name} at ${path}"
        }
        return path
}

/ протокол / settings.gradle

rootProject.name = 'protocol'

Затем в корне проекта я могу запустить gradle assemble и:

$ gradle assemble

> Configure project :protocol
Found GRPC plugin for cpp at /usr/bin/grpc_cpp_plugin
Found GRPC plugin for python at /usr/bin/grpc_python_plugin

> Task :cpp-app:linkMainExecutable NO-SOURCE
> Task :cpp-app:mainExecutable UP-TO-DATE
> Task :cpp-app:assemble UP-TO-DATE
> Task :protocol:extractIncludeProto
> Task :protocol:extractProto
> Task :protocol:generateProto
> Task :protocol:compileJava
> Task :protocol:processResources
> Task :protocol:classes
> Task :protocol:jar
> Task :protocol:assemble
> Task :java-app:extractIncludeProto
> Task :java-app:extractProto
> Task :java-app:generateProto
> Task :java-app:compileKotlin
> Task :java-app:compileJava
> Task :java-app:processResources
> Task :java-app:classes
> Task :java-app:inspectClassesForKotlinIC
> Task :java-app:jar
> Task :java-app:startScripts
> Task :java-app:distTar
> Task :java-app:distZip
> Task :java-app:assemble

BUILD SUCCESSFUL in 10s
17 actionable tasks: 17 executed
...