aboutsummaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
Diffstat (limited to 'ext')
-rw-r--r--ext/wasm/GNUmakefile244
-rw-r--r--ext/wasm/c-pp.c3
-rwxr-xr-xext/wasm/make-make.sh98
-rw-r--r--ext/wasm/mkwasmbuilds.c216
-rw-r--r--ext/wasm/speedtest1-wasmfs.mjs12
-rw-r--r--ext/wasm/wasmfs.make21
6 files changed, 314 insertions, 280 deletions
diff --git a/ext/wasm/GNUmakefile b/ext/wasm/GNUmakefile
index 50fedfef7..e40db6a5f 100644
--- a/ext/wasm/GNUmakefile
+++ b/ext/wasm/GNUmakefile
@@ -56,8 +56,8 @@ ifeq (,$(SHELL))
$(error Cannot find the bash shell)
endif
MAKEFILE := $(lastword $(MAKEFILE_LIST))
-CLEAN_FILES := .gen.make
-DISTCLEAN_FILES := ./--dummy--
+CLEAN_FILES :=
+DISTCLEAN_FILES :=
MAKING_CLEAN := $(if $(filter %clean,$(MAKECMDGOALS)),1,0)
.PHONY: clean distclean
clean:
@@ -111,14 +111,13 @@ dir.common := common
dir.fiddle := fiddle
dir.fiddle-debug := fiddle-debug
dir.tool := $(dir.top)/tool
-# Maintenance reminder: the names of $(dir.dout) and $(dir.tmp) must
-# stay in sync with make-make.sh
-#
+# dir.dout = output dir for deliverables
+dir.dout := $(dir.wasm)/jswasm
# dir.tmp = output dir for intermediary build files, as opposed to
# end-user deliverables.
-dir.dout := $(dir.wasm)/jswasm
-# dir.dout = output dir for deliverables
dir.tmp := $(dir.wasm)/bld
+dir.wasmfs := $(dir.dout)
+
CLEAN_FILES += *~ $(dir.jacc)/*~ $(dir.api)/*~ $(dir.common)/*~ $(dir.fiddle)/*~ \
$(dir.fiddle-debug)/* $(dir.dout)/* $(dir.tmp)/*
@@ -143,6 +142,13 @@ sqlite3.canonical.c := $(dir.top)/sqlite3.c
sqlite3.c ?= $(firstword $(wildcard $(dir.top)/sqlite3-see.c) $(sqlite3.canonical.c))
sqlite3.h := $(dir.top)/sqlite3.h
+ifeq (,$(shell grep sqlite3_activate_see $(sqlite3.c)))
+ SQLITE_C_IS_SEE := 0
+else
+ SQLITE_C_IS_SEE := 1
+ $(info This is an SEE build)
+endif
+
########################################################################@
# It's important that sqlite3.h be built to completion before any
# other parts of the build run, thus we use .NOTPARALLEL to disable
@@ -152,27 +158,51 @@ $(sqlite3.h):
$(MAKE) -C $(dir.top) sqlite3.c
$(sqlite3.c): $(sqlite3.h)
-########################################################################
-# .gen.make is generated by a shell script and holds certain parts
-# of the makefile, some of which are relatively expensive to calculate
-# on each run (that is, they can take a human-visible amount of time).
-#
-# Sidebar: three attempts have been made to move much of the
-# $(eval)-generated makefile code into make-make.sh but the result is
-# even less legible/maintainable than make-side $(eval).
-ifeq (0,$(MAKING_CLEAN))
-.gen.make: $(MAKEFILE) $(sqlite3.c)
- rm -f $@
- $(SHELL) make-make.sh $(sqlite3.c) > $@
- chmod -w $@
--include .gen.make
-endif
-
ifeq (,$(filter release snapshot,$(MAKECMDGOALS)))
$(info Development build. Use 'release' or 'snapshot' target for a smaller release build.)
endif
########################################################################
+# Find emcc (Emscripten compiler)...
+emcc.bin := $(shell which emcc 2>/dev/null)
+ifeq (,$(emcc.bin))
+ ifneq (,$(EMSDK_HOME))
+ emcc.bin := $(wildcard $(EMSDK_HOME)/upstream/emscripten/emcc)
+ endif
+ ifeq (,$(emcc.bin))
+ $(error Cannot find emcc in path.)
+ endif
+endif
+emcc.version := $(shell $(emcc.bin) --version | sed -n 1p | sed -e 's/^.* \([3-9][^ ]*\) .*$$/\1/;')
+$(info using emcc version [$(emcc.version)])
+#########################################################################
+# Find wasm-strip, which we need for release builds (see below for
+# why) but not strictly for non-release builds.
+wasm-strip.bin ?= $(shell which wasm-strip 2>/dev/null)
+ifeq (,$(wasm-strip.bin))
+ ifeq (,$(filter clean,$(MAKECMDGOALS)))
+ $(info WARNING: *******************************************************************)
+ $(info WARNING: builds using -O2/-O3/-Os/-Oz will minify WASM-exported names,)
+ $(info WARNING: breaking _All The Things_. The workaround for that is to build)
+ $(info WARNING: with -g3 (which explodes the file size) and then strip the debug)
+ $(info WARNING: info after compilation, using wasm-strip, to shrink the wasm file.)
+ $(info WARNING: wasm-strip was not found in the PATH so we cannot strip those.)
+ $(info WARNING: If this build uses any optimization level higher than -O1 then)
+ $(info WARNING: the ***resulting JS code WILL NOT BE USABLE***.)
+ $(info WARNING: wasm-strip is part of the wabt package:)
+ $(info WARNING: https://github.com/WebAssembly/wabt)
+ $(info WARNING: on Ubuntu-like systems it can be installed with:)
+ $(info WARNING: sudo apt install wabt)
+ $(info WARNING: *******************************************************************)
+ endif
+ ifneq (,$(filter release snapshot,$(MAKECMDGOALS)))
+ $(error Cannot make release-quality binary because wasm-strip is not available.)
+ endif
+ wasm-strip.bin := echo "not wasm-stripping"
+endif
+maybe-wasm-strip := $(wasm-strip.bin)
+
+########################################################################
# barebones=1 disables all "extraneous" stuff from sqlite3-wasm.c, the
# goal being to create a WASM file with only the core APIs.
ifeq (1,$(barebones))
@@ -332,6 +362,18 @@ $(bin.stripccomments): $(bin.stripccomments).c $(MAKEFILE)
$(CC) -o $@ $<
DISTCLEAN_FILES += $(bin.stripccomments)
+########################################################################
+# bin.mkwb is used for generating some of the makefile code for the
+# various build builds. It used to be generated in this makefile via a
+# difficult-to-read/maintain block of $(eval)'d code. Attempts were
+# made to generate it from tcl and bash (shell) but having to escape
+# the $ references in those languages made it just as illegible as the
+# native makefile code. Somewhat surprisingly, moving that code generation
+# to C makes it slightly less illegible than the previousq 3 options.
+bin.mkwb := ./mkwasmbuilds
+$(bin.mkwb): $(bin.mkwb).c $(MAKEFILE)
+ $(CC) -o $@ $<
+DISTCLEAN_FILES += $(bin.mkwb)
########################################################################
# C-PP.FILTER: a $(call)able to transform $(1) to $(2) via:
@@ -749,55 +791,6 @@ $(post-js.js.in): $(post-jses.js) $(MAKEFILE)
done > $@
-########################################################################
-# call-make-pre-post is a $(call)able which creates rules for
-# pre-js.$(1)-$(2).js. $1 = the base name of the JS file on whose
-# behalf this pre-js is for (one of: $(JS_BUILD_NAMES)). $2 is
-# the build mode: one of $(JS_BUILD_MODES). This sets up
-# --[extern-][pre/post]-js flags in $(pre-post-$(1)-$(2).flags) and
-# dependencies in $(pre-post-$(1)-$(2).deps). The resulting files get
-# filtered using $(C-PP.FILTER). Any flags necessary for such
-# filtering need to be set in $(c-pp.D.$(1)-$(2)) before $(call)ing
-# this.
-#
-# Maintenance note: a shell script was written to generate these rules
-# with the hope that it would make them more legible and maintainable,
-# but embedding makefile code in another language makes it even less
-# legible than having the level of $(eval) indirection which we have
-# here.
-define call-make-pre-post
-pre-post-$(1)-$(2).flags ?=
-pre-js.js.$(1)-$(2).intermediary := $$(dir.tmp)/pre-js.$(1)-$(2).intermediary.js
-pre-js.js.$(1)-$(2) := $$(dir.tmp)/pre-js.$(1)-$(2).js
-#$$(error $$(pre-js.js.$(1)-$(2).intermediary) $$(pre-js.js.$(1)-$(2)))
-$$(eval $$(call C-PP.FILTER,$$(pre-js.js.in),$$(pre-js.js.$(1)-$(2).intermediary),$$(c-pp.D.$(1)-$(2))))
-post-js.js.$(1)-$(2) := $$(dir.tmp)/post-js.$(1)-$(2).js
-$$(eval $$(call C-PP.FILTER,$$(post-js.js.in),$$(post-js.js.$(1)-$(2)),$$(c-pp.D.$(1)-$(2))))
-extern-post-js.js.$(1)-$(2) := $$(dir.tmp)/extern-post-js.$(1)-$(2).js
-$$(eval $$(call C-PP.FILTER,$$(extern-post-js.js.in),$$(extern-post-js.js.$(1)-$(2)),$$(c-pp.D.$(1)-$(2))))
-pre-post-common.flags.$(1)-$(2) := \
- $$(pre-post-common.flags) \
- --post-js=$$(post-js.js.$(1)-$(2)) \
- --extern-post-js=$$(extern-post-js.js.$(1)-$(2))
-pre-post-jses.$(1)-$(2).deps := $$(pre-post-jses.deps.common) \
- $$(post-js.js.$(1)-$(2)) $$(extern-post-js.js.$(1)-$(2))
-$$(pre-js.js.$(1)-$(2)): $$(pre-js.js.$(1)-$(2).intermediary) $$(MAKEFILE)
- cp $$(pre-js.js.$(1)-$(2).intermediary) $$@
- @if [ sqlite3-wasmfs = $(1) ]; then \
- echo "delete Module[xNameOfInstantiateWasm] /*for WASMFS build*/;"; \
- elif [ sqlite3 != $(1) ]; then \
- echo "Module[xNameOfInstantiateWasm].uri = '$(1).wasm';"; \
- fi >> $$@
-pre-post-$(1)-$(2).deps := \
- $$(pre-post-jses.$(1)-$(2).deps) \
- $$(dir.tmp)/pre-js.$(1)-$(2).js
-pre-post-$(1)-$(2).flags += \
- $$(pre-post-common.flags.$(1)-$(2)) \
- --pre-js=$$(dir.tmp)/pre-js.$(1)-$(2).js
-endef
-# /post-js and pre-js
-########################################################################
-
# Undocumented Emscripten feature: if the target file extension is
# "mjs", it defaults to ES6 module builds:
# https://github.com/emscripten-core/emscripten/issues/14383
@@ -811,11 +804,14 @@ sqlite3-wasmfs.cfiles := $(sqlite3-wasm.cfiles)
# difference, so we build all binaries against sqlite3-wasm.c instead
# of building a shared copy of sqlite3-wasm.o to link against.
########################################################################
-# SQLITE3.xJS.EXPORT-DEFAULT is part of SQLITE3-WASMFS.xJS.RECIPE and
-# SETUP_LIB_BUILD_MODE, factored into a separate piece to avoid code
-# duplication. $1 is 1 if the build mode needs this workaround (esm,
-# bundler-friendly, node) and 0 if not (vanilla). $2 must be empty for
-# all builds except sqlite3-wasmfs.mjs, in which case it must be 1.
+
+########################################################################
+# SQLITE3.xJS.ESM-EXPORT-DEFAULT is part of SQLITE3-WASMFS.xJS.RECIPE
+# and SETUP_LIB_BUILD_MODE, factored into a separate piece to avoid
+# code duplication. $1 is 1 if the build mode needs this workaround
+# (esm, bundler-friendly, node) and 0 if not (vanilla). $2 must be
+# 0 for all builds except sqlite3-wasmfs.mjs, in which case it
+# must be 1.
#
# Reminder for ESM builds: even if we use -sEXPORT_ES6=0, emcc _still_
# adds:
@@ -838,7 +834,7 @@ if [ x1 = x$(1) ]; then \
{\
awk '/^export default/ && !f{f=1; next} 1' $@ > $@.tmp && mv $@.tmp $@; \
} || exit $$?; \
- if [ x != x$(2) ]; then \
+ if [ x1 = x$(2) ]; then \
if ! grep -q '^export default' $@; then \
echo "Cannot find export default." 1>&2; \
exit 1; \
@@ -847,78 +843,6 @@ if [ x1 = x$(1) ]; then \
fi
endef
-########################################################################
-# extern-post-js* and extern-pre-js* are files for use with
-# Emscripten's --extern-pre-js and --extern-post-js flags.
-extern-pre-js.js := $(dir.api)/extern-pre-js.js
-extern-post-js.js.in := $(dir.api)/extern-post-js.c-pp.js
-# Emscripten flags for --[extern-][pre|post]-js=... for the
-# various builds.
-pre-post-common.flags := \
- --extern-pre-js=$(sqlite3-license-version.js)
-# pre-post-jses.deps.* = a list of dependencies for the
-# --[extern-][pre/post]-js files.
-pre-post-jses.deps.common := $(extern-pre-js.js) $(sqlite3-license-version.js)
-
-########################################################################
-# SETUP_LIB_BUILD_MODE is a $(call)'able which sets up numerous pieces
-# for one of the build modes.
-#
-# $1 = one of: $(JS_BUILD_NAMES)
-# $2 = build mode name: one of $(JS_BUILD_MODES)
-# $3 = 1 for ESM build mode, else 0
-# $4 = resulting sqlite-api JS/MJS file
-# $5 = resulting JS/MJS file
-# $6 = -D... flags for $(bin.c-pp)
-# $7 = optional extra flags for emcc
-#
-# Maintenance reminder: be careful not to introduce spaces around args
-# ($1, $2), otherwise string concatenation will malfunction.
-#
-# Before calling this, emcc.environment.$(2) must be set to a value
-# for emcc's -sENVIRONMENT flag.
-#
-# $(cflags.$(1)) and $(cflags.$(1).$(2)) may be defined to append
-# CFLAGS to a given build mode.
-#
-# $(emcc.flags.$(1)) and $(emcc.flags.$(1).$(2)) may be defined to
-# append emcc-specific flags to a given build mode.
-define SETUP_LIB_BUILD_MODE
-$(info Setting up build [$(1)-$(2)]: $(5))
-c-pp.D.$(1)-$(2) := $(6)
-$$(eval $$(call call-make-pre-post,$(1),$(2)))
-emcc.flags.$(1).$(2) ?=
-emcc.flags.$(1).$(2) += $(7)
-$$(eval $$(call C-PP.FILTER, $$(sqlite3-api.js.in), $(4), $(6)))
-$(5): $(4) $$(MAKEFILE) $$(sqlite3-wasm.cfiles) $$(EXPORTED_FUNCTIONS.api) $$(pre-post-$(1)-$(2).deps)
- @echo "Building $$@ ..."
- $$(emcc.bin) -o $$@ $$(emcc_opt_full) $$(emcc.flags) \
- $$(emcc.jsflags) \
- -sENVIRONMENT=$$(emcc.environment.$(2)) \
- $$(pre-post-$(1)-$(2).flags) \
- $$(emcc.flags.$(1)) $$(emcc.flags.$(1).$(2)) \
- $$(cflags.common) $$(SQLITE_OPT) \
- $$(cflags.$(1)) $$(cflags.$(1).$(2)) \
- $$(cflags.wasm_extra_init) $$(sqlite3-wasm.cfiles)
- @$$(call SQLITE3.xJS.ESM-EXPORT-DEFAULT,$(3))
- @dotwasm=$$(basename $$@).wasm; \
- chmod -x $$$$dotwasm; \
- $(maybe-wasm-strip) $$$$dotwasm; \
- case $(2) in \
- bundler-friendly|node) \
- echo "Patching $$@ for $(1).wasm..."; \
- rm -f $$$$dotwasm; \
- dotwasm=; \
- sed -i -e 's/$(1)-$(2).wasm/$(1).wasm/g' $$@ || exit $$$$?; \
- ;; \
- esac; \
- ls -la $$$$dotwasm $$@
-all: $(5)
-#quick: $(5)
-#CLEAN_FILES += $(4) $(5)
-endef
-# ^^^ /SETUP_LIB_BUILD_MODE
-########################################################################
sqlite3-api.js := $(dir.dout)/sqlite3-api.js
sqlite3.js := $(dir.dout)/sqlite3.js
sqlite3-api.mjs := $(dir.dout)/sqlite3-api.mjs
@@ -927,17 +851,14 @@ sqlite3-api-bundler-friendly.mjs := $(dir.dout)/sqlite3-api-bundler-friendly.mjs
sqlite3-bundler-friendly.mjs := $(dir.dout)/sqlite3-bundler-friendly.mjs
sqlite3-api-node.mjs := $(dir.dout)/sqlite3-api-node.mjs
sqlite3-node.mjs := $(dir.dout)/sqlite3-node.mjs
-#$(info $(call SETUP_LIB_BUILD_MODE,sqlite3,vanilla,0, $(sqlite3-api.js), $(sqlite3.js)))
-$(eval $(call SETUP_LIB_BUILD_MODE,sqlite3,vanilla,0,\
- $(sqlite3-api.js), $(sqlite3.js)))
-$(eval $(call SETUP_LIB_BUILD_MODE,sqlite3,esm,1,\
- $(sqlite3-api.mjs), $(sqlite3.mjs), -Dtarget=es6-module))
-$(eval $(call SETUP_LIB_BUILD_MODE,sqlite3,bundler-friendly,1,\
- $(sqlite3-api-bundler-friendly.mjs),$(sqlite3-bundler-friendly.mjs),\
- $(c-pp.D.sqlite3-esm) -Dtarget=es6-bundler-friendly))
-$(eval $(call SETUP_LIB_BUILD_MODE,sqlite3,node,1,\
- $(sqlite3-api-node.mjs),$(sqlite3-node.mjs),\
- $(c-pp.D.sqlite3-bundler-friendly) -Dtarget=node))
+sqlite3-api-wasmfs.mjs := $(dir.tmp)/sqlite3-api-wasmfs.mjs
+sqlite3-wasmfs.mjs := $(dir.wasmfs)/sqlite3-wasmfs.mjs
+.wasmbuilds.make: $(bin.mkwb)
+ @rm -f $@
+ $(bin.mkwb) > $@
+ @chmod -w $@
+DISTCLEAN_FILES += .wasmbuilds.make
+-include .wasmbuilds.make
# The various -D... values used by *.c-pp.js include:
#
# -Dtarget=es6-module: for all ESM module builds
@@ -1267,4 +1188,3 @@ endif
# Run local web server for the test/demo pages.
httpd:
althttpd -max-age 1 -enable-sab 1 -page index.html
-
diff --git a/ext/wasm/c-pp.c b/ext/wasm/c-pp.c
index c439a0d09..6815cb845 100644
--- a/ext/wasm/c-pp.c
+++ b/ext/wasm/c-pp.c
@@ -1,7 +1,8 @@
/*
** 2022-11-12:
**
-** In place of a legal notice, here is a blessing:
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
**
** * May you do good and not evil.
** * May you find forgiveness for yourself and forgive others.
diff --git a/ext/wasm/make-make.sh b/ext/wasm/make-make.sh
deleted file mode 100755
index 6f93d8883..000000000
--- a/ext/wasm/make-make.sh
+++ /dev/null
@@ -1,98 +0,0 @@
-#!/usr/bin/bash
-########################################################################
-# Emits the makefile code for .cache.make. Any makefile bits which are
-# potentially expensive to calculate on every build but rarely change
-# should be emitted from here.
-#
-# Arguments:
-#
-# $1 = path to sqlite3.c. Default: ../../sqlite3.c
-#
-########################################################################
-
-function die(){
- local rc=$1
- shift
- echo "\$(error $0 failed: $@)"
- # ^^^ Ensure that if this output is being redirected, the
- # resulting makefile will fail loudly instead of just being
- # truncated.
- echo "Error: $@" 1>&2
- exit $rc
-}
-
-SQLITE3_C="${1-../../sqlite3.c}"
-
-separator='########################################################################'
-
-cat <<EOF
-# GENERATED makefile code. DO NOT EDIT.
-# Generated by $0 on $(date)
-_GEN_MAKE := \$(lastword \$(MAKEFILE_LIST))
-\$(_GEN_MAKE): ${SQLITE3_C} $0
-EOF
-
-if grep sqlite3_activate_see "$SQLITE3_C" &>/dev/null; then
- echo 'SQLITE_C_IS_SEE := 1'
- echo '$(info This is an SEE build)'
-else
- echo 'SQLITE_C_IS_SEE := 0'
-fi
-
-########################################################################
-# Locate the emcc (Emscripten) binary...
-echo $separator
-EMCC_BIN=$(which emcc)
-if [[ x = "x${EMCC_BIN}" ]]; then
- if [[ x != "x${EMSDK_HOME}" ]]; then
- EMCC_BIN="${EMSDK_HOME}/upstream/emscripten/emcc"
- fi
-fi
-if [[ x = "x${EMCC_BIN}" ]]; then
- die 1 "Cannot find emcc binary in PATH or EMSDK_HOME."
-fi
-[[ -x "${EMCC_BIN}" ]] || die 1 "emcc is not executable"
-echo "emcc.bin := ${EMCC_BIN}"
-echo "emcc.version :=" $("${EMCC_BIN}" --version | sed -n 1p \
- | sed -e 's/^.* \([3-9][^ ]*\) .*$/\1/;')
-echo '$(info using emcc version [$(emcc.version)])'
-
-#########################################################################
-# wasm-strip binary...
-echo $separator
-WASM_STRIP_BIN=$(which wasm-strip 2>/dev/null)
-echo "wasm-strip ?= ${WASM_STRIP_BIN}"
-if [[ x = "x${WASM_STRIP_BIN}" ]]; then
-cat <<EOF
-maybe-wasm-strip = echo "not wasm-stripping"
-ifeq (,\$(filter clean,\$(MAKECMDGOALS)))'
- \$(info WARNING: *******************************************************************)
- \$(info WARNING: builds using -O2/-O3/-Os/-Oz will minify WASM-exported names,)
- \$(info WARNING: breaking _All The Things_. The workaround for that is to build)
- \$(info WARNING: with -g3 (which explodes the file size) and then strip the debug)
- \$(info WARNING: info after compilation, using wasm-strip, to shrink the wasm file.)
- \$(info WARNING: wasm-strip was not found in the PATH so we cannot strip those.)
- \$(info WARNING: If this build uses any optimization level higher than -O1 then)
- \$(info WARNING: the ***resulting JS code WILL NOT BE USABLE***.)
- \$(info WARNING: wasm-strip is part of the wabt package:)
- \$(info WARNING: https://github.com/WebAssembly/wabt)
- \$(info WARNING: on Ubuntu-like systems it can be installed with:)
- \$(info WARNING: sudo apt install wabt)
- \$(info WARNING: *******************************************************************)
-endif
-ifneq (,\$(filter release snapshot,\$(MAKECMDGOALS)))
- \$(error Cannot make release-quality binary because wasm-strip is not available.)
-endif
-EOF
-else
-echo 'maybe-wasm-strip = $(wasm-strip)'
-fi
-# /$(wasm-strip)
-########################################################################
-
-########################################################################
-# Make necessary dirs. Note that these need to align with their names
-# in the main makefile.
-for d in jswasm bld; do
- [ -d $d ] || mkdir -p $d
-done
diff --git a/ext/wasm/mkwasmbuilds.c b/ext/wasm/mkwasmbuilds.c
new file mode 100644
index 000000000..6f1488319
--- /dev/null
+++ b/ext/wasm/mkwasmbuilds.c
@@ -0,0 +1,216 @@
+/*
+** 2024-09-23
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+**
+** This app's single purpose is to emit parts of the Makefile code for
+** building sqlite3's WASM build. The main motivation is to generate
+** code which "can" be created via GNU Make's eval command but is
+** highly illegible when built that way. Attempts to write this app in
+** Bash and TCL have failed because both require escaping $ symbols,
+** making the resulting script code as illegible as the eval spaghetti
+** we want to get away from. Writing it in C is, somewhat
+** surprisingly, _slightly_ less illegible than writing it in bash,
+** tcl, or native Make code.
+**
+** The emitted makefile code is not standalone - it depends on
+** variables and $(call)able functions from the main makefile.
+**
+*/
+
+#undef NDEBUG
+#define DEBUG 1
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+
+#define pf printf
+#define ps puts
+/* Very common printf() args combo. */
+#define zNM zName, zMode
+
+/*
+** Valid names for the zName arguments.
+*/
+#define JS_BUILD_NAMES sqlite3 sqlite3-wasmfs
+/*
+** Valid names for the zMode arguments.
+*/
+#define JS_BUILD_MODES vanilla esm bundler-friendly node
+
+/*
+** Emits common vars needed by the rest of the emitted code (but not
+** needed by code outside of these generated pieces).
+*/
+static void mk_prologue(void){
+ ps("########################################################################");
+ ps("# extern-post-js* and extern-pre-js* are files for use with");
+ ps("# Emscripten's --extern-pre-js and --extern-post-js flags.");
+ ps("extern-pre-js.js := $(dir.api)/extern-pre-js.js");
+ ps("extern-post-js.js.in := $(dir.api)/extern-post-js.c-pp.js");
+ ps("# Emscripten flags for --[extern-][pre|post]-js=... for the");
+ ps("# various builds.");
+ ps("pre-post-common.flags := --extern-pre-js=$(sqlite3-license-version.js)");
+ ps("# pre-post-jses.deps.* = a list of dependencies for the");
+ ps("# --[extern-][pre/post]-js files.");
+ ps("pre-post-jses.deps.common := $(extern-pre-js.js) $(sqlite3-license-version.js)");
+}
+
+/*
+** Emits makefile code for setting up values for the --pre-js=FILE,
+** --post-js=FILE, and --extern-post-js=FILE emcc flags, as well as
+** populating those files.
+*/
+static void mk_pre_post(const char *zName, const char *zMode){
+ pf("pre-post-%s-%s.flags ?=\n", zNM);
+
+ /* --pre-js=... */
+ pf("pre-js.js.%s-%s.intermediary := $(dir.tmp)/pre-js.%s-%s.intermediary.js\n",
+ zNM, zNM);
+ pf("pre-js.js.%s-%s := $(dir.tmp)/pre-js.%s-%s.js\n",
+ zNM, zNM);
+ pf("$(eval $(call C-PP.FILTER,$(pre-js.js.in),$(pre-js.js.%s-%s.intermediary),"
+ "$(c-pp.D.%s-%s)))\n", zNM, zNM);
+
+ /* --post-js=... */
+ pf("post-js.js.%s-%s := $(dir.tmp)/post-js.%s-%s.js\n", zNM, zNM);
+ pf("$(eval $(call C-PP.FILTER,$(post-js.js.in),"
+ "$(post-js.js.%s-%s),$(c-pp.D.%s-%s)))\n", zNM, zNM);
+
+ /* --extern-post-js=... */
+ pf("extern-post-js.js.%s-%s := $(dir.tmp)/extern-post-js.%s-%s.js\n", zNM, zNM);
+ pf("$(eval $(call C-PP.FILTER,$(extern-post-js.js.in),$(extern-post-js.js.%s-%s),"
+ "$(c-pp.D.%s-%s)))\n", zNM, zNM);
+
+ /* Combine flags for use with emcc... */
+ pf("pre-post-common.flags.%s-%s := "
+ "$(pre-post-common.flags) "
+ "--post-js=$(post-js.js.%s-%s) "
+ "--extern-post-js=$(extern-post-js.js.%s-%s)\n", zNM, zNM, zNM);
+
+ pf("pre-post-%s-%s.flags += $(pre-post-common.flags.%s-%s) "
+ "--pre-js=$(pre-js.js.%s-%s)\n", zNM, zNM, zNM);
+
+ pf("$(pre-js.js.%s-%s): $(pre-js.js.%s-%s.intermediary) $(MAKEFILE)\n",
+ zNM, zNM);
+ pf("\tcp $(pre-js.js.%s-%s.intermediary) $@\n", zNM);
+ /* Amend $(pre-js.js.zName-zMode) for all targets except the plain
+ "sqlite3" build... */
+ if( 0==strcmp("sqlite3-wasmfs", zName) ){
+ pf("\t@echo 'delete Module[xNameOfInstantiateWasm]; /"
+ "* for %s build *" "/' >> $@\n", zName);
+ }else if( 0!=strcmp("sqlite3", zName) ){
+ pf("\t@echo 'Module[xNameOfInstantiateWasm].uri = \"$(1).wasm\";' >> $@\n");
+ }
+
+ /* Set up deps... */
+ pf("pre-post-jses.%s-%s.deps := $(pre-post-jses.deps.common) "
+ "$(post-js.js.%s-%s) $(extern-post-js.js.%s-%s)\n",
+ zNM, zNM, zNM);
+ pf("pre-post-%s-%s.deps := $(pre-post-jses.%s-%s.deps) $(dir.tmp)/pre-js.%s-%s.js\n",
+ zNM, zNM, zNM);
+}
+
+/*
+** Emits makefile code for one build of the library, primarily defined
+** by the combination of zName and zMode, each of which must be values
+** from JS_BUILD_NAMES resp. JS_BUILD_MODES.
+*/
+static void mk_lib_mode(const char *zName /* build name */,
+ const char *zMode /* build mode */,
+ int bIsEsm /* true only for ESM build */,
+ const char *zApiJsOut /* name of generated sqlite3-api.js/.mjs */,
+ const char *zJsOut /* name of generated sqlite3.js/.mjs */,
+ const char *zCmppD /* extra -D flags for c-pp */,
+ const char *zEmcc /* extra flags for emcc */){
+ assert( zName );
+ assert( zMode );
+ assert( zApiJsOut );
+ assert( zJsOut );
+ if( !zCmppD ) zCmppD = "";
+ if( !zEmcc ) zEmcc = "";
+
+ pf("#################### begin build [%s-%s]\n", zNM);
+ pf("$(info Setting up build [%s-%s]: %s)\n", zNM, zJsOut);
+ pf("c-pp.D.%s-%s := %s\n", zNM, zCmppD);
+ mk_pre_post(zNM);
+ pf("emcc.flags.%s.%s ?=\n", zNM);
+ if( zEmcc[0] ){
+ pf("emcc.flags.%s.%s += %s\n", zNM, zEmcc);
+ }
+ pf("$(eval $(call C-PP.FILTER, $(sqlite3-api.js.in), %s, %s))\n",
+ zApiJsOut, zCmppD);
+
+ /* target zJsOut */
+ pf("%s: %s $(MAKEFILE) $(sqlite3-wasm.cfiles) $(EXPORTED_FUNCTIONS.api) "
+ "$(pre-post-%s-%s.deps)\n",
+ zJsOut, zApiJsOut, zNM);
+ pf("\t@echo \"Building $@ ...\"\n");
+ pf("\t$(emcc.bin) -o $@ $(emcc_opt_full) $(emcc.flags) \\\n");
+ pf("\t\t$(emcc.jsflags) -sENVIRONMENT=$(emcc.environment.%s) \\\n", zMode);
+ pf("\t\t$(pre-post-%s-%s.flags) \\\n", zNM);
+ pf("\t\t$(emcc.flags.%s) $(emcc.flags.%s.%s) \\\n", zName, zNM);
+ pf("\t\t$(cflags.common) $(SQLITE_OPT) \\\n"
+ "\t\t$(cflags.%s) $(cflags.%s.%s) \\\n"
+ "\t\t$(cflags.wasm_extra_init) $(sqlite3-wasm.cfiles)\n", zName, zNM);
+ if( bIsEsm ){
+ /* TODO? Replace this CALL with the corresponding makefile code.
+ ** OTOH, we also use this $(call) in the speedtest1-wasmfs build,
+ ** which is not part of the rules emitted by this program. */
+ pf("\t@$(call SQLITE3.xJS.ESM-EXPORT-DEFAULT,1,%d)\n",
+ 0==strcmp("sqlite3-wasmfs", zName) ? 1 : 0);
+ }
+ pf("\t@dotwasm=$(basename $@).wasm; \\\n"
+ "\tchmod -x $$dotwasm; \\\n"
+ "\t$(maybe-wasm-strip) $$dotwasm; \\\n");
+ /*
+ ** The above $(emcc.bin) call will write zJsOut and will create a
+ ** like-named .wasm file. That .wasm file name gets hard-coded into
+ ** zJsOut so we need to, for some cases, patch zJsOut to use the
+ ** name sqlite3.wasm instead. Note that the resulting .wasm file is
+ ** identical for all builds for which zEmcc is empty.
+ */
+ if( 0==strcmp("bundler-friendly", zMode)
+ || 0==strcmp("node", zMode) ) {
+ pf("\techo 'Patching $@ for %s.wasm...' \\\n", zName);
+ pf("\trm -f $$dotwasm; dotwasm=; \\\n"
+ "\tsed -i -e 's/%s-%s.wasm/%s.wasm/g' $@ || exit $$?; \\\n",
+ zNM, zName);
+ }
+ pf("\tls -la $$dotwasm $@\n");
+ if( 0!=strcmp("sqlite3-wasmfs", zName) ){
+ /* The sqlite3-wasmfs build is optional and needs to be invoked
+ ** conditionally using info we don't have here. */
+ pf("all: %s\n", zJsOut);
+ }
+ pf("#################### end build [%s-%s]\n\n", zNM);
+}
+
+int main(void){
+ int rc = 0;
+ ps("# What follows was GENERATED by mkwasbuilds.c. Edit at your own risk.");
+ mk_prologue();
+ mk_lib_mode("sqlite3", "vanilla", 0,
+ "$(sqlite3-api.js)", "$(sqlite3.js)", 0, 0);
+ mk_lib_mode("sqlite3", "esm", 1,
+ "$(sqlite3-api.mjs)", "$(sqlite3.mjs)",
+ "-Dtarget=es6-module", 0);
+ mk_lib_mode("sqlite3", "bundler-friendly", 1,
+ "$(sqlite3-api-bundler-friendly.mjs)", "$(sqlite3-bundler-friendly.mjs)",
+ "$(c-pp.D.sqlite3-esm) -Dtarget=es6-bundler-friendly", 0);
+ mk_lib_mode("sqlite3" , "node", 1,
+ "$(sqlite3-api-node.mjs)", "$(sqlite3-node.mjs)",
+ "$(c-pp.D.sqlite3-bundler-friendly) -Dtarget=node", 0);
+ mk_lib_mode("sqlite3-wasmfs", "esm" ,1,
+ "$(sqlite3-api-wasmfs.mjs)", "$(sqlite3-wasmfs.mjs)",
+ "$(c-pp.D.sqlite3-bundler-friendly) -Dwasmfs",
+ "-sEXPORT_ES6 -sUSE_ES6_IMPORT_META");
+ return rc;
+}
diff --git a/ext/wasm/speedtest1-wasmfs.mjs b/ext/wasm/speedtest1-wasmfs.mjs
index 2d5ae322a..aeb37dd7f 100644
--- a/ext/wasm/speedtest1-wasmfs.mjs
+++ b/ext/wasm/speedtest1-wasmfs.mjs
@@ -10,14 +10,14 @@ wMsg('log',"speedtest1-wasmfs starting...");
*/
const wasmfsDir = function f(wasmUtil,dirName="/opfs"){
if(undefined !== f._) return f._;
- if( !self.FileSystemHandle
- || !self.FileSystemDirectoryHandle
- || !self.FileSystemFileHandle){
+ if( !globalThis.FileSystemHandle
+ || !globalThis.FileSystemDirectoryHandle
+ || !globalThis.FileSystemFileHandle){
return f._ = "";
}
try{
if(0===wasmUtil.xCallWrapped(
- 'sqlite3_wasm_init_wasmfs', 'i32', ['string'], dirName
+ 'sqlite3__wasm_init_wasmfs', 'i32', ['string'], dirName
)){
return f._ = dirName;
}else{
@@ -36,7 +36,7 @@ const logErr = (...args)=>wMsg('logErr',...args);
const runTests = function(sqlite3){
console.log("Module inited.",sqlite3);
const wasm = sqlite3.wasm;
- const __unlink = wasm.xWrap("sqlite3_wasm_vfs_unlink", "int", ["*","string"]);
+ const __unlink = wasm.xWrap("sqlite3__wasm_vfs_unlink", "int", ["*","string"]);
const unlink = (fn)=>__unlink(0,fn);
const pDir = wasmfsDir(wasm);
if(pDir) log("Persistent storage:",pDir);
@@ -46,7 +46,7 @@ const runTests = function(sqlite3){
}
const scope = wasm.scopedAllocPush();
const dbFile = pDir+"/speedtest1.db";
- const urlParams = new URL(self.location.href).searchParams;
+ const urlParams = new URL(globalThis.location.href).searchParams;
const argv = ["speedtest1"];
if(urlParams.has('flags')){
argv.push(...(urlParams.get('flags').split(',')));
diff --git a/ext/wasm/wasmfs.make b/ext/wasm/wasmfs.make
index 2bd7a0700..59ec55756 100644
--- a/ext/wasm/wasmfs.make
+++ b/ext/wasm/wasmfs.make
@@ -6,12 +6,10 @@
# GNUMakefile.
########################################################################
MAKEFILE.wasmfs := $(lastword $(MAKEFILE_LIST))
-$(warning The WASMFS build is currently incomplete.)
+$(warning The WASMFS build is not well-supported. \
+ WASMFS is a proverbial moving target, so what builds today might not tomorrow.)
-#dir.wasmfs := $(dir.wasm)
-dir.wasmfs := $(dir.dout)
sqlite3-wasmfs.js := $(dir.wasmfs)/sqlite3-wasmfs.js
-sqlite3-wasmfs.mjs := $(dir.wasmfs)/sqlite3-wasmfs.mjs
sqlite3-wasmfs.wasm := $(dir.wasmfs)/sqlite3-wasmfs.wasm
########################################################################
@@ -25,9 +23,11 @@ cflags.sqlite3-wasmfs += -DSQLITE_ENABLE_WASMFS
# emcc flags specific to building the final .js/.wasm file...
emcc.flags.sqlite3-wasmfs :=
emcc.flags.sqlite3-wasmfs += \
- -sEXPORTED_RUNTIME_METHODS=wasmMemory,allocateUTF8OnStack,stringToUTF8OnStack
+ -sEXPORTED_RUNTIME_METHODS=wasmMemory
# wasmMemory ==> for -sIMPORTED_MEMORY
- # *OnStack ==> wasmfs internals (leaky abstraction)
+# Some version of emcc between 3.1.60-ish and 3.1.62 deprecated the use of
+# (allocateUTF8OnStack,stringToUTF8OnStack). Earlier emcc versions will
+# fail to build without those in EXPORTED_RUNTIME_METHODS.
emcc.flags.sqlite3-wasmfs += -sUSE_CLOSURE_COMPILER=0
emcc.flags.sqlite3-wasmfs += -Wno-limited-postlink-optimizations
# ^^^^^ it likes to warn when we have "limited optimizations" via the -g3 flag.
@@ -46,12 +46,7 @@ emcc.flags.sqlite3-wasmfs += -sALLOW_MEMORY_GROWTH=0
# And, indeed, it runs slowly if memory is permitted to grow.
#emcc.flags.sqlite3-wasmfs.vanilla :=
#emcc.flags.sqlite3-wasmfs.esm := -sEXPORT_ES6 -sUSE_ES6_IMPORT_META
-sqlite3-api.mjs.wasmfs := $(dir.tmp)/sqlite3-api-wasmfs.mjs
-$(eval $(call SETUP_LIB_BUILD_MODE,sqlite3-wasmfs,esm,1,\
- $(sqlite3-api.mjs.wasmfs), $(sqlite3-wasmfs.mjs),\
- $(c-pp.D.sqlite3-bundler-friendly) -Dwasmfs,\
- -sEXPORT_ES6 -sUSE_ES6_IMPORT_META\
-))
+all: $(sqlite3-wasmfs.mjs)
$(sqlite3-wasmfs.js) $(sqlite3-wasmfs.mjs): $(MAKEFILE.wasmfs)
########################################################################
# Build quirk: we cannot build BOTH .js and .mjs with our current
@@ -98,7 +93,7 @@ $(speedtest1-wasmfs.mjs): $(speedtest1.cfiles) $(sqlite3-wasmfs.js) \
$(emcc.flags.sqlite3-wasmfs) \
$(emcc.flags.speedtest1-wasmfs) \
-o $@ $(speedtest1.cfiles) -lm
- @$(call SQLITE3.xJS.ESM-EXPORT-DEFAULT,1)
+ @$(call SQLITE3.xJS.ESM-EXPORT-DEFAULT,1,1)
$(maybe-wasm-strip) $(speedtest1-wasmfs.wasm)
chmod -x $(speedtest1-wasmfs.wasm)
ls -la $@ $(speedtest1-wasmfs.wasm)