SQLite3編譯

官方編譯方式

SQLite3 源碼提供了非常便捷的編譯腳本,通過執行以下命令可以編譯得到sqlite3.csqlite3.hsqlite3ext.hshell.c 以及一個可執行程序 sqlite3。所有的代碼都被合併到了sqlite3.c 文件中,根據官網How To Compile SQLite 一文中提到,這樣做的好處是編譯器能夠進行更進一步的優化,從而提升5%~10%的性能。

mkdir bld                ;#  Build will occur in a sibling directory
cd bld                   ;#  Change to the build directory
../sqlite/configure      ;#  Run the configure script
make                     ;#  Run the makefile.
make sqlite3.c           ;#  Build the "amalgamation" source file
make test                ;#  Run some tests (requires Tcl)

將所有源碼合併得到一個文件的方式儘管帶來了很多便利的地方,但在實際使用時卻有一些問題。由於合併得到的文件太大,通過Clion打開後會提示:

The file size (8.56MB) exceeds the configured limit(2.56MB). Code insight features are not available.

並且對其編輯或者調試可以感受到IDE明顯的卡頓。儘管這些是外部工具自身的問題,那麼我們能不能將SQLite退回多文件的編譯方式緩解由於工具性能不足帶來的問題呢?

改造項目

基於 3.39.4 版本更改

  • 新建一個空項目
  • 將 sqlite3 源碼底下 src 目錄中所有文件拷貝到新建的項目中
  • 將 sqlite3 源碼底下 tool 目錄中的lemon.clempar.c拷貝過來
  • 執行gcc -o lemon lemon.c生成lemon程序
  • 運行./lemon parse.y生成parse.cparse.h文件
  • 在 sqlite3 源碼執行./configuremake命令
  • 將編譯得到的tscr底下的opencodes.copencodec.hsqlite.h拷貝過來
  • 刪除 test* 等一系列測試文件,以及tclsqlite.c文件
  • 創建CMakeLists.txt如下
cmake_minimum_required(VERSION 3.21)  
project(SqliteBuild C)  
  
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -DSQLITE_CORE=1")  
  
include_directories(${CMAKE_CURRENT_SOURCE_DIR})  
file(GLOB sources "*.c")  
file(GLOB headers "*.h")  
list(REMOVE_ITEM sources ${CMAKE_CURRENT_SOURCE_DIR}/lempar.c)  
list(REMOVE_ITEM sources ${CMAKE_CURRENT_SOURCE_DIR}/lemon.c)  
  
add_executable(SqliteBuild ${sources} ${headers} SqliteMain.c)

SqliteMain.c 爲自己調試添加的入口文件,可自行更換

#include <stdio.h>  
#include "sqlite3.h"  
  
/* print a record from table outputed by sql statement */  
static int callback(void* NotUsed, int argc, char** argv, char** azColName) {  
    int i;  
    for (i = 0; i < argc; i++) {  
        printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");  
    }  
    printf("\n");  
    return 0;  
}  
  
int main(int argc, char** argv) {  
    sqlite3* db;  
    char* zErrMsg = 0;  
    int rc;  
  
    if (argc != 3) {  
        fprintf(stderr, "Usage: %s DATABASE SQL-STATEMENT\n", argv[0]);  
        return(1);  
    }  
    rc = sqlite3_open(argv[1], &db);  /* open database */  
    if (rc) {  
        fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));  
        sqlite3_close(db);  
        return(1);  
    }  
    rc = sqlite3_exec(db, argv[2], callback, 0, &zErrMsg);  /* execute SQL statement */  
    if (rc != SQLITE_OK) {  
        fprintf(stderr, "SQL error: %s\n", zErrMsg);  
        sqlite3_free(zErrMsg);  
    }  
    sqlite3_close(db);  /* close database */  
    return 0;  
}

完整源碼地址:https://github.com/ZhaoxiZhang/SQLite-3.39.4

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章