嵌入式Linux 之 sqlite3 交叉编译和使用

简介: hello 大家好,今天给大家推荐一个小型的嵌入式数据库sqlite,介绍一下sqlite 交叉编译和使用。

1. 什么是sqlite?


sqlite 是一个小型,高速、高可靠性功能齐全的sql数据库引擎,并且是C语言开源的库,可以很方便的移植到各种嵌入式平台上。


官网如下:


image.png


地址:http://www3.sqlite.org/index.html


最新版本:3.3.52


2. sqlite 交叉编译


源码下载


image.png


tar -zxvf sqlite-autoconf-3350200.tar.gz


交叉编译


cd sqlite-autoconf-3350200
mkdir pc_out
./configure --prefix=~/work/github/sqlite-autoconf-3350200/pc_out
make 
make install


安装完成文件如下:


image.png


  • sqlite3:应用程序,直接可以打开和创建数据库


  • include:头文件,开发用


  • lib:sqlite3 的库,开发用


  • share:共享文件和手册


编译完成可以直接在pc上运行 sqlite3。


mips


mips 交叉编译和 pc 差不多,不过有一点不同,我们需要配置工具链:


准备工作:


cd sqlite-autoconf-3350200
mkdir mips_out
mkdir mips_out/glibc #创建glibc 目录
mkdir mips_out/uclibc#创建uclibc 目录
make distclean


编译glibc:


第一步:配置configure。设置工具链和安装路径


./configure --prefix=~/work/github/sqlite-autoconf-3350200/mips_out/glibc --host=mips-linux-gnu


  • --prefix:指定安装路径。


  • --host:指定工具链。注意,需要设置工具链的环境变量,否则检测不到工具链。


配置完成后,可以打开Makefile 验证:


image.png


第二步:编译和安装:


make 
make install


image.png


编译 uclibc:


第一步:配置configure。设置工具链和安装路径


# 需要手动修改Makefile CFLAGS += -muclibc
./configure --prefix=~/work/github/sqlite-autoconf-3350200/mips_out/uclibc --host=mips-linux-gnu
# 或者
CFLAGS += -muclibc ./configure --prefix=~/work/github/sqlite-autoconf-3350200/mips_out/uclibc --host=mips-linux-gnu


  • --prefix:指定安装路径。


  • --host:指定工具链。注意,需要设置工具链的环境变量,否则检测不到工具链。


  • CFLAGS += -muclibc:指定uclibc 环境



第二步:编译和安装


make 
make install


image.png


arm


arm 平台交叉编译类似。需要注意的点如下:


  • 设置工具链的环境变量


  • 指定交叉编译工具链为arm平台所用的工具链。比如 arm-linux-gnu(只要前缀)


3. sqlite 使用


当交叉编译后,就可以直接把sqlite3 拷贝到板子上运行。注意,glibc环境拷贝glibc的,uclibc环境拷贝uclibc的。


我们来看一个简单的示例:


#include <stdio.h>
#include <pthread.h>
#include <dlfcn.h>
#include <stdlib.h>
#include <string.h>
#include <sqlite3.h>
#define DATABASE_NAME                 "MyDBDemo.db"
#define DATABASE_TABLE_NAME           "table1"
#define DATABASE_TABLE_MEMBER         "name text, age int, note text, count int"
#define DATABASE_TABLE_LABEL          "name, age, note, count"
#define CREATE                        0
#define INSERT                        1
#define DELETE                        2
#define SELECT                        3
#define UPDATE                        4
#define DROP                          5
#define VACUUM                        6
#define PRAGMA                        7
struct sqlite_db_str {
 char *sql;
};
struct sqlite_db_str db_sqlstr[] = {
 [CREATE] = { .sql = "CREATE TABLE " },
 [INSERT] = { .sql = "INSERT INTO "  },
 [DELETE] = { .sql = "DELETE FROM "  },
 [SELECT] = { .sql = "SELECT "  },
 [UPDATE] = { .sql = "UPDATE "  },
 [DROP] =   { .sql = "DROP TABLE "  },
 [VACUUM] = { .sql = "VACUUM "  },
 [PRAGMA] = { .sql = "PRAGMA "  },
};
int main(int argc, char *argv[])
{
 int ret = -1;
 int k = 0;
 sqlite3 *db_ctx = NULL;
 char *zErrMsg = NULL;
 /*Step1: create database */
 ret = sqlite3_open_v2(DATABASE_NAME, &db_ctx, SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE | SQLITE_OPEN_NOMUTEX | SQLITE_OPEN_SHAREDCACHE, NULL);
 if(ret){
  printf("Open %s database errror!, ret: %d\n", DATABASE_NAME, ret);
  return -1;
 }
 /*Step2: create table */
 char sql_buf[256] = {'\0'};
 sprintf(sql_buf, "%s %s (%s);", db_sqlstr[CREATE].sql, DATABASE_TABLE_NAME, DATABASE_TABLE_LABEL);
 ret = sqlite3_exec(db_ctx, sql_buf, NULL, NULL, &zErrMsg);
 if( ret != SQLITE_OK ){
  if( ret == 1 ){
   /* table already exists */
   printf("database [%s]: %s\n", DATABASE_NAME, zErrMsg);
  } else {
   fprintf(stderr, "SQL error: %s, ret: %d\n", zErrMsg, ret);
   sqlite3_free(zErrMsg);
   return -1;
  }
 }
 /*Step3: insert*/
 for (k = 0; k < 10; k++) {
  char insert_buf[128] = {0};
  sprintf(insert_buf, "'%s%d', %d, 'note_%d', %d", "Vinson", k, k, k, k);
  char sql_buf[1024] = {'\0'};
  unsigned int sql_prefix_len = 0;
  sprintf(sql_buf, "%s %s (%s) VALUES (", db_sqlstr[INSERT].sql, DATABASE_TABLE_NAME, DATABASE_TABLE_LABEL);
  sql_prefix_len = strlen(sql_buf);
  memcpy(sql_buf+sql_prefix_len, insert_buf, strlen(insert_buf));
  memcpy(sql_buf+sql_prefix_len + strlen(insert_buf), ");", strlen(");"));
  /* INSERT table1 (name age note count) VALUES (Vinson1,note1,1,1 )*/
  ret = sqlite3_exec(db_ctx, sql_buf, NULL, NULL, &zErrMsg);
  if( ret != SQLITE_OK ){
   fprintf(stderr, "SQL error: %s\n", zErrMsg);
   sqlite3_free(zErrMsg);
   return -1;
  }
  if (ret < 0) {
   printf("insert table error! %d\n", ret);
   return -1;
  }
 }
 /*Step4: close*/
 sqlite3_close(db_ctx);
 return 0;
}


编译:


# 嵌入式设备 改成对应工具链:mips-linux-gun-gcc/arm-linux-gun-gcc
gcc sqlite3_demo.c -o sqlite3_test 
-I./sqlite/include  
-L./sqlite/lib/ -lsqlite3 
-ldl 
-lpthread
-lm


  • -I:指定sqlite 头文件包含


  • -L:链接sqlite3 库。


  • ldl:使用库需要


  • lpthread:libsqlite3.a 使用。多线程相关


  • lm:libsqlite3.a 使用。数学库


执行:将生成的程序拷到板子上可直接运行。(./sqlite3_test)生成 MyDBDemo.db 验证:通过交叉编译生成的bin文件 sqlite3,可直接打开查看,我们sqlite3_test生成的数据库。


./sqlite3 MyDBDemo.db



查看数据库信息:


.dump



查看数据库表:


.table


image.png


退出:


.quit


用 Navicat Premium 打开对比查看。


image.png


4. 总结


本文,主要就是嵌入式端sqlite3移植进行介绍,关于数据库的语法和使用,留待读者自行研究。有关sqlite3的接口使用,本文只给出了简单的示例,详细应用,见官网使用说明。


相关文章
|
21天前
|
Linux 编译器 Android开发
FFmpeg开发笔记(九)Linux交叉编译Android的x265库
在Linux环境下,本文指导如何交叉编译x265的so库以适应Android。首先,需安装cmake和下载android-ndk-r21e。接着,下载x265源码,修改crosscompile.cmake的编译器设置。配置x265源码,使用指定的NDK路径,并在配置界面修改相关选项。随后,修改编译规则,编译并安装x265,调整pc描述文件并更新PKG_CONFIG_PATH。最后,修改FFmpeg配置脚本启用x265支持,编译安装FFmpeg,将生成的so文件导入Android工程,调整gradle配置以确保顺利运行。
FFmpeg开发笔记(九)Linux交叉编译Android的x265库
|
1月前
|
JSON 机器人 Linux
推荐一款嵌入式Linux开源框架与封装-cpp-tbox
推荐一款嵌入式Linux开源框架与封装-cpp-tbox
59 3
|
1月前
|
Linux Shell
嵌入式Linux系统脚本小技巧之启动脚本
嵌入式Linux系统脚本小技巧之启动脚本
19 2
|
22天前
|
Unix Linux Shell
FFmpeg开发笔记(八)Linux交叉编译Android的FFmpeg库
在Linux环境下交叉编译Android所需的FFmpeg so库,首先下载`android-ndk-r21e`,然后解压。接着,上传FFmpeg及相关库(如x264、freetype、lame)源码,修改相关sh文件,将`SYSTEM=windows-x86_64`改为`SYSTEM=linux-x86_64`并删除回车符。对x264的configure文件进行修改,然后编译x264。同样编译其他第三方库。设置环境变量`PKG_CONFIG_PATH`,最后在FFmpeg源码目录执行配置、编译和安装命令,生成的so文件复制到App工程指定目录。
FFmpeg开发笔记(八)Linux交叉编译Android的FFmpeg库
|
7天前
|
安全 Linux Android开发
FFmpeg开发笔记(十六)Linux交叉编译Android的OpenSSL库
该文介绍了如何在Linux服务器上交叉编译Android的FFmpeg库以支持HTTPS视频播放。首先,从GitHub下载openssl源码,解压后通过编译脚本`build_openssl.sh`生成64位静态库。接着,更新环境变量加载openssl,并编辑FFmpeg配置脚本`config_ffmpeg_openssl.sh`启用openssl支持。然后,编译安装FFmpeg。最后,将编译好的库文件导入App工程的相应目录,修改视频链接为HTTPS,App即可播放HTTPS在线视频。
FFmpeg开发笔记(十六)Linux交叉编译Android的OpenSSL库
|
12天前
|
Ubuntu 算法 Linux
嵌入式Linux的学习误区
该文指出了学习嵌入式Linux开发的两个常见误区。一是过分专注于学习桌面或服务器版Linux,而非关注嵌入式开发本身,实际上只需熟悉基本操作即可。二是试图在没有基础的情况下直接阅读Linux内核源代码,这是不切实际的,应先建立基础知识再进行源码学习。文章还提到了在嵌入式系统中获取和处理屏幕数据的示例,包括使用gsnap工具将framebuffer数据转为图像,以及涉及的交叉编译过程。
11 0
|
27天前
|
Linux 编译器 测试技术
嵌入式 Linux 下的 LVGL 移植
嵌入式 Linux 下的 LVGL 移植
|
27天前
|
Linux 开发工具
【ZYNQ】配置嵌入式 Linux 静态 IP 地址
【ZYNQ】配置嵌入式 Linux 静态 IP 地址
|
1月前
|
Linux 计算机视觉
Linux交叉编译opencv并移植ARM端
通过以上步骤,你可以在Linux上交叉编译OpenCV,并将生成的库文件和头文件移植到ARM平台上,从而在ARM上使用OpenCV。 买CN2云服务器,免备案服务器,高防服务器,就选蓝易云。百度搜索:蓝易云
62 0
|
1月前
|
JSON Ubuntu Linux
LuaJit交叉编译移植到ARM Linux
LuaJit交叉编译移植到ARM Linux
28 1