P5.1: vendor SQLite 3.53.2 + sx bindings

Subplan 02 Slice 2 foundation. vendor/sqlite/ holds the amalgamation
(provenance + upgrade notes in its README); make build compiles it into
build/vendor/libsqlite3.a (statically linked into dist via -L) and
build/vendor/jit/libsqlite3.dylib (dlopen'd by sx run via tests/run.sh's
-L flag) — separate directories because the macOS linker prefers a dylib
over an archive in one search dir.

The sx JIT resolves #foreign symbols via dlsym(RTLD_DEFAULT), where the
already-loaded OS libsqlite3 wins by load order — so the vendored build
renames its API to dist_sqlite3_* (vendor/sqlite/rename.h, -include'd),
making resolution unambiguous in both modes: those symbols exist only in
the vendored products.

src/db/sqlite.sx binds the renamed surface behind Sqlite/SqliteStmt
(open/exec/prepare/bind/step/column/finalize, errmsg, last_insert_rowid,
changes, libversion); opaque handles cross the FFI as usize, strings
read from sqlite are copied before its buffers die.

make test 20/20 (new: sqlite_smoke.sx — pins the loaded version to the
vendored 3.53.2, round trip, reopen persistence, BEGIN/ROLLBACK, errmsg;
also verified as an AOT binary with no libsqlite3 in otool -L).
This commit is contained in:
agra
2026-06-12 12:07:22 +03:00
parent aea3d62b60
commit afec94a113
8 changed files with 284184 additions and 4 deletions

View File

@@ -12,13 +12,35 @@ BUILD_DIR := build
SMOKE := tests/smoke.sx
DIST := src/dist.sx
.PHONY: build test publish-example clean
# Vendored SQLite (vendor/sqlite/README.md): one amalgamation, two build
# products in two DIRECTORIES — the macOS linker prefers a dylib over an
# archive in the same -L directory, and `sx build` must link the static
# copy while `sx run` (the test runner) dlopens the dylib.
VENDOR_DIR := $(BUILD_DIR)/vendor
SQLITE_SRC := vendor/sqlite/sqlite3.c
SQLITE_DEFS := -DSQLITE_DQS=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 \
-DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_SHARED_CACHE \
-DSQLITE_LIKE_DOESNT_MATCH_BLOBS \
-include vendor/sqlite/rename.h
$(VENDOR_DIR)/libsqlite3.a: $(SQLITE_SRC) vendor/sqlite/sqlite3.h vendor/sqlite/rename.h
@mkdir -p $(VENDOR_DIR)
cc $(SQLITE_DEFS) -O2 -c $(SQLITE_SRC) -o $(VENDOR_DIR)/sqlite3.o
ar rcs $@ $(VENDOR_DIR)/sqlite3.o
$(VENDOR_DIR)/jit/libsqlite3.dylib: $(SQLITE_SRC) vendor/sqlite/sqlite3.h vendor/sqlite/rename.h
@mkdir -p $(VENDOR_DIR)/jit
cc $(SQLITE_DEFS) -O2 -dynamiclib $(SQLITE_SRC) -o $@
.PHONY: build test publish-example vendor clean
vendor: $(VENDOR_DIR)/libsqlite3.a $(VENDOR_DIR)/jit/libsqlite3.dylib
# Compile the product sources (and the smoke program) without running.
build:
build: vendor
@mkdir -p $(BUILD_DIR)
$(SX) build -o $(BUILD_DIR)/smoke $(SMOKE)
$(SX) build -o $(BUILD_DIR)/dist $(DIST)
$(SX) build -o $(BUILD_DIR)/dist $(DIST) -L $(VENDOR_DIR)
# Run the test runner over every tests/**/*.sx. Exits non-zero on any
# failure. Depends on `build` so the CLI acceptance test (tests/cli_*.sx)