-
Notifications
You must be signed in to change notification settings - Fork 101
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add explicit module-info for JPMS compatibility #135
Merged
Merged
Changes from 8 commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
d0e305d
Add explicit module-info for JPMS compatability
lion7 acde5da
Generate module-info using jdeps and include it in the JAR
lion7 c9d7ede
Rework based on comments from https://github.com/Kotlin/kotlinx.seria…
lion7 5d99e9b
Rework based on comments from https://github.com/Kotlin/kotlinx.seria…
lion7 81e2e44
Use released kotlin gradle plugin
lion7 7ae0691
Merge branch 'master' into master
lion7 c4f55f9
Synchronize with buildSrc in kotlinx.serialization
lion7 77fd1a3
Use kotlin version of root project
lion7 7998462
Fix Gradle project import in IDEA 2021.2
ilya-g 584d5f6
Migrate useExperimentalAnnotation->optIn
ilya-g 45585a1
Update Gradle to 6.9
ilya-g 7f5351b
Generate module-info using jdeps and include it in the JAR
lion7 4bf87e1
Rework based on comments from https://github.com/Kotlin/kotlinx.seria…
lion7 e5d8dba
Simplify and rework after review comments
lion7 3f55a47
Merge branch 'Kotlin:master' into master
lion7 74276aa
Merge branch 'Kotlin:master' into master
lion7 28737ee
Process feedback
lion7 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import java.util.Properties | ||
|
||
plugins { | ||
`kotlin-dsl` | ||
} | ||
|
||
repositories { | ||
mavenCentral() | ||
} | ||
|
||
val kotlinVersion = file("../gradle.properties").inputStream().use { | ||
Properties().apply { load(it) } | ||
}.getProperty("kotlinVersion") ?: throw IllegalStateException("Property 'kotlinVersion' must be defined in ../gradle.properties") | ||
|
||
dependencies { | ||
implementation(kotlin("gradle-plugin", kotlinVersion)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
import org.gradle.api.* | ||
import org.gradle.api.tasks.bundling.* | ||
import org.gradle.api.tasks.compile.* | ||
import org.gradle.kotlin.dsl.* | ||
import org.jetbrains.kotlin.gradle.dsl.* | ||
import org.jetbrains.kotlin.gradle.plugin.mpp.* | ||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.* | ||
import org.jetbrains.kotlin.gradle.targets.jvm.* | ||
import java.io.* | ||
|
||
object Java9Modularity { | ||
|
||
@JvmStatic | ||
@JvmOverloads | ||
fun configureJava9ModuleInfo(project: Project, multiRelease: Boolean = true) { | ||
val kotlin = project.extensions.findByType<KotlinProjectExtension>() ?: return | ||
project.configureModuleInfoForKotlinProject(kotlin, multiRelease) | ||
} | ||
|
||
private fun Project.configureModuleInfoForKotlinProject(kotlin: KotlinProjectExtension, multiRelease: Boolean = true) { | ||
val jvmTargets = kotlin.targets.filter { it is KotlinJvmTarget || it is KotlinWithJavaTarget<*> } | ||
if (jvmTargets.isEmpty()) { | ||
logger.warn("No Kotlin JVM targets found, can't configure compilation of module-info!") | ||
} | ||
jvmTargets.forEach { target -> | ||
val artifactTask = tasks.getByName<Jar>(target.artifactsTaskName) { | ||
if (multiRelease) { | ||
manifest { | ||
attributes("Multi-Release" to true) | ||
} | ||
} | ||
} | ||
|
||
target.compilations.forEach { compilation -> | ||
val compileKotlinTask = compilation.compileKotlinTask as AbstractCompile | ||
val defaultSourceSet = compilation.defaultSourceSet | ||
|
||
// derive the names of the source set and compile module task | ||
val sourceSetName = defaultSourceSet.name + "Module" | ||
val compileModuleTaskName = compileKotlinTask.name + "Module" | ||
|
||
kotlin.sourceSets.create(sourceSetName) { | ||
val sourceFile = this.kotlin.find { it.name == "module-info.java" } | ||
val targetFile = compileKotlinTask.destinationDirectory.file("../module-info.class").get().asFile | ||
|
||
// only configure the compilation if necessary | ||
if (sourceFile != null) { | ||
// the default source set depends on this new source set | ||
defaultSourceSet.dependsOn(this) | ||
|
||
// register a new compile module task | ||
val compileModuleTask = registerCompileModuleTask(compileModuleTaskName, compileKotlinTask, sourceFile, targetFile) | ||
|
||
// add the resulting module descriptor to this target's artifact | ||
artifactTask.dependsOn(compileModuleTask) | ||
artifactTask.from(targetFile) { | ||
if (multiRelease) { | ||
into("META-INF/versions/9/") | ||
} | ||
} | ||
} else { | ||
logger.info("No module-info.java file found in ${this.kotlin.srcDirs}, can't configure compilation of module-info!") | ||
// remove the source set to prevent Gradle warnings | ||
kotlin.sourceSets.remove(this) | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
private fun Project.registerCompileModuleTask(taskName: String, compileTask: AbstractCompile, sourceFile: File, targetFile: File) = | ||
tasks.register(taskName, JavaCompile::class) { | ||
// Also add the module-info.java source file to the Kotlin compile task; | ||
// the Kotlin compiler will parse and check module dependencies, | ||
// but it currently won't compile to a module-info.class file. | ||
compileTask.source(sourceFile) | ||
|
||
|
||
// Configure the module compile task. | ||
dependsOn(compileTask) | ||
source(sourceFile) | ||
outputs.file(targetFile) | ||
classpath = files() | ||
destinationDirectory.set(compileTask.destinationDirectory) | ||
sourceCompatibility = JavaVersion.VERSION_1_9.toString() | ||
targetCompatibility = JavaVersion.VERSION_1_9.toString() | ||
|
||
doFirst { | ||
// Provide the module path to the compiler instead of using a classpath. | ||
// The module path should be the same as the classpath of the compiler. | ||
options.compilerArgs = listOf( | ||
"--release", "9", | ||
"--module-path", compileTask.classpath.asPath, | ||
"-Xlint:-requires-transitive-automatic" | ||
) | ||
} | ||
|
||
doLast { | ||
// Move the compiled file out of the Kotlin compile task's destination dir, | ||
// so it won't disturb Gradle's caching mechanisms. | ||
val compiledFile = destinationDirectory.file(targetFile.name).get().asFile | ||
targetFile.parentFile.mkdirs() | ||
compiledFile.renameTo(targetFile) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
module kotlinx.datetime { | ||
requires transitive kotlin.stdlib; | ||
requires transitive static kotlinx.serialization.core; | ||
|
||
exports kotlinx.datetime; | ||
exports kotlinx.datetime.serializers; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This approach significantly limits the ways how
kotlinVersion
can be defined. Due to that we'd like to avoid having the code that depends on kotlin plugin in buildSrc, especially considering that it is only needed in one subproject so far.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I totally agree, this was actually the most annoying part. I just wished that the
buildSrc
project had access to the properties of the root project, but that is unfortunately not the case.Anyway, I'll move the relevant code to an (simplified) inline block inside the
core
subproject, since that is the only place that uses this.