This message was deleted.
# community-support
s
This message was deleted.
n
Given the java plugin’s lifecycle, you don’t want to have assemble depend on the code generation, as that’s way too late in the lifecycle. Compilation happens many steps before, which is what gradle is flagging here.
g
so, what would you suggest? Give up the dependency and call it manually?
n
I think you get implicit dependencies if you add the generated folder to the main sourceset though. That would allow gradle to figure out the dependencies by itself.
g
this should do it?
Copy code
sourceSets {
    main {
        java.srcDir("$buildDir/generated")
    }
}
I just tried: deleted the generated code, run
assemble
and got error because the code supposed to be generated wasn't there..
n
it might be
sourceSets.main.kotlin
. Not sure how java and kotlin relate to eachother.
if implicit doesn’t work, you can always be explicit about it:
compileKotlin.dependsOn(generateCode)
, as that’s the task that actually requires the generated code
g
compileKotlin.dependsOn(generateCode)
did do it indeed, thanks now I get the same for
sourcesJar
and I'll do the same
n
does your generateCode task mark the generated folder as its output? perhaps gradle doesn’t see the link 🤔 because chasing down all these dependencies is why you’d like for gradle to do it implicitly
g
it's weird though, Gradle complains about
sourcesJar
> Task :generateCode
> Task :compileKotlin UP-TO-DATE
> Task :compileJava NO-SOURCE
> Task :pluginDescriptors UP-TO-DATE
> Task :processResources UP-TO-DATE
> Task :classes UP-TO-DATE
> Task :inspectClassesForKotlinIC UP-TO-DATE
> Task :jar UP-TO-DATE
> Task :javadoc NO-SOURCE
> Task :javadocJar UP-TO-DATE
> Task :sourcesJar
Execution optimizations have been disabled for task ':sourcesJar' to ensure correctness due to the following reasons:
- Gradle detected a problem with the following location: '/home/elect/IdeaProjects/gradle-catalog/build/generated'. Reason: Task ':sourcesJar' uses this output of task ':compileJava' without declaring an explicit or implicit dependency. This can lead to incorrect results being produced, depending on what order the tasks are executed. Please refer to https://docs.gradle.org/7.4.2/userguide/validation_problems.html#implicit_dependency for more details about this problem.
But if I try to
Copy code
getByName("sourcesJar") { dependsOn(generateCode) }
then
Task with name 'sourcesJar' not found in root project 'gradle-catalog'.
a
Possibly you can declare an (implicit) dependency between the task and the source set using Gradle’s
builtBy
function. See an example in this section: https://docs.gradle.org/current/userguide/more_about_tasks.html#sec:link_output_dir_to_input_files
n
note also that you don’t need the
getByName
if you use kotlin dsl, this task has an accessor:
tasks.sourcesJar
a
It depends whether the goal is to include the sources only into the
sourcesJar
artifact, or to actually compile them and include in the binary artifact. In the latter case, I think,
sourcesJar
is the wrong path, and the generated sources must be included in the
main
source set (after which they will automatically be included in the
sourcesJar
).
g
note also that you don’t need the
getByName
if you use kotlin dsl, this task has an accessor:
tasks.sourcesJar
I can't see it
@Alex Semin the generated source code should be treated the same as traditional source code, that is, compiled and included in the binary artifact. I think I'm already including the in the
main
source set
Copy code
val SourceSet.kotlin: SourceDirectorySet
    get() = project.extensions.getByType<KotlinJvmProjectExtension>().sourceSets.getByName(name).kotlin

sourceSets {
    main {
        kotlin.srcDir("$buildDir/generated")
    }
}
a
If you do it this way, I suppose, Gradle does not see the direct dependency between the
main
source set and the output of the task, because they are connected only via the directory name.
g
then what do you mean by
generated sources must be included in the
main
source set (after which they will automatically be included in the
sourcesJar
how shall I do it?
a
By that I mean that you still want to include the generated sources in the source set, but you need to do it in a way that introduces a dependency between the source set and the
generateSources
task.
g
and that's where
builtBy
comes into play?
a
Yes, this is my current theory
g
ok, so,
builtBy
looks to be available only on `Property`s, how can I use that in my case? I'd need somehow to have the input files for
kotlinCompile
call
builtBy(generateCode
n
Copy code
sourceSets.main.kotlin.srcDir("$buildDir/generated", "builtBy" to "generateSources")
I believe this should work
a
I don’t think there is an overload in Kotlin the accepts the map. Is there?
g
no it's not
a
I think I found a solution.
builtBy
was in the right direction, but not available in the scope we want.
n
oh, sorry, you can only specify that on the output of the sourceset, so
Copy code
sourceSets.main.output.dir("$buildDir/generated", "builtBy" to "generateSources")
a
First of all, I think you should remove the custom
kotlin
extension that you declare, to not get confused:
val SourceSet.kotlin: SourceDirectorySet
After that all you need to do is this:
Copy code
kotlin {
    sourceSets["main"].kotlin.srcDir(generateSources.get().outputs.files)
}
The important difference with all the approaches above is that we have a live instance of
generateSources
task, and we take the reference to it’s output file collection. This collection tracks dependencies. Because of this the main source set now depends on the
generateSources
task, and you don’t need to duplicate the
"$buildDir/generated"
path at all (which is not advised anyways).
Then, running a
jar
task would execute the
generatedSources
task automatically:
Copy code
$ ./gradlew --console plain :lib:jar 
> Task :lib:generateSources
> Task :lib:compileKotlin FROM-CACHE
> Task :lib:compileJava NO-SOURCE
> Task :lib:processResources NO-SOURCE
> Task :lib:classes UP-TO-DATE
> Task :lib:inspectClassesForKotlinIC
> Task :lib:jar
(ignore the
:lib
prefixes, it’s just my local setup)
g
ok, I just tried, only
Copy code
tasks {
    ..
    kotlin.sourceSets["main"].kotlin.srcDir(generateCode.get().outputs.files)
}
running
assemble
, I see
generateCode
is called properly before
compileKotlin
(and the generated directory is also properly marked by Idea as src folder) but I do still get the warning on
sourcesJar
> Task :generateCode
> Task :compileKotlin UP-TO-DATE
> Task :compileJava NO-SOURCE
> Task :pluginDescriptors UP-TO-DATE
> Task :processResources UP-TO-DATE
> Task :classes UP-TO-DATE
> Task :inspectClassesForKotlinIC UP-TO-DATE
> Task :jar UP-TO-DATE
> Task :javadoc NO-SOURCE
> Task :javadocJar UP-TO-DATE
> Task :sourcesJar
Execution optimizations have been disabled for task ':sourcesJar' to ensure correctness due to the following reasons:
- Gradle detected a problem with the following location: '/home/elect/IdeaProjects/gradle-catalog/build/generated'. Reason: Task ':sourcesJar' uses this output of task ':compileJava' without declaring an explicit or implicit dependency. This can lead to incorrect results being produced, depending on what order the tasks are executed. Please refer to https://docs.gradle.org/7.4.2/userguide/validation_problems.html#implicit_dependency for more details about this problem.
Ps: I also pushed in case you want to try this yourselves
a
I don’t immediately see where you configure the sources jar at all. But consider adding
Copy code
java {
    withSourcesJar()
}
To the build script. Seems to be working for me:
Copy code
$ gw --console plain :lib:assemble 
> Task :lib:generateSources
> Task :lib:compileKotlin UP-TO-DATE
> Task :lib:compileJava NO-SOURCE
> Task :lib:processResources NO-SOURCE
> Task :lib:classes UP-TO-DATE
> Task :lib:inspectClassesForKotlinIC UP-TO-DATE
> Task :lib:jar UP-TO-DATE
> Task :lib:sourcesJar
> Task :lib:assemble

BUILD SUCCESSFUL in 1s
(Btw, I see you use an RC version of Gradle’s plugin-publish. A stable release
1.0.0
has landed recently) https://plugins.gradle.org/plugin/com.gradle.plugin-publish
g
thanks for the heads up, I just updated to it however this
Copy code
java {
    withSourcesJar()
}
didn't solve yet the warning about
sourcesJar
I'm still puzzled why I get the warning about it but if the moment I try to configure it (
getByName("sourcesJar") { .. }
) then I have the following error:
Task with name 'sourcesJar' not found in root project 'gradle-catalog'.
so Alex, to sum up, you don't get the warning I cant understand how is that possible
to sum up, I fixed with (it's a mp project)
Copy code
val generateCode by registering(GenerateCode::class)
kotlin.sourceSets.commonMain { kotlin.srcDir(generateCode.get().outputs.files) }
👍 1