由于项目需要所以在网上找了很久的android版本的nginx,终于不负有心人找到一个能用的android nginx的bin文件:https://github.com/dna2github/dna2oslab/releases,但是由于项目需要rtmp模块,不得已只有亲自下手一试交叉编译android版本的nginx。
需要编译安装nginx需要的前置库,一共有三个:zlib,pcre和openssl.
下载路径如下:
zlib-1.2.11:http://www.zlib.net/
pcre-8.43:http://www.pcre.org/
openssl-1.0.2:https://oomake.com/download/openssl
nginx-1.9.9:http://nginx.org/en/download.html
spawn-cgi-1.6.4:链接: https://pan.baidu.com/s/16ukD_MLW6AtVH14tPBdbOA 提取码: gfys(永久有效)
fcgi-2.4.1:链接: https://pan.baidu.com/s/16ukD_MLW6AtVH14tPBdbOA 提取码: gfys(永久有效)
在sdk中下载解压,这些操作就不多介绍了,要说的是,在configure时一定要执行以下configure --help查看以下configure的配置说明,在编译开源的模块时很有帮助。
android下编译pcre一定要弄清楚当前SDK中的NDK详细路径和版本。
configure命令参考如下:
./configure --host=arm-linux-androideabi --prefix=SDK/module/jznginx/build CPPFLAGS="-ISDK/prebuilts/ndk/8/sources/cxx-stl/gnu-libstdc++/libs/armeabi-v7a/include -ISDK/prebuilts/ndk/8/sources/cxx-stl/gnu-libstdc++/include" LDFLAGS="-LSDK/prebuilts/ndk/8/sources/cxx-stl/gnu-libstdc++/libs/armeabi-v7a" CFLAGS="-pie -fPIE -g -O2" LIBS="-lgnustl_shared -lgnustl_static -lsupc++"
1.CFLAGS中一定要添加-pie -fPIE这两个标志,这是android5.0以后要的,否则你编出来的bin文件将无法在android的环境中执行,会报一个错误:
2.LIBS中一定要配置-lgnustl_shared -lgnustl_static -lsupc++当然对应的LDFLAGS一定要配对,我的SDK中存在多个NDK版本,所以在配置的时候一定要选择正在使用的那个,这里完全是试错试出来的。
3.这里面默认使用环境变量中指定的交叉编译工具,如:arm-linux-androideabi-gcc、arm-linux-androideabi-g++等,所以我在configure中就没有指定,当你的环境变量指定的交叉编译工具和你配置的LDFLAGS、CPPFLAGS不在一条线上,那就坑了。
make && make install:
这块没啥好说的,都挺顺利的,需要注意的就是最好将--prefix的路径都指定同一个(意思是无论接下来的openssl编译还是zlib编译都放一个路径下,后面编译nginx的时候好处自现)
我这边用的openssl1.0.2,算是比较old的版本了,nginx版本是1.9.9,貌似nginx不挑,也照常编译通过,也可能是我没配置对,总之没有影响功能。
openssl的configure有点特殊,Configure(注意开头的大C)能用config也能用。
config命令配置参考如下:
./config no-asm no-shared --prefix=SDK/jznginx/build
sed -i "s/-m64//g" Makefile
解释:no-asm:是否在编译过程中使用汇编代码加快编译过程(不加这个貌似会报错,采坑太多,姑且忘记了);no-shared:因为我们要干干爽爽的nginx bin当然不希望贴一堆动态库。sed -i "s/-m64//g" Makefile我们要编的都是arm 32位所以要干掉64位的选项,just do it。
修改Makefile:
这里给一个参考:
CC= arm-linux-androideabi-gcc
CFLAG= -pie -fPIE -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -ISDK/prebuilts/ndk/current/platforms/android-18/arch-arm/usr/include --sysroot=SDK/prebuilts/ndk/current/platforms/android-18/arch-arm -DL_ENDIAN -DTERMIO -O3 -Wall
DEPFLAG= -DOPENSSL_NO_EC_NISTP_64_GCC_128 -DOPENSSL_NO_GMP -DOPENSSL_NO_JPAKE -DOPENSSL_NO_LIBUNBOUND -DOPENSSL_NO_MD2 -DOPENSSL_NO_RC5 -DOPENSSL_NO_RFC3779 -DOPENSSL_NO_SCTP -DOPENSSL_NO_SSL_TRACE -DOPENSSL_NO_STORE -DOPENSSL_NO_UNIT_TEST
PEX_LIBS=
EX_LIBS= -LSDK/prebuilts/ndk/current/platforms/android-18/arch-arm/usr/lib -ldl
EXE_EXT=
ARFLAGS=
AR= arm-linux-androideabi-ar $(ARFLAGS) r
RANLIB= arm-linux-androideabi-ranlib
NM= arm-linux-androideabi-nm
PERL= /usr/bin/perl
TAR= tar
TARFLAGS= --no-recursion
MAKEDEPPROG= arm-linux-androideabi-gcc
LIBDIR=lib
注意:EX_LIBS表示外联库的路径,类似LDFLAGS,-ldl一定要加很重要,不加会报错,踩坑经验。
漫长而没有灵魂的过程,不多介绍。
这是一个不闹幺蛾子的部分,所以它被安排在nginx中一块编译。
nginx这个东东,对嵌入式设备支持真的很不友好,不过嵌入式设备跑nginx确实有点法拉利犁地,可惜。
首先在configure之前要消灭一些潜在的不友好的部分,让configure通过。
cd nginx/auto/types
vim sizeof
#找到ngx_size=`$NGX_AUTOTEST` 改成ngx_size=4
#找到ngx_test="CC $CC_TEST_FLAGS $CC_AUX_FLAGS..." 改成ngx_test="gcc $CC_TEST_FLAGS $CC_AUX_FLAGS..."
vim typedef
#找到ngx_test="CC $CC_TEST_FLAGS $CC_AUX_FLAGS..." 改成ngx_test="gcc $CC_TEST_FLAGS $CC_AUX_FLAGS..."
vim uintptr_t
#找到ngx_test="CC $CC_TEST_FLAGS $CC_AUX_FLAGS..." 改成ngx_test="gcc $CC_TEST_FLAGS $CC_AUX_FLAGS..."
vim auto/cc/name
#找到ngx_feature_run=yes 改为ngx_feature_run=no
configure参考命令:
./configure --with-cc=arm-linux-androideabi-gcc --with-cpp=arm-linux-androideabi-g++ --prefix=$SDK/jzby/jznginx/build --with-pcre=../pcre-8.43 --with-zlib=../zlib-1.2.11 --with-openssl=../openssl-1.0.2 --user=root --group=root --add-module=../nginx-rtmp-module-master --without-http_upstream_zone_module
修改Makefile:
直接贴一个吧,算了,太长了。
说点关键的:
1.CFLAGS中去掉-Werror,有些无聊的告警会打断make过程,所以还是干掉吧。CFLAGS中添加-pie -fPIE参考如下
CFLAGS = -pie -fPIE -O -W -Wall -Wpointer-arith -Wno-unused-parameter -g -I../nginx-rtmp-module-master
2.在objs/nginx:中修改链接的pcre路径,如(build是之前编译pcre时配置的--prefix的路径):
3.在$(LINK)的过程中修改链接库的位置,如(build是之前配置的--prefix的路径):
4.在objs/Makefile中去掉pcre和openssl的编译选项(都编过了,这里不需要再操作编译了):
5.在zlib的编译CFLAGS中添加-pie -fPIE的标志(哪个报错没记录,相信你一旦遇到一定能快速的知道是则么回事):
修改objs/config文件:
vim ngx_auto_config.h
#在文档部分添加如下内容:
#ifndef NGX_HAVE_MAP_ANON
#define NGX_HAVE_MAP_ANON 1
#endif
#ifndef NGX_SYS_NERR
#define NGX_SYS_NERR 132
#endif
修改src/file文件:
1.删除nginx中关于glob的部分:
cd nginx/src/
grep "glob" ./ -r
2.找不到的头文件,都干掉。
3.将所有in_port_t改成uint16_t;
4.将SO_REUSEPORT 改 0x2000
5.将AT_EMPTY_PATH 改 0x2000
6.将IOV_MAX 改 1024(注意有隐藏的IOV_MAX,一定要把所有引用的地方都改掉)
暂时就这些,如果你不能痛快的make到最后,你把你的问题留言下来,我遇到过的话会回复,当然我也是菜鸟,大家相互学习。
没有灵魂,但又让人满怀期待,如果一切顺利就OK了。nginx这部分很磨人,我搞了但记忆又不是很清楚了,可能再遇到同样的问题会激活我的记忆。
这里多说一嘴,nginx在板子上起来,需要手动指定配置文件的路径,也就说nginx需要-p启动,这肯定不合理,但我已经不想再解决了,所有我每次都执行nginx -p /etc/nginx/ 来启动。如果提示缺少logs/error.log文件直接在/etc/nginx/下mkdir一个logs,touch error.log,很笨,但有效。
fcgi不支持androideabi所以在configure时--host=arm-linux
./configure --host=arm-linux --prefix=$SDK/jznginx/build CC=arm-linux-androideabi-gcc CPP=arm-linux-androideabi-cpp CXX=arm-linux-androideabi-g++ CFLAGS="-pie -fPIE -g -O2" LIBS="-lm"
踩坑点:LIBS一定要加-lm,CFLAGS中一定有-pie,-fPIE
nothing!!!
./configure --host=arm-linux-androideabi --prefix=$SDK/jznginx/build CC=arm-linux-androideabi-gcc CPP=arm-linux-androideabi-cpp CXX=arm-linux-androideabi-g++ CFLAGS="-pie -fPIE -g -O2"
修改config.h
删除#define malloc rpl_malloc
nothing!!!
最后给伸手党一些现成的吧,希望能帮助到你。
链接:https://pan.baidu.com/s/1QZ_o5rj_sgEHnciK9K2V4A
提取码:vla5
参考: 拥抱Android:编译nginx搭建移动平台
参考:交叉编译Hi3536上面使用的nginx
参考:nginx交叉编译
感谢大神们!!!