Android平台下tinyproxy-1.8.4移植

由于工作需要,需要在Android平台运行一个http代理服务器软件。首先找了一些apk,分析发现,大多都是让手机使用代理服务器上网的(如ProxyDroid),并不是自身建立一个代理服务器。于是,想自己编译一个linux平台开源的代理服务器软件,首先想到是squid,但看网上反馈squid大复杂,编译难度较大,最后选定一个轻量级开源软件--tinyproxy。
按说,我的工作仅仅是下载tinyproxy源码,做交叉编译,如果顺利的话,半小时就搞定了。但实际情况是编译中遇到各种各样的问题,折腾了好几天,这里记录下供广大开发者参考,少走一点弯路。
一. 建立交叉编译环境
参考 http://blog.csdn.net/zm_21/article/details/17397173,先设置一些环境变量,会使后面操作简单一点。我的交叉编译环境是直接使用Android源码中带的编译器,如果没有源码,直接下载一个ndk应该也是可以的。

export ANDROID_SRC_ROOT="/home/Android5.1"
export SYSROOT="$ANDROID_SRC_ROOT/prebuilts/ndk/current/platforms/android-21/arch-arm"
export CC="$ANDROID_SRC_ROOT/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8/bin/arm-linux-androideabi-gcc --sysroot=$SYSROOT"
export CXX="$ANDROID_SRC_ROOT/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8/bin/arm-linux-androideabi-g++.exe --sysroot=$SYSROOT -I$ANDROID_SRC_ROOT/ndk/sources/cxx-stl/gabi++/include" 
export AR="$ANDROID_SRC_ROOT/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8/bin/arm-linux-androideabi-ar --sysroot=$SYSROOT"
二. configure
使用命令./configure --host=arm-eabi,但过程中遇到各种问题,这里简单记录下。

问题1:
configure报错: 
configure: error: Your system's regexec() function is broken.
分析:
查看config.log,大概是检测正则表达式没有成功。开始以为是缺少一些依赖的库,在网上也没有查到,于是在pc编译了一个简单的示例,用ldd看下,发现并没有依赖什么库,那应该是libc自带的函数了。
后来,用./configure --help查看帮组,发现有一个选项可以忽略这个问题
解决:
./configure --host=arm-eabi --disable-regexcheck

问题2:
configure报错
checking for a2x... no
configure: error: Test for asciidoc failed. See the file 'INSTALL' for help.
分析:
根据这个提示,大概判断是生成文档工具错误,这对我的交叉编译实际是没有影响的;通过查看config.log,找到configure脚本中出错的那一行,直接屏蔽。
解决:
configure中
if test x"$A2X" = x"no"; then
改成
if test x"$A2X" != x"no"; then

上面2个问题处理后,configure完成。

三. make

问题1:
make报错:main.c:212:31: error: 'EX_OK' undeclared (first use in this function)
分析:
源码目录搜索“grep -r EX_OK .”,没有找到定义的地方,网上也没查到,开始怀疑难道是configure生成的,后来在编译主机的/usr/include/sysexits.h找到定义,看来是我的交叉编译环境缺少这个定义。
解决:
拷贝sysexits.h文件到源码的src下,同时config.h中加一行
/* #undef HAVE_SYSEXITS_H */
#define HAVE_SYSEXITS_H 1

问题2:
buffer.c:110: error: undefined reference to 'rpl_malloc'
buffer.c:66: error: undefined reference to 'rpl_malloc'
buffer.c:70: error: undefined reference to 'rpl_malloc'
buffer.c:226: error: undefined reference to 'rpl_malloc'
network.c:114: error: undefined reference to 'rpl_realloc'
reqs.c:675: error: undefined reference to 'rpl_realloc'
分析:
网上搜索了下,有遇到类似的问题,可能是configure过程中,由于某种原因,把malloc重新定义了。
解决:
config.h中注释掉
#define malloc rpl_malloc
#define realloc rpl_realloc

后面还有一些报错,但src/tinyproxy可执行文件已经生成了,其他就不用管了。

四. 安装
tinyproxy push到/system/bin;
tinyproxy.conf push到/system/etc。

tinyproxy.conf文件内容如下:
User root
Group root
Port 8888
Timeout 600
LogFile "/data/tinyproxy.log"
LogLevel Error
PidFile "/data/tinyproxy.pid"
MaxClients 100
MinSpareServers 5
MaxSpareServers 20
StartServers 10
MaxRequestsPerChild 0
ViaProxyName "tinyproxy"
ConnectPort 443
ConnectPort 563
源码的etc/tinyproxy.conf是配置文件模板,这里删除了注释。主要修改 LogFile,PidFile等,由于一些默认配置是/usr/local目录,android下不存在。

五. 运行
使用命令行启动:
tinyproxy -c /system/etc/tinyproxy.conf

问题1:
运行错误:
error: only position independent executables (PIE) are supported.
分析:
这个问题之前遇到过,网上介绍也很多。
解决:
export CFLAGS="-pie -fPIE"
export LDFLAGS="-pie -fPIE"
重新configure,make。

问题2:
运行错误:
init: untracked pid 4435 exited with status 0
init: untracked pid 4436 exited with status 70
分析:
查看日志文件: /data/tinyproxy.log
ERROR     Feb 11 09:41:11 [4436]: Could not allocate memory for child counting.
源码中查找这个错误提示,经过分析是android系统与普通linux目录结构差异导致的。
解决:
 源码 heap.c中,修改
static const char *shared_file = "/tmp/tinyproxy.shared.XXXXXX";
static const char *shared_file = "/mnt/tinyproxy.shared.XXXXXX";

成功运行后是这样的,tinyproxy会自动到后台,开始以为又出错了。
# tinyproxy -c /system/etc/tinyproxy.conf                   
init: untracked pid 5665 exited with status 0
 # ps | grep tinyproxy                                       
root      5666  1     9280   968   c00752d0 b6f01660 S tinyproxy
root      5667  5666  9280   456   c012f990 b6f007f0 S tinyproxy
...

五. 总结
1. 以上很多问题都是通过规避处理的,有空闲时间可以再分析下根本原因,可能有更好的处理方法。
2. 多分析日志可以快速定位问题;上面configure问题可以查看config.log日志文件,运行问题可以查看/data/tinyproxy.log日志文件。
3. 源码中使用grep搜索一些关键字,也容易找到问题原因。

你可能感兴趣的:(Android平台下tinyproxy-1.8.4移植)