########################################################################
# This GNU makefile drives the build of the sqlite3 WASM
# components. It is not part of the canonical build process.
+#
+# This build assumes a Linux platform and is not intended for
+# client-level use. It is for the sqlite project's own development of
+# the JS/WASM components.
+#
+# Primary targets:
+#
+# default, all = build in dev mode
+#
+# o0, o1, o2, o3, os, oz = full clean/rebuild with the -Ox level indicated
+# by the target name. Rebuild is necessary for all components to get
+# the desired optimization level.
+#
+# dist = create end user deliverables. Add dist-opt=oX to build with a
+# specific optimization level, where oX is one of the above-listed
+# o? target names.
+#
+# clean = clean up
########################################################################
SHELL := $(shell which bash 2>/dev/null)
MAKEFILE := $(lastword $(MAKEFILE_LIST))
-all:
-release: all
+default: all
+release: default
# Emscripten SDK home dir and related binaries...
EMSDK_HOME ?= $(word 1,$(wildcard $(HOME)/src/emsdk $(HOME)/emsdk))
dir.jacc := jaccwabyt
dir.common := common
dir.fiddle := fiddle
+dir.tool := $(dir.top)/tool
CLEAN_FILES := *~ $(dir.jacc)/*~ $(dir.api)/*~ $(dir.common)/*~
+DISTCLEAN_FILES := ./-dummy
emcc_enable_bigint ?= 1
sqlite3.c := $(dir.top)/sqlite3.c
sqlite3.h := $(dir.top)/sqlite3.h
$(sqlite3.c) $(sqlite3.h):
$(MAKE) -C $(dir.top) sqlite3.c
+.PHONY: clean distclean
clean:
-rm -f $(CLEAN_FILES)
+distclean: clean
+ -rm -f $(DISTCLEAN_FILES)
ifeq (release,$(filter release,$(MAKECMDGOALS)))
ifeq (,$(wasm-strip))
version-info := $(dir.wasm)/version-info
$(version-info): $(dir.wasm)/version-info.c $(sqlite3.h) $(MAKEFILE)
$(CC) -O0 -I$(dir.top) -o $@ $<
-CLEAN_FILES := $(version-info)
+DISTCLEAN_FILES += $(version-info)
+
+stripccomments := $(dir.tool)/stripccomments
+$(stripccomments): $(stripccomments).c $(MAKEFILE)
+ $(CC) -o $@ $<
+DISTCLEAN_FILES += $(stripccomments)
EXPORTED_FUNCTIONS.api.in := $(dir.api)/EXPORTED_FUNCTIONS.sqlite3-api
# painful.
.PHONY: o0 o1 o2 o3 os oz
-o-xtra := -g3
-# ^^^ -g3 is important to keep higher -O levels from mangling (via
-# minification), or outright removing, otherwise working code.
-
-o-xtra += -flto
+o-xtra := -flto
# ^^^^ -flto can have a considerably performance boost at -O0 but
# doubles the build time and seems to have negligible effect on
# higher optimization levels.
THIS_ARCH := $(shell /usr/bin/uname -m)
ifneq (,$(filter $(THIS_ARCH),$(PLATFORMS_WITH_NO_WASMFS)))
$(info This platform does not support the WASMFS build.)
+HAVE_WASMFS := 0
else
+HAVE_WASMFS := 1
include wasmfs.make
endif
but is less portable than the main build, so is provided
as a separate binary.
-Both directories contain small demonstration apps. Browsers will not
-server WASM files from file:// URLs, so the demonstrations require a
-web server and that server must include the following headers in its
-response when serving the files:
+Both directories contain small demonstration and test apps. Browsers
+will not serve WASM files from file:// URLs, so the demo/test apps
+require a web server and that server must include the following
+headers in its response when serving the files:
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
#######################################################################
MAKEFILE.dist := $(lastword $(MAKEFILE_LIST))
+ifeq (0,$(HAVE_WASMFS))
+$(error The 'dist' target needs to be run on a WASMFS-capable platform.)
+endif
########################################################################
# Chicken/egg situation: we need $(version-info) to get the version
-# info for the archive name, but that binary may not yet be built, so
-# we have to use a temporary name for the archive.
+# info for the archive name, but that binary may not yet be built, and
+# won't be built until we expand the dependencies. We have to use a
+# temporary name for the archive.
dist-name = sqlite-wasm-TEMP
dist-archive = $(dist-name).zip
-
+.PHONY: $(dist-archive)
+CLEAN_FILES += $(wildcard sqlite-wasm-*.zip)
#ifeq (0,1)
# $(info WARNING *******************************************************************)
# $(info ** Be sure to create the desired build configuration before creating the)
# $(info ** distribution archive. Use one of the following targets to do so:)
+# $(info **)
# $(info ** o2: builds with -O2, resulting in the fastest builds)
# $(info ** oz: builds with -Oz, resulting in the smallest builds)
# $(info /WARNING *******************************************************************)
#endif
+########################################################################
+# dist-opt must be the name of a target which triggers the
+# build of the files to be packed into the dist archive. The
+# intention is that it be one of (o0, o1, o2, o3, os, oz), each of
+# which uses like-named -Ox optimization level flags. The o2 target
+# provides the best overall runtime speeds. The oz target provides
+# slightly slower speeds (roughly 10%) with significantly smaller WASM
+# file sizes. Note that -O2 (the o2 target) results in faster binaries
+# than both -O3 and -Os (the o3 and os targets) in all tests run to
+# date.
+dist-opt ?= oz
+
demo-123.html := $(dir.wasm)/demo-123.html
demo-123-worker.html := $(dir.wasm)/demo-123-worker.html
demo-123.js := $(dir.wasm)/demo-123.js
-demo-files := $(demo-123.js) $(demo-123.html) $(demo-123-worker.html)
+demo-files := $(demo-123.js) $(demo-123.html) $(demo-123-worker.html) \
+ tester1.html tester1.js tester1-worker.html
README-dist := $(dir.wasm)/README-dist.txt
-$(dist-archive): $(sqlite3.wasm) $(sqlite3.js) $(sqlite3-wasmfs.wasm) $(sqlite3-wasmfs.js)
-#$(dist-archive): $(sqlite3.h) $(sqlite3.c) $(sqlite3-wasm.c)
-$(dist-archive): $(MAKEFILE.dist) $(version-info) $(demo-files) $(README-dist)
-$(dist-archive): oz
- rm -fr $(dist-name)
- mkdir -p $(dist-name)/main $(dist-name)/wasmfs
- cp -p $(README-dist) $(dist-name)/README.txt
- cp -p $(sqlite3.wasm) $(sqlite3.js) $(dist-name)/main
- cp -p $(demo-files) $(dist-name)/main
- cp -p $(sqlite3-wasmfs.wasm) $(sqlite3-wasmfs.js) $(dist-name)/wasmfs
- for i in $(demo-123.js) $(demo-123.html); do \
+dist-dir-main := $(dist-name)/main
+dist-dir-wasmfs := $(dist-name)/wasmfs
+########################################################################
+# $(dist-archive): create the end-user deliverable archive.
+#
+# Maintenance reminder: because $(dist-archive) depends on
+# $(dist-opt), and $(dist-opt) will depend on clean, having any deps
+# on $(dist-archive) which themselves may be cleaned up by the clean
+# target will lead to grief in parallel builds (-j #). Thus
+# $(dist-target)'s deps must be trimmed to non-generated files or
+# files which are _not_ cleaned up by the clean target.
+$(dist-archive): \
+ $(stripccomments) $(version-info) \
+ $(dist-opt) \
+ $(MAKEFILE) $(MAKEFILE.dist)
+ @echo "Making end-user deliverables..."
+ @rm -fr $(dist-name)
+ @mkdir -p $(dist-dir-main) $(dist-dir-wasmfs)
+ @cp -p $(README-dist) $(dist-name)/README.txt
+ @cp -p $(sqlite3.wasm) $(dist-dir-main)
+ @$(stripccomments) -k -k < $(sqlite3.js) \
+ > $(dist-dir-main)/$(notdir $(sqlite3.js))
+ @cp -p $(demo-files) $(dist-dir-main)
+ @cp -p $(sqlite3-wasmfs.wasm) sqlite3-wasmfs.worker.js $(dist-dir-wasmfs)
+ @$(stripccomments) -k -k < $(sqlite3-wasmfs.js) \
+ > $(dist-dir-wasmfs)/$(notdir $(sqlite3-wasmfs.js))
+ @for i in $(demo-123.js) $(demo-123.html); do \
sed -e 's/\bsqlite3\.js\b/sqlite3-wasmfs.js/' $$i \
- > $(dist-name)/wasmfs/$${i##*/} || exit; \
+ > $(dist-dir-wasmfs)/$${i##*/} || exit; \
done
- vnum=$$($(version-info) --version-number); \
+ @vnum=$$($(version-info) --version-number); \
vdir=sqlite-wasm-$$vnum; \
arc=$$vdir.zip; \
+ echo "Making $$arc ..."; \
rm -f $$arc; \
mv $(dist-name) $$vdir; \
zip -qr $$arc $$vdir; \
rm -fr $$vdir; \
ls -la $$arc; \
- unzip -l $$arc
+ unzip -lv $$arc || echo "Missing unzip app? Not fatal."
#$(shell $(version-info) --version-number)
dist: $(dist-archive)
-C Add\snew\stest\sfile\swindowE.test,\sto\stest\sthe\swindow\sfunctions\smodules\sresponse\sto\san\sinconsistent\scollation\ssequence.
-D 2022-10-18T15:02:08.725
+C More\swork\son\sthe\sJS\send-user\sdeliverables.\sAdd\stool/stripccomments.c\sto\ssupport\sthat.
+D 2022-10-18T20:36:50.562
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865f002fc80cb
F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c
F ext/wasm/EXPORTED_RUNTIME_METHODS.fiddle 0e88c8cfc3719e4b7e74980d9da664c709e68acf863e48386cda376edfd3bfb0
-F ext/wasm/GNUmakefile 2fd83d7183bce3f9236fdd2dbe20a4ea37b1d7b26e1a422054ec63008319f065
-F ext/wasm/README-dist.txt bc1fb4f90a28ad2ed0e555a637f393b9249d8d928ac509dad6293b7cae628ea4
+F ext/wasm/GNUmakefile 279fd4589ba602e24d8e66ca795ec5a2275a0e329405e4e984e8ea0579339bae
+F ext/wasm/README-dist.txt 170be2d47b4b52504ef09088ca2f143aab657de0f9ac04d3a68e366f40929c3d
F ext/wasm/README.md 1e5b28158b74ab3ffc9d54fcbc020f0bbeb82c2ff8bbd904214c86c70e8a3066
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api 89983a8d122c35a90c65ec667844b95a78bcd04f3198a99c1e0c8368c1a0b03a
F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de2470b0e9e7fbf7a5b41261c367cf4f1b7287
F ext/wasm/demo-123.js e0cbeb3495e14103763d5c49794a24d67cf3d78e0ed5b82843be70c0c2ee4b3b
F ext/wasm/demo-kvvfs1.html 7d4f28873de67f51ac18c584b7d920825139866a96049a49c424d6f5a0ea5e7f
F ext/wasm/demo-kvvfs1.js 105596bd2ccd0b1deb5fde8e99b536e8242d4bb5932fac0c8403ff3a6bc547e8
-F ext/wasm/dist.make d7076e90f04396f1cc54cb41ee106451496179c10d54bbdebb65ae7b1ae12211
+F ext/wasm/dist.make 1d59fafdfcf6fc5ee0f3351b21199585dba21afcf0518241789fd5d37a1c011d
F ext/wasm/fiddle.make b609dfde299b4523d7123b7e0cecaa1a0aff0dd984e62cea653aae91f5063c90
F ext/wasm/fiddle/emscripten.css 3d253a6fdb8983a2ac983855bfbdd4b6fa1ff267c28d69513dd6ef1f289ada3f
F ext/wasm/fiddle/fiddle-worker.js 531859a471924a0ea48afa218e6877f0c164ca324d51e15843ed6ecc1c65c7ee
F tool/sqltclsh.tcl 862f4cf1418df5e1315b5db3b5ebe88969e2a784525af5fbf9596592f14ed848
F tool/srcck1.c 371de5363b70154012955544f86fdee8f6e5326f
F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43
+F tool/stripccomments.c 20b8aabc4694d0d4af5566e42da1f1a03aff057689370326e9269a9ddcffdc37
F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d
F tool/symbols.sh 1612bd947750e21e7b47befad5f6b3825b06cce0705441f903bf35ced65ae9b9
F tool/varint.c 5d94cb5003db9dbbcbcc5df08d66f16071aee003
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 904b54625d985e742888e06ba792cab316b9ec9d6669d9cf509bac48030373ca
-R 609c010622cb8a1edf242ffa07ea33a0
-U dan
-Z 47ec91d5045ad14459bc2cd80292963b
+P 740a2eb0928d54fdf735a8e573c6a61a34dbd295b46e5b6ef39e957fd2623293
+R f3423b9e5fdd1b3c8749326c161b8bbf
+U stephan
+Z 8ed4b03e8c6243f1d25f4dc2d31715c7
# Remove this line to create a well-formed Fossil manifest.
-740a2eb0928d54fdf735a8e573c6a61a34dbd295b46e5b6ef39e957fd2623293
\ No newline at end of file
+2156f0744acfe425457430a0f6a7e02de907de85edba81a6d4eef40293e561c8
\ No newline at end of file
--- /dev/null
+/**
+ Strips C- and C++-style comments from stdin, sending the results to
+ stdout. It assumes that its input is legal C-like code, and does
+ only little error handling.
+
+ It treats string literals as anything starting and ending with
+ matching double OR single quotes OR backticks (for use with
+ scripting languages which use those). It assumes that a quote
+ character within a string which uses the same quote type is escaped
+ by a backslash. It should not be used on any code which might
+ contain C/C++ comments inside heredocs, and similar constructs, as
+ it will strip those out.
+
+ Usage: $0 [--keep-first|-k] < input > output
+
+ The --keep-first (-k) flag tells it to retain the first comment in the
+ input stream (which is often a license or attribution block). It
+ may be given repeatedly, each one incrementing the number of
+ retained comments by one.
+
+ License: Public Domain
+ Author: Stephan Beal (stephan@wanderinghorse.net)
+*/
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+
+#if 1
+#define MARKER(pfexp) \
+ do{ printf("MARKER: %s:%d:\t",__FILE__,__LINE__); \
+ printf pfexp; \
+ } while(0)
+#else
+#define MARKER(exp) if(0) printf
+#endif
+
+struct {
+ FILE * input;
+ FILE * output;
+ int rc;
+ int keepFirst;
+} App = {
+ 0/*input*/,
+ 0/*output*/,
+ 0/*rc*/,
+ 0/*keepFirst*/
+};
+
+void do_it_all(void){
+ enum states {
+ S_NONE = 0 /* not in comment */,
+ S_SLASH1 = 1 /* slash - possibly comment prefix */,
+ S_CPP = 2 /* in C++ comment */,
+ S_C = 3 /* in C comment */
+ };
+ int ch, prev = EOF;
+ FILE * out = App.output;
+ int const slash = '/';
+ int const star = '*';
+ int line = 1;
+ int col = 0;
+ enum states state = S_NONE /* current state */;
+ int elide = 0 /* true if currently eliding output */;
+ int state3Col = -99
+ /* huge kludge for odd corner case: */
+ /*/ <--- here. state3Col marks the source column in which a C-style
+ comment starts, so that it can tell if star-slash inside a
+ C-style comment is the end of the comment or is the weird corner
+ case marked at the start of _this_ comment block. */;
+ for( ; EOF != (ch = fgetc(App.input)); prev = ch,
+ ++col){
+ switch(state){
+ case S_NONE:
+ if('\''==ch || '"'==ch || '`'==ch){
+ /* Read string literal...
+ needed to properly catch comments in strings. */
+ int const quote = ch,
+ startLine = line, startCol = col;
+ int ch2, escaped = 0, endOfString = 0;
+ fputc(ch, out);
+ for( ++col; !endOfString && EOF != (ch2 = fgetc(App.input));
+ ++col ){
+ switch(ch2){
+ case '\\': escaped = !escaped;
+ break;
+ case '`':
+ case '\'':
+ case '"':
+ if(!escaped && quote == ch2) endOfString = 1;
+ escaped = 0;
+ break;
+ default:
+ escaped = 0;
+ break;
+ }
+ if('\n'==ch2){
+ ++line;
+ col = 0;
+ }
+ fputc(ch2, out);
+ }
+ if(EOF == ch2){
+ fprintf(stderr, "Unexpected EOF while reading %s literal "
+ "on line %d column %d.\n",
+ ('\''==ch) ? "char" : "string",
+ startLine, startCol);
+ App.rc = 1;
+ return;
+ }
+ break;
+ }
+ else if(slash == ch){
+ /* MARKER(("state 0 ==> 1 @ %d:%d\n", line, col)); */
+ state = S_SLASH1;
+ break;
+ }
+ fputc(ch, out);
+ break;
+ case S_SLASH1: /* 1 slash */
+ /* MARKER(("SLASH1 @ %d:%d App.keepFirst=%d\n",
+ line, col, App.keepFirst)); */
+ switch(ch){
+ case '*':
+ /* Enter C comment */
+ if(App.keepFirst>0){
+ elide = 0;
+ --App.keepFirst;
+ }else{
+ elide = 1;
+ }
+ /*MARKER(("state 1 ==> 3 @ %d:%d\n", line, col));*/
+ state = S_C;
+ state3Col = col-1;
+ if(!elide){
+ fputc(prev, out);
+ fputc(ch, out);
+ }
+ break;
+ case '/':
+ /* Enter C++ comment */
+ if(App.keepFirst>0){
+ elide = 0;
+ --App.keepFirst;
+ }else{
+ elide = 1;
+ }
+ /*MARKER(("state 1 ==> 2 @ %d:%d\n", line, col));*/
+ state = S_CPP;
+ if(!elide){
+ fputc(prev, out);
+ fputc(ch, out);
+ }
+ break;
+ default:
+ /* It wasn't a comment after all. */
+ state = S_NONE;
+ if(!elide){
+ fputc(prev, out);
+ fputc(ch, out);
+ }
+ }
+ break;
+ case S_CPP: /* C++ comment */
+ if('\n' == ch){
+ /* MARKER(("state 2 ==> 0 @ %d:%d\n", line, col)); */
+ state = S_NONE;
+ elide = 0;
+ }
+ if(!elide){
+ fputc(ch, out);
+ }
+ break;
+ case S_C: /* C comment */
+ if(!elide){
+ fputc(ch, out);
+ }
+ if(slash == ch){
+ if(star == prev){
+ /* MARKER(("state 3 ==> 0 @ %d:%d\n", line, col)); */
+ /* Corner case which breaks this: */
+ /*/ <-- slash there */
+ /* That shows up twice in a piece of 3rd-party
+ code i use. */
+ /* And thus state3Col was introduced :/ */
+ if(col!=state3Col+2){
+ state = S_NONE;
+ elide = 0;
+ state3Col = -99;
+ }
+ }
+ }
+ break;
+ default:
+ assert(!"impossible!");
+ break;
+ }
+ if('\n' == ch){
+ ++line;
+ col = 0;
+ state3Col = -99;
+ }
+ }
+}
+
+static void usage(char const *zAppName){
+ fprintf(stderr, "Strips C- and C++-style comments from stdin and sends "
+ "the results to stdout.\n");
+ fprintf(stderr, "Usage: %s [--keep-first|-k] < input > output\n", zAppName);
+}
+
+int main( int argc, char const * const * argv ){
+ int i;
+ for(i = 1; i < argc; ++i){
+ char const * zArg = argv[i];
+ while( '-'==*zArg ) ++zArg;
+ if( 0==strcmp(zArg,"k")
+ || 0==strcmp(zArg,"keep-first") ){
+ ++App.keepFirst;
+ }else{
+ usage(argv[0]);
+ return 1;
+ }
+ }
+ App.input = stdin;
+ App.output = stdout;
+ do_it_all();
+ return App.rc ? 1 : 0;
+}