aboutsummaryrefslogtreecommitdiff
path: root/ext/wasm/mkwasmbuilds.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/wasm/mkwasmbuilds.c')
-rw-r--r--ext/wasm/mkwasmbuilds.c203
1 files changed, 110 insertions, 93 deletions
diff --git a/ext/wasm/mkwasmbuilds.c b/ext/wasm/mkwasmbuilds.c
index bc2ae0423..d33a10c01 100644
--- a/ext/wasm/mkwasmbuilds.c
+++ b/ext/wasm/mkwasmbuilds.c
@@ -11,18 +11,17 @@
*************************************************************************
**
** 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
+** sqlite3's canonical WASM build. The main motivation is to generate
+** code which "could" be created via GNU Make's eval command but is
** highly illegible when constructed that way. Attempts to write this
-** app in Bash and TCL have suffered from the problem that 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.
+** app in Bash and TCL have suffered from the problem that those
+** languages require escaping $ symbols, making the resulting script
+** code as illegible as the eval spaghetti we want to get away
+** from. Maintaining 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
@@ -35,15 +34,19 @@
#define ps puts
/*
-** Valid names for the zName arguments.
+** Valid build names. Each build is a combination of one of these and
+** one of JS_BUILD_MODES, but only certain combinations are legal.
+** This macro and JS_BUILD_MODES exist solely for documentation
+** purposes: they are not expanded into code anywhere.
*/
#define JS_BUILD_NAMES sqlite3 sqlite3-wasmfs
/*
-** Valid names for the zMode arguments of the "sqlite3" build. For the
-** "sqlite3-wasmfs" build, only "esm" (ES6 Module) is legal.
+** Valid build modes. For the "sqlite3-wasmfs" build, only "esm" (ES6
+** Module) is legal.
*/
#define JS_BUILD_MODES vanilla esm bundler-friendly node
-/* Separator to help eyeballs find the different sections */
+
+/* Separator to help eyeballs find the different output sections */
static const char * zBanner =
"\n########################################################################\n";
@@ -56,14 +59,14 @@ static const char * zBanner =
** to breakage in some of the flag checks.
*/
enum LibModeFlags {
- /* Sentinel value */
- LIBMODE_PLAIN = 0,
/* Indicates an ESM module build. */
LIBMODE_ESM = 0x01,
/* Indicates a "bundler-friendly" build mode. */
LIBMODE_BUNDLER_FRIENDLY = 0x02,
- /* Indicates to _not_ add this build to the 'all' target. */
- LIBMODE_DONT_ADD_TO_ALL = 0x04,
+ /* Indicates that this build is unsupported. Such builds are not
+ ** added to the 'all' target. The unsupported builds exist primarily
+ ** for experimentation's sake. */
+ LIBMODE_UNSUPPORTED = 0x04,
/* Indicates a node.js-for-node.js build (untested and
** unsupported). */
LIBMODE_NODEJS = 0x08,
@@ -80,8 +83,9 @@ struct BuildDef {
const char *zName; /* Name from JS_BUILD_NAMES */
const char *zMode; /* Name from JS_BUILD_MODES */
int flags; /* Flags from LibModeFlags */
- const char *zApiJsOut; /* Name of generated sqlite3-api.js/.mjs */
const char *zJsOut; /* Name of generated sqlite3.js/.mjs */
+ /* TODO: dynamically determine zJsOut based on zName, zMode, and
+ flags. */
const char *zCmppD; /* Extra -D... flags for c-pp */
const char *zEmcc; /* Extra flags for emcc */
};
@@ -90,41 +94,42 @@ typedef struct BuildDef BuildDef;
/*
** The set of WASM builds for the library (as opposed to the apps
** (fiddle, speedtest1)). This array must end with an empty sentinel
-** entry, but their order is otherwise not significant.
+** entry. Their order is mostly insignificant, but some makefile vars
+** used by some builds are set up by prior builds. Because of that,
+** the (sqlite3, vanilla), (sqlite3, esm), and (sqlite3,
+** bundler-friendly) builds should be defined first (in that order).
*/
const BuildDef aBuildDefs[] = {
{/* Core build */
- "sqlite3", "vanilla", LIBMODE_PLAIN,
- "$(sqlite3-api.js)", "$(sqlite3.js)", 0, 0},
+ "sqlite3", "vanilla", 0, "$(sqlite3.js)", 0, 0},
{/* Core ESM */
- "sqlite3", "esm", LIBMODE_ESM,
- "$(sqlite3-api.mjs)", "$(sqlite3.mjs)",
+ "sqlite3", "esm", LIBMODE_ESM, "$(sqlite3.mjs)",
"-Dtarget=es6-module", 0},
- {/* Core bundler-friend. Untested and "not really" supported, but
- ** required by the downstream npm subproject. */
+ {/* Core bundler-friendly build. Untested and "not really"
+ ** supported, but required by the downstream npm subproject.
+ ** Testing these would require special-purpose node-based tools and
+ ** custom test apps. Or we can pass them off as-is to the npm
+ ** subproject and they spot failures pretty quickly ;). */
"sqlite3", "bundler-friendly",
LIBMODE_BUNDLER_FRIENDLY | LIBMODE_ESM,
- "$(sqlite3-api-bundler-friendly.mjs)",
- "$(sqlite3-bundler-friendly.mjs)",
+ "$(dir.dout)/sqlite3-bundler-friendly.mjs",
"$(c-pp.D.sqlite3-esm) -Dtarget=es6-bundler-friendly", 0},
{/* node.js mode. Untested and unsupported. */
- "sqlite3", "node", LIBMODE_NODEJS | LIBMODE_DONT_ADD_TO_ALL,
- "$(sqlite3-api-node.mjs)", "$(sqlite3-node.mjs)",
+ "sqlite3", "node", LIBMODE_UNSUPPORTED | LIBMODE_NODEJS,
+ "$(dir.dout)/sqlite3-node.mjs",
"$(c-pp.D.sqlite3-bundler-friendly) -Dtarget=node", 0},
- {/* The wasmfs build is optional, untested, unsupported, and
- ** needs to be invoked conditionally using info we don't have
- ** here. */
+ {/* Wasmfs build. Fully unsupported and largely untested. */
"sqlite3-wasmfs", "esm" ,
- LIBMODE_WASMFS | LIBMODE_ESM | LIBMODE_DONT_ADD_TO_ALL,
- "$(sqlite3-api-wasmfs.mjs)", "$(sqlite3-wasmfs.mjs)",
+ LIBMODE_UNSUPPORTED | LIBMODE_WASMFS | LIBMODE_ESM,
+ "$(dir.wasmfs)/sqlite3-wasmfs.mjs",
"$(c-pp.D.sqlite3-bundler-friendly) -Dwasmfs",
"-sEXPORT_ES6 -sUSE_ES6_IMPORT_META"},
- {/*End-of-list sentinel*/0,0,0,0,0,0,0}
+ {/*End-of-list sentinel*/0,0,0,0,0,0}
};
/*
@@ -132,17 +137,40 @@ const BuildDef aBuildDefs[] = {
** needed by makefile code outside of these generated pieces).
*/
static void mk_prologue(void){
+ /* A 0-terminated list of makefile vars which we expect to have been
+ ** set up by this point in the build process. */
+ char const * aRequiredVars[] = {
+ "dir.top",
+ "dir.api", "dir.dout", "dir.tmp",
+ "sqlite3-license-version.js",
+ "MAKEFILE", "MAKEFILE_LIST",
+ /* Fiddle... */
+ "dir.fiddle", "dir.fiddle-debug",
+ "MAKEFILE.fiddle",
+ "EXPORTED_FUNCTIONS.fiddle",
+ /*"just-testing",*/
+ 0
+ };
+ char const * zVar;
+ int i;
+ pf("%s# Build setup sanity checks...\n", zBanner);
+ for( i = 0; (zVar = aRequiredVars[i]); ++i ){
+ pf("ifeq (,$(%s))\n", zVar);
+ pf(" $(error build process error: expecting make var $$(%s) to "
+ "have been set up by now)\n", zVar);
+ ps("endif");
+ }
pf("%s", zBanner);
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("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)");
+ ps("pre-post-common.flags = --extern-pre-js=$(sqlite3-license-version.js)");
+ ps("# pre-post-jses.deps.* = a list of dependencies for the\n"
+ "# --[extern-][pre/post]-js files.");
+ ps("pre-post-jses.deps.common = $(extern-pre-js.js) $(sqlite3-license-version.js)");
{
/* SQLITE.CALL.WASM-OPT = shell code to run $(1) (source wasm file
@@ -221,27 +249,26 @@ static void mk_prologue(void){
*/
static void mk_pre_post(const char *zName /* build name */,
const char *zMode /* build mode */,
- int flags /* LIBMODE_... mask */,
const char *zCmppD /* optional -D flags for c-pp for the
** --pre/--post-js files. */){
/* Very common printf() args combo. */
#define zNM zName, zMode
pf("%s# Begin --pre/--post flags for %s-%s\n", zBanner, zNM);
- pf("c-pp.D.%s-%s := %s\n", zNM, zCmppD ? zCmppD : "");
+ pf("c-pp.D.%s-%s = %s\n", zNM, zCmppD ? zCmppD : "");
pf("pre-post-%s-%s.flags ?=\n", zNM);
/* --pre-js=... */
- pf("pre-js.js.%s-%s := $(dir.tmp)/pre-js.%s-%s.js\n",
+ pf("pre-js.js.%s-%s = $(dir.tmp)/pre-js.%s-%s.js\n",
zNM, zNM);
- pf("$(pre-js.js.%s-%s): $(MAKEFILE_LIST)\n", zNM);
+ pf("$(pre-js.js.%s-%s): $(MAKEFILE_LIST) $(sqlite3-license-version.js)\n", zNM);
#if 1
pf("$(eval $(call SQLITE.CALL.C-PP.FILTER,$(pre-js.js.in),$(pre-js.js.%s-%s),"
"$(c-pp.D.%s-%s)))\n", zNM, zNM);
#else
/* This part is needed if/when we re-enable the custom
** Module.instantiateModule() impl in api/pre-js.c-pp.js. */
- pf("pre-js.js.%s-%s.intermediary := $(dir.tmp)/pre-js.%s-%s.intermediary.js\n",
+ pf("pre-js.js.%s-%s.intermediary = $(dir.tmp)/pre-js.%s-%s.intermediary.js\n",
zNM, zNM);
pf("$(eval $(call SQLITE.CALL.C-PP.FILTER,$(pre-js.js.in),$(pre-js.js.%s-%s.intermediary),"
"$(c-pp.D.%s-%s) -Dcustom-Module.instantiateModule))\n", zNM, zNM);
@@ -259,17 +286,17 @@ static void mk_pre_post(const char *zName /* build name */,
#endif
/* --post-js=... */
- pf("post-js.js.%s-%s := $(dir.tmp)/post-js.%s-%s.js\n", zNM, zNM);
+ pf("post-js.js.%s-%s = $(dir.tmp)/post-js.%s-%s.js\n", zNM, zNM);
pf("$(eval $(call SQLITE.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("extern-post-js.js.%s-%s = $(dir.tmp)/extern-post-js.%s-%s.js\n", zNM, zNM);
pf("$(eval $(call SQLITE.CALL.C-PP.FILTER,$(extern-post-js.js.in),$(extern-post-js.js.%s-%s),"
"$(c-pp.D.%s-%s)))\n", zNM, zNM);
/* Combined flags for use with emcc... */
- pf("pre-post-common.flags.%s-%s := "
+ 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);
@@ -278,10 +305,10 @@ static void mk_pre_post(const char *zName /* build name */,
"--pre-js=$(pre-js.js.%s-%s)\n", zNM, zNM, zNM);
/* Set up deps... */
- pf("pre-post-jses.%s-%s.deps := $(pre-post-jses.deps.common) "
+ 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",
+ pf("pre-post-%s-%s.deps = $(pre-post-jses.%s-%s.deps) $(dir.tmp)/pre-js.%s-%s.js\n",
zNM, zNM, zNM);
pf("# End --pre/--post flags for %s-%s%s", zNM, zBanner);
#undef zNM
@@ -289,20 +316,18 @@ static void mk_pre_post(const char *zName /* build name */,
/*
** Emits rules for the fiddle builds.
-**
*/
static void mk_fiddle(void){
int i = 0;
- mk_pre_post("fiddle-module","vanilla", 0, 0);
+ mk_pre_post("fiddle-module","vanilla", 0);
for( ; i < 2; ++i ){
+ /* 0==normal, 1==debug */
const char *zTail = i ? ".debug" : "";
const char *zDir = i ? "$(dir.fiddle-debug)" : "$(dir.fiddle)";
pf("%s# Begin fiddle%s\n", zBanner, zTail);
- pf("fiddle-module.js%s := %s/fiddle-module.js\n", zTail, zDir);
- pf("fiddle-module.wasm%s := "
- "$(subst .js,.wasm,$(fiddle-module.js%s))\n", zTail, zTail);
+ pf("fiddle-module.js%s = %s/fiddle-module.js\n", zTail, zDir);
pf("$(fiddle-module.js%s):%s $(MAKEFILE_LIST) $(MAKEFILE.fiddle) "
"$(EXPORTED_FUNCTIONS.fiddle) "
"$(fiddle.cses) $(pre-post-fiddle-module-vanilla.deps) "
@@ -314,7 +339,9 @@ static void mk_fiddle(void){
pf("\t$(bin.emcc) -o $@ $(fiddle.emcc-flags%s) "
"$(pre-post-fiddle-module-vanilla.flags) $(fiddle.cses)\n",
zTail);
- pf("\t$(maybe-wasm-strip) $(fiddle-module.wasm%s)\n", zTail);
+ ps("\t@chmod -x $(basename $@).wasm");
+ ps("\t@$(maybe-wasm-strip) $(basename $@).wasm");
+ ps("\t@$(SQLITE.strip-createExportWrapper)");
pf("\t@cp -p $(SOAP.js) $(dir $@)\n");
if( 1==i ){/*fiddle.debug*/
pf("\tcp -p $(dir.fiddle)/index.html "
@@ -323,13 +350,13 @@ static void mk_fiddle(void){
"$(dir $@)\n");
}
pf("\t@for i in %s/*.*js %s/*.html %s/*.wasm; do \\\n"
- "\t\ttest -f $${i} || continue; \\\n"
+ "\t\ttest -f $${i} || continue; \\\n"
"\t\tgzip < $${i} > $${i}.gz; \\\n"
"\tdone\n", zDir, zDir, zDir);
if( 0==i ){
ps("fiddle: $(fiddle-module.js)");
}else{
- ps("fiddle-debug: $(fiddle-module-debug.js)");
+ ps("fiddle-debug: $(fiddle-module.js.debug)");
}
pf("# End fiddle%s%s", zTail, zBanner);
}
@@ -347,36 +374,36 @@ static void mk_lib_mode(const BuildDef * pB){
** post-processing after Emscripten generates X.wasm. */;
assert( pB->zName );
assert( pB->zMode );
- assert( pB->zApiJsOut );
assert( pB->zJsOut );
-#define MT(X) ((X) ? (X) : "")
/* Very common printf() args combo. */
#define zNM pB->zName, pB->zMode
- pf("%s# Begin build [%s-%s]\n", zBanner, zNM);
- pf("# zApiJsOut=%s\n# zJsOut=%s\n# zCmppD=%s\n",
- pB->zApiJsOut, pB->zJsOut, MT(pB->zCmppD));
+ pf("%s# Begin build [%s-%s]. flags=0x%02x\n", zBanner, zNM, pB->flags);
+ pf("# zJsOut=%s\n# zCmppD=%s\n", pB->zJsOut,
+ pB->zCmppD ? pB->zCmppD : "<none>");
pf("$(info Setting up build [%s-%s]: %s)\n", zNM, pB->zJsOut);
- mk_pre_post(zNM, pB->flags, pB->zCmppD);
+ mk_pre_post(zNM, pB->zCmppD);
pf("\nemcc.flags.%s.%s ?=\n", zNM);
if( pB->zEmcc && pB->zEmcc[0] ){
pf("emcc.flags.%s.%s += %s\n", zNM, pB->zEmcc);
}
- pf("$(eval $(call SQLITE.CALL.C-PP.FILTER, $(sqlite3-api.js.in), %s, %s))\n",
- pB->zApiJsOut, MT(pB->zCmppD));
/* target pB->zJsOut */
- pf("%s: %s $(MAKEFILE_LIST) $(sqlite3-wasm.cfiles) $(EXPORTED_FUNCTIONS.api) "
+ pf("%s: $(MAKEFILE_LIST) $(sqlite3-wasm.cfiles) $(EXPORTED_FUNCTIONS.api) "
"$(pre-post-%s-%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). */
+ ** 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). */
"\n",
- pB->zJsOut, pB->zApiJsOut, zNM);
+ pB->zJsOut, zNM);
pf("\t@echo \"Building $@ ...\"\n");
+ if( LIBMODE_UNSUPPORTED & pB->flags ){
+ ps("\t@echo 'ACHTUNG: $@ is an unsupported build. "
+ "Use at your own risk.'");
+ }
pf("\t$(bin.emcc) -o $@ $(emcc_opt_full) $(emcc.flags) \\\n");
pf("\t\t$(emcc.jsflags) -sENVIRONMENT=$(emcc.environment.%s) \\\n",
pB->zMode);
@@ -393,28 +420,19 @@ static void mk_lib_mode(const BuildDef * pB){
pf("\t@$(call SQLITE.CALL.xJS.ESM-EXPORT-DEFAULT,1,%d)\n",
(LIBMODE_WASMFS & pB->flags) ? 1 : 0);
}
- pf("\t@chmod -x %s; \\\n"
- "\t\t$(maybe-wasm-strip) %s;\n",
- zWasmOut, zWasmOut);
+ pf("\t@chmod -x %s\n", zWasmOut);
+ pf("\t@$(maybe-wasm-strip) %s\n", zWasmOut);
pf("\t@$(call SQLITE.CALL.WASM-OPT,%s)\n", zWasmOut);
- pf("\t@sed -i -e '/^var _sqlite3.*createExportWrapper/d' %s || exit; \\\n"
- /* ^^^^^^ reminder: Mac/BSD sed has no -i flag */
- "\t\techo 'Stripped out createExportWrapper() parts.'\n",
- pB->zJsOut) /* Our JS code installs bindings of each 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
- considerably, by stripping them out. */;
+ ps("\t@$(SQLITE.strip-createExportWrapper)");
/*
- ** The above $(bin.emcc) call will write zJsOut and will create a
- ** like-named .wasm file (zWasmOut). 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
+ ** The above $(bin.emcc) call will write pB->zJsOut, a.k.a. $@, and
+ ** will create a like-named .wasm file (zWasmOut). That .wasm file
+ ** name gets hard-coded into $@ 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( (LIBMODE_BUNDLER_FRIENDLY & pB->flags)
- || (LIBMODE_NODEJS & pB->flags) ){
+ if( (LIBMODE_BUNDLER_FRIENDLY & pB->flags) ){
pf("\t@echo 'Patching $@ for %s.wasm...'; \\\n", pB->zName);
pf("\t\trm -f %s; \\\n", zWasmOut);
pf("\t\tsed -i -e 's/%s-%s.wasm/%s.wasm/g' $@ || exit;\n",
@@ -435,11 +453,10 @@ static void mk_lib_mode(const BuildDef * pB){
}else{
pf("\t@ls -la %s $@\n", zWasmOut);
}
- if( 0==(LIBMODE_DONT_ADD_TO_ALL & pB->flags) ){
+ if( 0==(LIBMODE_UNSUPPORTED & pB->flags) ){
pf("all: %s\n", pB->zJsOut);
}
pf("# End build [%s-%s]%s", zNM, zBanner);
-#undef MT
#undef zNM
}
@@ -452,8 +469,8 @@ int main(void){
mk_lib_mode( pB );
}
mk_fiddle();
- mk_pre_post("speedtest1","vanilla", 0, 0);
- mk_pre_post("speedtest1-wasmfs","esm", 0,
+ mk_pre_post("speedtest1","vanilla", 0);
+ mk_pre_post("speedtest1-wasmfs","esm",
"$(c-pp.D.sqlite3-bundler-friendly) -Dwasmfs");
return rc;
}