如何编译SQLite

1. 概述

可以这样编译SQLite:

  • Unix和Mac:./configure && make
  • Windows:nmake /f Makefile.msc

以上命令将构建合并源码文件(amalgamation)和命令行接口(CLI)。它们没有必需的依赖,只要安装了编译器,上述命令就应能工作,不需要第三方软件。更多细节见:

不过,本文并不是提供逐步编译SQLite的操作配方,而是解释SQLite编译背后的原理。文中提供典型编译命令作为示例,期望应用开发者以此为指导,制定自己的定制编译过程。换句话说,本文提供思路与见解,而非开箱即用的解决方案。

因此,如果上面的概述命令还没有解答你的疑问,请继续阅读。

2. 合并源码文件与独立源文件

SQLite由分布在多个目录中的一百多个C代码文件和脚本构建而成。SQLite实现本身是纯ANSI C,但很多C语言源文件在纳入最终SQLite库之前,须由辅助C程序以及AWK、SED、TCL脚本生成或转换。构建这些必要的C程序,再转换或创建SQLite所需的C语言源码,是一个复杂过程。

为简化工作,SQLite也提供预先打包的合并源码文件sqlite3.c。它是一个ANSI C文件,实现了整个SQLite库。合并源码文件更容易使用:所有内容集中在一个代码文件中,可以方便地放入较大的C或C++程序源码树。

所有代码生成与转换步骤均已完成,因此不必配置和编译辅助C程序,也不用运行相关脚本。此外,由于整个库位于一个翻译单元中,编译器可以进行更深入的优化,原文指出可带来5%到10%的性能提升。因此,所有应用都建议使用合并源码文件sqlite3.c。

建议所有应用使用合并源码文件,可以从网站下载预先生成的版本,也可以自行从规范源码构建。

也可以使用各个独立源文件将SQLite库链接到应用中,但下载合并源码,或通过Makefile的sqlite3.c目标自行生成它,再用于后续构建,会容易得多。某些专用应用可能需要通过非标准编译期选项定制合并源码,而不能直接使用网站上的预生成版本。

也就是说,即便项目要求从独立源文件开始构建SQLite,仍然建议将合并源码文件作为中间步骤。

3. 编译命令行接口

构建命令行接口需要三个源文件:

  • sqlite3.c:SQLite合并源码文件。
  • sqlite3.h:配套头文件,定义SQLite的C语言接口。
  • shell.c:命令行接口程序本身。这个C源文件定义main()函数,以及提示用户输入、将输入交给SQLite数据库引擎处理的循环。

这三个源文件均包含在下载页面提供的合并源码tarball中;也可以通过Makefile的sqlite3.c目标,从规范源码构建它们。

构建CLI时,只需将这三个文件放在同一目录中,一起编译。使用MSVC时:

cl shell.c sqlite3.c -Fesqlite3.exe

在Unix系统上,命令通常类似这样:

gcc shell.c sqlite3.c -lpthread -ldl -lm -o sqlite3

SQLite要实现线程安全,需要pthreads库。但CLI本身是单线程的,因此可以让SQLite以非线程安全模式构建,从而省略pthreads库:

gcc -DSQLITE_THREADSAFE=0 shell.c sqlite3.c -ldl -lm -o sqlite3

-ldl库用于支持动态加载、sqlite3_load_extension()接口与load_extension() SQL函数。如果不需要这些功能,可以使用SQLITE_OMIT_LOAD_EXTENSION编译期选项将它们省略:

gcc -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION shell.c sqlite3.c -lm -o sqlite3

还可以提供其他编译期选项,例如:

要在EXPLAIN列表中看到额外注释,添加-DSQLITE_ENABLE_EXPLAIN_COMMENTS选项。添加-DHAVE_READLINE以及-lreadline、-lncurses库可获得命令行编辑支持。还可以指定编译器优化开关;SQLite网站上可下载的预编译CLI使用-Os。这里有无数种组合,一个功能丰富的shell编译命令可能如下:

gcc -Os -I. -DSQLITE_THREADSAFE=0 -DSQLITE_ENABLE_FTS4 \
       -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_JSON1 \
       -DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
       -DHAVE_READLINE \
       shell.c sqlite3.c -ldl -lm -lreadline -lncurses -o sqlite3

关键在于:构建CLI就是将两个C语言文件一起编译。shell.c定义入口和用户输入循环,SQLite合并源码sqlite3.c则包含SQLite库的完整实现。

4. 编译TCL接口

SQLite的TCL接口是加入常规合并源码中的小模块,最终生成新的合并源码文件tclsqlite3.c。只需这个单独源文件,就可以生成一个共享库,通过TCL load命令加载到标准tclsh或wish中;也可以生成内置SQLite的独立tclsh。

在Linux上生成可由TCL加载的SQLite库,使用以下命令即可:

gcc -o libtclsqlite3.so -shared tclsqlite3.c -lpthread -ldl -ltcl

遗憾的是,在Mac OS X和Windows上构建共享库远没有这么简单。

要生成静态链接SQLite的独立tclsh,可以使用以下编译命令:

gcc -DTCLSH=1 tclsqlite3.c -ltcl -lpthread -ldl -lz -lm

关键是-DTCLSH=1选项。SQLite的TCL接口模块在以-DTCLSH=1编译时,会包含一个main()过程,用于初始化TCL解释器并进入命令行循环。以上命令适用于Linux和Mac OS X,但可能需要根据平台以及所链接的TCL版本调整库选项。

5. 构建合并源码文件

下载页面提供的SQLite合并源码版本通常足以满足多数用户。然而,有些项目可能希望或需要自行构建合并源码。常见原因是使用某些编译期选项定制SQLite库。请记住,SQLite合并源码包含许多由辅助程序与脚本生成的C代码。

不少编译期选项会影响这些生成的代码,必须在组合合并源码之前传给代码生成器。所需选项集合可能随SQLite版本变化。原文此处的时间范围是SQLite 3.6.20前后,即2009年11月4日;当时生成器必须知道的选项包括:

要构建定制的合并源码,首先在Unix或类Unix开发平台下载原始独立源文件。务必取得原始源文件,而不是“预处理源文件”。完整的原始源文件集合可以从下载页面获取,也可以直接从配置管理系统获取。

假设SQLite源码树位于sqlite目录中,计划在并列目录(例如bld)中构建合并源码。首先在源码树顶层运行configure脚本,或者复制顶层的某个模板Makefile,创建合适的Makefile。然后手动编辑它,加入所需编译期选项。最后运行:

make sqlite3.c

在Windows上使用MSVC时,则运行:

nmake /f Makefile.msc sqlite3.c

sqlite3.c这个make目标会自动生成常规合并源码sqlite3.c、头文件sqlite3.h,以及包含TCL接口的合并源码tclsqlite3.c。之后可将所需文件复制到项目目录中,按前文介绍的方式编译。

6. 构建Windows DLL

要构建供Windows使用的SQLite DLL,首先取得相应的合并源码文件sqlite3.c与sqlite3.h。它们可以从SQLite网站下载,也可以按上文方法从源码定制生成。

源文件位于工作目录后,可使用下面的MSVC命令生成DLL:

cl sqlite3.c -link -dll -out:sqlite3.dll

该命令应从MSVC Native Tools Command Prompt(本机工具命令提示符)运行。安装MSVC后,通常有多个版本的命令提示符,分别用于x86、x64本机构建,也可能有交叉编译到ARM的版本。请根据目标DLL选择合适的命令提示符。

使用MinGW编译器时,命令为:

gcc -shared sqlite3.c -o sqlite3.dll

原文指出MinGW只生成32位DLL;另有独立的MinGW64项目可以生成64位DLL,其命令语法可能类似。原文还指出,较新MSVC版本生成的DLL无法在WinXP及更早Windows版本上运行,所以为尽可能提高兼容性,建议使用MinGW。原文给出的经验规则是:使用MinGW生成32位DLL,使用MSVC生成64位DLL。

大多数情况下,还应为以上基础命令补充适合应用的编译期选项。常用选项包括:

  • -Os:优化体积,使DLL尽可能小。
  • -O2:优化速度。循环展开和函数内联会使DLL变大。
  • -DSQLITE_ENABLE_FTS4:包含SQLite的全文搜索引擎代码。
  • -DSQLITE_ENABLE_RTREE:包含R-Tree扩展。
  • -DSQLITE_ENABLE_COLUMN_METADATA:启用某些常见系统(包括Ruby-on-Rails)需要的额外API。

原文:How To Compile SQLite,SQLite官方文档;页面最后更新:2025年11月13日07:12:58 UTC。按转载授权汉化。历史版本与工具链兼容性叙述按原文保留,命令未在本环境编译验证。SQLite源码的公共领域声明与许可说明应以官方页面为准。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容