sqlite 安裝與編譯


本文簡述了SQLite的概念,並詳細描述了SQLite在Linux和Windows平台下的編譯方法

關於 SQLite

SQLite是一個進程內的庫,實現了自給自足的、無服務器的、零配置的、事務性的 SQL 數據庫引擎。它是一個零配置的數據庫,這意味着與其他數據庫一樣,您不需要在系統中配置。

就像其他數據庫,SQLite 引擎不是一個獨立的進程,可以按應用程序需求進行靜態或動態連接。SQLite 直接訪問其存儲文件。

SQLite3命令

與關系數據庫進行交互的標准 SQLite 命令類似於 SQL。命令包括 CREATE、SELECT、INSERT、UPDATE、DELETE 和 DROP。這些命令基於它們的操作性質可分為以下幾種:

DDL - 數據定義語言

命 令 描    述
CREATE 創建一個新的表,一個表的視圖,或者數據庫中的其他對象。
ALTER 修改數據庫中的某個已有的數據庫對象,比如一個表
DROP 刪除整個表,或者表的視圖,或者數據庫中的其他對象

DML - 數據操作語言

命 令 描    述
INSERT 創建一條記錄
UPDATE 修改記錄
DELETE 刪除記錄

DQL - 數據查詢語言

命 令 描    述
SELECT

從一個或多個表中檢索某些記錄

 SQLite3的源碼

關於SQLite3的源碼下載請移步SQLite官網下載:

image

image

image

SQLite3 在Linux下的編譯

本文的編譯環境如下:

clipboard

編譯命令行管理工具

gcc shell.c sqlite3.c -lpthread -ldl -o sqlite3  //將生成sqlit3命令行管理工具

關於libsqlite3.so共享庫的編譯與使用

編譯

gcc -o sqlite3.o sqlite3.c -c -fPIC -lpthread –ldl  
gcc -o libsqlite3.so sqlite3.o -shared

-fPIC:PIC(Position-Independent Code),表示編譯為位置獨立的代碼,在產生的代碼中,沒有絕對地址,全部使用相對地址,因此代碼可以被加載至內存的任意位置。不用此選項的話編譯后的代碼是位置相關的,再加載時根據加載到的位置再次重定位.所以動態載入時是通過代碼拷貝的方式來滿足不同進程的需要,而不能達到真正代碼段共享的目的。

-shared:表示生成一個共享目標文件(讓連接器生成T類型的導出符號表,有時候也生成弱連接W類型的導出符號),即我們所說的共享庫(動態鏈接庫)。它可以和其他目標文件連接產生可執行文件。只有部分系統支持該選項。

-lpthread:用於確保SQLite是線程安全的。但因為命令行工具是單線程的,對命令行工具則可編譯成非線程安全的,可以忽略pthread庫。

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

-ldl:用於支持動態裝載,sqlite3_load_extension()接口和SQL函數load_extension()需要用到它。如果不需要這些特性,可以使用SQLITE_OMIT_LOAD_EXTENSION編譯選項來忽略

gcc -DSQLITE_OMIT_LOAD_EXTENSION shell.c sqlite3.c -o sqlite3

使用

在你的程序中(例如test.c)通過包含頭文件sqlite3.h來使用庫中的函數,編譯程序的命令為

export LD_LIBRARY_PATH=共享庫所在目錄
gcc test.c -L. -lsqlite3 -o test

-L. : 告訴編譯器在當前目錄(.)中查找共享函數庫

-lsqlite3:  指明編譯器查找共享庫libsqlite3.so,編譯器查找共享庫時有隱含的命名規則,即在給出的名字前面加上lib,后面加上.so來確定庫的名稱。

通過ldd test可查看test程序是如何調用共享庫中的函數的,當未指定LD_LIBRARY_PATH時,共享庫libsqlite3.so是找不到的。

image

image

 

編譯和使用靜態庫

gcc -o sqlite3.o -c sqlite3.c -lpthread -ldl  //編譯成目標文件
ar -rcv libsqlite3.a sqlite3.o   //將列出的各個目標文件一起打包成一個靜態庫libsqlite3.a
gcc -o test test.c -L. -lsqlite3 –static   //鏈接靜態庫,也可不加-static選項

-static:添加static后會將庫也包含在目標文件中,使得目標文件體積非常大,下圖為兩者的區別

clipboard

note: 關於ar命令

ar [-]p[mod] [……] archive [member...]

p:該參數描述了接下來要執行的操作,具體操作命令如下,但在單次命令執行過程中,只能選擇其中一個

              

參 數

描    述

參 數

描    述

d

從文件包中刪除文件

r

在文件包中代替文件

m

從文件包中移動文件到包尾

t

列出包中文件名為files指明的文件名的文件內容

p

打印出文件包中的文件

x

從文件包中解壓出文件名為files指明的文件

q

在文件包尾加入文件

   

[mod]:若干關鍵字跟隨在p參數后,用於描述施加在操作行為上的變化

 

                           

參 數

描    述

參 數

描    述

a

與r或m共同使用來將files指明的文件放置於posname之后

s

強制重新生成文件包的符號表

b

與a作用相同,但是是在posname之前使用

T

只在Solaris中有這個參數.在不支持長文件名的文件系統中減短長文件名.

沒有這個操作的話,長文件的解壓結果是錯誤的

c

無提示模式創建文件包

u

與r共同使用,用來僅取代那些在生成文件包之后改動過的文件

i

與b相同

v

細節化,並打印一個文件包的描述

 

note: 當靜態庫與共享庫同名時,優先使用共享庫

 

SQLite在windows下編譯(VS2019)

靜態編譯庫文件

創建新項目

clipboard[1]

將下載的文件添加到項目中,本項目配置選用Release, x64版本

clipboard[2]

clipboard[3]

增加預處理定義

_USRDLL

SQLITE_ENABLE_RTREE

SQLITE_ENABLE_COLUMN_METADATA

SQLITE_ENABLE_FTS5

SQLITE_ENABLE_UNLOCK_NOTIFY

clipboard[4]

添加並修改模板定義文件 sqlite3.def

clipboard[5]

修改模塊定義文件:在最后追加 sqlite3_unlock_notify

image 7

配置類型改為靜態庫lib

clipboard[6]

生成解決方案

在項目路徑的\x64\Release文件下,即可找到.lib文件

創建測試工程

將上一步生成的.lib文件,連同sqlite3.h和sqlite3ext.h共同添加到項目當中

clipboard[7]

設置頭文件包含路徑及庫路徑,此處的路徑分別為頭文件(sqlite3.h和sqlite3ext.h)存放路徑和庫文件(.lib)存放路徑

clipboard[8]

編輯測試代碼

添加main.cpp文件,編輯測試代碼

 1 #include <stdio.h>  
 2 #include "sqlite3.h"  
 3 #pragma comment(lib,"test_sqlite_lib")  
 4 
 5 /* print a record from table outputed by sql statement */
 6 static int callback(void* NotUsed, int argc, char** argv, char** azColName) {
 7     int i;
 8     for (i = 0; i < argc; i++) {
 9         printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
10     }
11     printf("\n");
12     return 0;
13 }
14 
15 int main(int argc, char** argv) {
16     sqlite3* db;
17     char* zErrMsg = 0;
18     int rc;
19 
20     if (argc != 3) {
21         fprintf(stderr, "Usage: %s DATABASE SQL-STATEMENT\n", argv[0]);
22         return(1);
23     }
24     rc = sqlite3_open(argv[1], &db);  /* open database */
25     if (rc) {
26         fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
27         sqlite3_close(db);
28         return(1);
29     }
30     rc = sqlite3_exec(db, argv[2], callback, 0, &zErrMsg);  /* execute SQL statement */
31     if (rc != SQLITE_OK) {
32         fprintf(stderr, "SQL error: %s\n", zErrMsg);
33         sqlite3_free(zErrMsg);
34     }
35     sqlite3_close(db);  /* close database */
36     return 0;
37 }

 

編譯后生成test_sqlite.exe程序,它的運行依賴於sqlite3.dll。注意程序中也可以不使用pragma指令導入sqlite3.lib,而是在test項目屬性中添加對上面的dll項目sqlit3的引用。
這個C程序的例子顯示怎么使用sqlite的C/C++接口。數據庫的名字由第一個參數取得,第二個參數是一條或更多的SQL執行語句。這個程序調用sqlite3_open()打開指定的數據庫,調用sqlite3_exec()對數據庫執行SQL語句,callback函數會作用在SQL語句結果集的每條記錄上。最后用sqlite3_close()關閉數據庫連接。

編譯並執行

在VS環境實測過程中,在工具選項卡中打開命令行,在.exe文件路徑下執行以下命令即可

clipboard[9]

 

主要參考:

SQLite 教程

WIN10 VS2019下編譯GDAL3.0+PROJ6+SQLite

SQLite安裝、編譯與應用


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM