我想在sqlite中编译扩展以便在运行时加载。
我使用的文件是https://www.sqlite.org/contrib
的扩展名 - functions.c我已经能够编译成可加载的模块,但我需要静态链接它以便在运行时加载(使用shell.c
在运行时创建接口)
我已阅读有关链接的手册,但说实话,它超出了我的理解范围!
有人可以让我知道我需要做什么来编译吗?
答案 0 :(得分:1)
我找到了一种使用extension_functions.c
提供的附加功能从源代码编译sqlite3的方法。
注意:
这一次,我展示了一种使用其他功能编译sqlite的相当肮脏且简单的方法,因为我没有成功地以正确的方式完成该操作。
但是请记住,如上面@ngreen所述,最好准备合并的全新部分以添加自定义功能。
这就是sqlite本身的设计方式。
https://www.sqlite.org/download.html
选择一个合并,最好使用autoconf版本。
例如,这是版本3.33.0的下载链接。
https://www.sqlite.org/2020/sqlite-autoconf-3330000.tar.gz
curl -O https://www.sqlite.org/2020/sqlite-autoconf-3330000.tar.gz
tar -xzvf sqlite-autoconf-3330000.tar.gz
cd sqlite-autoconf-3330000
extension_functions.c
在此网址列出。
实际网址:
https://sqlite.org/contrib/download/extension-functions.c?get=25
curl -o extension_functions.c https://sqlite.org/contrib/download/extension-functions.c?get=25
我们可以指定--prefix
选项来确定建筑材料的目的地。
./configure --prefix=/usr/local/sqlite/3.33.0
此时可以将其他配置时间选项指定为环境变量。
检查https://www.sqlite.org/draft/compile.html了解更多详细信息。
这里是启用JSON和RTree索引功能的示例。
CPPFLAGS="-DSQLITE_ENABLE_JSON1=1 -DSQLITE_ENABLE_RTREE=1" ./configure --prefix=/usr/local/sqlite/3.33.0
还可以指定autoconf选项。
CPPFLAGS="-DSQLITE_ENABLE_JSON1=1 -DSQLITE_ENABLE_RTREE=1" ./configure --prefix=/usr/local/sqlite/3.33.0 --enable-dynamic-extensions
我在官方网站上找不到有关这些选项的任何文档,但是在configure脚本本身中找到了一些东西。
Optional Features:
--disable-option-checking ignore unrecognized --enable/--with options
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
--enable-silent-rules less verbose build output (undo: "make V=1")
--disable-silent-rules verbose build output (undo: "make V=0")
--disable-largefile omit support for large files
--enable-dependency-tracking
do not reject slow dependency extractors
--disable-dependency-tracking
speeds up one-time build
--enable-shared[=PKGS] build shared libraries [default=yes]
--enable-static[=PKGS] build static libraries [default=yes]
--enable-fast-install[=PKGS]
optimize for fast installation [default=yes]
--disable-libtool-lock avoid locking (might break parallel builds)
--enable-editline use BSD libedit
--enable-readline use readline
--enable-threadsafe build a thread-safe library [default=yes]
--enable-dynamic-extensions
support loadable extensions [default=yes]
--enable-fts4 include fts4 support [default=yes]
--enable-fts3 include fts3 support [default=no]
--enable-fts5 include fts5 support [default=yes]
--enable-json1 include json1 support [default=yes]
--enable-rtree include rtree support [default=yes]
--enable-session enable the session extension [default=no]
--enable-debug build with debugging features enabled [default=no]
--enable-static-shell statically link libsqlite3 into shell tool
[default=yes]
仅供参考,这是Homebrew中使用的默认安装脚本。确定应该指定哪个选项可能会很有用。
def install
ENV.append "CPPFLAGS", "-DSQLITE_ENABLE_COLUMN_METADATA=1"
# Default value of MAX_VARIABLE_NUMBER is 999 which is too low for many
# applications. Set to 250000 (Same value used in Debian and Ubuntu).
ENV.append "CPPFLAGS", "-DSQLITE_MAX_VARIABLE_NUMBER=250000"
ENV.append "CPPFLAGS", "-DSQLITE_ENABLE_RTREE=1"
ENV.append "CPPFLAGS", "-DSQLITE_ENABLE_FTS3=1 -DSQLITE_ENABLE_FTS3_PARENTHESIS=1"
ENV.append "CPPFLAGS", "-DSQLITE_ENABLE_JSON1=1"
args = %W[
--prefix=#{prefix}
--disable-dependency-tracking
--enable-dynamic-extensions
--enable-readline
--disable-editline
--enable-session
]
system "./configure", *args
system "make", "install"
end
现在我们必须修改extension_functions.c
以避免与sqlite的源代码冲突,然后再将它们编译在一起。
打开extension_functions.c
,并将第123〜128行替换为单行SQLITE_EXTENSION_INIT1
。
#ifdef COMPILE_SQLITE_EXTENSIONS_AS_LOADABLE_MODULE
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1
#else
#include "sqlite3.h"
#endif
↓
SQLITE_EXTENSION_INIT1
我们需要在shell.c
中插入一些行,以导入并启用扩展功能。
打开shell.c
,搜索static void open_db
,并在上一行插入#include "extension_functions.c"
。
#include "extension_functions.c"
static void open_db(ShellState *p, int openFlags){
然后搜索sqlite3_shathree_init(p->db, 0, 0);
并将sqlite3_extension_init(p->db, 0, 0);
插入初始化函数的底部。
#endif
sqlite3_fileio_init(p->db, 0, 0);
sqlite3_shathree_init(p->db, 0, 0);
sqlite3_completion_init(p->db, 0, 0);
sqlite3_uint_init(p->db, 0, 0);
sqlite3_decimal_init(p->db, 0, 0);
sqlite3_ieee_init(p->db, 0, 0);
sqlite3_extension_init(p->db, 0, 0);
最后,可以编译包含扩展功能的sqlite了。
make install
需要一段时间,完成后,将在配置时通过--prefix
选项指定的目标位置生成分发文件。
# Now we can use extension_functions without loading it manually.
$ /usr/local/sqlite/3.33.0/bin/sqlite3
sqlite> select cos(10);
-0.839071529076452
答案 1 :(得分:0)
我不确定这是否是一个完整的答案,但是从how to compile文档看来,您可能想先制作一个amalgamation。在src/shell.c.in
中,您可以搜索ext/misc
,然后会看到类似以下的行:
INCLUDE ../ext/misc/completion.c
tool/mkshellc.tcl
脚本使用这些行来构建组合的源文件,该文件最终将被编译到命令行外壳中。 sqlite3.c
的制作过程完成后,您应该在组合的源文件中看到想要的代码。
然后,我找到了一个包含以下代码的函数:
sqlite3_shathree_init(p->db, 0, 0);
我要做的就是将它添加到同一位置:
sqlite3_series_init(p->db, 0, 0);
现在我可以使用generate_series
函数了。我找不到您在说的functions.c
文件,但是过程应该类似。
答案 2 :(得分:0)
问:“如何将扩展编译为sqlite?”
A:这取决于扩展名。编译OP中引用的extension-functions.c
:
gcc -fPIC -shared extension-functions.c -o libsqlitefunctions.so -lm
(要删除编译警告,请参见here)
用法:
$ sqlite3
sqlite3> select cos(radians(45));
0.707106781186548
sqlite> .exit