【问题标题】:Gradle: Java/Kotlin, C++, ProtoBuf in the same projectGradle:Java/Kotlin、C++、ProtoBuf 在同一个项目中
【发布时间】:2019-08-11 03:25:06
【问题描述】:

我有一个 Java+Kotlin 应用程序,使用 Gradle 构建。

它的一些低级功能由单独的 C++ 应用程序提供。

这两个应用程序使用协议缓冲区和 gRPC 通过套接字或管道进行通信。

最初,我希望在一个项目中构建所有三个(ProtoBuf 生成代码、Java 应用程序、C++ 应用程序),但是 cpp-applicationjava 在某些任务(编译/实现/测试?)上发生冲突。

我已经把它分成三个项目:

/
 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 应用程序项目解析并在其构建中使用这些输出?

【问题讨论】:

    标签: c++ gradle kotlin protocol-buffers


    【解决方案1】:

    我在写问题时解决了这个问题。

    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-app/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-app/settings.gradle

    rootProject.name = 'java-app'
    

    /cpp-app/build.gradle

    plugins {
            id 'maven'
            id 'cpp'
    }
    
    description = """"""
    
    project.tasks.build.dependsOn 'protocol'  // <-- name of protobuf project
    
    model {
            components {
                    main(NativeExecutableSpec) {
                            ...
                    }
            }
            ...
    }
    

    /cpp-app/settings.gradle

    rootProject.name = 'cpp-app'
    

    /protocol/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
    }
    

    /protocol/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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-11-23
      • 1970-01-01
      • 1970-01-01
      • 2021-04-07
      • 1970-01-01
      • 2018-07-05
      • 2022-01-08
      • 1970-01-01
      相关资源
      最近更新 更多