i社区用户: 密码:
搜索:
首页| 资讯| 信息化| 视频| 专题| 创业| 技术天地| 企业博客| 职场| 周报全文| 方案中心 |电子杂志
商城| 市场会展| Blog| i社区| 社区联盟| RSS| 直播 | 发行| wiki |i| 下载| 英才招聘|CIO文库
IT两会 | 互联网年会
产品中心| 笔记本|台式机| DIY|数码| 服务器|网络通信| 手机|软件|显示器|信息安全|存储|组网| 动漫
首页|文库|数据中心|方案中心|专家库|厂商黄页|供求招标| 责编电话:010-68130909-1053
 
uclinux下的sqlite嵌入式数据库移植
 
 
 
 
2004-12-15 11:46:23
 
  余涛  
 
我们在这里讨论的是比较流行的嵌入式开发组合ARM+uclinux,即目标开发板为三星S3C4510,完成sqlite在其uclinux上的移植。
 
文假设你已经具备正确编译uclinux的kernel的能力,即有能力完成make menuconfig;make dep;make lib_only;make user_only;make romfs;make image;make。而且还能将自己写的类似helloworld程序加到“用户自定义应用程序”中,即你能完成“uClinux-dist/Documentation/Adding-User-Apps-HOWTO”中所描述的“用户程序的订制”。
 
大多数需要移植sqlite到uclinux的开发者,应该已经具备上面的能力,而只是不清楚如何修改sqlite来完成其在uclinux下的编译。如果你还不能完成上面的要求,那么请先做一定的准备工作,因为本范例所涉及到的内容主要是跟sqlite在uclinux下的移植有关,其他的在这个过程中出现的问题,开发者需要自行处理。
 
本范例使用的uclinux是uClinux-dist-20030522.tar.gz,你可以从http://www.uclinux.org得到适合你的软件包。
交叉编译工具是arm-elf-tools-20030314.sh,你也可以在http://www.uclinux.org找到它。
本范例使用的sqlite是sqlite-2.8.15.tar.gz,本文的方法也适合于2.8.x系列的sqlite;可能有部分内容不适用于3.0.x系列的sqlite,因为3.0.x中源代码有较大的变化。
1、    下载sqlite:你可以到http://www.sqlite.org/download.html,下载sqlite-2.8.15.tar.gz软件包;
2、    将下载的软件包解压缩到uClinux-dist/user目录下;
命令:
$tar zxvf sqlite-2.8.15.tar.gz -C uClinux-dist/user/
现在在uclinux的user目录下,你应该可以看到sqlite目录了。解压缩到这个user目录主要是要将sqlite编译成一个普通的用户应用程序。
3、    用户应用程序的有关设置:
按uClinux-dist/Documentation/Adding-User-Apps-HOWTO文档中说提到的,来添加sqlite作为一个用户应用程序,将其做成一个shell,这样就类似于uclinux自己的ps命令。
编辑文件
uClinux-dist/user/Makefile
uClinux-dist/config/Configure.help
uClinux-dist/config/config.in
我是在这些文件里查找“cpu”有关的项,然后在它的下面,加上自己的sqlite项,这个过程并不复杂。
通过上面的修改后,你现在就可以运行uclinux的make menuconfig,
选中“CustomizeVendor/User Settings”,再选中“Miscellaneous Applications”,可以看到它现在出现了一个新的“sqlite (NEW)”,这个就是我们刚添加进去的sqlite项。
 
在稍后的make romfs中,uclinux会将你的sqlite编译进来,做成romfs的一部分,因为你在uClinux-dist/user/Makefile中已经加上要编译sqlite项了。这样在移植后的uclinux的/bin中将会有sqlite命令可以让你来执行。
 
好,现在我们就要对sqlite进行修改,来做移植工作。
在下面的描述中,我们将对以下几个文件进行一定的添加、修改,从而来完成sqlite在uclinux下的编译:
sqlite/main.mk        修改
sqlite/Makefile 添加
sqlite/src/os.c        修改
sqlite/src/shell.c     修改
 
对这几个文件进行修改时,请自己做好这些文件的备份,比如你可以将它们拷贝一份,改名成文件名后面带.bak。这个很重要,可以避免你在修改的过程出现问题而无法还原。
 
一、修改sqlite/main.mk
1、TCCX
TCCX = $(TCC) $(OPTS) $(THREADSAFE) $(USLEEP) -I. -I$(TOP)/src
修改为
TCCX = $(TCC) $(OPTS) $(THREADSAFE) $(USLEEP) -I. -I$(TOP)/src $(CFLAGS)
即加上$(CFLAGS)标记。
2、 LIBOBJ
找到 # Object files for the SQLite library.
将其中的tclsqlite.o去掉。即去掉tcl有关的东西。
如果没有tclsqlite.o,那么不用处理它。
3、 sqlite$(EXE)
找到类似sqlite$(EXE)的一句
sqlite$(EXE):  $(TOP)/src/shell.c libsqlite.a sqlite.h
       $(TCCX) $(READLINE_FLAGS) -o sqlite$(EXE) $(TOP)/src/shell.c \
              libsqlite.a $(LIBREADLINE) $(THREADLIB)
替换为
shell.o:    $(TOP)/src/shell.c sqlite.h
       $(TCCX) $(READLINE_FLAGS) -c $(TOP)/src/shell.c
 
sqlite$(EXE):  shell.o libsqlite.a
       $(TCC) $(LDFLAGS) -o $@ shell.o \
              libsqlite.a $(LIBREADLINE) $(THREADLIB) $(LDLIBS)
即在sqlite$(EXE)上一行加上shell.o,及在其后加上$(LDLIBS)标记。这个是对/src/shell.c的编译方法的修改。
4、romfs
install:     sqlite libsqlite.a sqlite.h
       mv sqlite /usr/bin
       mv libsqlite.a /usr/lib
       mv sqlite.h /usr/include
替换为
romfs:     sqlite
       $(ROMFSINST) /bin/sqlite
即去掉make install项,加上make romfs项。 这个很重要,这将在romfs的/bin目录下生成sqlite。
5、clean:
clean:     
       rm -f *.o sqlite libsqlite.a sqlite.h opcodes.*
       rm -f lemon lempar.c parse.* sqlite*.tar.gz
rm -f $(PUBLISH)
      rm -f *.da *.bb *.bbg gmon.out
      rm -rf tsrc
替换为
clean:     
       rm -f *.o sqlite libsqlite.a sqlite.h opcodes.* sqlite.gdb
      rm -f $(PUBLISH)
      rm -f *.da *.bb *.bbg gmon.out
      rm -rf tsrc
 
distclean: clean
       rm -f lemon lempar.c parse.* sqlite*.tar.gz
       rm -f config.h
即增加make distclean项。
 
二、在sqlite下增加Makefile文件
在sqlite目录下应该没有Makefile文件,而只是有一个sqlite/Makefile.linux-gcc文件。我们要移植sqlite到uclinux,那么就要自己写一个合适的Makefile。
内容如下:
===========Makefile内容开始===========
#!/usr/make
#
# Makefile for SQLITE
#
# This is a template makefile for SQLite.  Most people prefer to
# use the autoconf generated "configure" script to generate the
# makefile automatically.  But that does not work for everybody
# and in every situation.  If you are having problems with the
# "configure" script, you might want to try this makefile as an
# alternative.  Create a copy of this file, edit the parameters
# below and type "make".
#
 
#### The toplevel directory of the source tree.  This is the directory
#    that contains this "Makefile.in" and the "configure.in" script.
#
TOP = .
 
#### C Compiler and options for use in building executables that
#    will run on the platform that is doing the build.
#
BCC = gcc -g -O2
#BCC = /opt/ancic/bin/c89 -0
 
#### If the target operating system supports the "usleep()" system
#    call, then define the HAVE_USLEEP macro for all C modules.
#
#USLEEP =
USLEEP = -DHAVE_USLEEP=1
 
#### If you want the SQLite library to be safe for use within a
#    multi-threaded program, then define the following macro
#    appropriately:
#
#THREADSAFE = -DTHREADSAFE=1
THREADSAFE = -DTHREADSAFE=0
 
#### Specify any extra linker options needed to make the library
#    thread safe
#
#THREADLIB = -lpthread
THREADLIB =
 
#### Leave MEMORY_DEBUG undefined for maximum speed.  Use MEMORY_DEBUG=1
#    to check for memory leaks.  Use MEMORY_DEBUG=2 to print a log of all
#    malloc()s and free()s in order to track down memory leaks.
#   
#    SQLite uses some expensive assert() statements in the inner loop.
#    You can make the library go almost twice as fast if you compile
#    with -DNDEBUG=1
#
#OPTS = -DMEMORY_DEBUG=2
#OPTS = -DMEMORY_DEBUG=1
#OPTS = -DNDEBUG=1
OPTS = -DMEMORY_DEBUG=1
 
#### The suffix to add to executable files.  ".exe" for windows.
#    Nothing for unix.
#
#EXE = .exe
EXE =
 
#### C Compile and options for use in building executables that
#    will run on the target platform.  This is usually the same
#    as BCC, unless you are cross-compiling.
#
TCC = $(CROSS)gcc
FLTFLAGS += -s 12000
#TCC = gcc -g -O0 -Wall
#TCC = gcc -g -O0 -Wall -fprofile-arcs -ftest-coverage
#TCC = /opt/mingw/bin/i386-mingw32-gcc -O6
#TCC = /opt/ansic/bin/c89 -O +z -Wl,-a,archive
 
#### Tools used to build a static library.
#
AR = $(CROSS)ar cr
#AR = /opt/mingw/bin/i386-mingw32-ar cr
RANLIB = $(CROSS)ranlib
#RANLIB = /opt/mingw/bin/i386-mingw32-ranlib
 
#### Extra compiler options needed for programs that use the TCL library.
#
#TCL_FLAGS =
#TCL_FLAGS = -DSTATIC_BUILD=1
#TCL_FLAGS = -I/home/drh/tcltk/8.4linux
#TCL_FLAGS = -I/home/drh/tcltk/8.4win -DSTATIC_BUILD=1
#TCL_FLAGS = -I/home/drh/tcltk/8.3hpux
 
#### Linker options needed to link against the TCL library.
#
#LIBTCL = -ltcl -lm -ldl
#LIBTCL = /home/drh/tcltk/8.4linux/libtcl8.4g.a -lm -ldl
#LIBTCL = /home/drh/tcltk/8.4win/libtcl84s.a -lmsvcrt
#LIBTCL = /home/drh/tcltk/8.3hpux/libtcl8.3.a -ldld -lm -lc
 
#### Compiler options needed for programs that use the readline() library.
#
READLINE_FLAGS =
#READLINE_FLAGS = -DHAVE_READLINE=1 -I/usr/include/readline
 
#### Linker options needed by programs using readline() must link against.
#
#LIBREADLINE =
#LIBREADLINE = -static -lreadline -ltermcap
 
#### Should the database engine assume text is coded as UTF-8 or iso8859?
#
# ENCODING  = UTF8
ENCODING = ISO8859
 
# You should not have to change anything below this line
###############################################################################
include $(TOP)/main.mk
===========Makefile内容结束===========
注:
1、  在uclinux下的sqlite的Makefile将不去用到TCL相关的库。
2、  在uclinux下的sqlite的Makefile将不去用到readline()。
 
在sqlite/README中有关于Makefile的一段描述:
The configure script uses autoconf 2.50 and libtool.  If the configure script does not work out for you, there is a generic makefile named "Makefile.linux-gcc" in the top directory of the source tree that you can copy and edit to suite your needs.  Comments on the generic makefile show what changes are needed.
你可以用sqlite/Makefile.linux-gcc作为蓝本来修改适合你自己的Makefile。
你如果有兴趣的话,可以把上面的Makefile的内容和sqlite/Makefile.linux-gcc内容diff对比一下,看看uclinux下的sqlite编译有哪些不同的地方。
 
三、修改sqlite/src/os.c
如果你的sqlite包中包括os.c文件那么就对其进行修改,没有os.c文件可能是你的sqlite版本比较新,那么无须修改。
将所有你找到的
if( s!=0 )
用if( s!=0 && errno != ENOSYS )
替换。
 
四、修改sqlite/src/shell.c
1、struct previous_mode_data 结构定义项:
将  int colWidth[100];
用  int colWidth[20];
替换。
2、struct callback_data 结构定义项:
将 
int colWidth[100];
int actualWidth[100];
char outfile[FILENAME_MAX];
用 
int colWidth[20];
int actualWidth[20];
char *outfilep;
对应替换。
 
再在结构下面增加:
#ifndef FILENAME_MAX
#define FILENAME_MAX    4095
#endif
char outfilename[FILENAME_MAX]; /* Filename for *out */
struct callback_data
{
...
};
#ifndef FILENAME_MAX
#define FILENAME_MAX    4095
#endif
char outfilename[FILENAME_MAX]; /* Filename for *out */
 
3、函数do_meta_command(...)中:
找到类似这样的一句
sqlite_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
在它的前面有一句
memcpy(&data, p, sizeof(data));
现在在memcpy下面增加一行
data.cnt = 0;
即将结构中cnt的值赋为0 ;
现在代码会被修改成类似:
open_db(p);
memcpy(&data, p, sizeof(data));
data.cnt = 0;
 
再继续
找到类似这样的一句
strcmp(azArg[1],"stdout")==0
在它的下面的括号中
将      strcpy(p->outfile,"stdout");
用      p->outfilep = "stdout";
来替换。
 
再在它下面的5-6行处
将         strcpy(p->outfile,azArg[1]);
用         strcpy(outfilename,azArg[1]);
               p->outfilep = outfilename;
替换。
 
再继续
找到类似这样的一句
fprintf(p->out,"%9.9s: %s\n","output",
 
将fprintf(p->out,"%9.9s: %s\n","output", strlen(p->outfile) ? p->outfile : "stdout");
用fprintf(p->out,"%9.9s: %s\n","output", p->outfilep && strlen(p->outfilep) ? p->outfilep : "stdout");
替换。
 
完成修改。
 
上面的所有的对sqlite的修改完成后,你就可以make dep;make lib_only;make user_only;make romfs;make image了。
如果你对sqlite的修改,在make user_only过程中出现错误的话,你可以忽略make dep;make lib_only命令,直接再次进行make user_only;make romfs;make image;就可以了,而不用重复make dep;make lib_only。
make image会帮你生成romfs文件系统。现在在uClinux-dist/images下面就有编译生成的romfs文件系统了。这个就是我们需要的包含有sqlite的romfs了。
在上面的过程中,你可以不用在“make image”后再去“make”生成kernel内核,因为你只需要生成romfs就可以了,它里面已经有sqlite了。
现在你就可以把你生成的含有sqlite应用程序的romfs下载到开发板上运行一下。
Welcome to
          ____ _  _
         /  __| ||_|                
    _   _| |  | | _ ____  _   _  _  _
   | | | | |  | || |  _ \| | | |\ \/ /
   | |_| | |__| || | | | | |_| |/    \
   |  ___\____|_||_|_| |_|\____|\_/\_/
   | |
   |_|
 
GDB/ARMulator support by <davidm@snapgear.com>
For further information check:
http://www.uclinux.org/
 
Command: /bin/ifconfig eth0 up 10.0.0.2
Execution Finished, Exiting
init: Booting to single user mode
 
Sash command shell (version 1.1.1)
/> cd bin
/bin> ls -l sqlite
-rwxr-xr-x  1 0        0          327072  Jan 01 00:00 sqlite
/bin >cd /tmp
/tmp>sqlite test.sqlite
sqlite> create table my(name varchar(80), num smallint);
sqlite> insert into my values('yutao', 100);
sqlite> insert into my values('uclinux', 99);
sqlite> select * from my;
yutao|100
uclinux|99
sqlite> .tables
my
sqlite> .schema
create table my(name varchar(80), num smallint);
sqlite> .q
/tmp>ls –l test.sqlite
 
你要保证你的/tmp是可写的目录。
 

好,现在你的sqlite就已经在uclinux运行起来了。

来源:CCW

 
   
  (网页编辑:秋月  
     
  搜索相关内容 uclinux    
   
   
      如果您对“uclinux下的sqlite嵌入式数据库移植”有任何疑问要咨询,或者您对我们专家的解答有任何疑义,请您点击以下的链接提交意向单,我们的编辑和信息化专家将会很快为您做出回答,您提供的信息经过审核后将有机会出现在我们的网页上。
专家介绍
Informatica--数据集成业务
开源精神的化身--Linux
检索
 
 
 
检索词 >>
电信 金融 信息安全
软件 CRM 电子政务
ERP 物流 电子商务
行业 >>
电信 能源 医疗
农业 银行 政府
交通 制造业 教育

收藏此页到ViVi
  发表评论  您的姓名   您的Email   发布  
   
相关文章
关于我们 | 客服热线 | 广告服务 | 招聘信息 | 法律声明 | 投稿指南 | 联系方式 
Copyright(C) ccw.com.cn,All rights reserved
中国计算机世界出版服务公司内容版权所有
京ICP证010182