MacOS 上 SQLite-Vec 扩展加载报 dlopen 错?这 2 处改完就能跑
2026/9/20 2:10:04 网站建设 项目流程

MacOS 上 SQLite-Vec 扩展加载报 dlopen 错?这 2 处改完就能跑

【免费下载链接】sqlite-vecA vector search SQLite extension that runs anywhere!项目地址: https://gitcode.com/GitHub_Trending/sq/sqlite-vec

$ python3 demo.py sqlite3.OperationalError: dlopen(/path/to/dist/vec0.dylib, 0x0002): invalid dylib $ sqlite3 sqlite> .load ./vec0.dylib Parse error near line 2: unable to open library "./vec0.dylib" (14)

dlopen failedSQLITE_CANTOPEN,是 macOS 上折腾 SQLite-Vec 扩展加载时最常见的两张脸。别急,这两个坑都不在代码里,一个出在架构,一个出在路径。跟着下面的步骤走,10 分钟内能把扩展跑起来。

make 一把,拿到 dist/vec0.dylib

先说结论:编译产物叫dist/vec0.dylib,不是很多教程里写的sqlite-vec.dylib。找错文件名是路径坑的源头之一。

克隆仓库

把仓库克隆到本地:

git clone https://gitcode.com/GitHub_Trending/sq/sqlite-vec cd sqlite-vec # 预期输出: Cloning into 'sqlite-vec'... 之后无报错,目录切换成功

拉取 SQLite amalgamation,再编译

编译前要先跑一遍 vendor 脚本,把 SQLite 官方的 amalgamation 源码下到vendor/目录,编译扩展时会用到里面的sqlite3ext.h,这步跳过后面 make 会直接失败:

./scripts/vendor.sh

然后make loadable只编译可动态加载的库。Makefile 会自己认出你的机器架构,自动补 SIMD 加速参数:Intel 的 Mac 走 AVX,M 芯片走 NEON,所以"在谁机器上编,就是谁的架构":

make loadable # 预期输出: 最后一行类似 dist/vec0.dylib,无 error 即成功

编译完用file验一下产物,架构和机器对得上才算数:

file dist/vec0.dylib # 预期输出: Mach-O 64-bit dynamically linked shared library arm64 #(M 芯片是 arm64,Intel 是 x86_64)

把 dist 目录写进 shell,一次配置长期有效

DYLD_LIBRARY_PATH相当于 macOS 版LD_LIBRARY_PATH,作用是指明动态库去哪里找。注意它和.load的相对路径是两套独立机制:.load ./xxx相对的是你敲命令时所在的目录,不是扩展库住哪儿。所以建议.load用绝对路径,别依赖当前目录。

打开 shell 配置文件(zsh 用户是~/.zshrc,bash 用户是~/.bash_profile),把 dist 目录追加进去:

echo 'export DYLD_LIBRARY_PATH="$PWD/dist:$DYLD_LIBRARY_PATH"' >> ~/.zshrc

保存后让配置立即生效并确认:

source ~/.zshrc echo $DYLD_LIBRARY_PATH # 预期输出: /path/to/sqlite-vec/dist: 开头包含 dist 目录的完整路径

sqlite3 里敲一句,版本回来就对了

打开sqlite3命令行,加载扩展并查版本,vec_version()返回版本号就代表扩展真正跑起来了:

sqlite3 # 预期输出: 进入 sqlite> 交互提示符 sqlite> .load /path/to/sqlite-vec/dist/vec0.dylib sqlite> select vec_version(); # 预期输出: v0.1.10-alpha.4(版本号随版本变化)

⚠️ 如果.load时直接报SQLITE_CANTOPEN,是路径的事,回上一节再核对一次;报dlopen相关错误则是架构不匹配,跳下面"翻车"部分处理。

除了命令行,Python 里也能加载。macOS 的 Pythonsqlite3模块默认禁用扩展加载,必须先调enable_load_extension,这是和 Linux 上手感差最大的地方:

import sqlite3 conn = sqlite3.connect(":memory:") conn.enable_load_extension(True) conn.execute('SELECT load_extension("/path/to/sqlite-vec/dist/vec0.dylib")') conn.execute("SELECT vec_version()") # 预期输出: 无异常,vec_version() 返回版本号

翻车就这两处,各一刀

架构对不上,file 一下就有答案

症状:M 芯片上加载报invalid dylibdlopen ... failed原因:dylib 的编译架构和运行机器对不上,最常见的是 x86 编译的库跑在 Apple Silicon 上。

先核对产物架构:

file dist/vec0.dylib uname -m # 预期输出: 两行架构一致,比如都是 arm64

不一致的话,在当前机器上直接重编即可,make 会自动选对指令集:

make loadable

CANTOPEN 十有八九是路径

症状.loadunable to open library(错误码 14,即SQLITE_CANTOPEN)。原因.load用的相对路径跟当前工作目录不匹配,或者文件压根不在那个位置。

先确认产物在不在:

ls -l dist/vec0.dylib # 预期输出: -rwxr-xr-x ... dist/vec0.dylib

在,就把.load换成文件的绝对路径再试一次;不,回编译那节重跑make loadable

Python 报 not authorized 的开关

症状:Python 里执行load_extensionOperationalError: ... not authorized原因:macOS 的sqlite3模块默认把扩展加载关了。

注意顺序,先开权限再加载:

conn.enable_load_extension(True) conn.execute('SELECT load_extension("/path/to/sqlite-vec/dist/vec0.dylib")')

记住这三条,下次不会再踩

  • 编译产物在dist/vec0.dylibfile输出必须和uname -m对得上,这是第一条命。
  • .load的相对路径跟着"你敲命令的目录"走,DYLD_LIBRARY_PATH管的是全局查找,两者互不相通,别混着调试。
  • Python 场景里enable_load_extension(True)是硬前提,漏了必报not authorized,和路径无关。

更多加载方式可以参考仓库里的 site/getting-started/installation.md,Python 集成的细节在 site/using/python.md。

【免费下载链接】sqlite-vecA vector search SQLite extension that runs anywhere!项目地址: https://gitcode.com/GitHub_Trending/sq/sqlite-vec

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询