aboutsummaryrefslogtreecommitdiff
path: root/okio-wasifilesystem/build.gradle.kts
blob: aaf43faa160c2b34686fa98aab88c68f75a31b87 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import com.vanniktech.maven.publish.JavadocJar.Empty
import com.vanniktech.maven.publish.KotlinMultiplatform
import com.vanniktech.maven.publish.MavenPublishBaseExtension

plugins {
  kotlin("multiplatform")
  // TODO: Restore Dokka once this issue is resolved.
  //     https://github.com/Kotlin/dokka/issues/3038
  // id("org.jetbrains.dokka")
  id("com.vanniktech.maven.publish.base")
  id("build-support")
  id("binary-compatibility-validator")
}

kotlin {
  configureOrCreateWasmPlatform(
    js = false,
    wasi = true,
  )
  sourceSets {
    all {
      languageSettings.optIn("kotlin.wasm.unsafe.UnsafeWasmMemoryApi")
    }
    val wasmWasiMain by getting {
      dependencies {
        implementation(projects.okio)
      }
    }
    val wasmWasiTest by getting {
      dependencies {
        implementation(projects.okioTestingSupport)
        implementation(libs.kotlin.test)
      }
    }
  }
}

configure<MavenPublishBaseExtension> {
  // TODO: switch from 'Empty' to 'Dokka' once this issue is resolved.
  //     https://github.com/Kotlin/dokka/issues/3038
  configure(
    KotlinMultiplatform(javadocJar = Empty()),
  )
}

/**
 * Inspired by runner.mjs in kowasm, this rewrites the JavaScript bootstrap script to set up WASI.
 *
 * See also:
 *  * https://github.com/kowasm/kowasm
 *  * https://github.com/nodejs/node/blob/main/doc/api/wasi.md
 *
 * This task overwrites the output of `compileTestDevelopmentExecutableKotlinWasmWasi` and must run
 * after that task. It must also run before the WASM test execution tasks that read this script.
 *
 * Note that this includes which file paths are exposed to the WASI sandbox.
 */
val injectWasiInit by tasks.creating {
  dependsOn("compileTestDevelopmentExecutableKotlinWasmWasi")
  val moduleName = "${rootProject.name}-${project.name}-wasm-wasi-test"

  val entryPointMjs = File(
    buildDir,
    "compileSync/wasmWasi/test/testDevelopmentExecutable/kotlin/$moduleName.mjs"
  )

  outputs.file(entryPointMjs)

  doLast {
    val base = File(System.getProperty("java.io.tmpdir"), "okio-wasifilesystem-test")
    val baseA = File(base, "a")
    val baseB = File(base, "b")
    base.mkdirs()
    baseA.mkdirs()
    baseB.mkdirs()

    entryPointMjs.writeText(
      """
      import { WASI } from 'wasi';
      import { argv, env } from 'node:process';

      export const wasi = new WASI({
        version: 'preview1',
        preopens: {
          '/tmp': '$base',
          '/a': '$baseA',
          '/b': '$baseB'
        }
      });

      const module = await import(/* webpackIgnore: true */'node:module');
      const require = module.default.createRequire(import.meta.url);
      const fs = require('fs');
      const path = require('path');
      const url = require('url');
      const filepath = url.fileURLToPath(import.meta.url);
      const dirpath = path.dirname(filepath);
      const wasmBuffer = fs.readFileSync(path.resolve(dirpath, './$moduleName.wasm'));
      const wasmModule = new WebAssembly.Module(wasmBuffer);
      const wasmInstance = new WebAssembly.Instance(wasmModule, wasi.getImportObject());

      wasi.initialize(wasmInstance);

      export default wasmInstance.exports;
      """.trimIndent()
    )
  }
}
tasks.named("wasmWasiNodeTest").configure {
  dependsOn(injectWasiInit)
}