make — GNU Make for WASIX
GNU make 4.4.1 (Debian trixie's version), built for WASIX. Recipes run in a
real shell, -j really runs jobs in parallel, and recursive make works.
wasmer run icedcoffee/make -- -j4
wasmer run icedcoffee/make -- -C src all
wasmer run icedcoffee/make -- -f build.mk -B
What is in the package
make and gmake. Everything GNU make 4.4.1 does: explicit, implicit, pattern
and static pattern rules, suffix rules, order-only prerequisites, double-colon
rules, .PHONY/.SECONDARY/.INTERMEDIATE/.DELETE_ON_ERROR,
$(shell …), $(wildcard …), $(call …), $(foreach …), $(eval …),
$(file …), define/endef, conditionals, include/-include, vpath,
target-specific and pattern-specific variables, private/exported/unexported
variables, automatic variables ($@ $< $^ $+ $* $? $|), MAKEFLAGS and the
jobserver, -j, -k, -i, -n, -s, -B, -C, -W, -o, -q, -p,
-r/-R, --trace, .ONESHELL, and exit status 2 on a failed recipe.
--sync (file locking between make instances) is accepted but does nothing —
WASIX has no POSIX record locking. -l (load average) is accepted and ignored.
Verified
$ make -j4 # four one-second targets
parallel=1s (serial run of the same Makefile: 4s)
$ make # all: -> $(MAKE) -C sub
make[1]: Entering directory '/tmp/rec/sub'
sub-make ok
make[1]: Leaving directory '/tmp/rec/sub'
$ make -f M2 # X := $(shell echo from-shell)
X=from-shell
$ make -f M3 a.o # pattern rule
cc a.c - a.o
$ make -f bad x # recipe fails
make: *** [bad:2: x] Error 1 (exit 2)
$(wildcard), include, -C, -B, -q and stdin-driven makefiles
(make -f -) behave as upstream.
Three patches needed
src/dir.c. The glob interface wants astruct direntit can grow, so make computessizeof (*d) - sizeof (d->d_name) + len. wasi-libc declaresd_nameas a flexible array member (char d_name[]), sosizeof (d->d_name)cannot compile. Replaced withoffsetof (struct dirent, d_name) + len, which is the same number for both layouts.src/main.c, two-argumentmain. clang only maps the standardmain(int, char **)to__main_argc_argv, which is the symbol the wasi crt calls. make usesmain(int, char **, char **envp), which stays a symbol namedmain— and clang gives ithiddenvisibility, so the crt cannot resolve it and the link fails with__main_void.o: undefined symbol: main. The_AMIGAtwo-argument form is now used on__wasi__too, withenvp = environwhere the environment block is read.src/main.c,getlogin(). wasi-libc has none, but bothsrc/read.c(~userexpansion) and gnulib'sglob.creference it. A stub returning NULL is appended under#ifdef __wasi__.src/posixos.c.osync_acquire()/osync_release()usefcntl (F_SETLKW), which wasi-libc does not declare. Both become no-ops under#ifdef __wasi__, which only costs the--syncoption.- asyncify. Recipes and
$(shell …)fork and exec, and make longjmps out of its own error paths; on WASIX both are driven through the module's asyncify exports. Without it every run exits 45. 300 KiB raw, 1.0 MB asyncified.
Building
./configure --host=wasm32-wasi --build=x86_64-linux-gnu --disable-nls
make
wasm-opt --asyncify --enable-threads --enable-bulk-memory make -o make.wasm
with -matomics -mbulk-memory -mmutable-globals -pthread -mthread-model posix -ftls-model=local-exec, -D_WASI_EMULATED_{MMAN,SIGNAL,PROCESS_CLOCKS,GETPID},
-lwasi-emulated-{mman,process-clocks,getpid}, -Wl,--shared-memory -Wl,--max-memory=4294967296 -Wl,--import-memory, and the
__heap_base/__stack_pointer/__wasm_init_tls/__tls_* exports.
License: GPL-3.0-or-later, as upstream.