1.建立交叉编译环境
首先,在自己的机子上建立交叉编译环境。
我使用的是Ubuntu14.04 x86_64,gcc-4.8.3。如果要建立一套十分完整的交叉编译环境,需要安装openwrt buildroot环境,操作步骤:
http://wiki.openwrt.org/doc/howto/buildroot.exigence,
注意在其中make menuconfig之后出现配置界面,主要选定目标系统的体系架构,比如我的是x86,其他如ar71xx等,另外选中编译出toolchain,还有一项是打包openwrt SDK(这个很多文档有提到,我们不妨就勾选上吧)。
从make menuconfig界面来看,这个应该是在编译整个openwrt,于是乎像编译其他系统一样,这个过程显得漫长而无聊。我们不妨换个思路,我们一般交叉编译时使用源码包中configure脚本指定--host选项表示要编译的目标平台,如我的i486-openwrt-linux,而根据经验来看,configure是根据这个值,在其后加上-gcc/-g++构成i486-openwrt-linux-gcc/g++形成目标平台的编译器进行调用编译,之后根据所得到的编译器名字在环境变量PATH指定的目录下寻找到。
基于这个经验性原理,我们为什么要等待如此漫长的时间而位于编译的路上呢。好的,我们去openwrt x86的源上直接下载官方已经编译好的编译器,然后设置PATH路径不就好了吗。嗯,在
http://downloads.openwrt.org/barrier_breaker/14.07/x86/generic/
就可以看到toolchain了,下载之,解压,设置环境变量PATH即可,环境变量一般是$TOOLCHAIN_HOME/bin,这个$TOOLCHAIN_HOME表示你的工具链家目录。
可以测试一下在命令行输入i486-openwrt-linux- 然后按Tab键会不会补全出一大堆东西,如果可以,那就表示PATH设置好了。通过这样的方法,我编译通过了libnet, libpcap, libnids,这个根据我之前记录的文档,编译过程真是如丝般顺滑...... 不过这样的话,这个交叉编译工具链会爆出warning,说没有$STAGING_DIR这个环境变量,其实无视这个没有什么问题,前提是你不需要目标平台的其他库,如果实在不爽的话,可以设置一下,如果设置PATH的时候是$TOOLCHAIN_HOME/bin的话,这个$STAGING_DIR就是$TOOLCHAIN_HOME了。
如果安装了buildroot的话,也是要设置这两个环境变量的,跟上面一样的。
后来在编译另外一个东西的时候要链接pthread库,这个时候就必须用这个完整的buildroot了,编译器将STAGING_DIR指定的路径作为头文件和库的默认目录,应该是用到SDK中的pthread库了。
2.交叉编译libmysqlclient
这个过程可以参考
http://blog.csdn.net/lilongherolilong/article/details/7521736
这个文章,要严格遵守mysql-connector版本,并且参考下面5楼评论。
cmake生成Makefile之后,make进行编译,出现错误
my_global.h:1582:22: error: static declaration of 'rint' follows non-static declaration
这尼玛肯定是和参考文章的编译器版本不一致导致的,可恨原文章关于环境毫无强调,我这的cmake版本是2.8.12.2的,交叉编译器也是基于gcc-4.8.3的。
幸好,通过google发现有人说注释掉它,ok,那我们注释掉它吧。
接下来重新make,眼看着快好了,95%停下来了,观其错误,一看undefined reference,当然就是链接出错了,再看是关于floor,pow,log等函数的未定义引用,问题很明显,没有链接到math库,肯定是链接选项少了-lm。
那么到底是哪一条编译命令呢,从目前的make显示信息上看只能看到进度,和目标文件,错误信息,我们需要的是类似于gcc -o test test.c这样的东西,然后再后边加上-lm。
好的,如果你熟悉make的话,那么事情显得轻而易举,对,就是make VERBOSE=1,显示详情吧,很好,我们发现最后一条出错的命令是这样的:
/home/weizheng/openwrt/staging_dir/toolchain-i386_i486_gcc-4.8-linaro_uClibc-0.9.33.2/bin/i486-openwrt-linux-gcc -Wall -fno-rtti -fno-exceptions -O3 -DNDEBUG -DDBUG_OFF CMakeFiles/mysql_client_test.dir/mysql_client_test.c.o CMakeFiles/mysql_client_test.dir/__/mysys/my_memmem.c.o -o mysql_client_test -rdynamic ../libmysql/libmysqlclient.a -lpthread
哦,原来是这条编译命令后边没有加-lm。好的,我们分析这条命令,发现源文件是
CMakeFiles/mysql_client_test.dir/mysql_client_test.c.o CMakeFiles/mysql_client_test.dir/__/mysys/my_memmem.c.o
但似乎并不在源码直接目录下,因为在源码目录下重新执行命令,会说上面这两个文件不在,那怎么办呢,这个文件到底死到哪里去了呢,好的,如果你熟悉find命令的话,那么这个问题就迎刃而解了。
[email protected]:~/semanalysis/x86_openwrt_lib/mysql-connector-c-6.0.2$ find . -name mysql_client_test.c.o ./tests/CMakeFiles/mysql_client_test.dir/mysql_client_test.c.o
嗯,终于找到这货了,在test目录下,cd进去,执行编译命令,ok,这个就算过了。
退回上层目录,继续make,发现还有别的一样的错误,重复上述过程。当然似乎有一大堆编译命令都没有-lm,难道我们要一个个加上,这尼玛也真有够烦的。
嗯,再次拿出我们的杀手锏,如果你...对make,Makefile够熟悉的话,一般情况下是这样的,make按照Makefile的组织语法解释执行Makefile,好的,再一般情况下,会有一个选项叫LDFLAGS啦,嗯,就是这样,我们直接修改这个LDFLAGS加上-lm不就完事了吗,但是在Makefile中寻找LDFLAGS显然不是一个明智的选择,这么多Makefile,你知道人家放到哪个里面了,幸好,还有这个办法,就是环境变量。
export LDFLAGS+=-lm
之后重新cmake,make就ok了,终于尼玛华丽的成功了,呵呵呵呵...
对了,别忘了make install哦!
================= main =================
魏征WeiZ