How To Compile SQLite

本文介绍如何编译SQLite数据库,包括合并文件与未合并文件的区别、编译命令行工具CLI、TCL接口、生成定制合并文件及Windows DLL的方法。文中详细列举了不同平台下的典型编译命令,并介绍了编译选项对功能的影响。

概述

SQLite是符合ANSI-C规范的源码,在使用的时候必须编译成机器码.本文档是各种编译SQLite的方法指南.

本文档并不包含事无巨细的编译细节,这将是比较困难的,因为各个开发环境是不同的. 本文档描述说明了编译SQLite的原则,并提供了典型的编译命令, 开发人员可以根据这些编译命令, 定制自己的编译流程.也就是说, 本文档提供了编译SQLite的一些思想和见解,但不是一个交钥匙的解决方案.

1.合并文件与未合并文件

SQLite工程包含超过100多个C源码文件和脚本文件,这些文件分布在多个目录之中.尽管SQLite是由纯ANSI-C实现的, 但是在编译SQLite之前, 有些C源码文件是由其他辅助C程序或者AWK, SED和TCL脚本生成或者转换而来的, 这将是一个复杂的处理过程.

为了简化这个问题, SQLite提供了一种经过预处理的合并形式的源码文件:sqlite3.c, 该文件是一个单独的ANSI-C源码文件, 包含整个SQLite库执行逻辑.因为是一个单独的文件,所以很容易浏览其C源码程序实现细节,也很容易编译处理. 该合并文件中已经包含了那些辅助程序和脚本生成的代码, 同时,也因为只有一个翻译单元,编译器也能执行一些高级的优化, 有5%-10%的性能提升.因为如上这些原因, 推荐使用合并文件的形式(“sqlite3.c“).

更多关于合并文件信息请参考这里.

当然,直接编译未合并文件肯定是可以的, 但并不推荐.对一些特殊的应用程序,需要修改编译处理,而合并文件不能满足要求的情况下,推荐使用定制的合并文件(参考本文档第四部分). 也就是说, 即使工程需要编译未合并文件,也推荐使用合并文件作为编译的中间步骤.

2.编译CLI(Command-Line Interface)

编译CLI需要3个源代码文件:

  • sqlite3.c: 合并形式的源码文件
  • sqlite3.h: 头文件,定义了SQLite的C语言接口
  • shell.c: CLI程序本身.该C源码文件包含的main()执行入口,和循环处理用户在控制终端的输入参数.

这三个文件被归档在一个tar包里面, 可以从下载页面获得.
为了编译CLI, 只需要将这三个文件放到同一个目录下面进行编译即可.使用MSVC进行编译的命令如下:

cl shell.c sqlite3.c -Fesqlite3.exe

在类unix操作系统上,( 或者在配置了cygwin 或者mingw+msys的Windows操作系统下),典型的编译命令如下:

gcc shell.c sqlite3.c -lpthread -ldl

线程库是为了使SQLite是线程安全的,因为CLI是单线程的,因此可以忽略线程库而编译一个非线程安全模式的SQLite:

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

动态链接库是为了支持接口 sqlite3_load_extension()load_extension() 装载扩展库及其符号函数.可以在编译时通过定义 SQLITE_OMIT_LOAD_EXTENSION去掉这些特性:

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

你也可以提供其他的编译选项,比如 -DSQLITE_ENABLE_FTS4 或者-DSQLITE_ENABLE_FTS5来控制全文搜索, -DSQLITE_ENABLE_RTREE用来控制R*Tree搜索引擎扩展, -DSQLITE_ENABLE_JSON1来控制JSON SQL函数, -DSQLITE_ENABLE_DBSTAT_VTAB用来控制虚表, -DSQLITE_ENABLE_EXPLAIN_COMMENTS用来控制 EXPLAIN.在Unix操作系统上,通过定义-DHAVE_USLEEP=1来支持usleep()系统调用.定义 -DHAVE_READLINE并链接-lreadline 和 -lncurses库,来支持命令行编辑.官方文章编译的CLI的优化选项是”-Os”, 你也可以指定其他的编译优化开关.编译一个全功能的CLI的命令如下所示:

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

这里的关键点是,编译CLI时,需要编译2个C源码文件.shell.c文件包含执行入口和用户输入处理,合并文件sqlite3.c包含完整的SQLite库执行逻辑.

3.编译TCL接口

TCL接口是SQLite的一个小的模块,其实现逻辑在另一个合并文件中:”tclsqlite3.c“.可以编译该文件为共享库, 使用标准的tclsh或者wishTCL load命令进行装载,或者生成独立的tclsh而嵌入SQLite之中.可以从下载页中活动该合并文件的归档打包文件.

为了生成TCL可以装载的共享库, 在Linxu操作系统下,使用如下编译命令:

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

但是,在Mac OS X和Windows操作系统下编译该共享库并不是如此简单,在这两个平台下,最好使用归档tar包中的配置脚本和makefile进行编译.

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

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

这里的技巧就是-DTCLSH=1,当定义这个编译选项时, TCL接口模块包含main()执行入口,其初始化一个TCL解释器并且进入命令行处理循环.上面的编译命令在Linux和Mac OS X操作系统中都是可用的,但是不同的平台下,可能需要调节链接库选项,以及TCL链接库的版本.

4.生成定制的合并文件

官网下载页提供的SQLite合并文件对于大多数用户都是适用的,但是一些工程可能需要生成定制的合并文件.因为他们需要编译配置选项定制SQLite库的功能.回想之前的说明,SQLite包含辅助程序和脚本生成的C源代码,辅助程序和脚本使用一些列的编译选项来生成C源代码文件,随后这些生成的C源代码被整合到合并文件中.辅助程序和脚本使用的编译选项可能随着SQLite的版本变化而变化, 在SQLite 3.6.20版本中,辅助程序和脚本使用如下编译选项:

为了生成定制的合并文件, 首先下载原始的未合并文件到类unix操作系统,请确认下载的是原始文件,而不是经过预处理的源代码文件.可以通过官网的下载页获得原始的未合并的源码文件,和可以从SQLite的配置管理系统获得这些文件.

假设SQLite的源码树存储于目录”sqlite”中,计划生成的合并文件位于并行的目录”bld”中.在SQLite的源码树的根目录下运行配置脚本或者拷贝一个Makefile文件模板来生成一个Makefile文件,然后手工编辑这个Makefile文件,包含需要的编译配置选项.最后,运行如下命令:

make sqlite3.c

或者在安装有MSVC编译环境的Windows操作系统中,运行如下命令:

nmake /f Makefile.msc sqlite3.c

make的执行目标”sqlite3.c”将自动生成合并文件”sqlite3.c“,及其头文件”sqlite3.h“,和包含TCL接口的合并文件”tclsqlite3.c“.然后,根据需要拷贝这些文件到工程目录, 使用上面说明的编译流程编译这些文件.

5.编译Windows DLL

为了在Windows操作系统下,将SQLite编译成DLL,首先获得合适的合并文件sqlite3.c 和 sqlite3.h.这两个文件可以从官网下载,也可以使用之前提到的定制合并文件的方式生成.

使用MSVC编译SQLite 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系统.因此为了生成兼容的DLL, 推荐使用MinGW编译器.可以使用MinGW生成32位的DLL, 使用MSVC生成64位的DLL.

在多数情况下,你可以在这些基本命令中使用适当的编译选项,比较常用的编译选项包括:

  • Os 优化大小,使生成的DLL尽可能的小.
  • O2 优化速度,DLL将变大一些由于函数內联和循环展开.
  • -DSQLITE_ENABLE_FTS4 包含全文搜索引擎.
  • -DSQLITE_ENABLE_RTREE 包含R-tree扩展.
  • -DSQLITE_ENABLE_COLUMN_METADATA 为一些公共系统,比如Ruby-on-Rails,提供一些额外的API支持.

====================================分割线==========================================
原文链接:https://www.sqlite.org/howtocompile.html

注:
SQLite的源码仓库使用Fossil管理的,请参考其使用说明.

Here are some methods to defend against cross - lingual prompt injection: ### Input Validation and Sanitization - **Character and Syntax Checks**: Validate the input to ensure it only contains expected characters and follows the correct syntax for the language and the system's requirements. For example, if the system expects only alphanumeric characters in a certain field, reject inputs with special characters that could be used for injection. ```python import re def validate_input(input_str): pattern = r'^[a-zA-Z0-9]+$' return bool(re.match(pattern, input_str)) input_text = "validinput123" if validate_input(input_text): print("Input is valid.") else: print("Input may be malicious.") ``` - **Length Limitation**: Set reasonable length limits for user inputs. Long inputs may be more likely to contain malicious injection attempts. ### Encoding and Escaping - **Proper Encoding**: Use appropriate encoding for user inputs, such as UTF - 8. This can prevent some encoding - related injection attacks. - **Escaping Special Characters**: Escape special characters in the input to prevent them from being interpreted as part of a malicious command. For example, in SQL, characters like single quotes (' ) need to be properly escaped. ```python import sqlite3 def escape_input(input_str): return input_str.replace("'", "''") input_text = "O'Connor" escaped_text = escape_input(input_text) conn = sqlite3.connect('example.db') cursor = conn.cursor() query = f"SELECT * FROM users WHERE name = '{escaped_text}'" cursor.execute(query) ``` ### Context - Aware Filtering - **Understand the Context**: Analyze the context in which the input is used. For example, if the input is used in a translation context, filter out words or phrases that are not relevant to normal translation requests and may be injection attempts. - **Language - Specific Rules**: Apply language - specific rules and filters. Different languages have different grammar, vocabulary, and common patterns. Use these to identify abnormal inputs. ### Model - Based Detection - **Anomaly Detection Models**: Train machine learning or deep learning models to detect abnormal patterns in user inputs. These models can be trained on a large dataset of normal and malicious inputs. ```python import tensorflow as tf from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense # Assume X_train and y_train are pre - processed training data model = Sequential([ Dense(64, activation='relu', input_shape=(input_dim,)), Dense(32, activation='relu'), Dense(1, activation='sigmoid') ]) model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy']) model.fit(X_train, y_train, epochs=10, batch_size=32) ``` ### Isolation and Sandboxing - **Isolate User Inputs**: Run operations involving user inputs in isolated environments or sandboxes. This can prevent malicious code from affecting the main system. For example, use containerization technologies like Docker to isolate translation tasks.
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值