编译nginx到Android上踩坑了

上个月老细又话把产品移植到android上,哭吧。。。又一堆东西要搞了。收到任务,第一个移植的就是nginx,因为我们的软件使用了nginx作为http服务器,并且针对服务写了些插件绑定在nginx上。心想这个android也是linux内核的,应该左个跨平台编译就差不多了。谁知道折腾了一个多星期。

如果大家只是想最快编译一个nginx上android就不用看我的文章。直接在这里andoid-nginx下载这个针对android修改好的编译配置就可以了。想了解我采坑的就继续看下去。

编译nginx for android主要参考了 这个帖子和另外一个帖子。但是结合自己的遇到的情况做了一些调整。虽然编译不是很顺利,一路遇到不少问题。不过通过万能的google解决了。历尽千辛万苦终于编译完成了。

其中一个主要的修改是对 auto/types/sizeof文件进行修改,由于configure会对编译出来的测试程序并运行,测试出int,long等数值的长度。由于修改了编译器,编译出来的文件只能在arm的系统上跑,那么在编译的主机上是不能跑的。帖子的方法是教你写一个固定的值,我觉得不是太好,事实上也的确不太好。于是我把这个测试程序的编译器改成我编译主机(用的是mac osx系统)的gcc(其实是clang)。还有一个问题就是我的系统是64位的。而我的目标的android是32位的。不过好彩gcc(其实是clang编译器)有一个参数可以编译32位的程序,“-m32″

#ngx_test=”$CC $CC_TEST_FLAGS $CC_AUX_FLAGS \
ngx_test=”gcc -m32 $CC_TEST_FLAGS $CC_AUX_FLAGS \

放上模拟器上跑ok没有问题。太快乐了。放上真机上跑,悲剧了,虽然可以运行,但是运行过程出错,访问页面的时候。读取不了文件。总是显示pread()出错。开始以为这个函数在真机上没有这个函数又或者是android上这个函数有问题。使用的android系统不是标准的系统,是android主板厂家提供的。咨询厂家会否有些标准函数实现你们没有实现。得到的答复是的,不是所有接口都实现的。真tmd的。不过内心感觉这个这么基础的函数不会没有提供的。由于还有另外一个厂家的板子在。换一个android的板子,测试后,问题也是一样的。这个厂家答复是标准接口都有实现的。这次可以确认是编译问题。不过是什么问题呢?就是是厂家提供的库与android开发包提供的库文件不一样。导致程序连接动态库的时候有问题?尝试全部使用静态链接库,不过有好几个包的链接库只有so文件,没有.a文件。反正有.a的都使用静态连接。

结果还是一样的错误。于是在app市场上找了个app带nginx服务器的。看看别人是否有同样的问题。结果是别人的nginx很正常。也尝试按照别人nginx的版本和参数进行编译。最后结果是一样的错误。到了最后,我还是跟踪代码啦。发觉这个pread系统函数是没有问题的。因为在读取配置文件的时候是使用过的。而且尝试编译过另外一个不使用pread函数的,使用read函数的。结果也是报read函数有问题。这样基本定位了是读取有问题。经过反复调试。发现文件是可以读取的。只是访问页面的时候读取数据就出错。如果在那个读取函数内,重新打开要读取的文件,使用新的文件句柄读取就没有问题了。不过旧有的文件句柄的变量从打开文件到访问的时候都没有变化过。这样就可以很清晰了。估计是越界了。不过这个越界比较温柔,程序没有崩溃。其实我希望你崩溃多过好像你现在这样。

从我的判断,应该是编译前检查数据长度的时候有问题。不能简单使用参数-m32这样编译。估计arm的32位和intel的32有部分数据的长度还是不一样。后来重新修改 auto/types/sizeof文件,使用回原来的arm的编译器。运行程序的时候使用adb shell来桥接运行arm的程序

ngx_test=”$CC $CC_TEST_FLAGS $CC_AUX_FLAGS \
-o $NGX_AUTOTEST $NGX_AUTOTEST.c $NGX_LD_OPT $ngx_feature_libs”

eval “$ngx_test >> $NGX_AUTOCONF_ERR 2>&1″
#if [ -x $NGX_AUTOTEST ]; then
# ngx_size=`$NGX_AUTOTEST`
# echo ” $ngx_size bytes”
#fi

eval “adb push $NGX_AUTOTEST /data/local/tmp/ 2>&1″ > /dev/null
adb shell chmod 755 /data/local/tmp/$(basename $NGX_AUTOTEST)
ngx_size=`adb shell /data/local/tmp/$(basename $NGX_AUTOTEST 2>&1)`
echo ” $ngx_size bytes”

rm -rf $NGX_AUTOTEST*
adb shell rm /data/local/tmp/$(basename $NGX_AUTOTEST 2>&1)

发现”checking for off_t size … 4 bytes“与原来的使用-m32的参数的确不一样,arm是4位的。而-m32的时候是8位的。真系哭都没有眼泪啊。。。编译后放上真机运行没有问题。这次真的快乐了。

andoid-nginx这个库也有一个小坑,导致我开始使用的时候出问题。在网页浏览这个库的时候默认是android分支的。但是你clone下来的时候默认并不是这个分支的。由于他使用hg来管理的。hg现在比较少使用,开始只在终端shell上clone下来,并没有留意他的分支。心想应该和他页面显示的一样。结果就被坑了。这个坑也在我成功编译nginx后才发现的。所以这次踩坑真的多。

还有android系统缺少glob.c 和 glob.h这两个文件,自行下载。

 

 

《编译nginx到Android上踩坑了》有一个想法

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注