[Wasm] Support wasm target in multiplatform plugin

This commit is contained in:
Svyatoslav Kuzmich
2021-09-25 12:46:21 +03:00
parent 070c64f9b5
commit 841f5a583e
32 changed files with 183 additions and 20 deletions
@@ -17,6 +17,7 @@ open class KotlinMultiplatformExtension(project: Project) :
KotlinProjectExtension(project),
KotlinTargetContainerWithPresetFunctions,
KotlinTargetContainerWithJsPresetFunctions,
KotlinTargetContainerWithWasmPresetFunctions,
KotlinTargetContainerWithNativeShortcuts {
override lateinit var presets: NamedDomainObjectCollection<KotlinTargetPreset<*>>
internal set
@@ -0,0 +1,28 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.gradle.dsl
import groovy.lang.Closure
import org.gradle.util.ConfigureUtil
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsTargetDsl
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTargetPreset
interface KotlinTargetContainerWithWasmPresetFunctions : KotlinTargetContainerWithPresetFunctions {
fun wasm(
name: String = "wasm",
configure: KotlinJsTargetDsl.() -> Unit = { }
): KotlinJsTargetDsl =
configureOrCreate(
name,
presets.getByName("wasm") as KotlinJsIrTargetPreset,
configure
)
fun wasm() = wasm("wasm") { }
fun wasm(name: String) = wasm(name) { }
fun wasm(name: String, configure: Closure<*>) = wasm(name) { ConfigureUtil.configure(configure, this) }
fun wasm(configure: Closure<*>) = wasm { ConfigureUtil.configure(configure, this) }
}
@@ -138,6 +138,7 @@ private fun addStdlibToPm20Project(
KotlinPlatformType.common -> error("variants are not expected to be common")
KotlinPlatformType.jvm -> "kotlin-stdlib" // TODO get JDK from JVM variants
KotlinPlatformType.js -> "kotlin-stdlib-js"
KotlinPlatformType.wasm -> "kotlin-stdlib-wasm"
KotlinPlatformType.androidJvm -> null // TODO: expect support on the AGP side?
KotlinPlatformType.native -> null
}
@@ -189,6 +190,7 @@ private fun chooseAndAddStdlibDependency(
KotlinPlatformType.androidJvm ->
if (kotlinSourceSet.name == androidMainSourceSetName(project)) stdlibModuleForJvmCompilations(compilations) else null
KotlinPlatformType.js -> "kotlin-stdlib-js"
KotlinPlatformType.wasm -> "kotlin-stdlib-wasm"
KotlinPlatformType.native -> null
KotlinPlatformType.common -> // there's no platform compilation that the source set is default for
"kotlin-stdlib-common"
@@ -159,7 +159,10 @@ internal fun PropertiesProvider.mapKotlinDaemonProperties(task: CompileUsingKotl
val mppStabilityNoWarn: Boolean?
get() = booleanProperty(KotlinMultiplatformPlugin.STABILITY_NOWARN_FLAG)
val ignoreDisabledNativeTargets: Boolean?
val wasmStabilityNoWarn: Boolean
get() = booleanProperty("kotlin.wasm.stability.nowarn") ?: false
val ignoreDisabledNativeTargets: Boolean?
get() = booleanProperty(DisabledNativeTargetsReporter.DISABLE_WARNING_PROPERTY_NAME)
val ignoreIncorrectNativeDependencies: Boolean?
@@ -174,13 +174,14 @@ class KotlinMultiplatformPlugin : Plugin<Project> {
with(project.multiplatformExtension.presets) {
add(KotlinJvmTargetPreset(project))
add(KotlinJsTargetPreset(project).apply { irPreset = null })
add(KotlinJsIrTargetPreset(project).apply { mixedMode = false })
add(KotlinJsIrTargetPreset(project, isWasm = false).apply { mixedMode = false })
add(
KotlinJsTargetPreset(project).apply {
irPreset = KotlinJsIrTargetPreset(project)
irPreset = KotlinJsIrTargetPreset(project, isWasm = false)
.apply { mixedMode = true }
}
)
add(KotlinJsIrTargetPreset(project, isWasm = true).apply { mixedMode = false })
add(KotlinAndroidTargetPreset(project))
add(KotlinJvmWithJavaTargetPreset(project))
@@ -26,5 +26,7 @@ internal const val MODULE_NAME = "-Xir-module-name"
internal const val PER_MODULE_OUTPUT_NAME = "-Xir-per-module-output-name"
internal const val WASM_BACKEND = "-Xwasm"
fun KotlinJsOptions.isProduceUnzippedKlib() = PRODUCE_UNZIPPED_KLIB in freeCompilerArgs
fun KotlinJsOptions.isProduceZippedKlib() = PRODUCE_ZIPPED_KLIB in freeCompilerArgs
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinJsOptionsImpl
import org.jetbrains.kotlin.gradle.dsl.copyFreeCompilerArgsToArgs
import org.jetbrains.kotlin.gradle.logging.GradlePrintingMessageCollector
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData
import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService
@@ -184,6 +185,10 @@ abstract class KotlinJsIrLink @Inject constructor(
freeCompilerArgs += additionalCompilerArgs.toList() +
PRODUCE_JS +
"$ENTRY_IR_MODULE=${entryModule.get().asFile.canonicalPath}"
if (compilation.platformType == KotlinPlatformType.wasm) {
freeCompilerArgs += WASM_BACKEND
}
}
}
@@ -71,6 +71,10 @@ open class KotlinJsIrTargetConfigurator() :
target.compilations.all { compilation ->
compilation.kotlinOptions {
configureOptions()
if (target.platformType == KotlinPlatformType.wasm) {
freeCompilerArgs = freeCompilerArgs + WASM_BACKEND
}
var produceUnzippedKlib = isProduceUnzippedKlib()
val produceZippedKlib = isProduceZippedKlib()
@@ -16,7 +16,8 @@ import org.jetbrains.kotlin.gradle.utils.runProjectConfigurationHealthCheckWhenE
import org.jetbrains.kotlin.statistics.metrics.StringMetrics
open class KotlinJsIrTargetPreset(
project: Project
project: Project,
isWasm: Boolean,
) : KotlinOnlyTargetPreset<KotlinJsIrTarget, KotlinJsIrCompilation>(
project
) {
@@ -25,10 +26,21 @@ open class KotlinJsIrTargetPreset(
open val isMpp: Boolean
get() = true
override val platformType: KotlinPlatformType
get() = KotlinPlatformType.js
override val platformType: KotlinPlatformType =
if (isWasm)
KotlinPlatformType.wasm
else
KotlinPlatformType.js
override fun instantiateTarget(name: String): KotlinJsIrTarget {
if (platformType == KotlinPlatformType.wasm && !PropertiesProvider(project).wasmStabilityNoWarn) {
project.logger.warn(
"""
New 'wasm' target is Work-in-Progress and is subject to change without notice.
""".trimIndent()
)
}
return project.objects.newInstance(KotlinJsIrTarget::class.java, project, platformType, mixedMode).apply {
this.isMpp = this@KotlinJsIrTargetPreset.isMpp
if (!mixedMode) {
@@ -64,7 +76,11 @@ open class KotlinJsIrTargetPreset(
override fun createKotlinTargetConfigurator(): KotlinOnlyTargetConfigurator<KotlinJsIrCompilation, KotlinJsIrTarget> =
KotlinJsIrTargetConfigurator()
override fun getName(): String = PRESET_NAME
override fun getName(): String = when (platformType) {
KotlinPlatformType.wasm -> WASM_PRESET_NAME
KotlinPlatformType.js -> JS_PRESET_NAME
else -> error("Unsupported platform type")
}
//TODO[Ilya Goncharov] remove public morozov
public override fun createCompilationFactory(
@@ -73,17 +89,19 @@ open class KotlinJsIrTargetPreset(
KotlinJsIrCompilationFactory(project, forTarget)
companion object {
val PRESET_NAME = lowerCamelCaseName(
val JS_PRESET_NAME = lowerCamelCaseName(
"js",
KotlinJsCompilerType.IR.lowerName
)
private const val WASM_PRESET_NAME = "wasm"
}
}
class KotlinJsIrSingleTargetPreset(
project: Project
) : KotlinJsIrTargetPreset(
project
project,
isWasm = false,
) {
override val isMpp: Boolean
get() = false
@@ -89,7 +89,8 @@ internal class KotlinProjectNpmResolver(
private fun addTargetListeners(target: KotlinTarget) {
check(!closed) { resolver.alreadyResolvedMessage("add target $target") }
if (target.platformType == KotlinPlatformType.js) {
if (target.platformType == KotlinPlatformType.js ||
target.platformType == KotlinPlatformType.wasm) {
target.compilations.all { compilation ->
if (compilation is KotlinJsCompilation) {
// compilation may be KotlinWithJavaTarget for old Kotlin2JsPlugin