|
1 |
| -import org.gradle.api.Project |
2 |
| -import org.gradle.api.tasks.bundling.Jar |
3 |
| -import org.gradle.api.tasks.compile.AbstractCompile |
4 |
| -import org.gradle.api.tasks.compile.JavaCompile |
5 |
| -import org.gradle.kotlin.dsl.register |
6 |
| -import java.util.spi.ToolProvider |
| 1 | +import org.gradle.api.* |
| 2 | +import org.gradle.api.file.* |
| 3 | +import org.gradle.api.tasks.bundling.* |
| 4 | +import org.gradle.api.tasks.compile.* |
| 5 | +import org.gradle.kotlin.dsl.* |
| 6 | +import org.gradle.util.GUtil.* |
| 7 | +import org.jetbrains.kotlin.gradle.dsl.* |
| 8 | +import org.jetbrains.kotlin.gradle.plugin.* |
| 9 | +import org.jetbrains.kotlin.gradle.plugin.mpp.* |
| 10 | +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.* |
| 11 | +import org.jetbrains.kotlin.gradle.targets.jvm.* |
| 12 | +import java.io.* |
7 | 13 |
|
8 | 14 | object Java9Modularity {
|
| 15 | + |
9 | 16 | @JvmStatic
|
10 |
| - fun configureJava9ModuleInfo(project: Project) { |
11 |
| - project.afterEvaluate { |
12 |
| - val jdeps = ToolProvider.findFirst("jdeps").orElseThrow { IllegalStateException("Tool 'jdeps' is not available") } |
13 |
| - val compileKotlinJvm = tasks.findByName("compileKotlinJvm") as AbstractCompile? |
14 |
| - val jvmJar = tasks.findByName("jvmJar") as Jar? |
15 |
| - |
16 |
| - if (compileKotlinJvm != null && jvmJar != null) { |
17 |
| - val modularityDir = buildDir.resolve("modularity") |
18 |
| - val generatedDir = modularityDir.resolve("generated") |
19 |
| - val classesDir = modularityDir.resolve("classes") |
20 |
| - val jvmGenerateModuleInfo = tasks.register("jvmGenerateModuleInfo", Jar::class) { |
21 |
| - dependsOn(compileKotlinJvm) |
22 |
| - destinationDirectory.set(modularityDir) |
23 |
| - from(jvmJar.source) |
24 |
| - exclude { it.file.startsWith(classesDir) } |
25 |
| - doLast { |
26 |
| - generatedDir.deleteRecursively() |
27 |
| - jdeps.run( |
28 |
| - System.out, System.err, |
29 |
| - "--multi-release", "9", |
30 |
| - "--generate-module-info", generatedDir.toString(), |
31 |
| - "--module-path", compileKotlinJvm.classpath.asPath, |
32 |
| - archiveFile.get().toString() |
33 |
| - ) |
34 |
| - } |
35 |
| - } |
36 |
| - val jvmCompileModuleInfo = tasks.register("jvmCompileModuleInfo", JavaCompile::class) { |
37 |
| - dependsOn(jvmGenerateModuleInfo) |
38 |
| - destinationDirectory.set(classesDir) |
39 |
| - source(generatedDir) |
40 |
| - classpath = files() |
41 |
| - doFirst { |
42 |
| - val moduleName = generatedDir.listFiles().first().name |
43 |
| - options.compilerArgs = listOf( |
44 |
| - "--release", "9", |
45 |
| - "--module-path", compileKotlinJvm.classpath.asPath, |
46 |
| - "--patch-module", "$moduleName=${compileKotlinJvm.destinationDir}", |
47 |
| - "-Xlint:-requires-transitive-automatic" |
48 |
| - ) |
49 |
| - } |
50 |
| - } |
51 |
| - jvmJar.apply { |
52 |
| - dependsOn(jvmCompileModuleInfo) |
53 |
| - from(classesDir) { |
54 |
| - into("META-INF/versions/9") |
55 |
| - } |
| 17 | + @JvmOverloads |
| 18 | + fun configureJava9ModuleInfo(project: Project, multiRelease: Boolean = true) { |
| 19 | + val kotlin = project.extensions.findByType<KotlinProjectExtension>() ?: return |
| 20 | + project.configureModuleInfoForKotlinProject(kotlin, multiRelease) |
| 21 | + } |
| 22 | + |
| 23 | + private fun Project.configureModuleInfoForKotlinProject(kotlin: KotlinProjectExtension, multiRelease: Boolean = true) { |
| 24 | + val jvmTargets = kotlin.targets.filter { it is KotlinJvmTarget || it is KotlinWithJavaTarget<*> } |
| 25 | + if (jvmTargets.isEmpty()) { |
| 26 | + logger.warn("No Kotlin JVM targets found, can't configure compilation of module-info!") |
| 27 | + } |
| 28 | + jvmTargets.forEach { target -> |
| 29 | + target.compilations.forEach { compilation -> |
| 30 | + configureModuleInfoForKotlinCompilation(compilation) |
| 31 | + } |
| 32 | + |
| 33 | + if (multiRelease) { |
| 34 | + tasks.getByName<Jar>(target.artifactsTaskName) { |
| 35 | + rename("module-info.class", "META-INF/versions/9/module-info.class") |
56 | 36 | manifest {
|
57 |
| - attributes(jvmJar.manifest.attributes + mapOf("Multi-Release" to true)) |
| 37 | + attributes("Multi-Release" to true) |
58 | 38 | }
|
59 | 39 | }
|
60 | 40 | }
|
61 | 41 | }
|
62 | 42 | }
|
| 43 | + |
| 44 | + private fun Project.configureModuleInfoForKotlinCompilation(compilation: KotlinCompilation<*>) { |
| 45 | + val defaultSourceSet = compilation.defaultSourceSet.kotlin |
| 46 | + val moduleInfoSourceFile = defaultSourceSet.find { it.name == "module-info.java" } |
| 47 | + |
| 48 | + if (moduleInfoSourceFile == null) { |
| 49 | + logger.info("No module-info.java file found in ${defaultSourceSet.srcDirs}, can't configure compilation of module-info!") |
| 50 | + } else { |
| 51 | + val targetName = toCamelCase(compilation.target.targetName) |
| 52 | + val compilationName = if (compilation.name != KotlinCompilation.MAIN_COMPILATION_NAME) toCamelCase(compilation.name) else "" |
| 53 | + val compileModuleInfoTaskName = "compile${compilationName}ModuleInfo$targetName" |
| 54 | + |
| 55 | + val compileKotlinTask = compilation.compileKotlinTask as AbstractCompile |
| 56 | + val modulePath = compileKotlinTask.classpath |
| 57 | + val moduleInfoClassFile = compileKotlinTask.destinationDirectory.file("module-info.class").get().asFile |
| 58 | + |
| 59 | + val compileModuleInfoTask = registerCompileModuleInfoTask(compileModuleInfoTaskName, modulePath, compileKotlinTask.destinationDirectory, moduleInfoSourceFile) |
| 60 | + tasks.getByName(compilation.compileAllTaskName).dependsOn(compileModuleInfoTask) |
| 61 | + } |
| 62 | + } |
| 63 | + |
| 64 | + private fun Project.registerCompileModuleInfoTask(taskName: String, modulePath: FileCollection, destinationDir: DirectoryProperty, moduleInfoSourceFile: File) = |
| 65 | + tasks.register(taskName, JavaCompile::class) { |
| 66 | + dependsOn(modulePath) |
| 67 | + source(moduleInfoSourceFile) |
| 68 | + classpath = files() |
| 69 | + destinationDirectory.set(destinationDir) |
| 70 | + sourceCompatibility = JavaVersion.VERSION_1_9.toString() |
| 71 | + targetCompatibility = JavaVersion.VERSION_1_9.toString() |
| 72 | + doFirst { |
| 73 | + options.compilerArgs = listOf( |
| 74 | + "--release", "9", |
| 75 | + "--module-path", modulePath.asPath, |
| 76 | + "-Xlint:-requires-transitive-automatic" |
| 77 | + ) |
| 78 | + } |
| 79 | + } |
63 | 80 | }
|
0 commit comments