mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-03 00:16:15 +00:00
cmd/gio: add -target=js support for creating webassembly packages
Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
+7
-3
@@ -14,10 +14,10 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
target = flag.String("target", "", "specify target (ios, tvos, android)")
|
||||
target = flag.String("target", "", "specify target (ios, tvos, android, js)")
|
||||
archNames = flag.String("arch", "", "specify architecture(s) to include")
|
||||
buildMode = flag.String("buildmode", "archive", "specify buildmode: archive or exe")
|
||||
destPath = flag.String("o", "", "output file (Android .aar or .apk file) or directory (iOS/tvOS .framework)")
|
||||
destPath = flag.String("o", "", "output file (Android .aar or .apk file) or directory (iOS/tvOS .framework or webassembly files)")
|
||||
appID = flag.String("appid", "org.gioui.app", "app identifier (for -buildmode=exe)")
|
||||
verbose = flag.Bool("v", false, "verbose output")
|
||||
)
|
||||
@@ -46,7 +46,7 @@ func main() {
|
||||
os.Exit(2)
|
||||
}
|
||||
switch *target {
|
||||
case "ios", "tvos", "android":
|
||||
case "ios", "tvos", "android", "js":
|
||||
default:
|
||||
errorf("invalid -target %s\n", *target)
|
||||
}
|
||||
@@ -64,6 +64,8 @@ func main() {
|
||||
pkg: pkg,
|
||||
}
|
||||
switch *target {
|
||||
case "js":
|
||||
bi.archs = []string{"wasm"}
|
||||
case "ios", "tvos":
|
||||
// Only 64-bit support.
|
||||
bi.archs = []string{"arm64", "amd64"}
|
||||
@@ -89,6 +91,8 @@ func build(bi *buildInfo) error {
|
||||
}
|
||||
defer os.RemoveAll(tmpDir)
|
||||
switch *target {
|
||||
case "js":
|
||||
return buildJS(bi)
|
||||
case "ios", "tvos":
|
||||
return buildIOS(tmpDir, *target, bi)
|
||||
case "android":
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
// SPDX-License-Identifier: Unlicense OR MIT
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
func buildJS(bi *buildInfo) error {
|
||||
out := *destPath
|
||||
if out == "" {
|
||||
out = filepath.Base(bi.pkg)
|
||||
}
|
||||
if err := os.MkdirAll(out, 0700); err != nil {
|
||||
return err
|
||||
}
|
||||
cmd := exec.Command(
|
||||
"go",
|
||||
"build",
|
||||
"-o", filepath.Join(out, "main.wasm"),
|
||||
bi.pkg,
|
||||
)
|
||||
cmd.Env = append(
|
||||
os.Environ(),
|
||||
"GOOS=js",
|
||||
"GOARCH=wasm",
|
||||
)
|
||||
_, err := runCmd(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
const indexhtml = `<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no">
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
<script src="wasm_exec.js"></script>
|
||||
<script>
|
||||
if (!WebAssembly.instantiateStreaming) { // polyfill
|
||||
WebAssembly.instantiateStreaming = async (resp, importObject) => {
|
||||
const source = await (await resp).arrayBuffer();
|
||||
return await WebAssembly.instantiate(source, importObject);
|
||||
};
|
||||
}
|
||||
|
||||
const go = new Go();
|
||||
WebAssembly.instantiateStreaming(fetch("main.wasm"), go.importObject).then((result) => {
|
||||
go.run(result.instance);
|
||||
});
|
||||
</script>
|
||||
<style>
|
||||
body,pre { margin:0;padding:0; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="giowindow"></div>
|
||||
</body>
|
||||
</html>`
|
||||
if err := ioutil.WriteFile(filepath.Join(out, "index.html"), []byte(indexhtml), 0600); err != nil {
|
||||
return err
|
||||
}
|
||||
goroot, err := runCmd(exec.Command("go", "env", "GOROOT"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
wasmjs := filepath.Join(goroot, "misc", "wasm", "wasm_exec.js")
|
||||
if _, err := os.Stat(wasmjs); err != nil {
|
||||
return fmt.Errorf("failed to find $GOROOT/misc/wasm/wasm_exec.js driver: %v", err)
|
||||
}
|
||||
return copyFile(filepath.Join(out, "wasm_exec.js"), wasmjs)
|
||||
}
|
||||
Reference in New Issue
Block a user