环境:
开发板:freescale 2.6 armv71,系统只读,唯一可以读写的路径是/tmp/sd(这是一个sd卡)。程序放在/tmp/sd/transfer下(下文以运行路径代替),sql语句以文件形式保存在开发板上,语句字符集是GBK。
服务器:服务器安装的是SQL SERVER 2008。
功能:程序能够连接上服务器的数据库,执行SQL语句等等。
考虑到开发板的sd卡容量有限,不便于安装编译器,于是决定交叉编译。
交叉编译环境:ubuntu 12.04 (也可以选择其他的)。待编译的transfer.c和transfer.h文件放在/home/arm下(下文以编译路径代替)
首先安装交叉编译器,去官网下载最新的arm-linux-gcc。
我使用的是arm-linux-gcc-4.4.3-20100728.tar.gz,下载之后解压即可使用(我解压到了/home/下)。
为了使用方便,将解压目录下的opt/toolschain/4.4.3/bin添加到系统环境变量中。
为了访问SQL SERVER,我们需要安装freetds。当然这个freetds编译出来的动态库也必须是要在开发板使用的,所以要使用交叉编译器编译
去官网下载最新的freetds-stable.tgz.tgz,下载完成后解压,然后进入解压目录
执行以下命令
./configure --prefix=/home/freetds-arm --sysconfdir=/tmp/sd/transfer --with-tdsver=7.1 --enable-msdblib --disable-libiconv --host=arm-none-linux-gnueabi
解释下各项参数的意义。
--prefix=/home/freetds-arm ,设置freetds安装的目录,考虑开发板上是只读的,所以最好自己手动指定链接库路径而不采用默认路径。另外个原因这是ubuntu,而编译出来的是arm版本的。
--sysconfdir=/tmp/sd/transfer ,如果确定SQl语句不使用中文,可以不要这个参数。这个参数设置freetds配置文件的路径。(默认是在prefix指定的路径下的ext文件夹)。为什么要单独把参数文件夹设定为/tmp/sd/transfer,下面再讲
--with-tdsver=7.1 ,设置tds协议的版本,适用于SQL SERVER2008。其他版本请自行修改版本号
--enable-msdblib,允许MS(微软)数据库连接,因为还有其他数据库使用tds协议。
--disable-libiconv,关闭字符集自动转换(不关闭的话会中文乱码)
--host=arm-none-linux-gnueabi,指定交叉编译器(如果之前没有设定系统环境变量的话这里要手动指定编译器路径)
然后
make
make install
解决中文乱码
freetds连接默认是采用ISO-8859-1编码,是不支持中文的。在freetds安装目录下的ext文件夹(如果使用--sysconfdir,就在其指定的路径下)里有个freetds.conf,可以设置连接字符集。方法是在[global]条目下添加一行client charset=GBK(假设你的sql语句是GBK格式的,其他格式请使用对应的字符集)。
不过在板子上使用异常,莫名其妙程序崩溃。后来查看freetds源代码,发现默认支持UTF-8。
于是首先将client charset=GBK改为client charset=UTF-8,然后将SQL语句从GBK格式转换成UTF-8格式即可
这里使用libiconv来进行转换(还用其他方法,请参考网络)
要包含头文件iconv.h
void GBK_To_UTF8(char * src,int srclen,char * dsc,int dsclen)
{
iconv_t cd;
cd = iconv_open("UTF-8","GBK");
memset(dsc,0,dsclen);
iconv(cd,&src,&srclen,&dsc,&dsclen);
iconv_close(cd);
}
当然libiconv也得使用交叉编译
首先下载libiconv-1.14.tar.gz,解压之后进入解压目录
./configure --prefix=/home/libiconv --host=arm-none-linux-gnueabi
make
make install
参数含义不多做解释,参考上文。
安装完成从安装目录找到libiconv.so.2.5.1,复制到编译目录并改名为libiconv.so.2
从安装目录下找到iconv.h,复制到编译目录下
编写Makefile文件如下
CC=/home/opt/FriendlyARM/toolschain/4.4.3/bin/arm-linux-gcc
CCD=gcc
FLAGS=-Wl,-rpath=/tmp/sd/transfer -I/home/freetds-arm/include/ /home/freetds-arm/lib/libsybdb.a librt.so libiconv.so.2
FLAGSD=-I/home/freetds/include/ /home/freetds/lib/libsybdb.a -lrt -liconv
transfer : transfer.c transfer.h
$(CC) -o transfer -g transfer.c $(FLAGS)
debug : transfer.c transfer.h
$(CCD) -o transferd -g transfer.c $(FLAGSD)
clean :
rm -rf *~ transfer transferd
执行make就可以得到transfer,这个是要放到板子上用
执行make debug就可以得到transferd,这个直接可以在ubuntu上用,方便调试
为了方便在ubuntu12.04使用gdb调试,增加了debug目标,freetds等的安装方法参考上文,只需要去掉--host=arm-none-linux-gnueabi。
解释下
FLAGS
-Wl,-rpath=/tmp/sd/transfer表示程序执行的时候优先从这个路径寻找依赖库,如果不使用此项,会报libiconv.so.2找不到。
-I/home/freetds-arm/include/这里指定freetds的头文件路径
/home/freetds-arm/lib/libsybdb.a指定freetds共享库路径
librt.so 这个是运行时库,需要从开发板拷过来,也可以从交叉编译器的安装目录下找到。(执行命令find / -name "*librt.so*" 即可找到)
libiconv.so.2 这个是libiconv的库
FLAGSD,由于本机都是装在/usr/lib下面的,所以直接使用-lrt连接librt.so,-liconv连接libiconv.so.2
最后
将编译目录的libiconv.so.2、transfer放到板子的 /tmp/sd/transfer下
将ubuntu的/tmp/sd/transfer/freetds.conf拷贝到板子/tmp/sd/transfer下
这样transfer就可以执行了