嵌入式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的接口使用,本文只给出了简单的示例,详细应用,见官网使用说明。


相关文章
|
4月前
|
消息中间件 存储 缓存
【嵌入式软件工程师面经】Linux系统编程(线程进程)
【嵌入式软件工程师面经】Linux系统编程(线程进程)
101 1
|
4月前
|
网络协议 算法 Linux
【嵌入式软件工程师面经】Linux网络编程Socket
【嵌入式软件工程师面经】Linux网络编程Socket
114 1
|
4月前
|
Linux
Linux交叉编译+粤嵌LCD实现三色图
Linux交叉编译+粤嵌LCD实现三色图
56 0
|
2月前
|
NoSQL Linux C语言
嵌入式GDB调试Linux C程序或交叉编译(开发板)
【8月更文挑战第24天】本文档介绍了如何在嵌入式环境下使用GDB调试Linux C程序及进行交叉编译。调试步骤包括:编译程序时加入`-g`选项以生成调试信息;启动GDB并加载程序;设置断点;运行程序至断点;单步执行代码;查看变量值;继续执行或退出GDB。对于交叉编译,需安装对应架构的交叉编译工具链,配置编译环境,使用工具链编译程序,并将程序传输到开发板进行调试。过程中可能遇到工具链不匹配等问题,需针对性解决。
|
2月前
|
传感器 人工智能 网络协议
:嵌入式 Linux 及其用途
【8月更文挑战第24天】
89 0
|
3月前
|
Ubuntu 算法 Linux
嵌入式Linux的学习误区
**嵌入式Linux学习误区摘要** 1. **过度聚焦桌面Linux** - 许多学习者误将大量时间用于精通桌面Linux系统(如RedHat、Fedora、Ubuntu),认为这是嵌入式Linux开发的基石。 - 实际上,桌面Linux仅作为开发工具和环境,目标不应是成为Linux服务器专家,而应专注于嵌入式开发工具和流程。 2. **盲目阅读Linux内核源码** - 初学者在不了解Linux基本知识时试图直接研读内核源码,这往往导致困惑和挫败感。 - 在具备一定嵌入式Linux开发经验后再有针对性地阅读源码,才能有效提升技能。
35 4
|
4月前
|
SQL Linux 数据库
Linux上sqlite的安装和使用方法以及在QT中如何使用sqlite&笔记总结
Linux上sqlite的安装和使用方法以及在QT中如何使用sqlite&笔记总结
|
4月前
|
物联网 Linux 芯片
学习嵌入式是选择单片机还是Linux?
单片机通常指的是一种集成了处理器、存储器和各种外设接口的微控制器芯片,常见的有STC、51系列、AVR、ARM Cortex-M等。单片机具有低成本、低功耗、实时性强等特点,适用于对资源要求较低、功耗要求较低、实时性要求较高的嵌入式系统。学习单片机开发可以让您深入了解嵌入式系统的底层原理和硬件编程,对于对嵌入式系统底层开发感兴趣的人来说,是一个很好的选择。
102 4
|
4月前
|
消息中间件 安全 Java
【嵌入式软件工程师面经】Linux多进程与多线程
【嵌入式软件工程师面经】Linux多进程与多线程
54 1
|
4月前
|
存储 缓存 Unix
【嵌入式软件工程师面经】Linux文件IO
【嵌入式软件工程师面经】Linux文件IO
41 1
下一篇
无影云桌面