xref: /sqlite-3.40.0/ext/wasm/fiddle.make (revision 1f095d48)
1#!/do/not/make
2#^^^ help emacs select edit mode
3#
4# Intended to include'd by ./GNUmakefile.
5#######################################################################
6MAKEFILE.fiddle := $(lastword $(MAKEFILE_LIST))
7
8########################################################################
9# shell.c and its build flags...
10make-np-0 := make -C  $(dir.top) -n -p
11make-np-1 := sed -e 's/(TOP)/(dir.top)/g'
12$(eval $(shell $(make-np-0) | grep -e '^SHELL_OPT ' | $(make-np-1)))
13$(eval $(shell $(make-np-0) | grep -e '^SHELL_SRC ' | $(make-np-1)))
14# ^^^ can't do that in 1 invocation b/c newlines get stripped
15ifeq (,$(SHELL_OPT))
16$(error Could not parse SHELL_OPT from $(dir.top)/Makefile.)
17endif
18ifeq (,$(SHELL_SRC))
19$(error Could not parse SHELL_SRC from $(dir.top)/Makefile.)
20endif
21$(dir.top)/shell.c: $(SHELL_SRC) $(dir.top)/tool/mkshellc.tcl
22	$(MAKE) -C $(dir.top) shell.c
23# /shell.c
24########################################################################
25
26fiddle.emcc-flags = \
27  $(emcc.cflags) $(emcc_opt) \
28  --minify 0 \
29  -sALLOW_TABLE_GROWTH \
30  -sABORTING_MALLOC \
31  -sSTRICT_JS \
32  -sENVIRONMENT=web,worker \
33  -sMODULARIZE \
34  -sDYNAMIC_EXECUTION=0 \
35  -sWASM_BIGINT=$(emcc_enable_bigint) \
36  -sEXPORT_NAME=initFiddleModule \
37  -sEXPORTED_RUNTIME_METHODS=@$(dir.wasm)/EXPORTED_RUNTIME_METHODS.fiddle \
38  -sEXPORTED_FUNCTIONS=@$(dir.wasm)/EXPORTED_FUNCTIONS.fiddle \
39  --post-js=$(post-js.js) \
40  $(SQLITE_OPT) $(SHELL_OPT) \
41  -DSQLITE_SHELL_FIDDLE
42# -D_POSIX_C_SOURCE is needed for strdup() with emcc
43
44fiddle.EXPORTED_FUNCTIONS.in := \
45    EXPORTED_FUNCTIONS.fiddle.in \
46    EXPORTED_FUNCTIONS.api
47
48EXPORTED_FUNCTIONS.fiddle: $(fiddle.EXPORTED_FUNCTIONS.in) $(MAKEFILE.fiddle)
49	grep -h -v jaccwabyt $(fiddle.EXPORTED_FUNCTIONS.in) | sort -u > $@
50
51fiddle-module.js := $(dir.fiddle)/fiddle-module.js
52fiddle-module.wasm := $(subst .js,.wasm,$(fiddle-module.js))
53fiddle.cs := $(dir.top)/shell.c $(sqlite3-wasm.c)
54
55SOAP.js := sqlite3-opfs-async-proxy.js
56$(dir.fiddle)/$(SOAP.js): $(SOAP.js)
57	cp $< $@
58
59$(fiddle-module.js): $(MAKEFILE) $(MAKEFILE.fiddle) \
60    EXPORTED_FUNCTIONS.fiddle EXPORTED_RUNTIME_METHODS.fiddle \
61    $(fiddle.cs) $(post-js.js) $(dir.fiddle)/$(SOAP.js)
62	$(emcc.bin) -o $@ $(fiddle.emcc-flags) $(fiddle.cs)
63	$(maybe-wasm-strip) $(fiddle-module.wasm)
64	gzip < $@ > $@.gz
65	gzip < $(fiddle-module.wasm) > $(fiddle-module.wasm).gz
66
67$(dir.fiddle)/fiddle.js.gz: $(dir.fiddle)/fiddle.js
68	gzip < $< > $@
69
70clean: clean-fiddle
71clean-fiddle:
72	rm -f $(fiddle-module.js) $(fiddle-module.js).gz \
73        $(fiddle-module.wasm) $(fiddle-module.wasm).gz \
74        $(dir.fiddle)/$(SOAP.js) \
75        EXPORTED_FUNCTIONS.fiddle
76.PHONY: fiddle
77fiddle: $(fiddle-module.js) $(dir.fiddle)/fiddle.js.gz
78all: fiddle
79
80########################################################################
81# Explanation of the emcc build flags follows. Full docs for these can
82# be found at:
83#
84#  https://github.com/emscripten-core/emscripten/blob/main/src/settings.js
85#
86# -sENVIRONMENT=web: elides bootstrap code related to non-web JS
87#  environments like node.js. Removing this makes the output a tiny
88#  tick larger but hypothetically makes it more portable to
89#  non-browser JS environments.
90#
91# -sMODULARIZE: changes how the generated code is structured to avoid
92#  declaring a global Module object and instead installing a function
93#  which loads and initializes the module. The function is named...
94#
95# -sEXPORT_NAME=jsFunctionName (see -sMODULARIZE)
96#
97# -sEXPORTED_RUNTIME_METHODS=@/absolute/path/to/file: a file
98#  containing a list of emscripten-supplied APIs, one per line, which
99#  must be exported into the generated JS. Must be an absolute path!
100#
101# -sEXPORTED_FUNCTIONS=@/absolute/path/to/file: a file containing a
102#  list of C functions, one per line, which must be exported via wasm
103#  so they're visible to JS. C symbols names in that file must all
104#  start with an underscore for reasons known only to the emcc
105#  developers. e.g., _sqlite3_open_v2 and _sqlite3_finalize. Must be
106#  an absolute path!
107#
108# -sSTRICT_JS ensures that the emitted JS code includes the 'use
109#  strict' option. Note that -sSTRICT is more broadly-scoped and
110#  results in build errors.
111#
112# -sALLOW_TABLE_GROWTH is required for (at a minimum) the UDF-binding
113#  feature. Without it, JS functions cannot be made to proxy C-side
114#  callbacks.
115#
116# -sABORTING_MALLOC causes the JS-bound _malloc() to abort rather than
117#  return 0 on OOM. If set to 0 then all code which uses _malloc()
118#  must, just like in C, check the result before using it, else
119#  they're likely to corrupt the JS/WASM heap by writing to its
120#  address of 0. It is, as of this writing, enabled in Emscripten by
121#  default but we enable it explicitly in case that default changes.
122#
123# -sDYNAMIC_EXECUTION=0 disables eval() and the Function constructor.
124#  If the build runs without these, it's preferable to use this flag
125#  because certain execution environments disallow those constructs.
126#  This flag is not strictly necessary, however.
127#
128# -sWASM_BIGINT is UNTESTED but "should" allow the int64-using C APIs
129#  to work with JS/wasm, insofar as the JS environment supports the
130#  BigInt type. That support requires an extremely recent browser:
131#  Safari didn't get that support until late 2020.
132#
133# --no-entry: for compiling library code with no main(). If this is
134#  not supplied and the code has a main(), it is called as part of the
135#  module init process. Note that main() is #if'd out of shell.c
136#  (renamed) when building in wasm mode.
137#
138# --pre-js/--post-js=FILE relative or absolute paths to JS files to
139#  prepend/append to the emcc-generated bootstrapping JS. It's
140#  easier/faster to develop with separate JS files (reduces rebuilding
141#  requirements) but certain configurations, namely -sMODULARIZE, may
142#  require using at least a --pre-js file. They can be used
143#  individually and need not be paired.
144#
145# -O0..-O3 and -Oz: optimization levels affect not only C-style
146#  optimization but whether or not the resulting generated JS code
147#  gets minified. -O0 compiles _much_ more quickly than -O3 or -Oz,
148#  and doesn't minimize any JS code, so is recommended for
149#  development. -O3 or -Oz are recommended for deployment, but
150#  primarily because -Oz will shrink the wasm file notably. JS-side
151#  minification makes little difference in terms of overall
152#  distributable size.
153#
154# --minify 0: disables minification of the generated JS code,
155#  regardless of optimization level. Minification of the JS has
156#  minimal overall effect in the larger scheme of things and results
157#  in JS files which can neither be edited nor viewed as text files in
158#  Fossil (which flags them as binary because of their extreme line
159#  lengths). Interestingly, whether or not the comments in the
160#  generated JS file get stripped is unaffected by this setting and
161#  depends entirely on the optimization level. Higher optimization
162#  levels reduce the size of the JS considerably even without
163#  minification.
164#
165########################################################################
166