I want to create a custom compilation. How do I se...
# gradle
h
I want to create a custom compilation. How do I setup srcDir of this compilation that accepts a Task which produces a folder?
👀 1
Copy code
val s = tasks.named("myCustomTask")

kotlin.target.compilations.register("foo") {
    kotlinSourceSets.forAll { 
        it.kotlin.srcDir(s)
    }
}
If I run:
compileFooKotlin
, the task
myCustomTask
won't be executed.
h
Yeah, I read the docs but even using this code:
Copy code
kotlin.target.compilations.register("foo") {
    defaultSourceSet {
        kotlin.srcDir(s)
    }
}
Does not execute the task, but creating a Java feature does (
compileBarKotlin
):
Copy code
val bar by sourceSets.registering {
    kotlin.srcDir(s)
}

java.registerFeature("bar") {
    usingSourceSet(bar.get())
}
a
Shouldn't you add the output dir of the task instead of the task itself to
srcDir
? I used this code to add generated source to
commonMain
, and it worked.
Copy code
val kotlinSourceDir = project.files(task.map { it.generatedSrcMainDirectory }).builtBy(task)
extensions.getByType(KotlinMultiplatformExtension::class).sourceSets["commonMain"].kotlin.srcDir(kotlinSourceDir)
(
task.generatedSrcMainDirectory
is an
@Output
of
task
.)
j
Adding the directory instead of the task will not help Gradle to determine the correct tasks execution order
a
It does.
mind blown 1
h
Yeah, I will try the project.files workaround, always forget it. It adds the task dependency using builtBy
m
Feels super weird that passing the task provider does not carry the task dependency. But that wouldn't be the first inconsistency....
m
This reminds me of a issue I had with AGP where the task dependency was also lost (although compiling worked fine): https://issuetracker.google.com/u/1/issues/376709932
But I think it's a different code path: AGP variants vs Kotlin compilations (but same symptom)
j
Calling
Copy code
./gradlew jvmFooClasses --dry-run
Shows
Copy code
:kotlin-stdlib:checkKotlinGradlePluginConfigurationErrors SKIPPED
:kotlin-stdlib:compileKotlinJvm SKIPPED
:kotlin-stdlib:jvmProcessResources SKIPPED
:kotlin-stdlib:jvmMainClasses SKIPPED
:kotlin-stdlib:random SKIPPED
:kotlin-stdlib:compileFooKotlinJvm SKIPPED
:kotlin-stdlib:jvmFooProcessResources SKIPPED
:kotlin-stdlib:jvmFooClasses SKIPPED
random
is executed, so using
implementation
+ getting the output files from the task does the trick.
implementation
+ adding directly the task does not work (you need to call
map
and get the files manually). IMO, it should be possible, so probably it could be a feature request for Gradle.
m
getting the output files from the task does the trick
I'm guessing the output files are source files, not class files?
j
Technically I am getting the random task output files, so it could be whatever thing, no?
m
Yea but
implementation
is adding files to the compile classpath of the compiler, not to the source files
👍 1
If you put
*.kt
in
implementation
, not sure if the Kotlin compiler is going to like it
j
haven't tried tbh, if @hfhbd has time and tries this, share the output as I am interested too 🙂
h
Well, I tested this code and it doesn’t work, the task is not executed and even if so, I don’t think implementation will support source files. Anyway, the sourceSet workaround does work, so I won’t try it further.
Copy code
val outputFolder = layout.buildDirectory.dir("a")
Copy code
val t = tasks.register("a") {
    outputs.dir(outputFolder)
    doLast { 
        outputFolder.get().file("foo.kt").asFile.writeText(
            "invalid code to fail compilation"
        )
    }
}
Copy code
kotlin.target.compilations.register("foo") {
    defaultSourceSet {
        dependencies {
            implementation(t.map { it.outputs.files })
        }
    }
}
j
That is weird as it is shown in the list. If you use dry run it is appearing?
h
I used
--info
And it didn’t show up in the list