From 80970cc2a04c532ede12170e3dba68f24d4ee6a3 Mon Sep 17 00:00:00 2001 From: Aaron Paterson Date: Fri, 23 Oct 2026 02:29:35 -0500 Subject: [PATCH] fix(sqlite-vec.h.tmpl): give SQLITE_VEC_API no __attribute__ under MSVC in static builds With -DSQLITE_VEC_STATIC the template defines SQLITE_VEC_API as __attribute__((visibility("default"))) on every compiler. MSVC has no __attribute__, so a static build with it stops at the header's declaration of sqlite3_vec_init(); with MSVC 19.44 on windows-2022: cl /c /W4 /Ivendor/ /O2 /DSQLITE_CORE /DSQLITE_VEC_STATIC sqlite-vec.c sqlite-vec.h(33): error C2143: syntax error: missing ')' before '(' sqlite-vec.h(33): error C2091: function returns function The loadable build, which CI compiles with cl.exe, takes the _WIN32 branch and is unaffected. The static branch now applies the attribute only under GCC and Clang outside Windows, the guard asg017/sqlite-vec#340 uses, and defines SQLITE_VEC_API empty otherwise. With GCC and Clang the static objects are byte-identical before and after. sqlite-vec.h regenerates from the template at release, as it does for the template's other changes. --- CHANGELOG.md | 1 + sqlite-vec.h.tmpl | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index da5f90d1..f7680ce7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ ### Fixed +- Compiling `sqlite-vec.c` with MSVC and `-DSQLITE_VEC_STATIC` succeeds; in that build `sqlite-vec.h` declared `sqlite3_vec_init()` with `__attribute__((visibility("default")))` on every compiler, and MSVC, which has no `__attribute__`, stopped with `error C2143`. GCC and Clang builds are unchanged. - A KNN query that takes its query vector, `k`, or `mmr_lambda` from another table of a join now uses it. `select v.rowid from p join v on v.embedding match ? and v.k = p.k` failed with `A LIMIT or 'k = ?' constraint is required`; the same join with `v.k = 3 and v.mmr_lambda = p.lambda` returned no rows; and `select v.rowid from v join p on p.id = v.tag where v.embedding match p.vector and v.k = 2`, with `p.id` an integer primary key, could return no rows. These joins now run one KNN per row of the other table, so a filter on the `vec0` table whose value comes from that table applies before the k nearest rows are chosen. Ported in part from the unmerged [vlasky#14](https://github.com/vlasky/sqlite-vec/pull/14) ([asg017#331](https://github.com/asg017/sqlite-vec/pull/331)), which also applies filters whose value comes from a joined table before the k nearest rows are chosen; that part is not ported, and ARCHITECTURE.md's idxStr section says why. ## [2.1.1] - 2026-10-09 diff --git a/sqlite-vec.h.tmpl b/sqlite-vec.h.tmpl index 33d977e4..e150c0d1 100644 --- a/sqlite-vec.h.tmpl +++ b/sqlite-vec.h.tmpl @@ -8,8 +8,12 @@ #endif #ifdef SQLITE_VEC_STATIC +#if defined(__GNUC__) && !defined(_WIN32) #define SQLITE_VEC_API __attribute__((visibility("default"))) #else +#define SQLITE_VEC_API +#endif +#else #ifdef _WIN32 #define SQLITE_VEC_API __declspec(dllexport) #else