如何为Qt 6.4.1编译带SQLITE_ENABLE_LOAD_EXTENSION的SQLite插件
Qt 6 编译SQLite/MySQL驱动(支持自定义函数加载)遇阻问题
我正将应用升级至Qt 6版本,需编译MySQL和SQLite插件。其中SQLite需支持加载自定义函数,这需要编译SQLite3时添加SQLITE_ENABLE_LOAD_EXTENSION宏定义。
我参考Qt官方文档尝试两种方案:
- 使用已编译好该宏的系统SQLite库,执行命令:
qt-cmake -G "Unix Makefiles" ~/Qt/6.4.1/Src/qtbase/src/plugins/sqldrivers -DCMAKE_INSTALL_PREFIX=~/Qt/6.4.1 -DFEATURE_system_sqlite=ON -DCMAKE_INCLUDE_PATH=~/Projects/sqlite-amalgamation-3390300 -DCMAKE_LIBRARY_PATH=~/Projects/sqlite-amalgamation-3390300
但编译时出现链接错误:undefined reference to sqlite3_column_table_name16,即使移除其他libsqlite3.so也无法解决。
- 改用Qt内置SQLite,关闭
FEATURE_system_sqlite并修改sqlite/CMakeLists.txt添加SQLITE_ENABLE_LOAD_EXTENSION宏、移除SQLITE_OMIT_LOAD_EXTENSION,编译成功但插件仍无法加载自定义函数。
之后尝试改用Ninja构建,重新拉取Qt 6.4.1源码并安装Ninja,配置和编译时仍遇到配置失效、相同链接错误等问题。请问我哪里操作有误?
问题排查与解决方案
针对方案1(系统SQLite库链接错误)
sqlite3_column_table_name16是SQLite 3.38.0及以上版本新增的API,你所用的sqlite-amalgamation-3390300对应SQLite 3.39.3,理论上包含该函数,但链接报错的核心原因:- 你编译的系统SQLite可能未启用
SQLITE_ENABLE_COLUMN_METADATA宏,这个宏控制元数据类API(包括sqlite3_column_table_name16)是否被编译进库。重新编译SQLite时,要同时添加SQLITE_ENABLE_LOAD_EXTENSION和SQLITE_ENABLE_COLUMN_METADATA两个宏。 - 编译Qt插件时可能仍链接到系统默认的旧版SQLite,即便删除了旧库文件,动态链接缓存未更新。执行
sudo ldconfig刷新缓存,或者直接在cmake命令中用绝对路径指定库文件:-DSQLITE_LIBRARY=/path/to/your/compiled/libsqlite3.so,替代依赖CMAKE_LIBRARY_PATH的模糊匹配。
- 你编译的系统SQLite可能未启用
针对方案2(内置SQLite无法加载自定义函数)
- 修改
sqlite/CMakeLists.txt后,仅编译sqldrivers插件无效——Qt内置SQLite是qtbase模块的一部分,必须重新完整编译qtbase:- 进入Qt源码的
qtbase目录 - 执行配置命令:
qt-cmake . -DCMAKE_INSTALL_PREFIX=~/Qt/6.4.1 -DFEATURE_system_sqlite=OFF -DSQLITE_ENABLE_LOAD_EXTENSION=ON -DSQLITE_OMIT_LOAD_EXTENSION=OFF - 执行
make -j$(nproc)(或ninja)完成编译,再执行make install
- 进入Qt源码的
- 代码层面需主动开启扩展加载:在加载自定义函数前,执行
QSqlDatabase::database().exec("PRAGMA enable_load_extension=1");,否则即便SQLite编译了宏,也无法触发扩展加载逻辑。
关于Ninja构建的配置失效问题
- 重新拉取源码后,必须彻底清理旧构建目录,避免缓存干扰:
- 删除之前的sqldrivers或qtbase构建目录
- 创建全新的构建目录,进入后执行配置命令
- 全程用
ninja执行编译,不要混用Makefiles和Ninja的构建缓存,确保qt-cmake生成的是纯Ninja构建文件
额外注意事项
- 编译MySQL插件时,需明确指定MySQL的头文件和库路径,例如添加参数:
-DMYSQL_INCLUDE_DIR=/usr/include/mysql -DMYSQL_LIBRARY=/usr/lib/x86_64-linux-gnu/libmysqlclient.so - 所有编译操作统一使用Qt官方提供的
qt-cmake,避免系统cmake版本不兼容导致的配置异常
内容的提问来源于stack exchange,提问作者Allen Kempe
相关产品推荐
相关产品推荐

