Login
Documentation
Login

Building a LumoSQL Amalgamation

A LumoSQL amalgamation is a sqlite3.c + sqlite3.h pair, generated from a not-fork-patched SQLite tree, that compiles into a LumoSQL build. It may have rowsum extensions, the LMDB backend, or both.

The sqlite3.c file #includes a fixed set of helper sources which must be on the include path. The LMDB backend also links two LMDB object files.

Files

make (see "Generate the amalgamation") produces these under build/<target>/sources/sqlite3/:

file role
sqlite3.c, sqlite3.h the amalgamation and its header
shell.c the LumoSQL-aware shell source (optional)
src/lumo-vdbeInt.h, src/lumo-vdbeAdd.c, src/lumo-func.c, src/lumo-sha3.c, src/lumo-blake3*.c helpers #included from sqlite3.c
src/blake3.h, src/blake3_impl.h helper headers

LMDB variants also need:

file location role
mdb.o, midl.o build/<target>/sources/lmdb/ link into a static binary
mdb.c, midl.c build/<target>/sources/lmdb/ rebuild with -fPIC for a shared object
lmdb.h, midl.h build/<target>/lumo/build/ LMDB headers
backend/ build/<target>/lumo/build/.lumosql/ the backend shim directory

For an lmdbv1 target, the .c/.o directory is sources/lmdbv1/; the headers and backend/ stay under lumo/build/.

The backend/ directory holds lumo_btree.c, lumo_pager.c, lumo_backup.c, lumo_btmutex.c, lumo_wal.c, and lumo_btreeInt.h (some empty for the LMDB 0.9.x backend). Take these from lumo/build/.lumosql/backend/. The same names appear under sources/sqlite3/.lumosql/backend/ as one-line redirect stubs that resolve only inside the LumoSQL build tree.

sqlite3.c keeps #include "lumo-*.c/.h" and #include "backend/lumo_*.c" directives verbatim, and each backend/lumo_*.c #includes lmdb.h. The helpers, the backend/ directory, and lmdb.h must therefore be on the include path when sqlite3.c is compiled ("Use the amalgamation" arranges this).

Variant matrix

variant extra defines extra link
stock-btree, rowsum-off (none) -
stock-btree, rowsum-on -DLUMO_EXTENSIONS=1 -DLUMO_ROWSUM=on -
lmdb, rowsum-off -DLUMO_LMDB_FIXED_ROWID -DLUMO_BACKEND_PRAGMA mdb.o midl.o -lpthread
lmdb, rowsum-on -DLUMO_EXTENSIONS=1 -DLUMO_ROWSUM=on -DLUMO_LMDB_FIXED_ROWID -DLUMO_BACKEND_PRAGMA mdb.o midl.o -lpthread
lmdbv1, rowsum-off -DLUMO_LMDB_FIXED_ROWID -DLUMO_BACKEND_PRAGMA mdb.o midl.o -lpthread
lmdbv1, encrypt-on -DLUMO_LMDBV1_ENCRYPT -DLUMO_BACKEND_PRAGMA mdb.o midl.o -lpthread -lsodium

Every variant also needs -DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_FTS5 -DSQLITE_THREADSAFE=1, the SQLite feature flags the LumoSQL test suite assumes.

The lmdbv1 rows use the LMDB 1.0 backend (not-fork.d/lmdbv1/). The encrypt-on row links libsodium and uses two lumo-crypto.* files that "Use the amalgamation" carries automatically. Add -DLUMO_EXTENSIONS=1 -DLUMO_ROWSUM=on to either lmdbv1 row for rowsum-on.

Generate the amalgamation

From the top of the LumoSQL checkout:

make build TARGETS="3.53.1+lmdb-0.9.35" KEEP_SOURCES=1 ALWAYS_REBUILD=1

Other targets:

make build TARGETS="3.53.1++rowsum-on" KEEP_SOURCES=1
make build TARGETS="3.53.1+lmdb-0.9.35+rowsum-on" KEEP_SOURCES=1
make build TARGETS="3.53.1+lmdbv1-1.0" KEEP_SOURCES=1
make build TARGETS="3.53.1+lmdbv1-1.0+lmdbv1_encrypt-on" KEEP_SOURCES=1   # needs libsodium-dev

KEEP_SOURCES=1 is required; without it the patched tree and sqlite3.c are deleted at the end of the build. <target> in the paths below is the literal target string, e.g. 3.53.1+lmdb-0.9.35+rowsum-on.

Sanity-check the result:

cd build/<target>/sources/sqlite3
grep -c '#include "lumo-vdbeInt.h"'   sqlite3.c   # >= 1
grep -c '#include "lumo-vdbeAdd.c"'   sqlite3.c   # 1
grep -c 'lumoExtensionAdd\|lumoRowsumFunc' sqlite3.c  # > 0 if rowsum-on
grep -c '#include "backend/lumo_'     sqlite3.c   # > 0 for LMDB variants, 0 for stock-btree

Use the amalgamation

Pick a directory $DST in your project where sqlite3.c and sqlite3.h will live. Copy the files there:

SRC=/path/to/lumosql/build/<target>/sources/sqlite3
LM=/path/to/lumosql/build/<target>/sources/lmdb    # sources/lmdbv1 for an lmdbv1 target
LB=/path/to/lumosql/build/<target>/lumo/build
DST=/path/to/your/project/sqlite-dir

cp $SRC/sqlite3.c $SRC/sqlite3.h $DST/
cp $SRC/src/lumo-vdbeInt.h $SRC/src/lumo-vdbeAdd.c $SRC/src/lumo-func.c $SRC/src/lumo-sha3.c $DST/
cp $SRC/src/lumo-blake3*.c $SRC/src/blake3.h $SRC/src/blake3_impl.h $DST/

# LMDB variants only:
cp -r $LB/.lumosql/backend $DST/backend   # the backend shim (see "Files")
cp $LB/lmdb.h $LB/midl.h    $DST/          # headers, from lumo/build/
cp $LM/mdb.o  $LM/midl.o    $DST/          # objects, for a static binary
# For a shared library, rebuild PIC objects (-I$DST so mdb.c finds lmdb.h):
# cc -fPIC -O2 -I$DST -c $LM/mdb.c  -o $DST/mdb_pic.o
# cc -fPIC -O2 -I$DST -c $LM/midl.c -o $DST/midl_pic.o

Compile sqlite3.c with -I$DST as the only LumoSQL include path. From there, #include "backend/lumo_btree.c" resolves to $DST/backend/lumo_btree.c and its #include "lmdb.h" resolves to $DST/lmdb.h.

Example: a standalone shell, lmdb + rowsum-on. Use the defines from the variant matrix.

cd $DST
cc -O2 -I. \
   -DLUMO_EXTENSIONS=1 -DLUMO_ROWSUM=on \
   -DLUMO_LMDB_FIXED_ROWID -DLUMO_BACKEND_PRAGMA \
   -DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_FTS5 -DSQLITE_THREADSAFE=1 \
   sqlite3.c shell.c mdb.o midl.o \
   -o lumo_sqlite3 -lpthread -lm -ldl

Drop mdb.o midl.o and the LMDB defines for stock-btree. Drop -DLUMO_EXTENSIONS=1 -DLUMO_ROWSUM=on for rowsum-off.

For encrypted lmdbv1, swap -DLUMO_LMDB_FIXED_ROWID for -DLUMO_LMDBV1_ENCRYPT and add -lsodium:

cd $DST
cc -O2 -I. \
   -DLUMO_LMDBV1_ENCRYPT -DLUMO_BACKEND_PRAGMA \
   -DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_FTS5 -DSQLITE_THREADSAFE=1 \
   sqlite3.c shell.c mdb.o midl.o \
   -o lumo_sqlite3 -lsodium -lpthread -lm -ldl

An encrypted database opens with a key in the connection URI, e.g. lumo_sqlite3 'file:/path/to/db?lumo_key=your passphrase'. The first open writes lumo.salt (mode 0600) in the database directory; later opens reuse it. The wrong key or no key fails with SQLITE_AUTH. A URI key is visible on the process command line (argv, shell history, /proc); use it for evaluation only.

Verify

A LumoSQL binary passes the LumoSQL SQL test suite. From the LumoSQL checkout:

make test-sql TARGETS="<target>"
tclsh tool/test-sql-filter.tcl -db test-sql.sqlite

A standalone lumo_sqlite3 from "Use the amalgamation" tests the amalgamation alone. If it passes and your application build fails, the difference is in your build.