From 87fdf8e764491db7a4461bde8fa3248975bc2113 Mon Sep 17 00:00:00 2001 From: Ilya Goncharov Date: Mon, 19 Feb 2024 09:06:44 +0000 Subject: [PATCH] [Gradle, Wasm] Binaryen by default for production main binary ^KT-64553 fixed --- .../kotlin/gradle/NewMultiplatformIT.kt | 1 - .../targets/js/binaryen/BinaryenExec.kt | 20 +++- .../targets/js/dsl/KotlinWasmTargetDsl.kt | 7 ++ .../kotlin/gradle/targets/js/ir/JsBinaries.kt | 45 ++++++++- .../targets/js/ir/KotlinJsIrSubTarget.kt | 39 +++++--- .../gradle/targets/js/ir/KotlinJsIrTarget.kt | 98 +------------------ 6 files changed, 90 insertions(+), 120 deletions(-) diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/NewMultiplatformIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/NewMultiplatformIT.kt index d7fdce1ac3d..8bebfe0b773 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/NewMultiplatformIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/NewMultiplatformIT.kt @@ -1679,7 +1679,6 @@ open class NewMultiplatformIT : BaseGradleIT() { } build(":wasmJs${name}Test") { assertTasksExecuted(":compileKotlinWasmJs") - assertTasksNotExecuted(":compileTestDevelopmentExecutableKotlinWasmJsOptimize") assertTasksFailed(":wasmJs${name}Test") assertTestResults( diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/binaryen/BinaryenExec.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/binaryen/BinaryenExec.kt index 674f0ddc933..9c821423a62 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/binaryen/BinaryenExec.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/binaryen/BinaryenExec.kt @@ -5,8 +5,12 @@ package org.jetbrains.kotlin.gradle.targets.js.binaryen +import org.gradle.api.file.DirectoryProperty import org.gradle.api.file.FileSystemOperations +import org.gradle.api.file.RegularFile import org.gradle.api.file.RegularFileProperty +import org.gradle.api.provider.Property +import org.gradle.api.provider.Provider import org.gradle.api.tasks.* import org.gradle.work.DisableCachingByDefault import org.gradle.work.NormalizeLineEndings @@ -37,8 +41,16 @@ constructor() : AbstractExecTask(BinaryenExec::class.java) { @NormalizeLineEndings val inputFileProperty: RegularFileProperty = project.newFileProperty() - @OutputFile - val outputFileProperty: RegularFileProperty = project.newFileProperty() + @get:OutputDirectory + abstract val outputDirectory: DirectoryProperty + + @get:Input + abstract val outputFileName: Property + + @Internal + val outputFileProperty: Provider = project.provider { + outputDirectory.file(outputFileName).get() + } override fun exec() { val inputFile = inputFileProperty.asFile.get() @@ -46,7 +58,7 @@ constructor() : AbstractExecTask(BinaryenExec::class.java) { newArgs.addAll(binaryenArgs) newArgs.add(inputFile.canonicalPath) newArgs.add("-o") - newArgs.add(outputFileProperty.asFile.get().canonicalPath) + newArgs.add(outputDirectory.file(outputFileName).get().asFile.normalize().absolutePath) workingDir = inputFile.parentFile this.args = newArgs super.exec() @@ -56,7 +68,7 @@ constructor() : AbstractExecTask(BinaryenExec::class.java) { fun create( compilation: KotlinJsIrCompilation, name: String, - configuration: BinaryenExec.() -> Unit = {} + configuration: BinaryenExec.() -> Unit = {}, ): TaskProvider { val target = compilation.target val project = target.project diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/dsl/KotlinWasmTargetDsl.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/dsl/KotlinWasmTargetDsl.kt index 766f0c7508a..60dbf01300f 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/dsl/KotlinWasmTargetDsl.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/dsl/KotlinWasmTargetDsl.kt @@ -17,8 +17,15 @@ import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrCompilation interface KotlinWasmTargetDsl : KotlinTarget, HasBinaries { val wasmTargetType: KotlinWasmTargetType? + @Suppress("DEPRECATION") + @Deprecated("Binaryen is enabled by default. This call is redundant.") fun applyBinaryen() = applyBinaryen { } + + @Deprecated("Binaryen is enabled by default. This call is redundant.") fun applyBinaryen(body: BinaryenExec.() -> Unit) + + @Suppress("DEPRECATION") + @Deprecated("Binaryen is enabled by default. This call is redundant.") fun applyBinaryen(fn: Action) { applyBinaryen { fn.execute(this) diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/JsBinaries.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/JsBinaries.kt index 35d068c9cb9..bb6a2d9ead4 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/JsBinaries.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/JsBinaries.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.gradle.targets.js.ir import org.gradle.api.Project +import org.gradle.api.file.Directory import org.gradle.api.file.RegularFile import org.gradle.api.provider.Provider import org.gradle.api.tasks.TaskProvider @@ -23,7 +24,6 @@ import org.jetbrains.kotlin.gradle.targets.js.subtargets.createDefaultDistributi import org.jetbrains.kotlin.gradle.targets.js.typescript.TypeScriptValidationTask import org.jetbrains.kotlin.gradle.tasks.configuration.KotlinJsIrLinkConfig import org.jetbrains.kotlin.gradle.tasks.registerTask -import org.jetbrains.kotlin.gradle.tasks.withType import org.jetbrains.kotlin.gradle.utils.filesProvider import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName import org.jetbrains.kotlin.gradle.utils.mapToFile @@ -189,10 +189,45 @@ open class ExecutableWasm( ) { val optimizeTaskName: String = optimizeTaskName() - val optimizeTask: TaskProvider - get() = target.project.tasks - .withType() - .named(optimizeTaskName) + val optimizeTask: TaskProvider = BinaryenExec.create(compilation, optimizeTaskName) { + val compileWasmDestDir = linkTask.map { + it.destinationDirectory + } + + val compiledWasmFile = linkTask.flatMap { link -> + link.destinationDirectory.locationOnly.zip(link.compilerOptions.moduleName) { destDir, moduleName -> + destDir.file("$moduleName.wasm") + } + } + + dependsOn(linkTask) + inputFileProperty.set(compiledWasmFile) + + val outputDirectory: Provider = target.project.layout.buildDirectory + .dir(COMPILE_SYNC) + .map { it.dir(compilation.target.targetName) } + .map { it.dir(compilation.name) } + .map { it.dir(name) } + .map { it.dir("optimized") } + + this.outputDirectory.set(outputDirectory) + + outputFileName.set( + compiledWasmFile.map { it.asFile.name } + ) + + doLast { + fs.copy { + it.from(compileWasmDestDir) + it.into(outputDirectory) + it.eachFile { + if (it.relativePath.getFile(outputDirectory.get().asFile).exists()) { + it.exclude() + } + } + } + } + } private fun optimizeTaskName(): String = "${linkTaskName}Optimize" diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrSubTarget.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrSubTarget.kt index b08a61e6942..c8a345aa483 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrSubTarget.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrSubTarget.kt @@ -16,10 +16,8 @@ import org.jetbrains.kotlin.gradle.plugin.AbstractKotlinTargetConfigurator import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation import org.jetbrains.kotlin.gradle.plugin.KotlinTargetWithTests import org.jetbrains.kotlin.gradle.plugin.mpp.isMain -import org.jetbrains.kotlin.gradle.utils.whenEvaluated import org.jetbrains.kotlin.gradle.targets.js.KotlinJsPlatformTestRun import org.jetbrains.kotlin.gradle.targets.js.KotlinWasmTargetType -import org.jetbrains.kotlin.gradle.targets.js.binaryen.BinaryenExec import org.jetbrains.kotlin.gradle.targets.js.dsl.Distribution import org.jetbrains.kotlin.gradle.targets.js.dsl.ExperimentalDistributionDsl import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsBinaryMode @@ -27,11 +25,12 @@ import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsSubTargetDsl import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject import org.jetbrains.kotlin.gradle.targets.js.testing.KotlinJsTest import org.jetbrains.kotlin.gradle.tasks.dependsOn -import org.jetbrains.kotlin.gradle.tasks.locateTask import org.jetbrains.kotlin.gradle.tasks.registerTask import org.jetbrains.kotlin.gradle.testing.internal.configureConventions import org.jetbrains.kotlin.gradle.testing.internal.kotlinTestRegistry import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName +import org.jetbrains.kotlin.gradle.utils.whenEvaluated +import org.jetbrains.kotlin.gradle.utils.withType abstract class KotlinJsIrSubTarget( val target: KotlinJsIrTarget, @@ -55,13 +54,17 @@ abstract class KotlinJsIrSubTarget( } internal fun configure() { + configureTests() target.compilations.all { val npmProject = it.npmProject @Suppress("DEPRECATION") it.compilerOptions.options.freeCompilerArgs.add("$PER_MODULE_OUTPUT_NAME=${npmProject.name}") + it.binaries + .withType() + .configureEach { binary -> + configureBinaryen(binary) + } } - - configureTests() } private val produceExecutable: Unit by lazy { @@ -126,15 +129,8 @@ abstract class KotlinJsIrSubTarget( testJs.dependsOn(binary.linkSyncTask) binary.mainFileSyncPath } else { - if (project.locateTask((binary as ExecutableWasm).optimizeTaskName) != null) { - testJs.dependsOn(binary.optimizeTask) - binary.optimizeTask.flatMap { optimizeTask -> - optimizeTask.outputFileProperty - } - } else { - testJs.dependsOn(binary.linkTask) - binary.mainFile - } + testJs.dependsOn(binary.linkTask) + binary.mainFile } testJs.inputFileProperty.set( @@ -233,6 +229,21 @@ abstract class KotlinJsIrSubTarget( } } + private fun configureBinaryen(binary: ExecutableWasm) { + val binaryenExec = binary.optimizeTask + if (binary.compilation.isMain() && binary.mode == KotlinJsBinaryMode.PRODUCTION) { + if (target.wasmTargetType == KotlinWasmTargetType.WASI) { + + project.tasks.named(LifecycleBasePlugin.ASSEMBLE_TASK_NAME).dependsOn(binaryenExec) + } else { + binary.linkSyncTask.configure { + it.from.setFrom(binaryenExec.flatMap { it.outputFileProperty.map { it.asFile.parentFile } }) + it.dependsOn(binaryenExec) + } + } + } + } + internal inline fun registerSubTargetTask( name: String, args: List = emptyList(), diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrTarget.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrTarget.kt index 615f68c9203..6dbc9c96e22 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrTarget.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrTarget.kt @@ -151,7 +151,6 @@ constructor( .withType(JsIrBinary::class.java) .all { binary -> val syncTask = binary.linkSyncTask - binaryenReplaceInput[binary]?.invoke() val tsValidationTask = registerTypeScriptCheckTask(binary) binary.linkTask.configure { @@ -182,97 +181,8 @@ constructor( } } - //Binaryen - private var binaryenReplaceInput: MutableMap Unit> = mutableMapOf() - + @Deprecated("Binaryen is enabled by default. This call is redundant.") override fun applyBinaryen(body: BinaryenExec.() -> Unit) { - compilations.all { - it.binaries.all { binary -> - if (binary is ExecutableWasm) { - val binaryenExec = createBinaryen(binary, body) - - if ( - wasmTargetType == KotlinWasmTargetType.WASI && nodejsLazyDelegate.isInitialized() || - project.locateTask(binary.linkSyncTaskName) != null - ) { - configureBinaryen(binary, binaryenExec) - } else { - binaryenReplaceInput[binary] = { - configureBinaryen(binary, binaryenExec) - } - } - } - } - } - } - - private fun createBinaryen(binary: ExecutableWasm, binaryenDsl: BinaryenExec.() -> Unit): TaskProvider { - val linkTask = binary.linkTask - - val compileWasmDestDir = linkTask.map { - it.destinationDirectory - } - - val compiledWasmFile = linkTask.map { link -> - link.destinationDirectory.asFile.get().resolve(link.compilerOptions.moduleName.get() + ".wasm") - } - - return BinaryenExec.create(binary.compilation, binary.optimizeTaskName) { - val compilation = binary.compilation - dependsOn(linkTask) - inputFileProperty.fileProvider(compiledWasmFile) - - val outputDirectory: Provider = binary.target.project.layout.buildDirectory - .dir(COMPILE_SYNC) - .map { it.dir(compilation.target.targetName) } - .map { it.dir(compilation.name) } - .map { it.dir(binary.name) } - .map { it.dir("optimized") } - .map { it.asFile } - - val outputFile = outputDirectory.map { it.resolve(compiledWasmFile.get().name) } - - outputFileProperty.fileProvider( - outputFile - ) - - doLast { - fs.copy { - it.from(compileWasmDestDir) - it.into(outputDirectory) - it.eachFile { - if (it.relativePath.getFile(outputDirectory.get()).exists()) { - it.exclude() - } - } - } - } - - binaryenDsl() - } - } - - private fun configureBinaryen(binary: JsIrBinary, binaryenExec: TaskProvider) { - if (wasmTargetType == KotlinWasmTargetType.WASI) { - if (binary.compilation.isMain() && binary.mode == KotlinJsBinaryMode.PRODUCTION) { - project.tasks.named(LifecycleBasePlugin.ASSEMBLE_TASK_NAME).dependsOn(binaryenExec) - } - - whenNodejsConfigured { - testTask { - val name = binary.mainFileName - it.inputFileProperty.fileProvider( - binaryenExec.flatMap { it.outputFileProperty.map { it.asFile.parentFile.resolve(name.get()) } } - ) - it.dependsOn(binaryenExec) - } - } - } else { - binary.linkSyncTask.configure { - it.from.setFrom(binaryenExec.flatMap { it.outputFileProperty.map { it.asFile.parentFile } }) - it.dependsOn(binaryenExec) - } - } } //Browser @@ -304,12 +214,8 @@ constructor( commonLazy } else { NodeJsRootPlugin.apply(project.rootProject) - compilations.all { compilation -> - compilation.binaries.all { binary -> - binaryenReplaceInput[binary]?.invoke() - } - } } + project.objects.newInstance(KotlinNodeJsIr::class.java, this).also { it.configureSubTarget() nodejsConfiguredHandlers.forEach { handler ->