[Gradle, Wasm] Add wasmWasi target, replace wasm target onto wasmJs

KT-60654
This commit is contained in:
Ilya Goncharov
2023-08-01 13:11:36 +00:00
committed by Space Team
parent a65953a7fb
commit b9e5b8a087
65 changed files with 577 additions and 160 deletions
+2 -1
View File
@@ -13,8 +13,9 @@ val commonMainSources by task<Sync> {
}
kotlin {
@Suppress("DEPRECATION")
@OptIn(org.jetbrains.kotlin.gradle.targets.js.dsl.ExperimentalWasmDsl::class)
wasm {
wasm("wasm") {
nodejs()
}
+2 -1
View File
@@ -78,8 +78,9 @@ val commonTestSources by task<Sync> {
D8RootPlugin.apply(rootProject).version = v8Version
kotlin {
@Suppress("DEPRECATION")
@OptIn(org.jetbrains.kotlin.gradle.targets.js.dsl.ExperimentalWasmDsl::class)
wasm {
wasm("wasm") {
d8()
}
@@ -0,0 +1,48 @@
/*
* 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
import com.google.gson.Gson
import com.google.gson.JsonNull
import com.google.gson.JsonObject
import org.gradle.testkit.runner.BuildResult
import org.gradle.util.GradleVersion
import org.jetbrains.kotlin.gradle.targets.js.dsl.Distribution
import org.jetbrains.kotlin.gradle.targets.js.ir.KLIB_TYPE
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProject
import org.jetbrains.kotlin.gradle.targets.js.npm.PackageJson
import org.jetbrains.kotlin.gradle.targets.js.npm.fromSrcPackageJson
import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnLockCopyTask.Companion.STORE_YARN_LOCK_NAME
import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnLockCopyTask.Companion.UPGRADE_YARN_LOCK
import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnLockCopyTask.Companion.YARN_LOCK_MISMATCH_MESSAGE
import org.jetbrains.kotlin.gradle.tasks.USING_JS_IR_BACKEND_MESSAGE
import org.jetbrains.kotlin.gradle.testbase.*
import org.jetbrains.kotlin.gradle.testbase.TestVersions.Gradle.G_7_6
import org.jetbrains.kotlin.gradle.util.modify
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.condition.DisabledIf
import java.nio.file.Files
import java.util.zip.ZipFile
import kotlin.io.path.*
import kotlin.streams.toList
import kotlin.test.*
@MppGradlePluginTests
class KotlinWasmGradlePluginIT : KGPBaseTest() {
@DisplayName("Check wasi target")
@GradleTest
fun wasiTarget(gradleVersion: GradleVersion) {
project("new-mpp-wasm-wasi-test", gradleVersion) {
buildGradleKts.modify(::transformBuildScriptWithPluginsDsl)
buildAndFail(":wasmWasiTest") {
assertTasksExecuted(":compileKotlinWasmWasi")
assertTasksFailed(":wasmWasiNodeTest")
}
}
}
}
@@ -1426,7 +1426,7 @@ open class NewMultiplatformIT : BaseGradleIT() {
}
val expectedDefaultSourceSets = listOf(
"jvm6", "nodeJs", "mingw64", "linux64", "macos64", "wasm"
"jvm6", "nodeJs", "mingw64", "linux64", "macos64", "wasmJs"
).flatMapTo(mutableSetOf()) { target ->
listOf("main", "test").map { compilation ->
Triple(
@@ -1805,7 +1805,7 @@ open class NewMultiplatformIT : BaseGradleIT() {
build("build") {
assertSuccessful()
assertTasksExecuted(":compileKotlinJs")
assertTasksExecuted(":compileKotlinWasm")
assertTasksExecuted(":compileKotlinWasmJs")
val outputPrefix = "build/js/packages/"
@@ -1827,17 +1827,17 @@ open class NewMultiplatformIT : BaseGradleIT() {
.replace("<JsEngine>", engine)
.replace("<ApplyBinaryen>", if (useBinaryen) "applyBinaryen()" else "")
}
build(":wasm${name}Test") {
assertTasksExecuted(":compileKotlinWasm")
build(":wasmJs${name}Test") {
assertTasksExecuted(":compileKotlinWasmJs")
if (useBinaryen) {
assertTasksExecuted(":compileTestDevelopmentExecutableKotlinWasmOptimize")
assertTasksExecuted(":compileTestDevelopmentExecutableKotlinWasmJsOptimize")
} else {
assertTasksNotExecuted(":compileTestDevelopmentExecutableKotlinWasmOptimize")
assertTasksNotExecuted(":compileTestDevelopmentExecutableKotlinWasmJsOptimize")
}
assertTasksFailed(":wasm${name}Test")
assertTasksFailed(":wasmJs${name}Test")
assertTestResults(
"testProject/new-mpp-wasm-test/TEST-${engine}.xml",
"wasm${name}Test"
"wasmJs${name}Test"
)
}
}
@@ -23,7 +23,7 @@ class WasmConfigurationCacheIT : KGPBaseTest() {
assertSimpleConfigurationCacheScenarioWorks(
"assemble",
buildOptions = defaultBuildOptions,
executedTaskNames = listOf(":compileKotlinWasm")
executedTaskNames = listOf(":compileKotlinWasmJs")
)
}
}
@@ -33,10 +33,10 @@ class WasmConfigurationCacheIT : KGPBaseTest() {
@GradleTestVersions(minVersion = TestVersions.Gradle.G_7_6)
fun testD8Run(gradleVersion: GradleVersion) {
project("wasm-d8-simple-project", gradleVersion) {
build("wasmD8Run", buildOptions = buildOptions) {
assertTasksExecuted(":wasmD8Run")
build("wasmJsD8Run", buildOptions = buildOptions) {
assertTasksExecuted(":wasmJsD8Run")
assertOutputContains(
"Calculating task graph as no configuration cache is available for tasks: wasmD8Run"
"Calculating task graph as no configuration cache is available for tasks: wasmJsD8Run"
)
assertConfigurationCacheStored()
@@ -45,8 +45,8 @@ class WasmConfigurationCacheIT : KGPBaseTest() {
build("clean", buildOptions = buildOptions)
// Then run a build where tasks states are deserialized to check that they work correctly in this mode
build("wasmD8Run", buildOptions = buildOptions) {
assertTasksExecuted(":wasmD8Run")
build("wasmJsD8Run", buildOptions = buildOptions) {
assertTasksExecuted(":wasmJsD8Run")
assertConfigurationCacheReused()
}
}
@@ -155,10 +155,10 @@ class TryK2IT : KGPBaseTest() {
assertCompilerArgument(":compileKotlinJs", "-language-version 2.0")
}
build(":compileKotlinWasm") {
assertTasksExecuted(":compileKotlinWasm")
build(":compileKotlinWasmJs") {
assertTasksExecuted(":compileKotlinWasmJs")
assertCompilerArgument(":compileKotlinWasm", "-language-version 2.0")
assertCompilerArgument(":compileKotlinWasmJs", "-language-version 2.0")
}
build(":compileKotlinLinuxX64") {
@@ -24,7 +24,7 @@ kotlin {
}
val linux64 = linuxX64("linux64")
wasm {
wasmJs {
}
configure(listOf(linux64)) {
@@ -52,7 +52,7 @@ kotlin {
}
}
wasm()
wasmJs()
targets {
fromPreset(presets.jvm, 'jvm6') {
@@ -22,7 +22,7 @@ kotlin {
// Check the new preset functions:
jvm('jvm6') { }
js('nodeJs')
wasm()
wasmJs()
targetFromPreset(presets.jvm, 'jvm6') { println targetName } // access existing target
targets {
@@ -21,7 +21,7 @@ kotlin {
} else null
linuxX64("linux64")
if (shouldBeJs)
wasm()
wasmJs()
targets.all {
mavenPublication(Action<MavenPublication> {
@@ -29,7 +29,7 @@ kotlin {
}
}
wasm()
wasmJs()
}
targetFromPreset(presets.jvm, 'jvm6') { println targetName } // access existing target
@@ -16,7 +16,7 @@ kotlin {
jvm()
js()
linuxX64()
wasm()
wasmJs()
sourceSets {
val commonMain by getting {
@@ -8,7 +8,7 @@ repositories {
}
kotlin {
wasm {
wasmJs {
moduleName = "redefined-wasm-module-name"
d8 {
}
@@ -2,13 +2,13 @@
<results>
<testsuite name="my.pack.name.WasmTest" tests="3" skipped="1" failures="2" errors="0" timestamp="..." hostname="..." time="...">
<properties />
<testcase name="test1[wasm, d8]" classname="my.pack.name.WasmTest" time="...">
<testcase name="test1[wasmJs, d8]" classname="my.pack.name.WasmTest" time="...">
<failure message="..." type="AssertionError">...</failure>
</testcase>
<testcase name="test2[wasm, d8]" classname="my.pack.name.WasmTest" time="...">
<testcase name="test2[wasmJs, d8]" classname="my.pack.name.WasmTest" time="...">
<skipped />
</testcase>
<testcase name="test3[wasm, d8]" classname="my.pack.name.WasmTest" time="...">
<testcase name="test3[wasmJs, d8]" classname="my.pack.name.WasmTest" time="...">
<failure message="..." type="AssertionError">...</failure>
</testcase>
<system-out />
@@ -16,13 +16,13 @@
</testsuite>
<testsuite name="my.pack.name.WasmTest.InnerIgnored" tests="3" skipped="3" failures="0" errors="0" timestamp="..." hostname="..." time="...">
<properties />
<testcase name="test4[wasm, d8]" classname="my.pack.name.WasmTest.InnerIgnored" time="...">
<testcase name="test4[wasmJs, d8]" classname="my.pack.name.WasmTest.InnerIgnored" time="...">
<skipped />
</testcase>
<testcase name="test5[wasm, d8]" classname="my.pack.name.WasmTest.InnerIgnored" time="...">
<testcase name="test5[wasmJs, d8]" classname="my.pack.name.WasmTest.InnerIgnored" time="...">
<skipped />
</testcase>
<testcase name="test6[wasm, d8]" classname="my.pack.name.WasmTest.InnerIgnored" time="...">
<testcase name="test6[wasmJs, d8]" classname="my.pack.name.WasmTest.InnerIgnored" time="...">
<skipped />
</testcase>
<system-out />
@@ -2,13 +2,13 @@
<results>
<testsuite name="my.pack.name.WasmTest" tests="3" skipped="1" failures="2" errors="0" timestamp="..." hostname="..." time="...">
<properties />
<testcase name="test1[wasm, node]" classname="my.pack.name.WasmTest" time="...">
<testcase name="test1[wasmJs, node]" classname="my.pack.name.WasmTest" time="...">
<failure message="..." type="AssertionError">...</failure>
</testcase>
<testcase name="test2[wasm, node]" classname="my.pack.name.WasmTest" time="...">
<testcase name="test2[wasmJs, node]" classname="my.pack.name.WasmTest" time="...">
<skipped />
</testcase>
<testcase name="test3[wasm, node]" classname="my.pack.name.WasmTest" time="...">
<testcase name="test3[wasmJs, node]" classname="my.pack.name.WasmTest" time="...">
<failure message="..." type="AssertionError">...</failure>
</testcase>
<system-out />
@@ -16,13 +16,13 @@
</testsuite>
<testsuite name="my.pack.name.WasmTest.InnerIgnored" tests="3" skipped="3" failures="0" errors="0" timestamp="..." hostname="..." time="...">
<properties />
<testcase name="test4[wasm, node]" classname="my.pack.name.WasmTest.InnerIgnored" time="...">
<testcase name="test4[wasmJs, node]" classname="my.pack.name.WasmTest.InnerIgnored" time="...">
<skipped />
</testcase>
<testcase name="test5[wasm, node]" classname="my.pack.name.WasmTest.InnerIgnored" time="...">
<testcase name="test5[wasmJs, node]" classname="my.pack.name.WasmTest.InnerIgnored" time="...">
<skipped />
</testcase>
<testcase name="test6[wasm, node]" classname="my.pack.name.WasmTest.InnerIgnored" time="...">
<testcase name="test6[wasmJs, node]" classname="my.pack.name.WasmTest.InnerIgnored" time="...">
<skipped />
</testcase>
<system-out />
@@ -29,7 +29,7 @@ tasks.named<org.jetbrains.kotlin.gradle.targets.js.yarn.YarnLockCopyTask>("kotli
}
kotlin {
wasm {
wasmJs {
<JsEngine> {
testTask {
filter.apply {
@@ -0,0 +1,44 @@
plugins {
kotlin("multiplatform").version("<pluginMarkerVersion>")
}
with(org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin.apply(rootProject)) {
nodeVersion = "20.2.0"
}
with(org.jetbrains.kotlin.gradle.targets.js.d8.D8RootPlugin.apply(rootProject)) {
// Test that we can set the version and it is a String.
// But use the default version since update this place every time anyway.
version = (version as String)
}
allprojects.forEach {
it.tasks.withType<org.jetbrains.kotlin.gradle.targets.js.npm.tasks.KotlinNpmInstallTask>().configureEach {
args.add("--ignore-engines")
}
}
tasks.named<org.jetbrains.kotlin.gradle.targets.js.yarn.YarnLockCopyTask>("kotlinStoreYarnLock") {
//A little hacky way to make yarn results
inputFile.fileValue(projectDir.resolve("yarnLockStub"))
}
repositories {
mavenLocal()
mavenCentral()
}
kotlin {
wasmWasi {
nodejs {}
}
sourceSets {
commonTest {
dependencies {
implementation("org.jetbrains.kotlin:kotlin-test")
}
}
}
}
@@ -0,0 +1,30 @@
package my.pack.name
import kotlin.test.Ignore
import kotlin.test.Test
import kotlin.test.assertEquals
class WasmTest {
@Test
fun test1() = assertEquals(foo(), 1)
@Test
@Ignore
fun test2() = assertEquals(foo(), 2)
@Test
fun test3() = assertEquals(foo(), 3)
@Ignore
class InnerIgnored {
@Test
fun test4() = assertEquals(foo(), 1)
@Test
@Ignore
fun test5() = assertEquals(foo(), 2)
@Test
fun test6() = assertEquals(foo(), 3)
}
}
@@ -8,7 +8,7 @@ repositories {
}
kotlin {
wasm {
wasmJs {
binaries.executable()
d8 {
}
@@ -188,16 +188,26 @@ public abstract class org/jetbrains/kotlin/gradle/dsl/KotlinMultiplatformExtensi
public fun tvosX64 (Ljava/lang/String;Lkotlin/jvm/functions/Function1;)Lorg/jetbrains/kotlin/gradle/plugin/mpp/KotlinNativeTargetWithSimulatorTests;
public fun tvosX64 (Ljava/lang/String;Lorg/gradle/api/Action;)Lorg/jetbrains/kotlin/gradle/plugin/mpp/KotlinNativeTargetWithSimulatorTests;
public fun tvosX64 (Lorg/gradle/api/Action;)Lorg/jetbrains/kotlin/gradle/plugin/mpp/KotlinNativeTargetWithSimulatorTests;
public fun wasm ()Lorg/jetbrains/kotlin/gradle/targets/js/dsl/KotlinJsTargetDsl;
public fun wasm (Ljava/lang/String;)Lorg/jetbrains/kotlin/gradle/targets/js/dsl/KotlinJsTargetDsl;
public fun wasm (Ljava/lang/String;Lkotlin/jvm/functions/Function1;)Lorg/jetbrains/kotlin/gradle/targets/js/dsl/KotlinJsTargetDsl;
public fun wasm (Ljava/lang/String;Lorg/gradle/api/Action;)Lorg/jetbrains/kotlin/gradle/targets/js/dsl/KotlinJsTargetDsl;
public fun wasm (Lorg/gradle/api/Action;)Lorg/jetbrains/kotlin/gradle/targets/js/dsl/KotlinJsTargetDsl;
public fun wasm ()Lorg/jetbrains/kotlin/gradle/targets/js/dsl/KotlinWasmJsTargetDsl;
public fun wasm (Ljava/lang/String;)Lorg/jetbrains/kotlin/gradle/targets/js/dsl/KotlinWasmJsTargetDsl;
public fun wasm (Ljava/lang/String;Lkotlin/jvm/functions/Function1;)Lorg/jetbrains/kotlin/gradle/targets/js/dsl/KotlinWasmJsTargetDsl;
public fun wasm (Ljava/lang/String;Lorg/gradle/api/Action;)Lorg/jetbrains/kotlin/gradle/targets/js/dsl/KotlinWasmJsTargetDsl;
public fun wasm (Lorg/gradle/api/Action;)Lorg/jetbrains/kotlin/gradle/targets/js/dsl/KotlinWasmJsTargetDsl;
public fun wasm32 ()Lorg/jetbrains/kotlin/gradle/plugin/mpp/KotlinNativeTarget;
public fun wasm32 (Ljava/lang/String;)Lorg/jetbrains/kotlin/gradle/plugin/mpp/KotlinNativeTarget;
public fun wasm32 (Ljava/lang/String;Lkotlin/jvm/functions/Function1;)Lorg/jetbrains/kotlin/gradle/plugin/mpp/KotlinNativeTarget;
public fun wasm32 (Ljava/lang/String;Lorg/gradle/api/Action;)Lorg/jetbrains/kotlin/gradle/plugin/mpp/KotlinNativeTarget;
public fun wasm32 (Lorg/gradle/api/Action;)Lorg/jetbrains/kotlin/gradle/plugin/mpp/KotlinNativeTarget;
public fun wasmJs ()Lorg/jetbrains/kotlin/gradle/targets/js/dsl/KotlinWasmJsTargetDsl;
public fun wasmJs (Ljava/lang/String;)Lorg/jetbrains/kotlin/gradle/targets/js/dsl/KotlinWasmJsTargetDsl;
public fun wasmJs (Ljava/lang/String;Lkotlin/jvm/functions/Function1;)Lorg/jetbrains/kotlin/gradle/targets/js/dsl/KotlinWasmJsTargetDsl;
public fun wasmJs (Ljava/lang/String;Lorg/gradle/api/Action;)Lorg/jetbrains/kotlin/gradle/targets/js/dsl/KotlinWasmJsTargetDsl;
public fun wasmJs (Lorg/gradle/api/Action;)Lorg/jetbrains/kotlin/gradle/targets/js/dsl/KotlinWasmJsTargetDsl;
public fun wasmWasi ()Lorg/jetbrains/kotlin/gradle/targets/js/dsl/KotlinWasmJsTargetDsl;
public fun wasmWasi (Ljava/lang/String;)Lorg/jetbrains/kotlin/gradle/targets/js/dsl/KotlinWasmWasiTargetDsl;
public fun wasmWasi (Ljava/lang/String;Lkotlin/jvm/functions/Function1;)Lorg/jetbrains/kotlin/gradle/targets/js/dsl/KotlinWasmWasiTargetDsl;
public fun wasmWasi (Ljava/lang/String;Lorg/gradle/api/Action;)Lorg/jetbrains/kotlin/gradle/targets/js/dsl/KotlinWasmWasiTargetDsl;
public fun wasmWasi (Lorg/gradle/api/Action;)Lorg/jetbrains/kotlin/gradle/targets/js/dsl/KotlinWasmWasiTargetDsl;
public fun watchos ()V
public fun watchos (Ljava/lang/String;)V
public fun watchos (Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V
@@ -459,11 +469,21 @@ public abstract interface class org/jetbrains/kotlin/gradle/dsl/KotlinTargetCont
}
public abstract interface class org/jetbrains/kotlin/gradle/dsl/KotlinTargetContainerWithWasmPresetFunctions : org/jetbrains/kotlin/gradle/dsl/KotlinTargetContainerWithPresetFunctions {
public abstract fun wasm ()Lorg/jetbrains/kotlin/gradle/targets/js/dsl/KotlinJsTargetDsl;
public abstract fun wasm (Ljava/lang/String;)Lorg/jetbrains/kotlin/gradle/targets/js/dsl/KotlinJsTargetDsl;
public abstract fun wasm (Ljava/lang/String;Lkotlin/jvm/functions/Function1;)Lorg/jetbrains/kotlin/gradle/targets/js/dsl/KotlinJsTargetDsl;
public abstract fun wasm (Ljava/lang/String;Lorg/gradle/api/Action;)Lorg/jetbrains/kotlin/gradle/targets/js/dsl/KotlinJsTargetDsl;
public abstract fun wasm (Lorg/gradle/api/Action;)Lorg/jetbrains/kotlin/gradle/targets/js/dsl/KotlinJsTargetDsl;
public abstract fun wasm ()Lorg/jetbrains/kotlin/gradle/targets/js/dsl/KotlinWasmJsTargetDsl;
public abstract fun wasm (Ljava/lang/String;)Lorg/jetbrains/kotlin/gradle/targets/js/dsl/KotlinWasmJsTargetDsl;
public abstract fun wasm (Ljava/lang/String;Lkotlin/jvm/functions/Function1;)Lorg/jetbrains/kotlin/gradle/targets/js/dsl/KotlinWasmJsTargetDsl;
public abstract fun wasm (Ljava/lang/String;Lorg/gradle/api/Action;)Lorg/jetbrains/kotlin/gradle/targets/js/dsl/KotlinWasmJsTargetDsl;
public abstract fun wasm (Lorg/gradle/api/Action;)Lorg/jetbrains/kotlin/gradle/targets/js/dsl/KotlinWasmJsTargetDsl;
public abstract fun wasmJs ()Lorg/jetbrains/kotlin/gradle/targets/js/dsl/KotlinWasmJsTargetDsl;
public abstract fun wasmJs (Ljava/lang/String;)Lorg/jetbrains/kotlin/gradle/targets/js/dsl/KotlinWasmJsTargetDsl;
public abstract fun wasmJs (Ljava/lang/String;Lkotlin/jvm/functions/Function1;)Lorg/jetbrains/kotlin/gradle/targets/js/dsl/KotlinWasmJsTargetDsl;
public abstract fun wasmJs (Ljava/lang/String;Lorg/gradle/api/Action;)Lorg/jetbrains/kotlin/gradle/targets/js/dsl/KotlinWasmJsTargetDsl;
public abstract fun wasmJs (Lorg/gradle/api/Action;)Lorg/jetbrains/kotlin/gradle/targets/js/dsl/KotlinWasmJsTargetDsl;
public abstract fun wasmWasi ()Lorg/jetbrains/kotlin/gradle/targets/js/dsl/KotlinWasmJsTargetDsl;
public abstract fun wasmWasi (Ljava/lang/String;)Lorg/jetbrains/kotlin/gradle/targets/js/dsl/KotlinWasmWasiTargetDsl;
public abstract fun wasmWasi (Ljava/lang/String;Lkotlin/jvm/functions/Function1;)Lorg/jetbrains/kotlin/gradle/targets/js/dsl/KotlinWasmWasiTargetDsl;
public abstract fun wasmWasi (Ljava/lang/String;Lorg/gradle/api/Action;)Lorg/jetbrains/kotlin/gradle/targets/js/dsl/KotlinWasmWasiTargetDsl;
public abstract fun wasmWasi (Lorg/gradle/api/Action;)Lorg/jetbrains/kotlin/gradle/targets/js/dsl/KotlinWasmWasiTargetDsl;
}
public abstract interface class org/jetbrains/kotlin/gradle/dsl/TargetsFromPresetExtension : org/gradle/api/NamedDomainObjectCollection {
@@ -7,33 +7,80 @@ package org.jetbrains.kotlin.gradle.dsl
import org.gradle.api.Action
import org.jetbrains.kotlin.gradle.targets.js.dsl.ExperimentalWasmDsl
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsTargetDsl
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinWasmTargetDsl
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinWasmJsTargetDsl
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinWasmWasiTargetDsl
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinWasmTargetPreset
@KotlinGradlePluginDsl
interface KotlinTargetContainerWithWasmPresetFunctions : KotlinTargetContainerWithPresetFunctions {
@ExperimentalWasmDsl
fun wasm(
name: String = "wasm",
configure: KotlinWasmTargetDsl.() -> Unit = { }
): KotlinJsTargetDsl =
fun wasmJs(
name: String = "wasmJs",
configure: KotlinWasmJsTargetDsl.() -> Unit = { },
): KotlinWasmJsTargetDsl =
configureOrCreate(
name,
@Suppress("DEPRECATION")
presets.getByName("wasm") as KotlinWasmTargetPreset,
presets.getByName("wasmJs") as KotlinWasmTargetPreset,
configure
)
@ExperimentalWasmDsl
fun wasm() = wasm("wasm") { }
fun wasmJs() = wasmJs("wasmJs") { }
@ExperimentalWasmDsl
fun wasm(name: String) = wasm(name) { }
fun wasmJs(name: String) = wasmJs(name) { }
@ExperimentalWasmDsl
fun wasm(name: String, configure: Action<KotlinWasmTargetDsl>) = wasm(name) { configure.execute(this) }
fun wasmJs(name: String, configure: Action<KotlinWasmJsTargetDsl>) = wasmJs(name) { configure.execute(this) }
@ExperimentalWasmDsl
fun wasm(configure: Action<KotlinWasmTargetDsl>) = wasm { configure.execute(this) }
fun wasmJs(configure: Action<KotlinWasmJsTargetDsl>) = wasmJs { configure.execute(this) }
@ExperimentalWasmDsl
fun wasmWasi(
name: String = "wasmWasi",
configure: KotlinWasmWasiTargetDsl.() -> Unit = { },
): KotlinWasmWasiTargetDsl =
configureOrCreate(
name,
@Suppress("DEPRECATION")
presets.getByName("wasmWasi") as KotlinWasmTargetPreset,
configure
)
@ExperimentalWasmDsl
fun wasmWasi() = wasmJs("wasmWasi") { }
@ExperimentalWasmDsl
fun wasmWasi(name: String) = wasmWasi(name) { }
@ExperimentalWasmDsl
fun wasmWasi(name: String, configure: Action<KotlinWasmWasiTargetDsl>) = wasmWasi(name) { configure.execute(this) }
@ExperimentalWasmDsl
fun wasmWasi(configure: Action<KotlinWasmWasiTargetDsl>) = wasmWasi { configure.execute(this) }
@Deprecated("Use wasmJs instead", replaceWith = ReplaceWith("wasmJs(name, configure)"))
@ExperimentalWasmDsl
fun wasm(
name: String = "wasmJs",
configure: KotlinWasmJsTargetDsl.() -> Unit = { },
): KotlinWasmJsTargetDsl = wasmJs(name, configure)
@Deprecated("Use wasmJs instead", replaceWith = ReplaceWith("wasmJs()"))
@ExperimentalWasmDsl
fun wasm() = wasmJs()
@Deprecated("Use wasmJs instead", replaceWith = ReplaceWith("wasmJs(name)"))
@ExperimentalWasmDsl
fun wasm(name: String) = wasmJs(name)
@Deprecated("Use wasmJs instead", replaceWith = ReplaceWith("wasmJs(name, configure)"))
@ExperimentalWasmDsl
fun wasm(name: String, configure: Action<KotlinWasmJsTargetDsl>) = wasmJs(name, configure)
@Deprecated("Use wasmJs instead", replaceWith = ReplaceWith("wasmJs(configure)"))
@ExperimentalWasmDsl
fun wasm(configure: Action<KotlinWasmJsTargetDsl>) = wasmJs(configure)
}
@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.gradle.targets.js.KotlinJsCompilerAttribute
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsTarget
import org.jetbrains.kotlin.gradle.targets.js.KotlinWasmTargetAttribute
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTarget
import org.jetbrains.kotlin.gradle.targets.js.toAttribute
import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget
import org.jetbrains.kotlin.gradle.tasks.locateOrRegisterTask
import org.jetbrains.kotlin.gradle.tasks.registerTask
@@ -314,6 +315,10 @@ abstract class KotlinOnlyTargetConfigurator<KotlinCompilationType : KotlinCompil
it.from(target.compilations.getByName(KotlinCompilation.MAIN_COMPILATION_NAME).output.allOutputs)
it.isPreserveFileTimestamps = false
it.isReproducibleFileOrder = true
target.disambiguationClassifier?.let { classifier ->
it.archiveAppendix.set(classifier.toLowerCaseAsciiOnly())
}
}
}
@@ -324,12 +329,6 @@ abstract class KotlinOnlyTargetConfigurator<KotlinCompilationType : KotlinCompil
val task = createArchiveTasks(target)
target.disambiguationClassifier?.let { classifier ->
task.configure { taskInstance ->
taskInstance.archiveAppendix.set(classifier.toLowerCaseAsciiOnly())
}
}
// Workaround: adding the artifact during configuration seems to interfere with the Java plugin, which results into missing
// task dependency 'assemble -> jar' if the Java plugin is applied after this steps
project.afterEvaluate {
@@ -440,7 +439,7 @@ fun Configuration.usesPlatformOf(target: KotlinTarget): Configuration {
if (target.platformType == KotlinPlatformType.js) {
attributes.attribute(KotlinJsCompilerAttribute.jsCompilerAttribute, KotlinJsCompilerAttribute.ir)
} else {
attributes.attribute(KotlinWasmTargetAttribute.wasmTargetAttribute, KotlinWasmTargetAttribute.js)
attributes.attribute(KotlinWasmTargetAttribute.wasmTargetAttribute, target.wasmTargetType!!.toAttribute())
}
}
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.gradle.plugin.sources.awaitPlatformCompilations
import org.jetbrains.kotlin.gradle.plugin.sources.internal
import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService
import org.jetbrains.kotlin.gradle.scripting.internal.ScriptingGradleSubplugin
import org.jetbrains.kotlin.gradle.targets.js.KotlinWasmTargetType
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTargetPreset
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinWasmTargetPreset
import org.jetbrains.kotlin.gradle.targets.native.createFatFrameworks
@@ -136,7 +137,8 @@ class KotlinMultiplatformPlugin : Plugin<Project> {
irPreset = KotlinJsIrTargetPreset(project).apply { mixedMode = true }
}
)
add(KotlinWasmTargetPreset(project))
add(KotlinWasmTargetPreset(project, KotlinWasmTargetType.JS))
add(KotlinWasmTargetPreset(project, KotlinWasmTargetType.WASI))
add(project.objects.newInstance(KotlinAndroidTargetPreset::class.java, project))
add(KotlinJvmWithJavaTargetPreset(project))
@@ -12,12 +12,14 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import javax.inject.Inject
interface HasBinaries<out T : DomainObjectSet<*>> {
val binaries: T
}
abstract class KotlinTargetWithBinaries<T : KotlinCompilation<*>, out R : DomainObjectSet<*>> @Inject constructor(
project: Project,
platformType: KotlinPlatformType
) : KotlinOnlyTarget<T>(project, platformType) {
abstract val binaries: R
) : KotlinOnlyTarget<T>(project, platformType), HasBinaries<R> {
fun binaries(configure: R.() -> Unit) {
binaries.configure()
}
@@ -12,7 +12,8 @@ import java.io.Serializable
// For Gradle attributes
@Suppress("EnumEntryName")
enum class KotlinWasmTargetAttribute : Named, Serializable {
js, wasi;
wasi,
js;
override fun getName(): String =
name
@@ -0,0 +1,18 @@
/*
* 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.targets.js
enum class KotlinWasmTargetType {
WASI,
JS;
}
fun KotlinWasmTargetType.toAttribute(): KotlinWasmTargetAttribute {
return when(this) {
KotlinWasmTargetType.WASI -> KotlinWasmTargetAttribute.wasi
KotlinWasmTargetType.JS -> KotlinWasmTargetAttribute.js
}
}
@@ -33,7 +33,7 @@ interface KotlinJsSubTargetContainerDsl : KotlinTarget {
fun whenBrowserConfigured(body: KotlinJsBrowserDsl.() -> Unit)
}
interface KotlinJsTargetDsl : KotlinTarget {
interface KotlinJsTargetDsl : KotlinTarget, KotlinTargetWithNodeJsDsl {
var moduleName: String?
fun browser() = browser { }
@@ -44,14 +44,6 @@ interface KotlinJsTargetDsl : KotlinTarget {
}
}
fun nodejs() = nodejs { }
fun nodejs(body: KotlinJsNodeDsl.() -> Unit)
fun nodejs(fn: Action<KotlinJsNodeDsl>) {
nodejs {
fn.execute(this)
}
}
fun useCommonJs()
fun useEsModules()
@@ -74,6 +66,16 @@ interface KotlinJsTargetDsl : KotlinTarget {
override val compilations: NamedDomainObjectContainer<out KotlinJsCompilation>
}
interface KotlinTargetWithNodeJsDsl {
fun nodejs() = nodejs { }
fun nodejs(body: KotlinJsNodeDsl.() -> Unit)
fun nodejs(fn: Action<KotlinJsNodeDsl>) {
nodejs {
fn.execute(this)
}
}
}
interface KotlinJsSubTargetDsl {
@ExperimentalDistributionDsl
fun distribution(body: Action<Distribution>)
@@ -0,0 +1,43 @@
/*
* Copyright 2010-2022 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.targets.js.dsl
import org.gradle.api.Action
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
import org.jetbrains.kotlin.gradle.targets.js.binaryen.BinaryenExec
import org.jetbrains.kotlin.gradle.targets.js.d8.D8Exec
interface KotlinWasmSubTargetContainerDsl : KotlinTarget {
val d8: KotlinWasmD8Dsl
val isD8Configured: Boolean
fun whenD8Configured(body: KotlinWasmD8Dsl.() -> Unit)
fun whenBinaryenApplied(body: (BinaryenExec.() -> Unit) -> Unit)
}
interface KotlinWasmJsTargetDsl : KotlinWasmTargetDsl, KotlinJsTargetDsl {
fun d8() = d8 { }
fun d8(body: KotlinWasmD8Dsl.() -> Unit)
fun d8(fn: Action<KotlinWasmD8Dsl>) {
d8 {
fn.execute(this)
}
}
fun applyBinaryen() = applyBinaryen { }
fun applyBinaryen(body: BinaryenExec.() -> Unit)
fun applyBinaryen(fn: Action<BinaryenExec>) {
applyBinaryen {
fn.execute(this)
}
}
}
interface KotlinWasmD8Dsl : KotlinJsSubTargetDsl {
fun runTask(body: D8Exec.() -> Unit)
}
@@ -5,39 +5,9 @@
package org.jetbrains.kotlin.gradle.targets.js.dsl
import org.gradle.api.Action
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
import org.jetbrains.kotlin.gradle.targets.js.binaryen.BinaryenExec
import org.jetbrains.kotlin.gradle.targets.js.d8.D8Exec
import org.jetbrains.kotlin.gradle.targets.js.KotlinWasmTargetType
interface KotlinWasmSubTargetContainerDsl : KotlinTarget {
val d8: KotlinWasmD8Dsl
val isD8Configured: Boolean
fun whenD8Configured(body: KotlinWasmD8Dsl.() -> Unit)
fun whenBinaryenApplied(body: (BinaryenExec.() -> Unit) -> Unit)
}
interface KotlinWasmTargetDsl : KotlinJsTargetDsl {
fun d8() = d8 { }
fun d8(body: KotlinWasmD8Dsl.() -> Unit)
fun d8(fn: Action<KotlinWasmD8Dsl>) {
d8 {
fn.execute(this)
}
}
fun applyBinaryen() = applyBinaryen { }
fun applyBinaryen(body: BinaryenExec.() -> Unit)
fun applyBinaryen(fn: Action<BinaryenExec>) {
applyBinaryen {
fn.execute(this)
}
}
}
interface KotlinWasmD8Dsl : KotlinJsSubTargetDsl {
fun runTask(body: D8Exec.() -> Unit)
interface KotlinWasmTargetDsl : KotlinTarget {
val wasmTargetType: KotlinWasmTargetType?
}
@@ -0,0 +1,14 @@
/*
* Copyright 2010-2022 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.targets.js.dsl
import org.jetbrains.kotlin.gradle.plugin.mpp.HasBinaries
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsBinaryContainer
interface KotlinWasmWasiTargetDsl :
KotlinWasmTargetDsl,
KotlinTargetWithNodeJsDsl,
HasBinaries<KotlinJsBinaryContainer>
@@ -29,3 +29,4 @@ internal const val PER_MODULE = "-Xir-per-module"
internal const val PER_MODULE_OUTPUT_NAME = "-Xir-per-module-output-name"
internal const val WASM_BACKEND = "-Xwasm"
internal const val WASM_WASI_MODE = "-Xwasm-wasi-mode"
@@ -5,16 +5,18 @@
package org.jetbrains.kotlin.gradle.targets.js.ir
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinCompilationFactory
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinOnlyTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.DefaultKotlinCompilationFriendPathsResolver
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.factory.JsIrCompilationSourceSetsContainerFactory
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.factory.JsKotlinCompilationDependencyConfigurationsFactory
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.factory.KotlinCompilationImplFactory
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.factory.KotlinJsCompilerOptionsFactory
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.DefaultKotlinCompilationPreConfigure
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.factory.*
import org.jetbrains.kotlin.gradle.plugin.mpp.isMain
import org.jetbrains.kotlin.gradle.plugin.mpp.sourcesJarTask
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
class KotlinJsIrCompilationFactory internal constructor(
override val target: KotlinOnlyTarget<KotlinJsIrCompilation>
override val target: KotlinOnlyTarget<KotlinJsIrCompilation>,
) : KotlinCompilationFactory<KotlinJsIrCompilation> {
override val itemClass: Class<KotlinJsIrCompilation>
get() = KotlinJsIrCompilation::class.java
@@ -27,7 +29,14 @@ class KotlinJsIrCompilationFactory internal constructor(
}
),
compilationSourceSetsContainerFactory = JsIrCompilationSourceSetsContainerFactory,
compilationDependencyConfigurationsFactory = JsKotlinCompilationDependencyConfigurationsFactory
compilationDependencyConfigurationsFactory = JsKotlinCompilationDependencyConfigurationsFactory,
preConfigureAction = DefaultKotlinCompilationPreConfigure + { compilation ->
if (compilation.platformType == KotlinPlatformType.wasm && compilation.isMain()) {
val artifactNameAppendix = (compilation.target as KotlinJsIrTarget).wasmDecamelizedDefaultNameOrNull()
?: compilation.target.targetName.toLowerCaseAsciiOnly()
sourcesJarTask(compilation, compilation.target.targetName, artifactNameAppendix)
}
}
)
override fun create(name: String): KotlinJsIrCompilation = target.project.objects.newInstance(
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinTargetWithTests
import org.jetbrains.kotlin.gradle.plugin.mpp.isMain
import org.jetbrains.kotlin.gradle.plugin.whenEvaluated
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsPlatformTestRun
import org.jetbrains.kotlin.gradle.targets.js.KotlinWasmTargetType
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
@@ -33,7 +34,7 @@ import org.jetbrains.kotlin.gradle.utils.newFileProperty
abstract class KotlinJsIrSubTarget(
val target: KotlinJsIrTarget,
private val disambiguationClassifier: String
private val disambiguationClassifier: String,
) : KotlinJsSubTargetDsl {
val project get() = target.project
@@ -121,8 +122,8 @@ abstract class KotlinJsIrSubTarget(
KotlinJsBinaryMode.DEVELOPMENT
).single()
testJs.dependsOn(binary.linkSyncTask)
testJs.inputFileProperty.fileProvider(
val inputFileProperty = if (target.wasmTargetType != KotlinWasmTargetType.WASI) {
testJs.dependsOn(binary.linkSyncTask)
binary.linkSyncTask.flatMap { linkSyncTask ->
binary.linkTask.flatMap { linkTask ->
linkTask.outputFileProperty.map { file ->
@@ -130,6 +131,15 @@ abstract class KotlinJsIrSubTarget(
}
}
}
} else {
testJs.dependsOn(binary.linkTask)
binary.linkTask.flatMap { linkTask ->
linkTask.outputFileProperty
}
}
testJs.inputFileProperty.fileProvider(
inputFileProperty
)
configureTestDependencies(testJs)
@@ -238,7 +248,7 @@ abstract class KotlinJsIrSubTarget(
internal inline fun <reified T : Task> registerSubTargetTask(
name: String,
args: List<Any> = emptyList(),
noinline body: (T) -> (Unit)
noinline body: (T) -> (Unit),
): TaskProvider<T> =
project.registerTask(name, args) {
it.group = taskGroupName
@@ -10,24 +10,32 @@ import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.tasks.TaskProvider
import org.jetbrains.kotlin.gradle.dsl.KotlinJsOptions
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.AbstractKotlinTargetConfigurator.Companion.runTaskNameSuffix
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.Companion.MAIN_COMPILATION_NAME
import org.jetbrains.kotlin.gradle.plugin.mpp.DefaultKotlinUsageContext
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinTargetWithBinaries
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsageContext
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
import org.jetbrains.kotlin.gradle.plugin.mpp.*
import org.jetbrains.kotlin.gradle.targets.js.JsAggregatingExecutionSource
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsReportAggregatingTestRun
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsTarget
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.*
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmResolverPlugin
import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject
import org.jetbrains.kotlin.gradle.targets.js.typescript.TypeScriptValidationTask
import org.jetbrains.kotlin.gradle.tasks.locateOrRegisterTask
import org.jetbrains.kotlin.gradle.tasks.registerTask
import org.jetbrains.kotlin.gradle.utils.dashSeparatedName
import org.jetbrains.kotlin.gradle.utils.decamelize
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
import org.jetbrains.kotlin.gradle.utils.setProperty
import org.jetbrains.kotlin.util.capitalizeDecapitalize.capitalizeAsciiOnly
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
import org.jetbrains.kotlin.utils.addIfNotNull
import javax.inject.Inject
abstract class KotlinJsIrTarget
@@ -35,14 +43,16 @@ abstract class KotlinJsIrTarget
constructor(
project: Project,
platformType: KotlinPlatformType,
internal val mixedMode: Boolean
internal val mixedMode: Boolean,
) :
KotlinTargetWithBinaries<KotlinJsIrCompilation, KotlinJsBinaryContainer>(project, platformType),
KotlinTargetWithTests<JsAggregatingExecutionSource, KotlinJsReportAggregatingTestRun>,
KotlinJsTargetDsl,
KotlinWasmTargetDsl,
KotlinWasmJsTargetDsl,
KotlinWasmWasiTargetDsl,
KotlinJsSubTargetContainerDsl,
KotlinWasmSubTargetContainerDsl {
private val propertiesProvider = PropertiesProvider(project)
override lateinit var testRuns: NamedDomainObjectContainer<KotlinJsReportAggregatingTestRun>
internal set
@@ -50,6 +60,9 @@ constructor(
open var isMpp: Boolean? = null
internal set
override var wasmTargetType: KotlinWasmTargetType? = null
internal set
var legacyTarget: KotlinJsTarget? = null
internal set
@@ -61,6 +74,38 @@ constructor(
field = value
}
override val kotlinComponents: Set<KotlinTargetComponent> by lazy {
val mainCompilation = compilations.getByName(KotlinCompilation.MAIN_COMPILATION_NAME)
val usageContexts = createUsageContexts(mainCompilation).toMutableSet()
val componentName =
if (project.kotlinExtension is KotlinMultiplatformExtension)
targetName
else PRIMARY_SINGLE_COMPONENT_NAME
usageContexts.addIfNotNull(
createSourcesJarAndUsageContextIfPublishable(
producingCompilation = mainCompilation,
componentName = componentName,
artifactNameAppendix = wasmDecamelizedDefaultNameOrNull() ?: dashSeparatedName(targetName.toLowerCaseAsciiOnly())
)
)
val result = createKotlinVariant(componentName, mainCompilation, usageContexts)
setOf(result)
}
override fun createKotlinVariant(
componentName: String,
compilation: KotlinCompilation<*>,
usageContexts: Set<DefaultKotlinUsageContext>,
): KotlinVariant {
return super.createKotlinVariant(componentName, compilation, usageContexts).apply {
artifactTargetName = wasmDecamelizedDefaultNameOrNull() ?: componentName
}
}
override fun createUsageContexts(producingCompilation: KotlinCompilation<*>): Set<DefaultKotlinUsageContext> {
val usageContexts = super.createUsageContexts(producingCompilation)
@@ -211,7 +256,11 @@ constructor(
//node.js
private val nodejsLazyDelegate = lazy {
commonLazy
if (wasmTargetType != KotlinWasmTargetType.WASI) {
commonLazy
} else {
NodeJsRootPlugin.apply(project.rootProject)
}
project.objects.newInstance(KotlinNodeJsIr::class.java, this).also {
it.configureSubTarget()
nodejsConfiguredHandlers.forEach { handler ->
@@ -341,3 +390,14 @@ constructor(
}
}
}
fun KotlinJsIrTarget.wasmDecamelizedDefaultNameOrNull(): String? = if (platformType == KotlinPlatformType.wasm) {
val defaultWasmTargetName = wasmTargetType?.let {
KotlinWasmTargetPreset.WASM_PRESET_NAME + it.name.toLowerCaseAsciiOnly().capitalizeAsciiOnly()
}
defaultWasmTargetName
?.takeIf {
targetName == defaultWasmTargetName
}?.decamelize()
} else null
@@ -13,13 +13,16 @@ import org.jetbrains.kotlin.gradle.dsl.JsModuleKind
import org.jetbrains.kotlin.gradle.dsl.JsSourceMapEmbedMode
import org.jetbrains.kotlin.gradle.dsl.KotlinJsCompilerOptions
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.internal.BasePluginConfiguration
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages
import org.jetbrains.kotlin.gradle.plugin.mpp.isMain
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.libsDirectory
import org.jetbrains.kotlin.gradle.plugin.mpp.sourcesJarTask
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsReportAggregatingTestRun
import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider
import org.jetbrains.kotlin.gradle.testing.internal.kotlinTestRegistry
import org.jetbrains.kotlin.gradle.testing.testTaskName
import org.jetbrains.kotlin.gradle.utils.decamelize
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
open class KotlinJsIrTargetConfigurator :
KotlinOnlyTargetConfigurator<KotlinJsIrCompilation, KotlinJsIrTarget>(true),
@@ -73,6 +76,14 @@ open class KotlinJsIrTargetConfigurator :
configure {
it.archiveExtension.set(KLIB_TYPE)
it.destinationDirectory.set(libsDirectory)
if (target.platformType == KotlinPlatformType.wasm) {
if (target.wasmDecamelizedDefaultNameOrNull() != null) {
target.disambiguationClassifier?.let { classifier ->
it.archiveAppendix.set(classifier.decamelize())
}
}
}
}
}
}
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.gradle.targets.js.ir
import org.gradle.api.Action
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import org.jetbrains.kotlin.gradle.targets.js.KotlinWasmTargetType
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsNodeDsl
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsExec
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin.Companion.kotlinNodeJsExtension
@@ -31,6 +32,12 @@ abstract class KotlinNodeJsIr @Inject constructor(target: KotlinJsIrTarget) :
project.tasks.withType<NodeJsExec>().named(runTaskName).configure(body)
}
override fun configureRun(compilation: KotlinJsIrCompilation) {
if (target.wasmTargetType != KotlinWasmTargetType.WASI) {
super.configureRun(compilation)
}
}
override fun locateOrRegisterRunTask(binary: JsIrBinary, name: String) {
if (project.locateTask<NodeJsExec>(name) != null) return
@@ -51,11 +58,13 @@ abstract class KotlinNodeJsIr @Inject constructor(target: KotlinJsIrTarget) :
}
override fun configureTestDependencies(test: KotlinJsTest) {
test.dependsOn(
nodeJsTaskProviders.npmInstallTaskProvider,
nodeJsTaskProviders.storeYarnLockTaskProvider,
nodeJsTaskProviders.nodeJsSetupTaskProvider
)
if (target.wasmTargetType != KotlinWasmTargetType.WASI) {
test.dependsOn(
nodeJsTaskProviders.npmInstallTaskProvider,
nodeJsTaskProviders.storeYarnLockTaskProvider,
nodeJsTaskProviders.nodeJsSetupTaskProvider
)
}
}
override fun configureDefaultTestFramework(test: KotlinJsTest) {
@@ -8,13 +8,16 @@ package org.jetbrains.kotlin.gradle.targets.js.ir
import org.gradle.api.Project
import org.jetbrains.kotlin.gradle.DeprecatedTargetPresetApi
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinCompilationFactory
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinOnlyTargetPreset
import org.jetbrains.kotlin.gradle.targets.js.KotlinWasmTargetType
import org.jetbrains.kotlin.util.capitalizeDecapitalize.capitalizeAsciiOnly
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
@DeprecatedTargetPresetApi
class KotlinWasmTargetPreset(
project: Project,
private val targetType: KotlinWasmTargetType
) : KotlinOnlyTargetPreset<KotlinJsIrTarget, KotlinJsIrCompilation>(project) {
override val platformType: KotlinPlatformType = KotlinPlatformType.wasm
@@ -25,6 +28,7 @@ class KotlinWasmTargetPreset(
val irTarget = project.objects.newInstance(KotlinJsIrTarget::class.java, project, KotlinPlatformType.wasm, false)
irTarget.isMpp = true
irTarget.wasmTargetType = targetType
return irTarget
}
@@ -32,7 +36,7 @@ class KotlinWasmTargetPreset(
override fun createKotlinTargetConfigurator(): AbstractKotlinTargetConfigurator<KotlinJsIrTarget> =
KotlinJsIrTargetConfigurator()
override fun getName(): String = WASM_PRESET_NAME
override fun getName(): String = WASM_PRESET_NAME + targetType.name.toLowerCaseAsciiOnly().capitalizeAsciiOnly()
public override fun createCompilationFactory(
forTarget: KotlinJsIrTarget
@@ -40,6 +44,6 @@ class KotlinWasmTargetPreset(
KotlinJsIrCompilationFactory(forTarget)
companion object {
private const val WASM_PRESET_NAME = "wasm"
internal const val WASM_PRESET_NAME = "wasm"
}
}
@@ -37,8 +37,10 @@ open class NpmProject(@Transient val compilation: KotlinJsCompilation) : Seriali
buildNpmProjectName()
}
@Transient
val nodeJs = project.rootProject.kotlinNodeJsExtension
@delegate:Transient
val nodeJs by lazy {
project.rootProject.kotlinNodeJsExtension
}
val dir: File by lazy {
nodeJs.projectPackagesDir.resolve(name)
@@ -75,7 +77,9 @@ open class NpmProject(@Transient val compilation: KotlinJsCompilation) : Seriali
val publicPackageJsonTaskName: String
get() = compilation.disambiguateName(PublicPackageJsonTask.NAME)
internal val modules = NpmProjectModules(dir)
internal val modules by lazy {
NpmProjectModules(dir)
}
private val nodeExecutable by lazy {
nodeJs.requireConfigured().nodeExecutable
@@ -42,8 +42,6 @@ constructor(
private val nodeExecutable by project.provider { nodeJs.requireConfigured().nodeExecutable }
private val npmProjectDir by project.provider { compilation.npmProject.dir }
@Input
var environment = mutableMapOf<String, String>()
@@ -159,7 +157,7 @@ constructor(
override fun createTestExecutionSpec(): TCServiceMessagesTestExecutionSpec {
val forkOptions = DefaultProcessForkOptions(fileResolver)
forkOptions.workingDir = npmProjectDir
forkOptions.workingDir = testFramework!!.workingDir.toFile()
forkOptions.executable = nodeExecutable
environment.forEach { (key, value) ->
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.gradle.targets.js.testing
import org.gradle.process.ProcessForkOptions
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecutionSpec
import org.jetbrains.kotlin.gradle.targets.js.npm.RequiresNpmDependencies
import java.nio.file.Path
interface KotlinJsTestFramework : RequiresNpmDependencies {
val settingsState: String
@@ -18,4 +19,6 @@ interface KotlinJsTestFramework : RequiresNpmDependencies {
nodeJsArgs: MutableList<String>,
debug: Boolean
): TCServiceMessagesTestExecutionSpec
val workingDir: Path
}
@@ -15,9 +15,11 @@ import org.jetbrains.kotlin.gradle.targets.js.RequiredKotlinJsDependency
import org.jetbrains.kotlin.gradle.targets.js.addWasmExperimentalArguments
import org.jetbrains.kotlin.gradle.targets.js.d8.D8RootPlugin
import org.jetbrains.kotlin.gradle.targets.js.internal.parseNodeJsStackTraceAsJvm
import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject
import org.jetbrains.kotlin.gradle.targets.js.writeWasmUnitTestRunner
import org.jetbrains.kotlin.gradle.utils.doNotTrackStateCompat
import org.jetbrains.kotlin.gradle.utils.getValue
import java.nio.file.Path
internal class KotlinWasmD8(private val kotlinJsTest: KotlinJsTest) : KotlinJsTestFramework {
override val settingsState: String = "KotlinWasmD8"
@@ -29,6 +31,10 @@ internal class KotlinWasmD8(private val kotlinJsTest: KotlinJsTest) : KotlinJsTe
private val d8 = D8RootPlugin.apply(project.rootProject)
private val d8Executable by project.provider { d8.requireConfigured().executablePath }
private val isTeamCity = project.providers.gradleProperty(TCServiceMessagesTestExecutor.TC_PROJECT_PROPERTY)
private val npmProjectDir by project.provider { compilation.npmProject.dir }
override val workingDir: Path
get() = npmProjectDir.toPath()
init {
kotlinJsTest.doNotTrackStateCompat("Should always re-run for WASM")
@@ -5,16 +5,22 @@
package org.jetbrains.kotlin.gradle.targets.js.testing
import org.gradle.api.Project
import org.gradle.process.ProcessForkOptions
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesClientSettings
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecutionSpec
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecutor
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation
import org.jetbrains.kotlin.gradle.targets.js.KotlinWasmTargetType
import org.jetbrains.kotlin.gradle.targets.js.RequiredKotlinJsDependency
import org.jetbrains.kotlin.gradle.targets.js.addWasmExperimentalArguments
import org.jetbrains.kotlin.gradle.targets.js.internal.parseNodeJsStackTraceAsJvm
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTarget
import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject
import org.jetbrains.kotlin.gradle.targets.js.writeWasmUnitTestRunner
import org.jetbrains.kotlin.gradle.utils.doNotTrackStateCompat
import org.jetbrains.kotlin.gradle.utils.getValue
import java.nio.file.Path
internal class KotlinWasmNode(private val kotlinJsTest: KotlinJsTest) : KotlinJsTestFramework {
override val settingsState: String = "KotlinWasmNode"
@@ -22,6 +28,23 @@ internal class KotlinWasmNode(private val kotlinJsTest: KotlinJsTest) : KotlinJs
override val compilation: KotlinJsCompilation = kotlinJsTest.compilation
private val isTeamCity = compilation.target.project.providers.gradleProperty(TCServiceMessagesTestExecutor.TC_PROJECT_PROPERTY)
@Transient
private val target: KotlinJsIrTarget = compilation.target as KotlinJsIrTarget
@Transient
private val project: Project = target.project
private val npmProjectDir by project.provider { compilation.npmProject.dir }
private val wasmTargetType: KotlinWasmTargetType? = target.wasmTargetType
override val workingDir: Path
get() = if (wasmTargetType != KotlinWasmTargetType.WASI) {
npmProjectDir.toPath()
} else {
kotlinJsTest.inputFileProperty.get().asFile.toPath().parent
}
init {
kotlinJsTest.doNotTrackStateCompat("Should always re-run for WASM")
}
@@ -36,10 +36,12 @@ import org.jetbrains.kotlin.gradle.targets.js.testing.*
import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig
import org.jetbrains.kotlin.gradle.tasks.KotlinTest
import org.jetbrains.kotlin.gradle.utils.appendLine
import org.jetbrains.kotlin.gradle.utils.getValue
import org.jetbrains.kotlin.gradle.utils.property
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
import org.slf4j.Logger
import java.io.File
import java.nio.file.Path
class KotlinKarma(
@Transient override val compilation: KotlinJsCompilation,
@@ -70,9 +72,14 @@ class KotlinKarma(
}
private val isTeamCity = project.providers.gradleProperty(TCServiceMessagesTestExecutor.TC_PROJECT_PROPERTY)
private val npmProjectDir by project.provider { npmProject.dir }
override val requiredNpmDependencies: Set<RequiredKotlinJsDependency>
get() = requiredDependencies + webpackConfig.getRequiredDependencies(versions)
override val workingDir: Path
get() = npmProjectDir.toPath()
override fun getPath() = "$basePath:kotlinKarma"
override val settingsState: String
@@ -20,6 +20,8 @@ import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject
import org.jetbrains.kotlin.gradle.targets.js.testing.KotlinJsTest
import org.jetbrains.kotlin.gradle.targets.js.testing.KotlinJsTestFramework
import org.jetbrains.kotlin.gradle.targets.js.testing.KotlinTestRunnerCliArgs
import org.jetbrains.kotlin.gradle.utils.getValue
import java.nio.file.Path
class KotlinMocha(@Transient override val compilation: KotlinJsCompilation, private val basePath: String) :
KotlinJsTestFramework {
@@ -28,6 +30,10 @@ class KotlinMocha(@Transient override val compilation: KotlinJsCompilation, priv
private val npmProject = compilation.npmProject
private val versions = project.rootProject.kotlinNodeJsExtension.versions
private val isTeamCity = project.providers.gradleProperty(TCServiceMessagesTestExecutor.TC_PROJECT_PROPERTY)
private val npmProjectDir by project.provider { npmProject.dir }
override val workingDir: Path
get() = npmProjectDir.toPath()
override val settingsState: String
get() = "mocha"
@@ -36,6 +36,7 @@ import org.jetbrains.kotlin.gradle.tasks.registerTask
import org.jetbrains.kotlin.gradle.utils.*
import org.jetbrains.kotlin.statistics.metrics.BooleanMetrics
import org.jetbrains.kotlin.tooling.core.extrasLazyProperty
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
internal const val COMMON_MAIN_ELEMENTS_CONFIGURATION_NAME = "commonMainMetadataElements"
@@ -152,6 +153,10 @@ class KotlinMetadataTargetConfigurator :
if (target.project.isCompatibilityMetadataVariantEnabled) {
allMetadataJar.archiveClassifier.set("all")
}
target.disambiguationClassifier?.let { classifier ->
allMetadataJar.archiveAppendix.set(classifier.toLowerCaseAsciiOnly())
}
}
if (target.project.isCompatibilityMetadataVariantEnabled) {
@@ -6,6 +6,8 @@
package org.jetbrains.kotlin.gradle.tasks.configuration
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationInfo
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import org.jetbrains.kotlin.gradle.targets.js.KotlinWasmTargetType
import org.jetbrains.kotlin.gradle.targets.js.internal.LibraryFilterCachingService
import org.jetbrains.kotlin.gradle.targets.js.ir.*
import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile
@@ -103,5 +105,13 @@ internal open class BaseKotlin2JsCompileConfig<TASK : Kotlin2JsCompile>(
add("$KLIB_MODULE_NAME=${project.klibModuleName(baseName)}")
}
}
if (compilation.platformType == KotlinPlatformType.wasm) {
add(WASM_BACKEND)
val wasmTargetType = ((compilation.origin as KotlinJsIrCompilation).target as KotlinJsIrTarget).wasmTargetType!!
if (wasmTargetType == KotlinWasmTargetType.WASI) {
add(WASM_WASI_MODE)
}
}
}
}
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.gradle.tasks.configuration
import org.gradle.api.InvalidUserDataException
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationInfo
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import org.jetbrains.kotlin.gradle.targets.js.KotlinWasmTargetType
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsBinaryMode
import org.jetbrains.kotlin.gradle.targets.js.ir.*
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProject
@@ -98,6 +99,10 @@ internal open class KotlinJsIrLinkConfig(
if (compilation.platformType == KotlinPlatformType.wasm) {
add(WASM_BACKEND)
val wasmTargetType = ((compilation.origin as KotlinJsIrCompilation).target as KotlinJsIrTarget).wasmTargetType!!
if (wasmTargetType == KotlinWasmTargetType.WASI) {
add(WASM_WASI_MODE)
}
}
}
}
@@ -33,17 +33,17 @@ class WasmDependencyResolutionSmokeTest {
project.repositories.mavenLocal()
project.repositories.mavenCentralCacheRedirector()
}
producer.multiplatformExtension.apply {
jvm()
js(IR) { browser() }
wasm()
wasmJs()
}
consumer.multiplatformExtension.apply {
jvm()
js(IR) { browser() }
wasm()
wasmJs()
sourceSets.commonMain.dependencies {
implementation(producer)
@@ -59,17 +59,17 @@ class WasmDependencyResolutionSmokeTest {
binaryCoordinates(Regex(".*stdlib-common.*"))
)
consumer.kotlinIdeMultiplatformImport.resolveDependencies("wasmMain").assertMatches(
consumer.kotlinIdeMultiplatformImport.resolveDependencies("wasmJsMain").assertMatches(
dependsOnDependency(":consumer/commonMain"),
projectArtifactDependency(type = Regular, ":producer", FilePathRegex(".*/producer-wasm.klib")),
projectArtifactDependency(type = Regular, ":producer", FilePathRegex(".*/producer-wasm-js.klib")),
binaryCoordinates(Regex(".*stdlib-wasm.*"))
)
consumer.kotlinIdeMultiplatformImport.resolveDependencies("wasmTest").assertMatches(
consumer.kotlinIdeMultiplatformImport.resolveDependencies("wasmJsTest").assertMatches(
friendSourceDependency(":consumer/commonMain"),
friendSourceDependency(":consumer/wasmMain"),
friendSourceDependency(":consumer/wasmJsMain"),
dependsOnDependency(":consumer/commonTest"),
projectArtifactDependency(type = Regular, ":producer", FilePathRegex(".*/producer-wasm.klib")),
projectArtifactDependency(type = Regular, ":producer", FilePathRegex(".*/producer-wasm-js.klib")),
binaryCoordinates(Regex(".*stdlib-wasm.*"))
)
}
@@ -163,7 +163,7 @@ class ConfigurationsTest : MultiplatformExtensionTest() {
js("nodeJs", KotlinJsCompilerType.IR) { attributes { attribute(jsAttribute, "nodeJs") } }
js("browser", KotlinJsCompilerType.IR) { attributes { attribute(jsAttribute, "browser") } }
@OptIn(ExperimentalWasmDsl::class)
wasm()
wasmJs()
val allJs = sourceSets.create("allJs")
targets.getByName("nodeJs").compilations.getByName("main").defaultSourceSet.dependsOn(allJs)
@@ -187,7 +187,7 @@ class ConfigurationsTest : MultiplatformExtensionTest() {
// WASM
val actualWasmConfigurations = targetSpecificConfigurationsToCheck
.map { project.configurations.getByName("wasm$it") }
.map { project.configurations.getByName("wasmJs$it") }
.filter { it.attributes.contains(KotlinJsCompilerAttribute.jsCompilerAttribute) }
assertEquals(
@@ -324,7 +324,7 @@ class KotlinHierarchyDslTest {
}
}
kotlin.wasm()
kotlin.wasmJs()
kotlin.js()
assertEquals(
@@ -333,7 +333,7 @@ class KotlinHierarchyDslTest {
)
assertEquals(
stringSetOf("jsMain", "wasmMain"),
stringSetOf("jsMain", "wasmJsMain"),
kotlin.dependingSourceSetNames("webMain")
)
}
@@ -353,7 +353,7 @@ class KotlinHierarchyDslTest {
}
}
kotlin.wasm()
kotlin.wasmJs()
kotlin.js()
kotlin.jvm()
kotlin.linuxX64()
@@ -369,7 +369,7 @@ class KotlinHierarchyDslTest {
)
assertEquals(
stringSetOf("wasmMain", "linuxX64Main"),
stringSetOf("wasmJsMain", "linuxX64Main"),
kotlin.dependingSourceSetNames("wasmAndLinuxMain")
)
}