Cross-compiling nginx used on Hi3536

https://www.jianshu.com/p/5d9b60f7b262

The host operating system is ubuntu 16.04. The software packages needed for cross-compilation are
openssl-OpenSSL_1_1_0i.tar.gz
pcre-8.42.tar.gz
nginx-1.14.0.tar.gz
I haven't added zlib yet.

1. Note that openssl and pcre only need to decompress the source code and do not need to compile separately!
At first, I didn't know. I foolishly compiled these two libraries in half a day. Who knows the -- with-pcre and -- with-openssl options of nginx, which specify the source code path of the two libraries, not the installation path? The compiling system of nginx can only find out whether there are pre-compiled pcre, zlib, OpenSSL libraries from a few directories such as / usr, / usr/local. For cross-compilation, it is obviously inappropriate to install cross-compiled PCRE and others directly in / usr, / usr/local, so you need to specify the source code location using -- with-pcre and -- with-openssl

II. Cross-compiling nginx
Compiling nginx on x64 linux is very simple, but there are many pits in cross-compiling. The following configuration is a compiled configuration

./configure --with-http_ssl_module --with-cc=arm-hisiv400-linux-gcc --with-cpp=arm-hisiv400-linux-cpp --with-pcre=/home/src/pcre-8.42 --with-openssl=/home/src/openssl-OpenSSL_1_1_0i --without-http_gzip_module --without-http_upstream_zone_module

Step on pit one and report errors when configure

checking for C compiler ... found but is not working
./configure: error: C compiler arm-hisiv400-linux-gcc is not found

This is because in compiling nginx, besides checking whether cc exists, compiled programs need to be executed. It is obvious that cross-compiled programs cannot be executed. Solution

vi auto/cc/name

    ngx_feature="C compiler"
    ngx_feature_name=
    ngx_feature_run=yes
   ==> ngx_feature_run=no

Error reporting when configuring

checking for int size ...objs/autotest: 1: objs/autotest: Syntax error: word unexpected (expecting ")")
bytes
./configure: error: can not detect int size

It is also because the cc compiled program can not be executed locally. Solution

vi auto/types/sizeof

ngx_test="$CC $CC_TEST_FLAGS $CC_AUX_FLAGS \
   ==> ngx_test="gcc $CC_TEST_FLAGS $CC_AUX_FLAG \

if [ -x $NGX_AUTOTEST ]; then
    ngx_size=`$NGX_AUTOTEST`
   ==>    ngx_size=4

Step on pit three and make a mistake

cd /home/src/pcre-8.42
&& if [ -f Makefile ]; then make distclean; fi
&& CC="arm-hisiv400-linux-gcc" CFLAGS="--host=arm-hisiv400-linux -pipe"
./configure --disable-shared
...
configure: error: in `/home/src/pcre-8.42':
configure: error: C compiler cannot create executables

This is because when compiling pcre, nginx does not set the cross-compilation chain correctly. Solve

vi auto/options

PCRE_CONF_OPT=
   ==> PCRE_CONF_OPT=--host=arm-hisiv400-linux

Stepping on pit four, making mistakes

src/core/ngx_rwlock.c:125:2: error: #error ngx_atomic_cmp_set() is not defined!

Where the error is reported, the source code for nginx is like this

#if (NGX_HTTP_UPSTREAM_ZONE || NGX_STREAM_UPSTREAM_ZONE)

#error ngx_atomic_cmp_set() is not defined!

#endif

The solution is to add -- without-http_upstream_zone_module when configuring

Step on pit five and make a mistake

src/os/unix/ngx_errno.c: In function 'ngx_strerror':
src/os/unix/ngx_errno.c:37:31: error: 'NGX_SYS_NERR' undeclared (first use in this function)
msg = ((ngx_uint_t) err < NGX_SYS_NERR) ? &ngx_sys_errlist[err]:

The reason for the error is still that the cross-compiler cannot run locally, resulting in the non-assignment of the NGX_SYS_NERR macro. Solution, manually edit objs/ngx_auto_config.h, and add

#ifndef NGX_SYS_NERR
#define NGX_SYS_NERR  132
#endif

Step on pit six, make a mistake

/home/src/openssl-OpenSSL_1_1_0i/.openssl/lib/libssl.a: error adding symbols: File format not recognized
collect2: error: ld returned 1 exit status
objs/Makefile:236: recipe for target 'objs/nginx' failed

This is due to the call to GCC of x86 at the time of SSL compilation, rather than cross-compiling gcc. Solution
vi auto/lib/openssl/make

&& ./config --prefix=$ngx_prefix no-shared no-threads $OPENSSL_OPT \
Change to
&& ./Configure --prefix=$ngx_prefix no-shared no-threads --cross-compile-prefix=arm-hisiv400-linux- linux-generic32 \

Step on pit seven and make a mistake

objs/src/core/ngx_cycle.o: In function 'ngx_init_cycle':
/home/src/nginx-1.14.0/src/core/ngx_cycle.c:476: undefined reference to 'ngx_shm_alloc'
/home/src/nginx-1.14.0/src/core/ngx_cycle.c:685: undefined reference to 'ngx_shm_free'

Solution
vi objs/ngx_auto_config.h

#ifndef NGX_HAVE_SYSVSHM
#define NGX_HAVE_SYSVSHM 1
#endif



Author: Ye Yingxian
Link: https://www.jianshu.com/p/5d9b60f7b262
Source: Brief Book
The copyright of the brief book belongs to the author. For any form of reprinting, please contact the author for authorization and indicate the source.

Tags: Mobile Nginx OpenSSL Linux zlib

Posted on Wed, 08 May 2019 08:30:39 -0400 by darkke