小巧。快速。可靠。
三者选其二。
如何编译 SQLite
如何编译 SQLite

概述

SQLite 是 ANSI-C 源代码。在使用之前,它必须编译成机器代码。本文将指导您了解编译 SQLite 的各种方法。

本文未包含编译 SQLite 的分步食谱。因为每种开发情况都不同,这会很困难。相反,本文介绍并阐述了 SQLite 编译的原理。示例中提供了典型的编译命令,应用程序开发人员可以将这些示例用作开发自己的自定义编译过程的指南。换句话说,本文提供的是思路和见解,而不是现成的解决方案。

1. 整合版与单个源文件

SQLite 由分布在多个目录中的 100 多个 C 代码文件和脚本构成。SQLite 的实现是纯 ANSI-C,但许多 C 语言源代码文件是在被合并到最终的 SQLite 库之前,由辅助 C 程序以及 AWK、SED 和 TCL 脚本生成的或转换的。构建必要的 C 程序以及转换和/或创建 SQLite 的 C 语言源代码是一个复杂的过程。

为了简化问题,SQLite 也以预打包的 整合版 源代码文件提供:sqlite3.c。整合版是一个包含整个 SQLite 库的 ANSI-C 代码的单个文件。整合版更容易处理。所有内容都包含在一个代码文件中,因此很容易将其放入更大的 C 或 C++ 程序的源代码树中。所有代码生成和转换步骤都已经完成,因此没有需要配置和编译的辅助 C 程序,也没有需要运行的脚本。而且,由于整个库包含在一个翻译单元中,编译器能够进行更高级别的优化,从而提高 5% 到 10% 的性能。出于这些原因,整合版源文件(“sqlite3.c”)推荐用于所有应用程序。

推荐所有应用程序使用 整合版

当然可以从单个源代码文件直接构建 SQLite,但不建议这样做。对于某些特殊应用程序,可能需要以无法使用从网站下载的预构建整合版源文件完成的方式修改构建过程。对于这些情况,建议构建自定义整合版(如 下方 所述)并使用它。换句话说,即使项目需要从单个源文件开始构建 SQLite,也建议将整合版源文件用作中间步骤。

2. 编译命令行界面

构建 命令行界面 需要三个源文件

以上三个源文件都包含在 整合版压缩包 中,可从 下载页面 获取。

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

cl shell.c sqlite3.c -Fesqlite3.exe

在 Unix 系统上(或在 Windows 上使用 cygwin 或 mingw+msys),命令通常如下所示

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

pthreads 库是使 SQLite 线程安全的必要条件。但由于 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 -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 库的完整实现。

3. 编译 TCL 接口

SQLite 的 TCL 接口是一个小型模块,它被添加到常规整合版中。结果是一个名为“tclsqlite3.c”的新整合版源文件。这个单个源文件是生成共享库的唯一需要的东西,该共享库可以使用 tclshwishTCL load 命令 加载到标准 tclshwish 中,或生成一个包含内置 SQLite 的独立 tclsh。下载页面 上的 TEA 压缩包 中包含 TCL 整合版的副本,作为一个文件。

要在 Linux 上生成可加载的 TCL SQLite 库,以下命令就足够了

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

不幸的是,为 Mac OS X 和 Windows 生成共享库并不那么简单。对于这些平台,最好使用 TEA 压缩包 中包含的配置脚本和 makefile。

要生成与 SQLite 静态链接的独立 tclsh,请使用以下编译器调用

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

这里的诀窍是 -DTCLSH=1 选项。SQLite 的 TCL 接口模块包含一个 main() 函数,该函数在使用 -DTCLSH=1 编译时会初始化 TCL 解释器并进入命令行循环。上面的命令在 Linux 和 Mac OS X 上都有效,但您可能需要根据平台和链接的 TCL 版本调整库选项。

4. 构建整合版

下载页面 上提供的 SQLite 整合版通常足以满足大多数用户的需求。但是,某些项目可能希望或需要构建自己的整合版。构建自定义整合版的一个常见原因是为了使用某些 编译时选项 来自定义 SQLite 库。请记住,SQLite 整合版包含许多由辅助程序和脚本生成的 C 代码。许多编译时选项会影响此生成的代码,并且必须在组装整合版之前将其传递给代码生成器。必须传递到代码生成器的编译时选项集可能会因 SQLite 的不同版本而异,但在撰写本文时(大约在 SQLite 3.6.20,2009-11-04),代码生成器必须知道的选项集包括

要构建自定义整合版,首先将原始的单个源文件下载到 Unix 或类 Unix 开发平台上。请务必获取原始源文件,而不是“预处理的源文件”。您可以在 下载页面 或直接从 配置管理系统 中获取完整的原始源文件集。

假设 SQLite 源代码树存储在名为“sqlite”的目录中。计划在名为(例如)“bld”的并行目录中构建整合版。首先通过在 SQLite 源代码树的顶部运行配置脚本,或通过在源代码树的顶部复制一个模板 Makefile 来构建适当的 Makefile。然后手动编辑此 Makefile 以包含所需的编译时选项。最后运行

make sqlite3.c

或者在 Windows 上使用 MSVC

nmake /f Makefile.msc sqlite3.c

“sqlite3.c” make 目标会自动构建常规的“sqlite3.c”整合版源文件,它的头文件“sqlite3.h”,以及包含 TCL 接口的“tclsqlite3.c”整合版源文件。之后,可以将所需的文件复制到项目目录中,并根据上面概述的步骤进行编译。

5. 构建 Windows DLL

要在 Windows 中构建 SQLite 的 DLL,首先获取相应的整合版源代码文件,sqlite3.c 和 sqlite3.h。这些文件可以从 SQLite 网站 下载,也可以如上所述从源代码中自定义生成。

在工作目录中拥有源代码文件后,可以使用 MSVC 通过以下命令生成 DLL

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

以上命令应从 MSVC 原生工具命令提示符运行。如果您在机器上安装了 MSVC,您可能有多个版本的此命令提示符,用于 x86 和 x64 的原生构建,以及可能用于交叉编译到 ARM 的命令提示符。根据所需的 DLL 使用相应的命令提示符。

如果使用 MinGW 编译器,命令行如下所示

gcc -shared sqlite3.c -o sqlite3.dll

请注意,MinGW 只生成 32 位 DLL。有一个单独的 MinGW64 项目可用于生成 64 位 DLL。据推测,命令行语法类似。还要注意,最近的 MSVC 版本生成的 DLL 无法在 WinXP 及更早版本的 Windows 上运行。因此,为了最大程度地兼容生成的 DLL,建议使用 MinGW。一个很好的经验法则是使用 MinGW 生成 32 位 DLL,使用 MSVC 生成 64 位 DLL。

在大多数情况下,您希望用适合您的应用程序的 编译时选项 来补充上面的基本命令。常用的编译时选项包括

本页面最后修改于 2023-10-10 17:29:48 UTC