# by the target name. Rebuild is necessary for all components to get
# the desired optimization level.
#
-# quick, q = do just build the essentials for testing
-# (sqlite3.js/wasm, tester1) for faster development-mode
-# turnaround.
-#
# dist = create end user deliverables. Add dist.build=oX to build
# with a specific optimization level, where oX is one of the
# above-listed o? or qo? target names.
# - InfoZip for 'dist' zip file
########################################################################
default: all
-#default: quick
MAKEFILE = $(lastword $(MAKEFILE_LIST))
MAKEFILE.fiddle = fiddle.make
CLEAN_FILES =
.PHONY: clean distclean
clean:
-rm -f $(CLEAN_FILES)
- -rm -fr $(dir.fiddle-debug) $(dir.dout) $(dir.dout) $(dir.tmp)
+ -rm -fr $(dir.fiddle-debug) $(dir.dout) $(dir.tmp)
distclean: clean
-rm -f $(DISTCLEAN_FILES)
more: all
-include util.make
-########################################################################
+# dir.top = the top dir of the canonical build tree, where
+# sqlite3.[ch] live.
+dir.top = ../..
+# Maintenance reminder: some Emscripten flags require absolute paths
+# but we want relative paths for most stuff simply to reduce
+# noise. The $(abspath...) GNU make function can transform relative
+# paths to absolute.
+dir.wasm = $(patsubst %/,%,$(dir $(MAKEFILE)))
+dir.api = api
+dir.jacc = jaccwabyt
+dir.common = common
+dir.fiddle = fiddle
+dir.fiddle-debug = fiddle-debug
+dir.tool = $(dir.top)/tool
+# 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.tmp = $(dir.wasm)/bld
+dir.wasmfs = $(dir.dout)
+
+CLEAN_FILES += *~ $(dir.jacc)/*~ $(dir.api)/*~ $(dir.common)/*~ $(dir.fiddle)/*~ \
+
+#
+# Emoji for log messages.
+#
+emo.bug = ๐
+emo.compile = โณ
+emo.roadblock = ๐ง
+emo.disk = ๐พ
+emo.done = โ
+emo.fire = ๐ฅ
+emo.folder = ๐
+emo.garbage = ๐
+emo.lock = ๐
+emo.magic = ๐ง
+emo.megaphone = ๐ฃ
+emo.mute = ๐
+emo.stop = ๐
+emo.strip = ๐
+emo.test = ๐งช
+emo.tool = ๐จ
+emo.wasm-opt = ๐งผ
+# ๐ท๐ช๐งฎ๐งซ๐งฝ๐ฟโฝ๐ง๐ฑ๐ช๐๐งผ
+
+#
# Special-case builds for which we require certain pre-conditions
# which, if not met, may cause warnings or fatal errors in the build.
# This also affects the default optimization level flags. The fiddle
# targets are in this list because they are used for generating
# sqlite.org/fiddle.
+#
OPTIMIZED_TARGETS = dist snapshot fiddle fiddle.debug
ifeq (1,$(MAKING_CLEAN))
else
# Include config.make and perform some bootstrapping...
ifeq (,$(wildcard ./config.make))
- $(error Missing config.make (gets generated by the configure script if the EMSDK is found))
+ $(error Missing config.make. It gets generated by the configure script if the EMSDK is found)
endif
include ./config.make
ifeq (,$(bin.bash))
emcc.version = $(shell $(bin.emcc) --version | sed -n 1p | sed -e 's/^.* \([3-9][^ ]*\) .*$$/\1/;')
$(info using emcc version [$(emcc.version)])
ifeq (,$(bin.wasm-strip))
- ####################################################################
+ #
# We need wasm-strip for release builds (see below for why) but
# not strictly for non-release builds.
- $(info WARNING: *******************************************************************)
- $(info WARNING: Builds using -Oz will minify WASM-exported names, breaking)
- $(info WARNING: _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: *******************************************************************)
+ #
+ achtung = $(emo.fire)WARNING
+ $(info $(achtung): *******************************************************************)
+ $(info $(achtung): Builds using -Oz will minify WASM-exported names, breaking)
+ $(info $(achtung): _All The Things_. The workaround for that is to build)
+ $(info $(achtung): with -g3 (which explodes the file size) and then strip the debug)
+ $(info $(achtung): info after compilation, using wasm-strip, to shrink the wasm file.)
+ $(info $(achtung): wasm-strip was not found in the PATH so we cannot strip those.)
+ $(info $(achtung): If this build uses any optimization level higher than -O1 then)
+ $(info $(achtung): the ***resulting JS code WILL NOT BE USABLE***.)
+ $(info $(achtung): wasm-strip is part of the wabt package:)
+ $(info $(achtung): https://github.com/WebAssembly/wabt)
+ $(info $(achtung): on Ubuntu-like systems it can be installed with:)
+ $(info $(achtung): sudo apt install wabt)
+ $(info $(achtung): *******************************************************************)
ifneq (,$(filter $(OPTIMIZED_TARGETS),$(MAKECMDGOALS)))
$(error Cannot make release-quality binary because wasm-strip is not available.)
endif
endif
endif
# ^^^ end of are-we-MAKING_CLEAN
-maybe-wasm-strip = $(bin.wasm-strip)
-########################################################################
-# JS_BUILD_NAMES exists for documentation purposes only. It enumerates
-# the core build styles:
#
-# - sqlite3 = canonical library build
+# Common vars and $(call)able utilities for the SQLite WASM build.
#
-# - sqlite3-wasmfs = WASMFS-capable library build
+# The "b." prefix on some APIs is for "build". It was initially used
+# only for build-specific features. That's no longer the case, but the
+# naming convention has stuck.
#
-JS_BUILD_NAMES = sqlite3 sqlite3-wasmfs
-########################################################################
-# JS_BUILD_MODES exists for documentation purposes only. It enumerates
-# the various "flavors" of build, each of which requires slight
-# customization of the output:
+loud ?= 0
+ifeq (1,$(loud))
+ $(info $(emo.megaphone) Emitting loud build info. Pass loud=0 to disable it.)
+ b.cmd@ =
+ loud.if = 1
+else
+ $(info $(emo.mute) Eliding loud build info. Pass loud=1 to enable it.)
+ b.cmd@ = @
+ loud.if =
+endif
+
+#
+# logtag.X value for log context labeling. logtag.OTHERX can be
+# assigned to customize it for a given X. This tag is used by the
+# b.call.X and b.eval.X for logging.
#
-# - vanilla = plain-vanilla JS for use in browsers. This is the
-# canonical build mode.
+logtag.@ = [$@]
+logtag.filter = [$(emo.disk) $@]
+logtag.test = [$(emo.test) $@]
+
#
-# - esm = ES6 module, a.k.a. ESM, for use in browsers.
+# $(call b.echo,LOGTAG,msg)
+#
+b.echo = echo $(logtag.$(1)) $(2)
+
#
-# - bundler-friendly = esm slightly tweaked for "bundler"
-# tools. Bundlers are invariably based on node.js, so these builds
-# are intended to be read at build-time by node.js but with a final
-# target of browsers. All bundler-friendly builds are UNTESTED.
-# They are provided primarily for use by the community-supported
-# subproject which hosts npm builds of sqlite3, and they are
-# actively supported only to the extent needed by that subproject.
+# $(call b.call.mkdir@)
#
-# - node = for use by node.js for node.js, as opposed to by node.js on
-# behalf of browser-side code (use bundler-friendly for that). Note
-# that persistent storage (OPFS) is not available in these builds.
-# These builds are UNTESTED and UNSUPPORTED!
+# $1 = optional LOGTAG
#
-JS_BUILD_MODES = vanilla esm bunder-friendly node
+b.call.mkdir@ = if [ ! -d $(dir $@) ]; then \
+ echo '[$(emo.folder)+] $(if $(1),$(logtag.$(1)),[$(dir $@)])'; \
+ mkdir -p $(dir $@) || exit; fi
-########################################################################
-# dir.top = the top dir of the canonical build tree, where
-# sqlite3.[ch] live.
-dir.top = ../..
-# Maintenance reminder: some Emscripten flags require absolute paths
-# but we want relative paths for most stuff simply to reduce
-# noise. The $(abspath...) GNU make function can transform relative
-# paths to absolute.
-dir.wasm = $(patsubst %/,%,$(dir $(MAKEFILE)))
-dir.api = api
-dir.jacc = jaccwabyt
-dir.common = common
-dir.fiddle = fiddle
-dir.fiddle-debug = fiddle-debug
-dir.tool = $(dir.top)/tool
-# 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.tmp = $(dir.wasm)/bld
-dir.wasmfs = $(dir.dout)
+#
+# $(call b.call.cp,@,src,dest)
+#
+# $1 = build name, $2 = src file(s). $3 = dest dir
+b.call.cp = $(call b.call.mkdir@); \
+ echo '$(logtag.$(1)) $(emo.disk) $(2) ==> $3'; \
+ cp -p $(2) $(3) || exit
-CLEAN_FILES += *~ $(dir.jacc)/*~ $(dir.api)/*~ $(dir.common)/*~ $(dir.fiddle)/*~ \
+#
+# $(eval $(call b.eval.c-pp,@,src,dest,-Dx=y...))
+#
+# $1 = build name
+# $2 = Input file(s): cat $(2) | $(bin.c-pp) ...
+# $3 = Output file: $(bin.c-pp) -o $(3)
+# $4 = optional $(bin.c-pp) -D... flags */
+#
+define b.eval.c-pp
+$(3): $$(MAKEFILE_LIST) $$(bin.c-pp) $(2)
+ @$$(call b.call.mkdir@); \
+ $$(call b.echo,$(1),$$(emo.disk)$$(emo.lock) $$(bin.c-pp) $(4) $(if $(loud.if),$(2))); \
+ rm -f $(3); \
+ $$(bin.c-pp) -o $(3) $(4) $(2) || exit; \
+ chmod -w $(3)
+CLEAN_FILES += $(3)
+endef
-########################################################################
+#
+# $(call b.call.strip-emcc-js-cruft)
+#
+# Our JS code installs bindings of each sqlite3_...() WASM export. The
+# generated Emscripten JS file does the same using its own framework,
+# but we don't use those results and can speed up lib init, and reduce
+# memory cost a bit, by stripping them out. Emscripten-side changes
+# can "break" this, causing this to be a no-op, but the worst that can
+# happen in that case is that it doesn't actually strip anything,
+# leading to slightly larger JS files.
+#
+# This snippet is intended to be used in makefile targets which
+# generate an Emscripten module and where $@ is the module's .js/.mjs
+# file.
+#
+# $1 = an optional log message prefix
+b.call.strip-emcc-js-cruft = \
+ sed -i -e '/^.*= \(_sqlite3\|_fiddle\)[^=]*=.*createExportWrapper/d' \
+ -e '/^var \(_sqlite3\|_fiddle\)[^=]*=.*makeInvalidEarlyAccess/d' $@ || exit; \
+ echo '$(1) $(emo.garbage) (Probably) /createExportWrapper()/d and /makeInvalidEarlyAccess()/d'
+
+
+#
+# bin.version-info = binary to output various sqlite3 version info for
+# embedding in the JS files and in building the distribution zip file.
+# It must NOT be in $(dir.tmp) because we need it to survive the
+# cleanup process for the dist build to work properly.
+#
+# Slight caveat: this uses the version info from the in-tree
+# sqlite3.c/h, which may diff from a user-provided $(sqlite3.c). The
+# end result is that the generated JS files may have static version
+# info from $(bin.version-info) which differ from their runtime-emitted
+# version info (e.g. from sqlite3_libversion()).
+bin.version-info = $(dir.top)/version-info
+$(bin.version-info): $(dir.tool)/version-info.c $(sqlite3.h) $(dir.top)/Makefile
+ $(MAKE) -C $(dir.top) version-info
+
+#
+# bin.stripcomments is used for stripping C/C++-style comments from JS
+# files. The JS files contain large chunks of documentation which we
+# don't need for all builds. That app's -k flag is of particular
+# importance here, as it allows us to retain the opening comment
+# block(s), which contain the license header and version info.
+bin.stripccomments = $(dir.tool)/stripccomments
+$(bin.stripccomments): $(bin.stripccomments).c $(MAKEFILE)
+ $(CC) -o $@ $<
+DISTCLEAN_FILES += $(bin.stripccomments)
+
+
+#
# Set up sqlite3.c and sqlite3.h...
#
# To build with SEE (https://sqlite.org/see), either put sqlite3-see.c
endif
-########################################################################
+#
# 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))
wasm-bare-bones = 1
$(info ==============================================================)
endif
# undefine barebones # relatively new gmake feature, not ubiquitous
-########################################################################@
+#
# It's important that sqlite3.h be built to completion before any
# other parts of the build run, thus we use .NOTPARALLEL to disable
# parallel build of that file and its dependants. However, that makes
# sqlite3.c) from the top of the tree before running this build.
#
#.NOTPARALLEL: $(sqlite3.h)
+#
$(sqlite3.h):
@echo "$(sqlite3.h) is out of date. "; \
echo "To avoid problems with parallel builds, we're exiting now. Please do:"; \
# deprecated and alternatives are in place, but this crash behavior
# can be used to find errant uses of sqlite3_js_vfs_create_file()
# in client code.
-
########################################################################
# The following flags are hard-coded into sqlite3-wasm.c and cannot be
# modified via the build process:
cflags.wasm_extra_init = -DSQLITE_WASM_EXTRA_INIT
endif
-#########################################################################
-# bin.version-info = binary to output various sqlite3 version info for
-# embedding in the JS files and in building the distribution zip file.
-# It must NOT be in $(dir.tmp) because we need it to survive the
-# cleanup process for the dist build to work properly.
-#
-# Slight caveat: this uses the version info from the in-tree
-# sqlite3.c/h, which may diff from a user-provided $(sqlite3.c). The
-# end result is that the generated JS files may have static version
-# info from $(bin.version-info) which differ from their runtime-emitted
-# version info (e.g. from sqlite3_libversion()).
-bin.version-info = $(dir.top)/version-info
-$(bin.version-info): $(dir.tool)/version-info.c $(sqlite3.h) $(dir.top)/Makefile
- $(MAKE) -C $(dir.top) version-info
-
-#########################################################################
-# bin.stripcomments is used for stripping C/C++-style comments from JS
-# files. The JS files contain large chunks of documentation which we
-# don't need for all builds. That app's -k flag is of particular
-# importance here, as it allows us to retain the opening comment
-# block(s), which contain the license header and version info.
-bin.stripccomments = $(dir.tool)/stripccomments
-$(bin.stripccomments): $(bin.stripccomments).c $(MAKEFILE)
- $(CC) -o $@ $<
-DISTCLEAN_FILES += $(bin.stripccomments)
-
#
# If $(WASM_CUSTOM_INSTANTIATE) is 1 then mkwasmbuilds will add
# -Dcustom-Module.instantiateWasm to some of the builds. This is
WASM_CUSTOM_INSTANTIATE = 0
########################################################################
-# SQLITE.CALL.C-PP.FILTER: a $(call)able to transform $(1) to $(2) via:
+# $(bin.c-pp): a minimal text file preprocessor. Like C's but much
+# less so.
#
-# cat $(1) | ./c-pp -o $(2) $(3)
-#
-# Historical notes:
+# Historical notes about preprocessing files in this project:
#
# - We first attempted to use gcc and/or clang to preprocess JS files
# in the same way we would normally do C files, but C-specific quirks
# builds but is maintained as a standalone project:
# https://fossil.wanderinghorse.net/r/c-pp
#
-# Note that the SQLITE_... build flags used here have NO EFFECT on the
-# JS/WASM build. They are solely for use with $(bin.c-pp) itself.
+# The SQLITE_... build flags used here have NO EFFECT on the JS/WASM
+# build. They are solely for use with $(bin.c-pp) itself.
#
# -D... flags which should be included in all invocations should be
# appended to $(b.eval.c-pp.flags).
ifeq (1,$(SQLITE_C_IS_SEE))
b.eval.c-pp.flags += -Denable-see
endif
-define SQLITE.CALL.C-PP.FILTER
-# Create $2 from $1 using $(bin.c-pp)
-# $1 = Input file(s): cat $(1) | c-pp ...
-# $2 = Output file: c-pp -o $(2).js
-# $3 = optional c-pp -D... flags
-$(2): $(1) $$(MAKEFILE_LIST) $$(bin.c-pp)
- @$$(call b.call.mkdir@)
- cat $(1) | $$(bin.c-pp) -o $$@ $(3) $(b.eval.c-pp.flags)
-CLEAN_FILES += $(2)
-endef
-# /end SQLITE.CALL.C-PP.FILTER
-########################################################################
# cflags.common = C compiler flags for all builds
cflags.common = -I. -I$(dir $(sqlite3.c))
# 1.0.34) or will fail to strip with "tables may not be 64-bit".
########################################################################
-ifneq (0,$(emcc.MEMORY64))
- emcc.WASM_BIGINT = 1
- # -sMEMORY64=1+ assumes -sWASM_BIGINT=1, so we'll make it explicit
-
- # b.eval.c-pp.flags += -D64bit
- # ^^ We no longer need build-time code filtering for 64-bit but if
- # we ever do again, just uncomment that line or, if it's just needed
- # in specific builds, update that build's -D flags in
- # mkwasmbuilds.c.
-endif
-
# emcc_opt = optimization-related flags. These are primarily used by
# the various oX targets. build times for -O levels higher than 0 are
# painful at dev-time.
emcc_opt ?= -Oz
endif
-# old name - to remove
-SQLITE.strip-emcc-js-cruft = $(b.call.strip-emcc-js-cruft)
-
# When passing emcc_opt from the CLI, += and re-assignment have no
# effect, so emcc_opt+=-g3 doesn't work. So...
emcc_opt_full = $(emcc_opt) -g3
@$(call b.call.mkdir@)
cat $(EXPORTED_FUNCTIONS.api.in) > $@
-########################################################################
-# SOAP.js is an external API file which is part of our distribution
-# but not part of the sqlite3-api.js amalgamation. It's a component of
-# the first OPFS VFS and necessarily an external file.
-SOAP.js.in = $(dir.api)/sqlite3-opfs-async-proxy.js
-SOAP.js = $(dir.dout)/sqlite3-opfs-async-proxy.js
-$(SOAP.js): $(SOAP.js.in)
- @$(call b.call.cp,@,$<,$@)
#
# $(sqlite3-api.ext.jses) = API-related files which are standalone
# files, not part of the amalgamation.
#
-sqlite3-api.ext.jses = $(SOAP.js)
+sqlite3-api.ext.jses = $(dir.api)/sqlite3-opfs-async-proxy.js
########################################################################
# emcc flags for .c/.o/.wasm/.js.
# -v is _very_ loud but also informative about what it's doing
endif
-
-########################################################################
+#
# emcc flags for .c/.o.
+#
emcc.cflags =
emcc.cflags += -std=c99 -fPIC
# -------------^^^^^^^^ we need c99 for $(sqlite3-wasm.c), primarily
# for variadic macros and snprintf() to implement
# sqlite3__wasm_enum_json().
emcc.cflags += -I. -I$(dir.top)
-########################################################################
+
+#
# emcc flags specific to building .js/.wasm files...
+#
emcc.jsflags = -fPIC
#emcc.jsflags += -Wno-gcc-install-dir-libstdcxx
#emcc is not passing ^^^ this on to clang
# -sSTRICT=1 Causes failures about unknown symbols which the build
# tools should be installing, e.g. __syscall_geteuid32
-########################################################################
+#
# -sINITIAL_MEMORY: How much memory we need to start with is governed
# at least in part by whether -sALLOW_MEMORY_GROWTH is enabled. If so,
# we can start with less. If not, we need as much as we'll ever
# but also says (in its changelog): "Note that it is currently not
# supported in all configurations (#21071)."
# https://github.com/emscripten-core/emscripten/blob/main/ChangeLog.md
+#
+# 2025-09-25: it turns out that _this_ WASM's heap size is not
+# affected by Emscripten's in-memory virtual filesystem, so we don't
+# strictly need a lot of heap. Resizing the heap is slow, though, so
+# we want to start off with some room to grow.
+#
emcc.jsflags += -sALLOW_MEMORY_GROWTH
emcc.INITIAL_MEMORY.128 = 134217728
emcc.INITIAL_MEMORY.96 = 100663296
emcc.INITIAL_MEMORY.32 = 33554432
emcc.INITIAL_MEMORY.16 = 16777216
emcc.INITIAL_MEMORY.8 = 8388608
-emcc.INITIAL_MEMORY ?= 8
+emcc.INITIAL_MEMORY.4 = 4194304
+emcc.INITIAL_MEMORY ?= 8
ifeq (,$(emcc.INITIAL_MEMORY.$(emcc.INITIAL_MEMORY)))
-$(error emcc.INITIAL_MEMORY must be one of: 8, 16, 32, 64, 96, 128 (megabytes))
+$(error emcc.INITIAL_MEMORY must be one of: 4, 8, 16, 32, 64, 96, 128 (megabytes))
endif
emcc.jsflags += -sINITIAL_MEMORY=$(emcc.INITIAL_MEMORY.$(emcc.INITIAL_MEMORY))
# /INITIAL_MEMORY
# of building a shared copy of sqlite3-wasm.o to link against.
########################################################################
-########################################################################
-# SQLITE.CALL.xJS.ESM-EXPORT-DEFAULT is used by mkwasmbuilds.c and the
+#
+# b.call.patch-export-default is used by mkwasmbuilds.c and the
# wasmfs build. $1 is 1 if the build mode needs this workaround
# (modes: 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.
+# be 1. $(3) is an optional log prefix, defaulting to $(logtag.@)
#
# Reminder for ESM builds: even if we use -sEXPORT_ES6=0, emcc _still_
# adds:
#
# Maintenance reminder: Mac sed works differently than GNU sed, so we
# use awk instead of sed for this.
-define SQLITE.CALL.xJS.ESM-EXPORT-DEFAULT
+define b.call.patch-export-default
if [ x1 = x$(1) ]; then \
- echo "$(3) $(emo.bug) Fragile workaround for emscripten/issues/18237." \
- "See SQLITE.CALL.xJS.ESM-EXPORT-DEFAULT."; \
+ echo "$(if $(3),$(3),$(logtag.@)) $(emo.bug) Fragile workaround for emscripten/issues/18237." \
+ "See b.call.patch-export-default."; \
{\
awk '/^export default/ && !f{f=1; next} 1' $@ > $@.tmp && mv $@.tmp $@; \
- } || exit $$?; \
+ } || exit; \
if [ x1 = x$(2) ]; then \
if ! grep -q '^export default' $@; then \
echo "Cannot find export default." 1>&2; \
endef
#
-# We define these to assist in deps handling to avoid concurrent
-# builds (more notes on that below).
+# We may not need these anymore in this file. They're primarily for
+# use in mkwasmbuilds.c.
#
sqlite3.js = $(dir.dout)/sqlite3.js
sqlite3.mjs = $(dir.dout)/sqlite3.mjs
sqlite3-64bit.wasm = $(dir.dout)/sqlite3-64bit.wasm
EXPORTED_FUNCTIONS.fiddle = $(dir.tmp)/EXPORTED_FUNCTIONS.fiddle
+#
# The various -D... values used by *.c-pp.js include:
#
# -Dtarget=es6-module: for all ESM module builds
# as string literals so that bundlers' static-analysis tools can
# find those files and include them in their bundles.
#
-# -Dtarget=es6-module -Dtarget=es6-bundler-friendly -Dtarget=node: is
-# intended for use by node.js for node.js, as opposed to by
-# node.js on behalf of a browser. Mixing -sENVIRONMENT=web and
-# -sENVIRONMENT=node leads to ambiguity and confusion on node's
-# part, as it's unable to reliably determine whether the target is
-# a browser or node.
+# -Dtarget=es6-module -Dtarget=node: is intended for use by node.js
+# for node.js, as opposed to by node.js on behalf of a
+# browser. Mixing -sENVIRONMENT=web and -sENVIRONMENT=node leads to
+# ambiguity and confusion on node's part, as it's unable to
+# reliably determine whether the target is a browser or node.
#
-# We repeat: all node.js builds are 100% untested and unsupported.
+# To repeat: all node.js builds are 100% untested and unsupported.
#
########################################################################
-########################################################################
-# We have to ensure that we do not build $(sqlite3*.*js) in parallel
-# for any builds which result in the creation of $(sqlite3.wasm). We
-# have no way to build just a .[m]js file without also building the
-# .wasm file because the generated .[m]js file has to include info
-# about the imports needed by the wasm file, so they have to be built
-# together. i.e. we're building $(sqlite3.wasm) multiple times, but
-# that's unavoidable (and harmless, but is a significant waste of
-# build time).
-#$(sqlite3.wasm): $(sqlite3.js)
-#$(sqlite3.mjs): $(sqlite3.js)
-#$(sqlite3-64bit.wasm): $(sqlite3-64bit.js)
-#$(sqlite3-64bit.mjs): $(sqlite3-64bit.js)
-#$(dir.dout)/sqlite3-bundler-friendly.mjs: $(sqlite3.mjs)
-#$(dir.dout)/sqlite3-node.mjs: $(sqlite3.mjs)
-#CLEAN_FILES += $(sqlite3.wasm)
-
#
# Only add wasmfs if wasmfs.enable=1 or we're running (dist)clean
#
# /wasmfs
########################################################################
-########################################################################
+#
+# Inputs/outputs for the sqlite3-api.js family.
+#
+# sqlite3-api.jses = the list of JS files which make up
+# sqlite3-api.js, in the order they need to be assembled.
+sqlite3-api.jses = $(sqlite3-license-version.js)
+sqlite3-api.jses += $(dir.api)/sqlite3-api-prologue.js
+sqlite3-api.jses += $(dir.common)/whwasmutil.js
+sqlite3-api.jses += $(dir.jacc)/jaccwabyt.js
+sqlite3-api.jses += $(dir.api)/sqlite3-api-glue.c-pp.js
+sqlite3-api.jses += $(sqlite3-api-build-version.js)
+sqlite3-api.jses += $(dir.api)/sqlite3-api-oo1.c-pp.js
+sqlite3-api.jses += $(dir.api)/sqlite3-api-worker1.c-pp.js
+sqlite3-api.jses += $(dir.api)/sqlite3-vfs-helper.c-pp.js
+ifeq (0,$(wasm-bare-bones))
+ sqlite3-api.jses += $(dir.api)/sqlite3-vtab-helper.c-pp.js
+endif
+sqlite3-api.jses += $(dir.api)/sqlite3-vfs-opfs.c-pp.js
+sqlite3-api.jses += $(dir.api)/sqlite3-vfs-opfs-sahpool.c-pp.js
+sqlite3-api.jses += $(dir.api)/sqlite3-api-cleanup.js
+
+#
+# $(sqlite3-license-version.js) contains the license header and
+# in-comment build version info.
+#
+# Maintenance reminder: there are awk binaries out there which do not
+# support -e SCRIPT.
+#
+sqlite3-license-version.js = $(dir.tmp)/sqlite3-license-version.js
+$(sqlite3-license-version.js): $(bin.version-info) \
+ $(dir.api)/sqlite3-license-version-header.js
+ @echo '$(logtag.@) $(emo.disk)'; { \
+ $(call b.call.mkdir@); \
+ cat $(dir.api)/sqlite3-license-version-header.js || exit $$?; \
+ echo '/*'; \
+ echo '** This code was built from sqlite3 version...'; \
+ echo '**'; \
+ awk '/define SQLITE_VERSION/{$$1=""; print "**" $$0}' $(sqlite3.h); \
+ awk '/define SQLITE_SOURCE_ID/{$$1=""; print "**" $$0}' $(sqlite3.h); \
+ echo '**'; echo '** Emscripten SDK: $(emcc.version)'; \
+ echo '**'; \
+ echo '*/'; \
+ } > $@
+
+#
+# $(sqlite3-api-build-version.js) injects the build version info into
+# the bundle in JSON form.
+#
+sqlite3-api-build-version.js = $(dir.tmp)/sqlite3-api-build-version.js
+$(sqlite3-api-build-version.js): $(bin.version-info) $(MAKEFILE)
+ @echo '$(logtag.@) $(emo.disk)'; { \
+ $(call b.call.mkdir@); \
+ echo 'globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){'; \
+ echo -n ' sqlite3.version = '; \
+ $(bin.version-info) --json; \
+ echo ';'; \
+ echo '});'; \
+ } > $@
+
+#
+# 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.in.js = $(dir.api)/extern-post-js.c-pp.js
+
+#
+# Emscripten flags for --[extern-][pre|post]-js=... for the
+# various builds.
+# pre-post-jses.*.deps = lists of dependencies for the
+# --[extern-][pre/post]-js files.
+#
+pre-post-jses.common.deps = $(extern-pre-js.js) $(sqlite3-license-version.js)
+
+# --post-js and --pre-js are emcc flags we use to append/prepend JS to
+# the generated emscripten module file. These rules set up the core
+# pre/post files for use by the various builds. --pre-js is used to
+# inject code which needs to run as part of the pre-WASM-load phase.
+# --post-js injects code which runs after the WASM module is loaded
+# and includes the entirety of the library plus some
+# Emscripten-specific post-bootstrapping code.
+pre-js.in.js = $(dir.api)/pre-js.c-pp.js
+post-js.in.js = $(dir.tmp)/post-js.c-pp.js
+post-jses.js = \
+ $(dir.api)/post-js-header.js \
+ $(sqlite3-api.jses) \
+ $(dir.api)/post-js-footer.js
+$(post-js.in.js): $(MKDIR.bld) $(post-jses.js) $(MAKEFILE)
+ @$(call b.echo,@,$(emo.disk)); \
+ for i in $(post-jses.js); do \
+ echo "/* BEGIN FILE: $$i */"; \
+ cat $$i || exit $$?; \
+ echo "/* END FILE: $$i */"; \
+ done > $@
+
+#
# bin.mkwb is used for generating much of the makefile code for the
# various wasm builds. It used to be generated in this makefile via a
# difficult-to-read/maintain block of $(eval)'d code. Attempts were
# native makefile code. Somewhat surprisingly, moving that code generation
# to C makes it slightly less illegible than the previous 3 options.
#
-# Maintenance note: the various $(c-pp.D.XYZ) vars are defined via
-# $(bin.mkwb).
+# Maintenance notes:
+#
+# - Ordering of this block within this file is fragile. The generated
+# makefile sets up many vars which are useful for the other targets.
+#
bin.mkwb = ./mkwasmbuilds
ifneq (1,$(MAKING_CLEAN))
$(bin.mkwb): $(bin.mkwb).c $(MAKEFILE)
endif
CLEAN_FILES += .wasmbuilds.make $(bin.mkwb)
-#$(error sqlite3-api.ext.jses=$(sqlite3-api.ext.jses))
-all quick: $(sqlite3-api.ext.jses)
-q: quick
-64bit: # populated by $(bin.mkwb)
-
-
########################################################################
# We need separate copies of certain supplementary JS files for the
# bundler-friendly build. Concretely, any supplemental JS files which
$(eval $(call gen-dwp,.js,.html,$(c-pp.D.vanilla)))
$(eval $(call gen-dwp,.mjs,-esm.html,$(c-pp.D.esm)))
+#
+# Add a dep of $(sqlite3-api.ext.jses) on every build's JS file.
+# The primary purpose of this is to force them to be copied early
+# in the build process, which is sometimes a time-saver during
+# development, allowing the developer to reload a test page while
+# other parts of the build are still running.
+#
+$(foreach B,$(b.names),$(eval $(out.$(B).js): $(sqlite3-api.ext.jses)))
+
########################################################################
# batch-runner.js is part of one of the test apps which reads in SQL
tester1: tester1-worker.html tester1-worker-64bit.html
# We do not include $(dir.dout)/sqlite3-bundler-friendly.mjs in this
# because bundlers are client-specific. We don't use any of them.
-all quick: tester1
-quick: $(sqlite3.js)
+all: tester1
########################################################################
# Convenience rules to rebuild with various -Ox levels. Much
o3: clean
$(MAKE) -e "emcc_opt=-O3 $(emcc-opt-extra)"
os: clean
- @echo "WARNING: -Os can result in a build with mysteriously missing pieces!"
+ @echo "$(emo.fire)WARNING$(emo.fire): -Os can result in a build with mysteriously missing pieces!"
$(MAKE) -e "emcc_opt=-Os $(emcc-opt-extra)"
oz: clean
$(MAKE) -j2 -e "emcc_opt=-Oz $(emcc-opt-extra)"
/* Indicates a wasmfs build (untested and unsupported). */
F_WASMFS = 1<<6,
-
/**
Which compiled files from $(dir.dout)/buildName/*.{js,mjs,wasm}
to copy to $(dir.dout) after creating them.
.zBaseName = "sqlite3-64bit",
.zDotWasm = 0,
.zCmppD = 0,
- .zEmcc = "-sMEMORY64=1",
+ .zEmcc = "-sMEMORY64=1 -sWASM_BIGINT=1",
.zEnv = 0,
.zIfCond = 0,
.flags = CP_ALL | F_64BIT
.zBaseName = "sqlite3-64bit",
.zDotWasm = 0,
.zCmppD = "-Dtarget=es6-module",
- .zEmcc = "-sMEMORY64=1",
+ .zEmcc = "-sMEMORY64=1 -sWASM_BIGINT=1",
.zEnv = 0,
.zIfCond = 0,
.flags = CP_JS | F_ESM | F_64BIT
/* 64-bit bundler-friendly. */
.bundler64 = {
.zEmo = "๐ฆ",
- .zBaseName = "sqlite3-bundler-friendly",
- .zDotWasm = 0,
+ .zBaseName = "sqlite3-bundler-friendlyu",
+ .zDotWasm = "sqlite3-64bit",
.zCmppD = "$(c-pp.D.bundler)",
.zEmcc = "-sMEMORY64=1",
.zEnv = 0,
.zIfCond = 0,
- .flags = CP_JS | F_ESM | F_BUNDLER_FRIENDLY | F_64BIT
- //| F_NOT_IN_ALL
+ .flags = CP_JS | F_ESM | F_BUNDLER_FRIENDLY | F_64BIT | F_NOT_IN_ALL
},
/*
ps("endif");
}
-#if 0
- ps(zBanner
- /** $1 = build name. */
- "b.call.mkdir@ = "
- "if [ ! -d $(dir $@) ]; then"
- " echo '[$(emo.folder)+] $(if $(1),$(logtag.$(1)),[$(dir $@)])';"
- " mkdir -p $(dir $@) || exit $$?;"
- "fi"
- );
-#endif
-
ps(zBanner
/** $1 = build name */
"b.call.wasm-strip = "
- "echo '$(logtag.$(1)) $(emo.strip) wasm-strip $(out.$(1).wasm)'; "
+ "echo '[$(emo.b.$(1)) $(out.$(1).wasm)] $(emo.strip) wasm-strip'; "
"$(bin.wasm-strip) $(out.$(1).wasm)\n"
);
- ps(zBanner
- "# Inputs/outputs for the sqlite3-api.js family.\n"
- "#\n"
- "sqlite3-license-version.js = $(dir.tmp)/sqlite3-license-version.js\n"
- "sqlite3-api-build-version.js = $(dir.tmp)/sqlite3-api-build-version.js\n"
- "# sqlite3-api.jses = the list of JS files which make up\n"
- "# sqlite3-api.js, in the order they need to be assembled.\n"
- "sqlite3-api.jses = $(sqlite3-license-version.js)\n"
- "sqlite3-api.jses += $(dir.api)/sqlite3-api-prologue.js\n"
- "sqlite3-api.jses += $(dir.common)/whwasmutil.js\n"
- "sqlite3-api.jses += $(dir.jacc)/jaccwabyt.js\n"
- "sqlite3-api.jses += $(dir.api)/sqlite3-api-glue.c-pp.js\n"
- "sqlite3-api.jses += $(sqlite3-api-build-version.js)\n"
- "sqlite3-api.jses += $(dir.api)/sqlite3-api-oo1.c-pp.js\n"
- "sqlite3-api.jses += $(dir.api)/sqlite3-api-worker1.c-pp.js\n"
- "sqlite3-api.jses += $(dir.api)/sqlite3-vfs-helper.c-pp.js\n"
- "ifeq (0,$(wasm-bare-bones))\n"
- " sqlite3-api.jses += $(dir.api)/sqlite3-vtab-helper.c-pp.js\n"
- "endif\n"
- "sqlite3-api.jses += $(dir.api)/sqlite3-vfs-opfs.c-pp.js\n"
- "sqlite3-api.jses += $(dir.api)/sqlite3-vfs-opfs-sahpool.c-pp.js\n"
- "sqlite3-api.jses += $(dir.api)/sqlite3-api-cleanup.js"
- );
-
- ps(zBanner
- "# $(sqlite3-license-version.js) contains the license header and\n"
- "# in-comment build version info.\n"
- "#\n"
- "# Maintenance reminder: there are awk binaries out there which do not\n"
- "# support -e SCRIPT.\n"
- "$(sqlite3-license-version.js): $(sqlite3.h) "
- "$(dir.api)/sqlite3-license-version-header.js $(MAKEFILE)\n"
- "\t@echo '$(logtag.@) $(emo.disk)'; { \\\n"
- "\t\t$(call b.call.mkdir@); \\\n"
- "\t\tcat $(dir.api)/sqlite3-license-version-header.js || exit $$?; \\\n"
- "\t\techo '/*'; \\\n"
- "\t\techo '** This code was built from sqlite3 version...'; \\\n"
- "\t\techo '**'; \\\n"
- "\t\tawk '/define SQLITE_VERSION/{$$1=\"\"; print \"**\" $$0}' $(sqlite3.h); \\\n"
- "\t\tawk '/define SQLITE_SOURCE_ID/{$$1=\"\"; print \"**\" $$0}' $(sqlite3.h); \\\n"
- "\t\techo '**'; \\\n"
- "\t\techo '** with the help of Emscripten SDK version $(emcc.version).'; \\\n"
- "\t\techo '*/'; \\\n"
- "\t} > $@"
- );
-
- ps(zBanner
- "# $(sqlite3-api-build-version.js) injects the build version info into\n"
- "# the bundle in JSON form.\n"
- "$(sqlite3-api-build-version.js): $(bin.version-info) $(MAKEFILE)\n"
- "\t@echo '$(logtag.@) $(emo.disk)'; { \\\n"
- "\t\t$(call b.call.mkdir@); \\\n"
- "\t\techo 'globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){'; \\\n"
- "\t\techo -n ' sqlite3.version = '; \\\n"
- "\t\t$(bin.version-info) --json; \\\n"
- "\t\techo ';'; \\\n"
- "\t\techo '});'; \\\n"
- "\t} > $@"
- );
-
- ps(zBanner
- "# extern-post-js* and extern-pre-js* are files for use with\n"
- "# Emscripten's --extern-pre-js and --extern-post-js flags.\n"
- "extern-pre-js.js = $(dir.api)/extern-pre-js.js\n"
- "extern-post-js.in.js = $(dir.api)/extern-post-js.c-pp.js\n"
- "# Emscripten flags for --[extern-][pre|post]-js=... for the\n"
- "# various builds.\n"
- "# pre-post-jses.*.deps = lists of dependencies for the\n"
- "# --[extern-][pre/post]-js files.\n"
- "pre-post-jses.common.deps = "
- "$(extern-pre-js.js) $(sqlite3-license-version.js)"
- );
-
- ps(zBanner
- "# --post-js and --pre-js are emcc flags we use to append/prepend JS to\n"
- "# the generated emscripten module file. These rules set up the core\n"
- "# pre/post files for use by the various builds. --pre-js is used to\n"
- "# inject code which needs to run as part of the pre-WASM-load phase.\n"
- "# --post-js injects code which runs after the WASM module is loaded\n"
- "# and includes the entirety of the library plus some\n"
- "# Emscripten-specific post-bootstrapping code.\n"
- "pre-js.in.js = $(dir.api)/pre-js.c-pp.js\n"
- "post-js.in.js = $(dir.tmp)/post-js.c-pp.js\n"
- "post-jses.js ="
- " $(dir.api)/post-js-header.js"
- " $(sqlite3-api.jses)"
- " $(dir.api)/post-js-footer.js\n"
- "$(post-js.in.js): $(MKDIR.bld) $(post-jses.js) $(MAKEFILE)\n"
- "\t@echo '$(logtag.@) $(emo.disk)'\n"
- "\t@for i in $(post-jses.js); do \\n"
- "\t\techo \"/* BEGIN FILE: $$i */\"; \\n"
- "\t\tcat $$i || exit $$?; \\n"
- "\t\techo \"/* END FILE: $$i */\"; \\n"
- "\tdone > $@\n"
- );
-
pf(zBanner
"define b.do.emcc\n"
/* $1 = build name */
;
ps(zBanner
"# post-compilation WASM file optimization");
- ps("ifeq (,$(bin.wasm-opt))");
- {
- ps("define b.do.wasm-opt");
- ps("echo '$(logtag.$(1)) wasm-opt not available'");
- ps("endef");
+
+ /* b.do.wasm-opt $1 = build name*/
+ ps("ifeq (,$(bin.wasm-opt))"); {
+ ps("b.do.wasm-opt = echo '$(logtag.$(1)) wasm-opt not available'");
}
- ps("else");
- {
+ ps("else"); {
ps("define b.do.wasm-opt"
- /* $1 = build name*/
);
pf(
- "echo '$(logtag.$(1)) $(emo.tool) Applying $(bin.wasm-opt)';\\\n"
- "\trm -f wasm-opt-tmp.$(1).wasm;\\\n"
- /* It's very likely that the set of wasm-opt flags varies from
- ** version to version, so we'll ignore any errors here. */
- "\tif $(bin.wasm-opt) $(out.$(1).wasm) -o wasm-opt-tmp.$(1).wasm \\\n"
+ "echo '[$(emo.b.$(1)) $(out.$(1).wasm)] $(emo.wasm-opt) $(bin.wasm-opt)';\\\n"
+ "\ttmpfile=$(dir.dout.$(1))/wasm-opt-tmp.$(1).wasm; \\\n"
+ "\trm -f $$tmpfile; \\\n"
+ "\tif $(bin.wasm-opt) $(out.$(1).wasm) "
+ "-o $$tmpfile \\\n"
"\t\t%s; then \\\n"
- "\t\tmv wasm-opt-tmp.$(1).wasm $(out.$(1).wasm); \\\n"
+ "\t\tmv $$tmpfile $(out.$(1).wasm); \\\n"
#if 0
"\t\techo -n 'After wasm-opt: '; \\\n"
"\t\tls -l $(1); \\\n"
#endif
+ /* It's very likely that the set of wasm-opt flags varies from
+ ** version to version, so we'll ignore any errors here. */
"\telse \\\n"
+ "\t\trm -f $$tmpfile; \\\n"
"\t\techo '$(2) $(emo.fire) ignoring wasm-opt failure'; \\\n"
"\tfi\n",
zOptFlags
*/
static void emit_api_js(char const *zBuildName,
char const *zCmppD){
- pf("c-pp.D.%s ?= %s\n"
+ pf("c-pp.D.%s = %s\n"
"sqlite3-api.%s.js = $(dir.tmp)/sqlite3-api.%s.js\n",
zBuildName, zCmppD ? zCmppD: "",
zBuildName, zBuildName);
"%s,"
"$(sqlite3-api.jses),"
"$(sqlite3-api.%s.js),"
- "$(c-pp.D.%s) %s"
+ "$(c-pp.D.%s)"
"))\n",
- zBuildName, zBuildName, zBuildName, zCmppD ? zCmppD : "");
+ zBuildName, zBuildName, zBuildName);
pf("$(out.%s.js): $(sqlite3-api.%s.js)\n",
zBuildName, zBuildName);
}
pf("# zCmppD=%s\n# zBaseName=%s\n",
pB->zCmppD ? pB->zCmppD : "", zBaseName);
+ pf(
+ "b.names += %s\n"
+ "emo.b.%s = %s\n",
+ zBuildName, zBuildName, pB->zEmo);
+ pf("b.names += %s\n", zBuildName);
+
pf("logtag.%s ?= [%s [%s] $@]:\n", zBuildName, pB->zEmo, zBuildName);
if( pB->zIfCond ){
pf("%s\n", pB->zIfCond );
pf(zBanner
"$(out.%s.js): $(MAKEFILE_LIST) $(sqlite3-wasm.cfiles)"
" $(EXPORTED_FUNCTIONS.api)"
- " $(bin.mkwb) $(pre-post.%s.deps) "
- " $(sqlite3-api.ext.jses)"
- /* maintenance reminder: we set these ^^^^ as deps so that they
- ** get copied into place early. That allows the developer to
- ** reload the base-most test pages while the later-stage builds
- ** are still compiling, which is especially helpful when
- ** running builds with long build times (like -Oz). */
+ " $(bin.mkwb) $(pre-post.%s.deps)"
"\n",
zBuildName, zBuildName);
** 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 SQLITE.CALL.xJS.ESM-EXPORT-DEFAULT,1,%d,$(logtag.%s))\n",
+ pf("\t@$(call b.call.patch-export-default,1,%d,$(logtag.%s))\n",
(F_WASMFS & pB->flags) ? 1 : 0,
zBuildName
);
pf("\t@$(call b.call.strip-js-cruft,$(logtag.%s))\n", zBuildName);
if( CP_JS & pB->flags && !(pB->zDotWasm/*handled below*/) ){
- pf("\t@$(call b.call.cp,%s,$@,$(dir.dout)/.)\n",
+ pf("\t@$(call b.call.cp,%s,$@,$(dir.dout))\n",
zBuildName
);
}
if( CP_WASM & pB->flags ){
- pf("\t@$(call b.call.cp,%s,$(out.%s.wasm),$(dir.dout)/.)\n",
- zBuildName, zBuildName
+ pf("\t@$(call b.call.cp,%s,$(basename $@).wasm,$(dir.dout))\n",
+ zBuildName
//"\techo '[%s $(out.%s.wasm)] $(emo.disk) $(dir.dout)/$(notdir $(out.%s.wasm))'
//pB->zEmo, zBuildName
);
"exit 1; fi;\n", zBuildName);
}
}
- pf("\t@echo '$(logtag.%s) $(emo.done)'\n", zBuildName);
+ pf("\t@$(call b.echo,%s,$(emo.done) done!)\n", zBuildName);
pf("\n%dbit: $(out.%s.js)\n"
"$(out.%s.wasm): $(out.%s.js)\n"
pf("$(out.%s.js): $(MAKEFILE_LIST) $(MAKEFILE.fiddle) "
"$(EXPORTED_FUNCTIONS.fiddle) "
"$(fiddle.cses) "
- "$(pre-post.%s.deps) "
- "$(SOAP.js)\n",
+ "$(pre-post.%s.deps)\n",
zBuildName, zBuildName);
emit_compile_start(zBuildName);
pf("\t$(b.cmd@)$(bin.emcc) -o $@"
pf("\t@chmod -x $(out.%s.wasm)\n", zBuildName);
pf("\t@$(call b.call.wasm-strip,%s)\n", zBuildName);
pf("\t@$(call b.call.strip-js-cruft,$(logtag.%s))\n", zBuildName);
- pf("\t@$(call b.call.cp,%s,$(SOAP.js),$(dir $@))\n", zBuildName);
+ pf("\t@$(call b.call.cp,"
+ "%s,"
+ "$(dir.api)/sqlite3-opfs-async-proxy.js,"
+ "$(dir $@))\n", zBuildName);
if( isDebug ){
pf("\t@$(call b.call.cp,%s,"
"$(dir.fiddle)/index.html "