[Wasm] Support wasm target in multiplatform plugin
This commit is contained in:
@@ -319,7 +319,7 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
||||
outputWatFile.writeText(res.wat)
|
||||
|
||||
val runner = """
|
||||
const ${sanitizeName(moduleName)} = WebAssembly.instantiateStreaming(fetch('${outputWasmFile.name}'), { runtime, js_code }).then((it) => {
|
||||
export default WebAssembly.instantiateStreaming(fetch('${outputWasmFile.name}'), { runtime, js_code }).then((it) => {
|
||||
wasmInstance = it.instance;
|
||||
wasmInstance.exports.main?.();
|
||||
return it.instance.exports;
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ import org.gradle.util.GradleVersion
|
||||
import java.io.Serializable
|
||||
|
||||
enum class KotlinPlatformType: Named, Serializable {
|
||||
common, jvm, js, androidJvm, native;
|
||||
common, jvm, js, androidJvm, native, wasm;
|
||||
|
||||
override fun toString(): String = name
|
||||
override fun getName(): String = name
|
||||
|
||||
+22
-2
@@ -1144,7 +1144,7 @@ class NewMultiplatformIT : BaseGradleIT() {
|
||||
}
|
||||
|
||||
assertEquals(
|
||||
setOf("commonMain", "jvm6Main", "linux64Main", "linuxMipsel32Main", "macos64Main", "mingw64Main", "mingw86Main", "nodeJsMain"),
|
||||
setOf("commonMain", "jvm6Main", "linux64Main", "linuxMipsel32Main", "macos64Main", "mingw64Main", "mingw86Main", "nodeJsMain", "wasmMain"),
|
||||
sourceJarSourceRoots[null]
|
||||
)
|
||||
assertEquals(setOf("commonMain", "jvm6Main"), sourceJarSourceRoots["jvm6"])
|
||||
@@ -1472,7 +1472,7 @@ class NewMultiplatformIT : BaseGradleIT() {
|
||||
}
|
||||
|
||||
val expectedDefaultSourceSets = listOf(
|
||||
"jvm6", "nodeJs", "mingw64", "mingw86", "linux64", "macos64", "linuxMipsel32"
|
||||
"jvm6", "nodeJs", "mingw64", "mingw86", "linux64", "macos64", "linuxMipsel32", "wasm"
|
||||
).flatMapTo(mutableSetOf()) { target ->
|
||||
listOf("main", "test").map { compilation ->
|
||||
Triple(target, compilation, "$target${compilation.capitalize()}")
|
||||
@@ -1872,6 +1872,26 @@ class NewMultiplatformIT : BaseGradleIT() {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testWasmJs() = with(Project("new-mpp-wasm-js", gradleVersion)) {
|
||||
setupWorkingDir()
|
||||
gradleBuildScript().modify(::transformBuildScriptWithPluginsDsl)
|
||||
build("build") {
|
||||
assertSuccessful()
|
||||
assertTasksExecuted(":compileKotlinJs")
|
||||
assertTasksExecuted(":compileKotlinWasm")
|
||||
|
||||
val outputPrefix = "build/js/packages/"
|
||||
|
||||
val jsOutput = outputPrefix + "redefined-js-module-name/kotlin/"
|
||||
assertFileExists(jsOutput + "redefined-js-module-name.js")
|
||||
|
||||
val wasmOutput = outputPrefix + "redefined-wasm-module-name/kotlin/"
|
||||
assertFileExists(wasmOutput + "redefined-wasm-module-name.js")
|
||||
assertFileExists(wasmOutput + "redefined-wasm-module-name.wasm")
|
||||
}
|
||||
}
|
||||
|
||||
private fun detectNativeEnabledCompilation(): String = when {
|
||||
HostManager.hostIsLinux -> "linuxX64"
|
||||
HostManager.hostIsMingw -> "mingwX64"
|
||||
|
||||
+3
@@ -22,6 +22,9 @@ kotlin {
|
||||
val nodeJs = js("nodeJs")
|
||||
val linux64 = linuxX64("linux64")
|
||||
|
||||
wasm {
|
||||
}
|
||||
|
||||
configure(listOf(linux64)) {
|
||||
binaries.executable("main", listOf(DEBUG)) {
|
||||
entryPoint = "com.example.app.native.main"
|
||||
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
import com.example.lib.*
|
||||
|
||||
fun wasmMain(args: Array<String>) {
|
||||
println("${id(123)} ${idUsage()} ${expectedFun()}")
|
||||
}
|
||||
+2
@@ -48,6 +48,8 @@ kotlin {
|
||||
|
||||
js('nodeJs')
|
||||
|
||||
wasm()
|
||||
|
||||
targets {
|
||||
fromPreset(presets.jvm, 'jvm6') {
|
||||
attributes.attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 6)
|
||||
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
import com.example.lib.*
|
||||
|
||||
fun wasmMain(args: Array<String>) {
|
||||
println("${id(123)} ${idUsage()} ${expectedFun()}")
|
||||
}
|
||||
+1
@@ -22,6 +22,7 @@ kotlin {
|
||||
// Check the new preset functions:
|
||||
jvm('jvm6') { }
|
||||
js('nodeJs')
|
||||
wasm()
|
||||
targetFromPreset(presets.jvm, 'jvm6') { println targetName } // access existing target
|
||||
|
||||
targets {
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package com.example.externalLib
|
||||
|
||||
fun idUsage() = id("123")
|
||||
|
||||
actual fun expectedFun() = Unit
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
expectedFun()
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
resource
|
||||
+1
@@ -15,6 +15,7 @@ kotlin {
|
||||
val jvm = jvm("jvm6")
|
||||
val js = js("nodeJs")
|
||||
linuxX64("linux64")
|
||||
wasm()
|
||||
|
||||
targets.all {
|
||||
mavenPublication(Action<MavenPublication> {
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package com.example.lib
|
||||
|
||||
fun idUsage() = id("123")
|
||||
|
||||
actual fun expectedFun() {
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
expectedFun()
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
Wasm resource
|
||||
+1
@@ -22,6 +22,7 @@ kotlin {
|
||||
// Check the new preset functions:
|
||||
jvm('jvm6') { }
|
||||
js('nodeJs')
|
||||
wasm()
|
||||
targetFromPreset(presets.jvm, 'jvm6') { println targetName } // access existing target
|
||||
|
||||
targets {
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package com.example.lib
|
||||
|
||||
fun idUsage() = id("123")
|
||||
|
||||
actual fun expectedFun() {
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
expectedFun()
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
Wasm resource
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
plugins {
|
||||
kotlin("multiplatform").version("<pluginMarkerVersion>")
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
kotlin {
|
||||
wasm {
|
||||
moduleName = "redefined-wasm-module-name"
|
||||
browser {
|
||||
}
|
||||
binaries.executable()
|
||||
}
|
||||
js {
|
||||
moduleName = "redefined-js-module-name"
|
||||
browser {
|
||||
}
|
||||
binaries.executable()
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
pluginManagement {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
gradlePluginPortal()
|
||||
}
|
||||
}
|
||||
|
||||
rootProject.name = "new-mpp-wasm-js"
|
||||
+1
@@ -0,0 +1 @@
|
||||
expect fun foo(): Int
|
||||
+1
@@ -0,0 +1 @@
|
||||
actual fun foo(): Int = 1
|
||||
+1
@@ -0,0 +1 @@
|
||||
actual fun foo(): Int = 2
|
||||
+1
@@ -17,6 +17,7 @@ open class KotlinMultiplatformExtension(project: Project) :
|
||||
KotlinProjectExtension(project),
|
||||
KotlinTargetContainerWithPresetFunctions,
|
||||
KotlinTargetContainerWithJsPresetFunctions,
|
||||
KotlinTargetContainerWithWasmPresetFunctions,
|
||||
KotlinTargetContainerWithNativeShortcuts {
|
||||
override lateinit var presets: NamedDomainObjectCollection<KotlinTargetPreset<*>>
|
||||
internal set
|
||||
|
||||
+28
@@ -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) }
|
||||
}
|
||||
+2
@@ -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"
|
||||
|
||||
+4
-1
@@ -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?
|
||||
|
||||
+3
-2
@@ -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))
|
||||
|
||||
|
||||
+2
@@ -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
|
||||
+5
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
@@ -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()
|
||||
|
||||
+24
-6
@@ -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
|
||||
|
||||
+2
-1
@@ -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
|
||||
|
||||
@@ -12,12 +12,6 @@ publish()
|
||||
val default = configurations.getByName(Dependency.DEFAULT_CONFIGURATION)
|
||||
default.extendsFrom(configurations.publishedRuntime.get())
|
||||
|
||||
dependencies {
|
||||
if (!kotlinBuildProperties.isInJpsBuildIdeaSync) {
|
||||
publishedRuntime(project(":kotlin-test:kotlin-test-js"))
|
||||
}
|
||||
}
|
||||
|
||||
node {
|
||||
version.set("16.2.0")
|
||||
download.set(true)
|
||||
|
||||
Reference in New Issue
Block a user