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.