Я решил это, когда писал вопрос.
Файлы конфигурации 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