nginx移植到mips平台

来源:互联网 发布:suse linux查看wwn号 编辑:程序博客网 时间:2024/05/11 05:01

因为工作需要在嵌入式mips平台上使用nginx做缓存。所以需要将nginx移植到mips平台上。移植过程还是相当简单的。下面给出移植步骤:

1.下载官方的源码包,并解压,准备好交叉编译环境;

2.编写配置脚本config.sh,脚本的主要功能如下:

  a.设置交叉编译工具的路径

b.对根据自身的需要对nginx做裁减

下面给出config.sh的样例:

#!/bin/bashexport CC=mips-unknown-linux-uclibc-gccexport CXX=mips-unknown-linux-uclibc-g++export SYSROOT="/home/command/crosstool/usr/mips-unknown-linux-uclibc/sysroot"#export CFLAGS="--sysroot=${SYSROOT}" ./configure \    --prefix=./cmd \    --conf-path=./conf/nginx.conf \    --error-log-path=./err_log \    --user=admin \    --group=root \    --with-select_module \    --with-poll_module \    --without-http_gzip_module \    --without-http_ssi_module \    --without-http_userid_module \    --without-http_access_module \    --without-http_auth_basic_module \    --without-http_autoindex_module \    --without-http_geo_module \    --without-http_map_module \    --without-http_split_clients_module \    --without-http_referer_module \    --without-http_rewrite_module \    --without-http_proxy_module \    --without-http_fastcgi_module \    --without-http_uwsgi_module \    --without-http_scgi_module \    --without-http_empty_gif_module \    --without-http_browser_module \    --without-http_upstream_hash_module \    --without-http_upstream_ip_hash_module \    --without-http_upstream_least_conn_module \    --without-http_upstream_keepalive_module \    --without-http_upstream_zone_module \    --with-cc=mips-unknown-linux-uclibc-gcc \    --with-cc-opt="--sysroot=/home/command/crosstool/usr/mips-unknown-linux-uclibc/sysroot" \    --without-pcre 


****************************************************************************************************************

3.将config.sh放到nginx源码的根目录下面,并执行./config.sh

  先解释 一下configure的错用,configure主要是在编译前检测本地的编译环境是否准备好,编译工具是否正常工作,相关的依赖库时候已安装等等。

由于nginx的configure脚本会自动检测当前平台的系统版本,然后根据系统版本进行相关的配置,所以这一步,我们会遇到几个错误,下面我会一一列举出来,并给出解决方法:

a.报错“checking for C compiler ... found but is not working”

原因:这个错误出现的原因是由于在执行configure时,会使用我们在config.sh里面配置的编译工具链去编一段测试程序,然后执行编译后的可执行文件。由于我们这里是交叉编译,编译的程序不能再编译的机器上执行,所以这里执行编译后的可执行程序肯定会出错,这回导致configure程序不通过。所以我们需要修改configure的脚本,使其不对编译后的可执行会文件做执行检查。

解决方法:修改源码根目录下面的auto/feature文件,找到下面的代码:

if [ -x $NGX_AUTOTEST ]; then    case "$ngx_feature_run" in        yes)            # /bin/sh is used to intercept "Killed" or "Abort trap" messages            if /bin/sh -c $NGX_AUTOTEST >> $NGX_AUTOCONF_ERR 2>&1; then                echo " found"                ngx_found=yes                if test -n "$ngx_feature_name"; then                    have=$ngx_have_feature . auto/have                fi            else                echo " found but is not working"            fi        ;;
我们见对编译后的可执行文件做执行检查的部分注释掉(行首加上#),修改后的如下(其它部分保持不变):

if [ -x $NGX_AUTOTEST ]; then    case "$ngx_feature_run" in        yes)            # /bin/sh is used to intercept "Killed" or "Abort trap" messages            #if /bin/sh -c $NGX_AUTOTEST >> $NGX_AUTOCONF_ERR 2>&1; then                echo " found"                ngx_found=yes                if test -n "$ngx_feature_name"; then                    have=$ngx_have_feature . auto/have                fi            #else            #    echo " found but is not working"            #fi        ;;

修改源码根目录下面的auto/cc/name文件找到如下部分:

if [ "$NGX_PLATFORM" != win32 ]; then    ngx_feature="C compiler"    ngx_feature_name=    ngx_feature_run=yes    ngx_feature_incs=    ngx_feature_path=    ngx_feature_libs=    ngx_feature_test=

修改后的如下:

if [ "$NGX_PLATFORM" != win32 ]; then    ngx_feature="C compiler"    ngx_feature_name=    ngx_feature_run=    ngx_feature_incs=    ngx_feature_path=    ngx_feature_libs=    ngx_feature_test=

=====================================================================

b. 报错”./configure: error: can not detect int size“

原因:这个报错是由于执行configure时会去执行一段代码检测当前机器上int占用多少个字节,由于我们是交叉编译,所以肯定不能正常检测。

解决方法:修改源码根目录下面的auto/types/sizeof文件,找到如下代码处:

if [ -x $NGX_AUTOTEST ]; then    ngx_size=`$NGX_AUTOTEST`    echo " $ngx_size bytes"fi
由于我们这里不能执行代码区检测,所以我们就直接将检测的size写死(根据自己的平台来写,我的mips平台上int占用4字节),修改后如下:

if [ -x $NGX_AUTOTEST ]; then    #ngx_size=`$NGX_AUTOTEST`    ngx_size=4    echo " $ngx_size bytes"fi


****************************************************************************************************************

4.到这里config.sh是执行通过了。执行make命令编译源码。很快会出现如下错误:

src/os/unix/ngx_errno.c: In function ‘ngx_strerror’:
src/os/unix/ngx_errno.c:37:43: error: expected expression before ‘)’ token
src/os/unix/ngx_errno.c: In function ‘ngx_strerror_init’:
src/os/unix/ngx_errno.c:58:24: error: invalid type argument of unary ‘*’ (have ‘unsigned int’)
src/os/unix/ngx_errno.c:65:37: error: expected expression before ‘;’ token
objs/Makefile:603: recipe for target 'objs/src/os/unix/ngx_errno.o' failed

原因:这个错误出现的原因是由于在configure阶段会检测当前系统的类型(linux, unix,win32 等等),然后根据系统类型去检测当前系统的errno的最大值,并设置环境变量NGX_SYS_NERR这个环境变量为这个最大值。由于我们是交叉编译,所以这个errno的最大值是检测不到的,所以NGX_SYS_NERR就是空的,放到代码里面去肯定是会出错的。

解决方法:修改configure是检测的系统类型为我们真实的类型(我这里是mips),并且根据平台将errno的最大值写死。

修改configure文件,找到如下部分将其注释掉并添加我们平台的定义:

    NGX_SYSTEM=`uname -s 2>/dev/null`    NGX_RELEASE=`uname -r 2>/dev/null`    NGX_MACHINE=`uname -m 2>/dev/null`

修改后的部分如下:

    #NGX_SYSTEM=`uname -s 2>/dev/null`    #NGX_RELEASE=`uname -r 2>/dev/null`    #NGX_MACHINE=`uname -m 2>/dev/null`        NGX_SYSTEM=Linux    NGX_RELEASE=3.4.11-rt19    NGX_MACHINE=mips

除此之外我们还需要修改设置NGX_SYS_NERR这边变量的地方,将其设置为我们平台对应的值(我这里的mips平台的值是47),找到auto/feature的如下部分:

#ifndef $ngx_feature_name#define $ngx_feature_name  `$NGX_AUTOTEST`#endif
修改后部分的如下:

#ifndef $ngx_feature_name//#define $ngx_feature_name  `$NGX_AUTOTEST`#define $ngx_feature_name  47#endif

到这里基本就完了,依次执行make clean; make; make install就可以了。

生成可执行文件以及库文件在源码和config.sh文件里面配置的prefix环境变量的值一致,我这里是源码根目录下面的cmd文件下面。


版权所有,转载请说明出处,谢谢!








1 0
原创粉丝点击