summaryrefslogtreecommitdiff
path: root/anthy/build-wasm.sh
blob: dfbafb0ba97fed5090e72548a04e9c466a1b95a8 (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
#!/bin/sh
# Build anthy as a WASI reactor module (wasm32-wasip1) for embedding in the plugin's JVM.
#
# Regenerates prebuilt/anthy.wasm. You only need this when anthy itself, the dictionary
# format, or the embedder API (src/anthy_wasm.c) changes: the generated module is
# committed, so a plain checkout builds the plugin without any of this toolchain.
#
# Requires: clang with a wasm32 target, a WASI sysroot, and an anthy-9100 source tree.
#   ANTHY_SRC   anthy source tree          (default /ROM/anthy-build/anthy-9100)
#   SYSROOT     WASI sysroot               (default /ROM/toolchains/wasi-sdk-25.0/share/wasi-sysroot)
#   RESDIR      clang resource dir         (default /ROM/toolchains/wasi-sdk-25.0/lib/clang/19)
#   CC          compiler                   (default /usr/local/llvm19/bin/clang)
#
# Why a reactor: the target is a library called from Java, not a command line tool, so there
# is no main(). The host instantiates, calls _initialize (runs libc ctors), then calls the
# lcanthy_* entry points in src/anthy_wasm.c.
#
# ★ Sysroot choice matters: the FreeBSD port's wasi-libc19 libc.a is built with FreeBSD's
#   default -fstack-protector-strong, which breaks wasi-libc's own SSP constructor: musl's
#   __stack_chk_fail.c writes __stack_chk_guard and then its own stack canary check fails, so
#   __wasilibc_init_ssp traps __stack_chk_fail during __wasm_call_ctors. Measured under BOTH
#   node's WASI and wasmtime, so it is the library, not the runtime. Use the reference
#   wasi-sdk sysroot instead.
set -e

HERE=$(cd "$(dirname "$0")" && pwd)

SYSROOT=${SYSROOT:-/ROM/toolchains/wasi-sdk-25.0/share/wasi-sysroot}
RESDIR=${RESDIR:-/ROM/toolchains/wasi-sdk-25.0/lib/clang/19}
CC=${CC:-/usr/local/llvm19/bin/clang}
SRC=${ANTHY_SRC:-/ROM/anthy-build/anthy-9100}
OUT=${OUT:-$HERE/prebuilt}
SHIM=$HERE/src/anthy_wasm.c
SHIMS=$HERE/src/shim_posix.c

test -d "$SYSROOT" || { echo "missing sysroot: $SYSROOT"; exit 1; }
test -x "$CC" || { echo "missing compiler: $CC"; exit 1; }
test -d "$SRC/src-main" || { echo "missing anthy source tree: $SRC"; exit 1; }

CFLAGS="--target=wasm32-wasip1 --sysroot=$SYSROOT -resource-dir=$RESDIR
 -O2 -fno-stack-protector
 -D_WASI_EMULATED_MMAN
 -DHAVE_CONFIG_H -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
 -DCONF_DIR=\"/work/.anthy\"
 -I$SRC -I$SRC/anthy -I$SRC/src-diclib -I$SRC/src-worddic -I$SRC/src-main
 -I$SRC -I$SRC/src-splitter -I$SRC/src-ordering
 -isystem $HERE/src/shim
 -w"

# The _SOURCES of each Makefile.am, minus the command line tools (they pull in terminal code
# that has no place in an embedded module). Same set as the arm build.
FILES="src-diclib/diclib.c src-diclib/file_dic.c src-diclib/filemap.c \
src-diclib/xstr.c src-diclib/xchar.c src-diclib/alloc.c src-diclib/conf.c \
src-diclib/logger.c src-diclib/ruleparser.c \
src-worddic/word_dic.c src-worddic/dic_util.c src-worddic/wtype.c \
src-worddic/texttrie.c src-worddic/textdict.c src-worddic/record.c \
src-worddic/word_lookup.c src-worddic/use_dic.c src-worddic/priv_dic.c \
src-worddic/mem_dic.c src-worddic/feature_set.c src-worddic/matrix.c \
src-worddic/ext_ent.c \
src-main/context.c src-main/main.c \
src-splitter/wordlist.c src-splitter/metaword.c src-splitter/depgraph.c \
src-splitter/splitter.c src-splitter/evalborder.c src-splitter/compose.c \
src-splitter/lattice.c src-splitter/segclass.c \
src-ordering/candswap.c src-ordering/candsort.c src-ordering/commit.c \
src-ordering/relation.c src-ordering/infosort.c src-ordering/candhistory.c"

rm -rf "$OUT/obj-wasm"
mkdir -p "$OUT/obj-wasm"

n=0
for f in $FILES; do
    if [ ! -f "$SRC/$f" ]; then
        echo "MISSING $f"
        continue
    fi
    o="$OUT/obj-wasm/$(echo "$f" | tr / _).o"
    # shellcheck disable=SC2086
    $CC $CFLAGS -c "$SRC/$f" -o "$o"
    n=$((n + 1))
done

# the embedder-facing shim itself, plus the POSIX stubs WASI lacks
# shellcheck disable=SC2086
$CC $CFLAGS -c "$SHIM" -o "$OUT/obj-wasm/anthy_wasm.o"
n=$((n + 1))
# shellcheck disable=SC2086
$CC $CFLAGS -c "$SHIMS" -o "$OUT/obj-wasm/shim_posix.o"
n=$((n + 1))

echo "compiled $n objects"

# -mexec-model=reactor: exports _initialize; no _start, no main
# -lwasi-emulated-mman: the mmap/munmap emulation anthy's filemap.c needs
$CC $CFLAGS -mexec-model=reactor -Wl,--no-entry -o "$OUT/anthy.wasm" \
    "$OUT"/obj-wasm/*.o -lwasi-emulated-mman -lwasi-emulated-getpid

echo "linked $OUT/anthy.wasm"
ls -la "$OUT/anthy.wasm"