Reputation: 11567
I have a build.gradle.kts
for a small, pure kotlin project (I am aware I am using slightly non-standard source paths):
plugins {
kotlin("jvm") version "1.3.72"
}
repositories { mavenCentral() }
dependencies {
implementation(kotlin("stdlib-jdk8"))
testImplementation("org.jetbrains.kotlin:kotlin-test")
testImplementation("org.jetbrains.kotlin:kotlin-test-junit")
}
sourceSets["main"].java.srcDir("src")
sourceSets["test"].java.srcDirs("test")
sourceSets {
create("demo")?.let {
it.java.srcDir("demo")
// Also tried: it.java.srcDirs("src", "demo")
it.compileClasspath += main.get().output
it.runtimeClasspath += main.get().output
}
}
tasks {
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
kotlinOptions.jvmTarget = "1.8"
}
}
listOf("InteractiveClient", "LockingBufferDemo").forEach {
tasks.register<Jar>(it) {
manifest { attributes["Main-Class"] = "${it}Kt" }
from(sourceSets.main.get().output)
from(sourceSets["demo"].output) {
include("**/${it}Kt.class")
}
dependsOn(configurations.runtimeClasspath)
from({
configurations.runtimeClasspath.get().filter {
it.name.endsWith("jar") }.map { zipTree(it) }
})
}
}
When I try to run one of the "demo" sourceSet based jar tasks ("InteractiveClient" and "LockingBufferDemo"),1 I get a the long list of "Cannot access built-in..." errors indicating the kotlin stdlib is not properly in play.
The actual failing task is compileDemoKotlin
, so I tried adding mimetically to the tasks
block:
withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
this.kotlinOptions.jvmTarget = "1.8"
}
Which makes no difference.
What's strange to me is that the demo stuff was originally in the test
sourceSet, and changing the above back to that (by removing the definition, changing from(sourceSets["demo"]...
to from(sourceSets.test...
in the jar task(s), and moving the source file) makes the problem disappear. It works.
I don't want this stuff in with automated tests. I imagine I could put them in branches of the main
or test
set and then use a from() { exclude(...
pattern in building the jars,
but that seems awkward and unnecessary.
How do I get a custom source set to compile against the default project dependencies?
from(... include(
in the jar tasks.Upvotes: 3
Views: 2867
Reputation: 7598
It looks to me like you are missing the configurations that will make the demo source sets use the same dependencies as the main set. Something like this:
configurations["demoImplementation"].extendsFrom(configurations.implementation.get())
configurations["demoRuntimeOnly"].extendsFrom(configurations.runtimeOnly.get())
There is an example in the user guide here that seems to have a very similar use case as yours.
Also, from the issue you created in the Gradle repository, you mentioned it failed with:
Unresolved reference: printlin
I am pretty sure this is a typo of println
.
Upvotes: 3
Reputation: 7121
I'm not entirely sure what you're trying to do with your jar files, but I spotted a few problems in your build script:
You have set your source sets like this:
sourceSets["main"].java.srcDir("src")
sourceSets["test"].java.srcDirs("src", "test")
sourceSets {
create("demo")?.let {
it.java.srcDir("demo")
}
}
This means you're supposed the following directory structure:
- <module root>
- src <-- Belongs to both 'main' and a 'test' source sets!
- test <-- Belongs to the 'test' source set
- demo <-- Belongs to the 'demo' source set
As you can see, there's a directory that belongs to two source sets. I'm not sure how this turns out in practice, probably one or the other is discarded. Here's a more standard directory structure:
- <module root>
- src
- main
- test
- demo
You configure it like this:
sourceSets {
main {
java.srcDir("src/main")
}
test {
java.srcDir("src/test")
}
create("demo") {
java.srcDir("src/demo")
}
}
The task compileDemoKotlin
actually exists, but you can't access it just like that. If you look at the compileKotlin
and compileTestKotlin
extension functions source, they look like this:
val TaskContainer.`compileKotlin`: TaskProvider<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>
get() = named<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>("compileKotlin")
So the trick is to use named
to get the task instead:
named<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>("compileDemoKotlin") {
kotlinOptions.jvmTarget = "1.8"
}
I don't know if that answers your question. If I missed anything please let me know.
Upvotes: 1