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
|
#!/usr/bin/env bash
# Nim -> WebAssembly, for the Flutter web build of the example.
#
# Nothing is installed system-wide. tool/bin/emcc is a DotSlash file pinning
# emscripten by content hash; DotSlash fetches it on first run (~285 MB) and
# caches it under ~/.cache/dotslash. Only `dotslash` itself has to be on PATH.
#
# Output lands in example/web/ and is loaded by a <script> tag in
# example/web/index.html. Re-run after editing src/nimflutter.nim.
set -euo pipefail
cd "$(dirname "$0")/.."
nim_bin="${NIM:-nim}"
command -v "$nim_bin" >/dev/null || {
echo "Nim compiler not on PATH (set NIM=/path/to/nim)"; exit 1; }
command -v node >/dev/null || { echo "node not on PATH (emscripten needs it)"; exit 1; }
command -v dotslash >/dev/null || {
echo "dotslash not on PATH — https://dotslash-cli.com/docs/installation/" >&2
exit 1
}
nim_lib="$(dirname "$(dirname "$(command -v "$nim_bin")")")/lib"
out=example/web
mkdir -p build "$out"
# Fetches on first call, then just prints the cached path.
emcc_path="$(dotslash -- fetch tool/bin/emcc)"
root="$(dirname "$(dirname "$emcc_path")")"
# emcc wants a config file; the DotSlash cache is content-addressed and must
# stay read-only, so the config and the sysroot cache live under build/.
cat > build/emscripten.config <<CONFIG
LLVM_ROOT = '$root/bin'
BINARYEN_ROOT = '$root'
NODE_JS = '$(command -v node)'
CACHE = '$PWD/build/emcache'
CONFIG
export EM_CONFIG="$PWD/build/emscripten.config"
# Nim emits C for the wasm32 target; emcc turns that into wasm. --threads:off
# because the emscripten module is single-threaded — bands still render, just
# sequentially (see supportsIsolateParallelism on the Dart side).
cache=build/nimcache_wasm
rm -rf "$cache"
"$nim_bin" c --compileOnly --nimcache:"$cache" --cpu:wasm32 --os:linux \
--mm:arc -d:danger --threads:off --noMain src/nimflutter.nim
# No -sGLOBAL_BASE here. The V build needed static data pushed above 1 MB to
# dodge a null-pointer heuristic in its builtin memcpy; Nim's runtime has no
# such guard, and a string round-trip through the default layout is verified
# by tool/test_wasm.mjs.
dotslash tool/bin/emcc "$cache"/*.c -I"$nim_lib" -O3 -o "$out/nimflutter.js" \
-sMODULARIZE=1 \
-sEXPORT_NAME=createNimFlutterModule \
-sENVIRONMENT=web,worker,node \
-sALLOW_MEMORY_GROWTH=1 \
-sEXPORTED_FUNCTIONS='["_nf_init","_nf_add","_nf_greet","_nf_free","_nf_mandelbrot","_malloc","_free"]' \
-sEXPORTED_RUNTIME_METHODS='["ccall","cwrap","UTF8ToString","stringToUTF8","lengthBytesUTF8","HEAPU8"]'
echo "built: $out/nimflutter.js ($(stat -c%s "$out/nimflutter.js") bytes)," \
"$out/nimflutter.wasm ($(stat -c%s "$out/nimflutter.wasm") bytes)"
|