Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

simple protobuf compilation with gradle

Tags:

If you're looking for sample gradle protobuf project look here.

I'm having hard time with gradle and protobuf, i want to create a simple gradle project that will take any proto files from default src/main/proto, src/test/proto and compile them to src/main/java, src/test/java accordingly, then pack that into a jar and publish to local repo.

Unfortunately i'm new to gradle and cant figure out how the original project is composed.

Here is my unfinished build.gradle file

apply plugin: 'java' apply plugin: "com.google.protobuf"  buildscript {     repositories {         mavenCentral()     }     dependencies {         classpath 'com.google.protobuf:protobuf-gradle-plugin:0.7.0'     } }  repositories {     mavenCentral() }  dependencies {     compile 'com.google.protobuf:protobuf-java:3.0.0-beta-1' }  sourceSets {     main {         proto {             srcDir 'src/main/proto'         }         java {             srcDir 'src/main/java'         }     }     test {         proto {             srcDir 'src/test/proto'         }         proto {             srcDir 'src/test/java'         }     } }  protobuf {     // Configure the protoc executable     protoc {         // Download from repositories         artifact = 'com.google.protobuf:protoc:3.0.0-alpha-3'     }     generateProtoTasks {         // all() returns the collection of all protoc tasks         all().each { task ->             // Here you can configure the task         }          // In addition to all(), you may get the task collection by various         // criteria:          // (Java only) returns tasks for a sourceSet         ofSourceSet('main')      } } 

After runing jar task we have this :

enter image description here

as you can see gradle builds both test and main protos to the same classes directory (red arrows), in the jar i can see both generated classes included (while tests should be skipped).

but the main problem is that I want to make compile proto files directly to appropriate source directories (blue arrows), after that ordinary build will do the correct thing... After all we need those classes in src to use them in business logic...

So we only need one task that compiles proto to appropriate src directory... nothing more.

src/main/proto to src/main/java src/test/proto to src/test/java 

The current project as it is is located here. Please help to configure this, i'm pretty sure lot of people will need it later...

like image 439
vach Avatar asked Sep 28 '15 10:09

vach


People also ask

How do I create a Java proto file?

The protocol buffer compiler produces Java output when invoked with the --java_out= command-line flag. The parameter to the --java_out= option is the directory where you want the compiler to write your Java output. For each . proto file input, the compiler creates a wrapper .

What is Buildscript in build gradle?

buildscript: This block is used to configure the repositories and dependencies for Gradle. dependencies: This block in buildscript is used to configure dependencies that the Gradle needs to build during the project.


1 Answers

If I don't misunderstand your question it's quite simple to solve. If you don't want to distinguish between your own and the generated sources you just have to add set the generatedFileBaseDir like this generateProtoTasks.generatedFilesBaseDir = 'src'

So the entire build file looks like:

// ...  protobuf { // Configure the protoc executable protoc {     // Download from repositories     artifact = 'com.google.protobuf:protoc:3.0.0-alpha-3' }  generateProtoTasks.generatedFilesBaseDir = 'src' // <- that line   generateProtoTasks {     // all() returns the collection of all protoc tasks     all().each { task ->         // Here you can configure the task     } 

Than your folder looks like:

  • src/main/java/com/vach/tryout/AddressBookProtos.java
  • src/main/java/com/vach/tryout/protobuf/Main.java

BUT: That might not be the best idea to mix generate with handcrafted source code. So my suggestion would be to generate the source code into an own directory like generatedSources and add this directory to the java sourceSet. The build file would look like this:

sourceSets {     main {         proto {             srcDir 'src/main/proto'         }         java {             // include self written and generated code             srcDirs 'src/main/java', 'generated-sources/main/java'                     }     }     // remove the test configuration - at least in your example you don't have a special test proto file }  protobuf {     // Configure the protoc executable     protoc {         // Download from repositories         artifact = 'com.google.protobuf:protoc:3.0.0-alpha-3'     }      generateProtoTasks.generatedFilesBaseDir = 'generated-sources'      generateProtoTasks {         // all() returns the collection of all protoc tasks         all().each { task ->             // Here you can configure the task         }          // In addition to all(), you may get the task collection by various         // criteria:          // (Java only) returns tasks for a sourceSet         ofSourceSet('main')      }    } 

Your directory will look like this

  • src/main/proto/dtos.proto
  • src/main/java/com/vach/tryout/protobuf/Main.java
  • generated-sources/main/java/com/vach/tryout/AddressBookProtos.java

A nice side effect is that you can ignore this generated-sources dir in your git configuration. That's always a good idea not to publish generated source code.

like image 194
TobiSH Avatar answered Nov 14 '22 13:11

TobiSH