nginx交叉编译
- 资源
- source code
- 编译脚本
- FAQ
- 编译过程错误解决
- 编译
- pcre编译
- openssl编译
- 交叉编译器检测错误
- 检查int、long、long long等的长度
- 多线程功能
- ATOMIC功能
- 大小端检查
- NERR错误码
- 参考文献
资源
source code
nginx:http://nginx.org/en/download.html
pcre:https://sourceforge.net/projects/pcre/files/pcre/
openssl:https://www.openssl.org/
针对以上资源这里选用的版本如下
nginx:1.16.1
pcre:8.44
openssl:1.0.2l
编译脚本
以arm-linux-gcc为例,并且安装目录为:/usr/local/arm-linux/bin/
nginx配置资源安装目录为:/opt/nginx.res
pcre源码路径:/home/test/source/pcre-8.44
openssl源码路径:/home/test/source/openssl-1.0.2l
BUILD_CC_PATH=/usr/local/arm-linux
NGINX_RES_PATH=/mnt/mtdblock/service/nginx.res
BUILD_PATH=${baseDir}
INSTALL_PATH=${baseDir}/${PLATFORM}-install
CC_PATH=$BUILD_CC_PATH/bin/arm-linux-gcc
CPP_PATH=$BUILD_CC_PATH/arm-linux-g++
CONFIG_DIR=$NGINX_RES_PATH/conf
LOG_DIR=$NGINX_RES_PATH/logs
TEMP_DIR=$$NGINX_RES_PATH/temp
./configure \
--prefix=$INSTALL_PATH\
--builddir=$BUILD_PATH/build \
--conf-path=$CONFIG_DIR/nginx.conf \
--error-log-path=$LOG_DIR/error.log \
--pid-path=$CONFIG_DIR/nginx.pid \
--lock-path=$CONFIG_DIR/nginx.lock \
--http-log-path=$LOG_DIR/access.log \
--http-client-body-temp-path=$TEMP_DIR/body \
--http-proxy-temp-path=$TEMP_DIR/proxy \
--http-fastcgi-temp-path=$TEMP_DIR/fastcgi \
--without-http_uwsgi_module \
--without-http_scgi_module \
--without-http_gzip_module \
--with-http_ssl_module \
--with-pcre=/home/test/source/pcre-8.44 \
--with-openssl=/home/test/source/openssl-1.0.2l \
--with-openssl-opt="no-asm" \
--with-cc=$CC_PATH \
--with-cpp=$CPP_PATH \
--with-cc-opt="-I $BUILD_CC_PATH/include" \
--with-ld-opt="-L $BUILD_CC_PATH/lib" \
--with-pcre-conf-opt="--host=${HOST}" \
--host=${ARCH}
FAQ
编译过程错误解决
编译
执行编译脚本后,接下来就是编译了,由于我们配置了–builddir,真正编译的时候是执行build/Makefile,所以执行命令:make -f build/Makefile
pcre编译
编译脚本执行完成后,nginx工程代码生成对应的Makefile文件(由于我们配置了–builddir,真正编译的时候是执行build/Makefile,make -f build/Makefile),在编译nginx的时候会需要同时编译pcre代码,由于我们是进行交叉编译的,查看了对应的Makefile文件发现对应的pcre编译配置并没有进行交叉编译配置,做如下修改
- 修改"auto/options"文件
--with-pcre-conf-opt=*) PCRE_CONF_OPT="$value" ;;
openssl编译
同pcre编译,openssl并没有进行交叉编译配置,做如下修改
- 修改"auto/lib/openssl/make"文件
$OPENSSL/.openssl/include/openssl/ssl.h: $NGX_MAKEFILE
cd $OPENSSL \\
&& if [ -f Makefile ]; then \$(MAKE) clean; fi \\
&& export CC=$CC \\
&& setarch i386 ./config --prefix=$ngx_prefix no-shared no-threads $OPENSSL_OPT \\
&& \$(MAKE) \\
&& \$(MAKE) install_sw LIBDIR=lib
备注:增加代码块如下,请自行对比
&& export CC=$CC \\
&& setarch i386 ./config
setarch i386是由于:开发版是使用32位系统,编译PC是使用的64位系统
交叉编译器检测错误
在执行编译脚本时,会进行编译器检查(检查方法:使用编译器编译test程序,看是否可以正常执行),由于我们是进行交叉编译,在编译PC上是无法正常的执行test程序的,做如下修改
- 修改"auto/options"文件
NGX_HOST=
--host=*) NGX_HOST="$value" ;;
- 修改"auto/cc/name"文件
ngx_feature_run=no
备注:ngx_feature_run=yes为ngx_feature_run=no,修改后意思是只编译不执行
检查int、long、long long等的长度
在执行编译脚本时,会进行基础类型长度检查(检查方法:使用编译器编译test程序,然后执行程序看输出长度大小为多少),由于我们是进行交叉编译,在编译PC上是无法正常的执行test程序的,做如下修改
- 修改"auto/types/sizeof"文件,(测试int、long、long long的长度),修改ngx_size=4(正如上面说到的移植的开发版为32位)
if [ -x $NGX_AUTOTEST ]; then
ngx_size=`$NGX_AUTOTEST`
if [ "$NGX_HOST" == arm ] || [ "$NGX_HOST" == mips ]; then
if [ "$ngx_type" = "long" ]; then
ngx_size=4
fi
if [ "$ngx_type" = "void *" ]; then
ngx_size=4
fi
if [ "$ngx_type" = "size_t" ]; then
ngx_size=4
fi
if [ "$ngx_type" = "off_t" ]; then
ngx_size=4
fi
if [ "$ngx_type" = "time_t" ]; then
ngx_size=4
fi
if [ "$ngx_type" = "int" ]; then
ngx_size=4
fi
if [ "$ngx_type" = "long long" ]; then
ngx_size=4
fi
if [ "$ngx_type" = "sig_atomic_t" ]; then
ngx_size=4
fi
fi
echo " $ngx_size bytes"
fi
备注:请自行根据开发及类型,进行定义
多线程功能
在执行编译脚本时,会进行多线程锁检查,由于我们是进行交叉编译,在编译PC上是无法正常的执行test程序的,做如下修改
- 修改"auto/unix"文件
ngx_feature_run=yes
if [ "$NGX_PLATFORM" == arm ] || [ "$NGX_PLATFORM" == mips ]; then
ngx_feature_run=no
fi
备注:ngx_feature_run=yes改为ngx_feature_run=no,修改后意思是只编译不执行
ATOMIC功能
在执行编译脚本时,会进行ATOMIC检查(对比过老版本(1.6.2)的nginx,在ATOMIC应用上有所区别,老版本对此项检测并不影响编译,在nginx新版本,对此项检查异常的话,会影响编译,检查方法:使用编译器编译test程序,然后执行程序根据执行结果进行功能判断),由于我们是进行交叉编译,在编译PC上是无法正常的执行test程序的,做如下修改
- 修改"auto/cc/conf"文件
if [ "$NGX_CC_NAME" = "sunc" ]; then
echo "checking for gcc builtin atomic operations ... disabled"
else
ngx_feature="gcc builtin atomic operations"
ngx_feature_name=NGX_HAVE_GCC_ATOMIC
ngx_feature_run=no
ngx_feature_incs=
ngx_feature_path=
ngx_feature_libs=
ngx_feature_test="long n = 0;
if (!__sync_bool_compare_and_swap(&n, 0, 1))
return 1;
if (__sync_fetch_and_add(&n, 1) != 1)
return 1;
if (n != 2)
return 1;
__sync_synchronize();"
. auto/feature
fi
备注:ngx_feature_run=yes改为ngx_feature_run=no,修改后意思是只编译不执行
大小端检查
在执行编译脚本时,会进行系统大小端检查(如果编译PC与开发版不一样的话,是需要进行修改的,检查方法:使用编译器编译test程序,然后执行程序根据执行结果进行功能判断),由于我们是进行交叉编译,在编译PC上是无法正常的执行test程序的,做如下修改
- 修改"auto/endianness"文件
if [ -x $NGX_AUTOTEST ]; then
if $NGX_AUTOTEST >/dev/null 2>&1; then
echo " little endian"
have=NGX_HAVE_LITTLE_ENDIAN . auto/have
else
if [[ $CC =~ "arm-linux-gcc" ]]; then
echo " little endian"
have=NGX_HAVE_LITTLE_ENDIAN . auto/have
else
echo " big endian"
fi
fi
rm -rf $NGX_AUTOTEST*
else
rm -rf $NGX_AUTOTEST*
echo
echo "$0: error: cannot detect system byte ordering"
exit 1
fi
备注:直接根据判断编译器是否为对应的交叉编译器,进行大小端设置,修改代码块如下
if [[ $CC =~ "arm-linux-gcc" ]]; then
echo " little endian"
have=NGX_HAVE_LITTLE_ENDIAN . auto/have
else
echo " big endian"
fi
NERR错误码
在执行编译脚本时,会进行系统错误码检查(检查方法:使用编译器编译test程序,然后执行程序根据执行结果进行最大值预编译定义),由于我们是进行交叉编译,在编译PC上是无法正常的执行test程序的,做如下修改
- 修改build/ngx_auto_config.h,增加宏定义
#ifndef NGX_SYS_NERR
#define NGX_SYS_NERR 135
#endif
#ifndef NGX_HAVE_SYSVSHM
#define NGX_HAVE_SYSVSHM 1
#endif
备注:最后增加
运动中修改!!!
参考文献
nginx 交叉编译 ( 上 )