Add EXQLITE_EXTRA_SRC: statically compile SQLite extensions into the NIF - #355
Open
AlanMcCann wants to merge 1 commit into
Open
Add EXQLITE_EXTRA_SRC: statically compile SQLite extensions into the NIF#355AlanMcCann wants to merge 1 commit into
AlanMcCann wants to merge 1 commit into
Conversation
Some targets cannot use run-time loadable extensions at all: iOS forbids
dynamic code loading, and hardened deployments often disable load_extension.
Shipping per-architecture .so files is also a maintenance burden that static
compilation removes.
EXQLITE_EXTRA_SRC takes a space-separated list of C files compiled and linked
into the NIF alongside the bundled sqlite3.c. Paired with the existing
EXQLITE_SYSTEM_CFLAGS (-DSQLITE_CORE=1 -DSQLITE_EXTRA_INIT=...), an extension
such as sqlite-vec registers itself on every connection with no load_extension
call anywhere.
- Only applies when compiling the bundled SQLite; ignored under
EXQLITE_USE_SYSTEM (linking is the system library's business there).
- No-op when the variable is unset: OBJ and the pattern rules are unchanged,
verified by building and running with and without the hook.
- Extra objects are namespaced as extra_<basename>.o in BUILD, with sources
resolved via vpath, so out-of-tree paths (deps, vendored dirs) work.
- POSIX make only for now; Makefile.win untouched.
Verified end-to-end against this branch via a path dep and make_env only
(no fork consumer patches): sqlite-vec v0.1.9 statically linked into the
bundled 3.53.4, SELECT vec_distance_cosine(vec_f32('[1,0]'), vec_f32('[0,1]'))
returning 1.0 and the 45-degree case returning 1 - 1/sqrt(2). Also verified on
iOS (device-SDK static archive + execution in the simulator) in the migration
that motivated this, where load_extension was not an option.
Member
|
At some point I am going to package https://sqlite.org/vec1/doc/trunk/doc/vec1.md with this project once it becomes "offical" and stable. |
warmwaffles
approved these changes
Aug 13, 2026
warmwaffles
left a comment
Member
There was a problem hiding this comment.
This doesn't seem too insane to me. Tools for people who know the risks they are taking.
I was contemplating bundling sqlite-vec with this project, but I don't know if I can get it to cross compile for all supported precompiled architectures.
Member
|
Question:
How is this possible? This is a precompiled binary or compiled straight from source, how is the "hardened" server deployments disabling load extension @AlanMcCann? |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Run-time loadable extensions don't cover every target: iOS forbids dynamic code loading outright, and some hardened server deployments disable
load_extension. Shipping one pre-compiled.soper architecture is also a real maintenance burden. For those cases the natural answer is compiling the extension into the NIF next to the bundledsqlite3.c— SQLite supports this officially viaSQLITE_EXTRA_INIT— but the Makefile's source list is currently fixed, so today this requires forking exqlite.We hit this migrating a production Elixir app (SQLite + sqlite-vec for vector search, including an iOS target) and carried exactly this patch as a vendored fork; upstreaming the generic hook so nobody else has to.
What
EXQLITE_EXTRA_SRC— a space-separated list of C files compiled and linked into the NIF. Combined with the existingEXQLITE_SYSTEM_CFLAGS, an extension registers on every connection with noload_extensionanywhere:with an 8-line shim calling
sqlite3_auto_extension(sqlite3_vec_init). README section and CHANGELOG entry included.Design notes
OBJand the existing pattern rules are byte-identical without the variable.EXQLITE_USE_SYSTEM(linking is the system library's business there).extra_<basename>.owith sources resolved viavpath, so out-of-tree paths (deps, vendored dirs) work. Basename collisions are documented.Makefile.winuntouched (happy to add if you want it).Verified by execution
Against this branch, consumed as a plain path dep through
make_envonly:(orthogonal vectors → cosine distance 1.0; 45° → 1 − 1/√2 — known-answer checks, not just "it loaded"). The same static-link approach (same flags + shim) was additionally verified on iOS: device-SDK static archive builds clean and the query executes correctly in the simulator, which is the platform where this hook is the only option.