1 import com.vanniktech.maven.publish.JavadocJar.Empty
2 import com.vanniktech.maven.publish.KotlinMultiplatform
3 import com.vanniktech.maven.publish.MavenPublishBaseExtension
4
<lambda>null5 plugins {
6 kotlin("multiplatform")
7 // TODO: Restore Dokka once this issue is resolved.
8 // https://github.com/Kotlin/dokka/issues/3038
9 // id("org.jetbrains.dokka")
10 id("com.vanniktech.maven.publish.base")
11 id("build-support")
12 id("binary-compatibility-validator")
13 }
14
<lambda>null15 kotlin {
16 configureOrCreateWasmPlatform(
17 js = false,
18 wasi = true,
19 )
20 sourceSets {
21 all {
22 languageSettings.optIn("kotlin.wasm.unsafe.UnsafeWasmMemoryApi")
23 }
24 val wasmWasiMain by getting {
25 dependencies {
26 implementation(projects.okio)
27 }
28 }
29 val wasmWasiTest by getting {
30 dependencies {
31 implementation(projects.okioTestingSupport)
32 implementation(libs.kotlin.test)
33 }
34 }
35 }
36 }
37
<lambda>null38 configure<MavenPublishBaseExtension> {
39 // TODO: switch from 'Empty' to 'Dokka' once this issue is resolved.
40 // https://github.com/Kotlin/dokka/issues/3038
41 configure(
42 KotlinMultiplatform(javadocJar = Empty()),
43 )
44 }
45
46 /**
47 * Inspired by runner.mjs in kowasm, this rewrites the JavaScript bootstrap script to set up WASI.
48 *
49 * See also:
50 * * https://github.com/kowasm/kowasm
51 * * https://github.com/nodejs/node/blob/main/doc/api/wasi.md
52 *
53 * This task overwrites the output of `compileTestDevelopmentExecutableKotlinWasmWasi` and must run
54 * after that task. It must also run before the WASM test execution tasks that read this script.
55 *
56 * Note that this includes which file paths are exposed to the WASI sandbox.
57 */
<lambda>null58 val injectWasiInit by tasks.creating {
59 dependsOn("compileTestDevelopmentExecutableKotlinWasmWasi")
60 val moduleName = "${rootProject.name}-${project.name}-wasm-wasi-test"
61
62 val entryPointMjs = File(
63 buildDir,
64 "compileSync/wasmWasi/test/testDevelopmentExecutable/kotlin/$moduleName.mjs"
65 )
66
67 outputs.file(entryPointMjs)
68
69 doLast {
70 val base = File(System.getProperty("java.io.tmpdir"), "okio-wasifilesystem-test")
71 val baseA = File(base, "a")
72 val baseB = File(base, "b")
73 base.mkdirs()
74 baseA.mkdirs()
75 baseB.mkdirs()
76
77 entryPointMjs.writeText(
78 """
79 import { WASI } from 'wasi';
80 import { argv, env } from 'node:process';
81
82 export const wasi = new WASI({
83 version: 'preview1',
84 preopens: {
85 '/tmp': '$base',
86 '/a': '$baseA',
87 '/b': '$baseB'
88 }
89 });
90
91 const module = await import(/* webpackIgnore: true */'node:module');
92 const require = module.default.createRequire(import.meta.url);
93 const fs = require('fs');
94 const path = require('path');
95 const url = require('url');
96 const filepath = url.fileURLToPath(import.meta.url);
97 const dirpath = path.dirname(filepath);
98 const wasmBuffer = fs.readFileSync(path.resolve(dirpath, './$moduleName.wasm'));
99 const wasmModule = new WebAssembly.Module(wasmBuffer);
100 const wasmInstance = new WebAssembly.Instance(wasmModule, wasi.getImportObject());
101
102 wasi.initialize(wasmInstance);
103
104 export default wasmInstance.exports;
105 """.trimIndent()
106 )
107 }
108 }
<lambda>null109 tasks.named("wasmWasiNodeTest").configure {
110 dependsOn(injectWasiInit)
111 }
112