How can I add generated kotlin sources to source path in gradle? - gradle

For generated java sources I use:
sourceSets["main"].java {
srcDir("$buildDir/generated/java")
}
tasks.withType(JavaCompile::class) {
dependsOn("myGenerator")
}
But now I have generated kotlin sources and function sourceSets["main"].kotlin is not defined.

Solution:
sourceSets["main"].withConvention(conventionType = KotlinSourceSet::class) {
kotlin.srcDir("$buildDir/generated/kotlin")
}
More: https://kotlinlang.org/docs/reference/using-gradle.html

Related

Gradle 7.2 Version Catalog specify library build type

I'm refactoring a multi module project with version catalogs and I have to add a dependency that is currently like this:
implementation com.mygroup:my-artifact:1.0.0:debug#aar
Since version catalogs doesn't allow to specify the aar type, a workaround would be to specify it directly in the gradle file like this:
implementation(libs.myDependency) { artifact { type = 'aar' } }
This works, but there's an extra complexity: I need to also specify the build type, in the example from above is debug, I cannot find a way to add it.
What I've tried is:
TOML
[libraries]
myDependency = { module = "com.mygroup:my-artifact", version = "1.0.0:debug" }
Gradle
implementation(libs.myDependency) { artifact { type = 'aar' } }
For some reason this doesn't work, how can I also specify the build type?
Found a way to do this! Need to add the classifier into the artifact.
So for the given regular declaration:
build.gradle
dependencies {
implementation com.mygroup:my-artifact:1.0.0:debug#aar
}
The version catalogs way would be:
TOML
[libraries]
myDependency = { module = "com.mygroup:my-artifact", version = "1.0.0" }
build.gradle
dependencies {
implementation(libs.myDependency) { artifact { classifier = 'debug'; type = 'aar' } }
}
or (multiline)
build.gradle
dependencies {
implementation(libs.myDependency) {
artifact {
classifier = 'debug'
type = 'aar'
}
}
}

Using Gradle to build a jar with dependencies with Kotlin-DSL

There is already an answer to the question: how to include all the dependencies in a jar file though it's for Groovy
I'm using gradle with kotlin-dsl and the code is not compatible. I tried to make it work using a few ways including:
tasks.withType<Jar> {
configurations["compileClasspath"].forEach { file: File ->
copy {
from(zipTree(file.absoluteFile))
}
}
}
Though this doesn't work. So how to include the dependencies using kotlin-dsl in gradle?
This will work:
tasks.withType<Jar>() {
configurations["compileClasspath"].forEach { file: File ->
from(zipTree(file.absoluteFile))
}
}
There's no need in copy { ... }, you should call from on the JAR task itself.
Note: Gradle does not allow changing the dependencies after they have been resolved. It means that the block above should be executed only after the dependencies { ... } are configured.
my case
withType<Jar> {
enabled = true
isZip64 = true
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
archiveFileName.set("$project.jar")
from(sourceSets.main.get().output)
dependsOn(configurations.compileClasspath)
from({
configurations.compileClasspath.get().filter {
it.name.endsWith("jar")
}.map { zipTree(it) }
}) {
exclude("META-INF/*.RSA", "META-INF/*.SF", "META-INF/*.DSA")
}
}

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

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')

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