本文讨论的是比较流行的嵌入式开发组合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,你可以从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:你可以到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。这个很重要,可以避免你在修改的过程出现问题而无法还原。
---------------------------------------------------------------------------------------------------------------------------------------
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 = .
#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
用:
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");
| | | | | | || | _ | | | | / /
| |_| | |__| || | | | | |_| |/
| ___/____|_||_|_| |_|/____|/_//_/
| |
|_|
GDB/ARMulator support by
For further information check:
Command:>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运行起来了,感觉如何呀,在uclinux也可以玩玩“select * from”,感觉很爽吧。