How to set proto source directory based on another sub-project's proto source directory? - gradle

The following doesn't work since test-data-proto-definition hasn't been configured yet so sourceSets.main.proto doesn't exist:
sourceSets {
main {
proto {
srcDirs = project(':test-data-proto-definition').sourceSets.main.proto.srcDirs
}
}
}
The following doesn't do what's intended, either:
generateProtoTasks {
all().each { task ->
project.sourceSets.main.proto.srcDirs = ["${project(':test-data-proto-definition').projectDir}/src/main/proto" as String]
}
}
What's needed to be able to reference the proto.srcDirs of another sub-project?

The issue here is that the sub-project test-data-proto-definition hasn't yet been configured. Configuration time dependencies indicates use of evaluationDependsOn should solve the issue. For example:
evaluationDependsOn(':test-data-proto-definition')

Related

How to import code from outside into gradle build file?

My build files are large and messy, making them difficult to read. like below:
plugins {
...
id "com.google.protobuf" version "0.8.17"
}
dependencies {
implementation "androidx.datastore:datastore-core:1.0.0"
implementation "com.google.protobuf:protobuf-javalite:3.18.0"
...
}
protobuf {
protoc {
artifact = "com.google.protobuf:protoc:3.14.0"
}
// Generates the java Protobuf-lite code for the Protobufs in this project. See
// https://github.com/google/protobuf-gradle-plugin#customizing-protobuf-compilation
// for more information.
generateProtoTasks {
all().each { task ->
task.builtins {
java {
option 'lite'
}
}
}
}
}
I want to define the above code into an external file, and then introduce it into the build file, how should I do it?
According to the Gradle documentation, as of now it is not possible to move the plugin block to other file than the project’s build script or settings.gradle file.
For the other sections, let's say dependencies or protobuf, then you can move these sections on a separate gradle files and import them by using the following statement:
apply from: "${project.rootDir}/your-gradle-file"
Of course the path of your-gradle-file should be adjusted according to the project's folder structure you decide.
If you want to split the dependencies into multiple gradle file you can do the following:
on your main gradle file:
dependencies {
apply from: "${project.rootDir}/depsGroup1.gradle"
apply from: "${project.rootDir}/depsGroup2.gradle"
}
and within each depsGroup file:
dependencies {
implementation xyz
}

How to specify classes output directory for Gradle 4?

Gradle project deprecated 'classesDir' so the previously working method:
sourceSets {
main {
output.classesDir = "myDir"
}
}
should be replaced with something else. Documentation talks about 'output.classesDirs' but this is read-only property.
What is the method to specify custom compilation output directory in Gradle 4.x scripts?
If you are working with java you can do this
apply plugin: 'java'
sourceSets {
main {
// Compiled Java classes should use this directory
java.outputDir = file('myDir')
}
}
See more: https://docs.gradle.org/current/javadoc/org/gradle/api/tasks/SourceSetOutput.html
As per Gradle 6.5.1 docs the java.outputDir property is has been replaced by classesDirectory:
Gradle 6.5.1 docs for SourceDirectorySet
However I think that the destinationDirectory property should be used to read or modify the compiler output dir. So the docs should say that it is replaced by the destinationDirectory property rather than the classesDirectory property.
The compiler output directory can be changed using either of the following ways:
sourceSets {
main {
java {
destinationDirectory.set(file("${project.buildDir}/classes/${sourceSets.main.name}/java"))
}
}
}
OR
sourceSets {
main {
java {
destinationDirectory.value(project.getLayout().getBuildDirectory().dir("classes/${sourceSets.main.name}/java"));
}
}
}
In my opinion, the second option is better.
To read the output dir for a particular sourceSet use:
project.sourceSets.main.java.destinationDirectory.get()

How to include headers for C compilation in Gradle?

I am a newbie to Gradle. I am trying to compile a set of source files which contain headers which are distributed across the project directory. My source directory structure does not comply with the Gradle convention. How do I add the header locations needed for compilation in my build.gradle? Attached here is my build.gradle file.
// build.gradle
apply plugin: 'c'
model {
components {
my_project (NativeExecutableSpec){
sources {
c {
source {
srcDir "my_proj_src/a/a1.1"
include "**/*.c"
}
exportedHeaders {
srcDir "my_proj_src/a/a1.1", "fsw/b/b1.2"
}
}
}
}
}
}
This does not work. And additionally, is there a possibility to do partial linking using Gradle?
EDIT: Additionally, I would like to also know how to make Gradle search recursively for headers within the source hierarchy.
exportedHeaders` are for exporting headers from the component itself, not for adding headers. So this would not work.
You would need to create a library and add it as the api linkage so that those headers will be added to headers your component is compiled against:
model {
repositories {
libs(PrebuiltLibraries) {
ffmpegHeaders {
headers.srcDirs "$ffmpegDir/include"
}
}
}
components {
libUsingHeaders(NativeLibrarySpec) {
sources {
c {
lib library: 'ffmpegHeaders', linkage: 'api'
}
}
}
}
}

How to include all src/test/resources/** AND src/main/java/**/*.html in the test sourceset in gradle?

I have the following and thought it was 'adding' to my sourceSet but actually just modified it..
sourceSets {
test {
resources {
srcDirs = ["src/main/java"]
includes = ["**/*.html"]
}
}
}
What I really want is both src/test/resources/** and the above as well. I don't want to exclude any files from src/test/resources though and the above is only including html from any directories I put there.
thanks,
Dean
The following will illustrate the technique using main (so it can be verified):
apply plugin: 'java'
sourceSets {
myExtra {
resources {
srcDirs "src/main/java"
includes = ["**/*.html"]
}
}
main {
resources {
source myExtra.resources
}
}
}
Proof of concept via the command-line:
bash$ ls src/main/java
abc.html
xyz.txt
bash$ ls src/main/resources/
def.html
ijk.txt
bash$ gradle clean jar
bash$ jar tf build/libs/myexample.jar
META-INF/
META-INF/MANIFEST.MF
abc.html
def.html
ijk.txt
In your case, change main to test. This answer was discovered via the Gradle doc for SourceDirectorySet. Interestingly, for 3.0, it contains a TODO:
TODO - configure includes/excludes for individual source dirs
which implies that this work-around (via this method) is probably necessary.
I got your point. I tried this and it worked . Please take a look into it:
sourceSets {
test {
resources {
srcDirs = ["src/main/java"]
includes = ["**/*.html"]
}
}
}
sourceSets.test.resources.srcDir 'src/test/resources'
Add these in build.gradle.
I was thinking whether or not to post this answer. So that if you are not satisfied with the previous answer, try the following hacky way (probably it will work with eclipse command):
apply plugin: 'java'
ConfigurableFileTree.metaClass.getAsSource = {
def fileTrees = delegate.asFileTrees
fileTrees.metaClass.getSrcDirTrees = {
return delegate as Set
}
fileTrees as SourceDirectorySet
}
sourceSets {
main {
resources {
srcDirs = [] // cleanup first
source fileTree('src/main/java').include('**/*.html').asSource
source fileTree('src/main/resources').asSource
}
}
}
Using srcDir may be what you want. Here's an example:
sourceSets {
main {
resources {
srcDir "src/main/resources"
exclude "file-to-be-excluded"
include "file-to-be-included"
srcDir "src/main/java"
include "**/*.html"
srcDir "image-folder-in-root"
include "**/*.png"
include "**/*.jpg"
exclude "**/*.xcf"
}
}
}
Not exactly what you asked for, but it could be helpful for someone who finds this question:
I only wanted to have the test resources next to the sources. So I only need to exclude the sources.
In your case, perhaps you could exclude those which you would mind getting in the JAR and/or classpath.
None of the other answers worked for me, and this did work:
sourceSets {
test {
resources {
srcDirs += "src/test/kotlin"
excludes = ["**/*.kt"]
}
}
}
Gradle 6.3.

How to keep Java code and Junit tests together building with Gradle

I have a project in which the main source and the test cases for that source are kept in the same package/directory. Each test class is the name of the class which it is testing with "Test" appended on the end. So if I have a Foo.java there will be a FooTest.java right next to it.
My question is, how do I build this project with Gradle? I'd still like to keep the class files separate, i.e. a folder for main classes and a folder for test classes.
This should do the trick:
sourceSets {
main {
java {
srcDirs = ["some/path"]
exclude "**/*Test.java"
}
}
test {
java {
srcDirs = ["some/path"]
include "**/*Test.java"
}
}
}
For reference, here is the code I used to try to get around the Eclipse plugin's classpath issue. Using this in combination with Peter's answer above seems to work.
// The following ensures that Eclipse uses only one src directory
eclipse {
classpath {
file {
//closure executed after .classpath content is loaded from existing file
//and after gradle build information is merged
whenMerged { classpath ->
classpath.entries.removeAll { entry -> entry.kind == 'src'}
def srcEntry = new org.gradle.plugins.ide.eclipse.model.SourceFolder('src', null)
srcEntry.dir = file("$projectDir/src")
classpath.entries.add( srcEntry )
}
}
}
}
this work for me:
eclipse {
classpath {
file {
withXml {
process(it.asNode())
}
}
}
}
def process(node) {
if (node.attribute('path') == 'src/test/java' || node.attribute('path') == 'src/test/resources')
node.attributes().put('output', "build/test-classes")
else
node.children().each {
process(it)
}}

Resources