nginx的交叉编译(二)(未完成)

前言

之前的文章描述了如何根据官网指引编译nginx以及如何交叉编译nginx,其中交叉编译部分以最简单的模式进行(去掉了很多模块)。本文继续描述更多交叉编译模块,包括:使用不同的交叉编译器,引入更多模块(尤其是ssl比较复杂)。

交叉编译器

笔者系统中存在若干个版本的交叉编译器,有些是笔者从项目中编译出来的、有些是供应商给的,这里挑选几款比较有典型意义的交叉编译器来完成交叉编译。

arm

交叉编译链的根目录如下:

root@ubuntu:one-arm-cross# ls -l
total 28
drwxrwxrwx 6 root root 4096 Mar  3  2018 arm-buildroot-linux-gnueabi
drwxrwxrwx 2 root root 4096 Mar  3  2018 bin
drwxrwxrwx 2 root root 4096 Mar  3  2018 include
drwxrwxrwx 5 root root 4096 Mar  3  2018 lib
drwxrwxrwx 4 root root 4096 Mar  3  2018 libexec
drwxrwxrwx 9 root root 4096 Mar  3  2018 share
-rwxrwxrwx 1 root root   72 Mar  3  2018 version
root@ubuntu:one-arm-cross#

在之前文章中描素过,我们需要找到gcc、g++、include和lib等目录,初看一眼,我们总会认为gcc、g++位于bin目录下,include和lib也在,其实再进入相关目录查看并非如此。比如gcc和g++的确在bin目录下:

root@ubuntu:one-arm-cross# ls -l bin/
total 31708
-rwxrwxrwx 1 root root  654392 Mar  3  2018 arm-buildroot-linux-gnueabi-addr2line
-rwxrwxrwx 1 root root  684146 Mar  3  2018 arm-buildroot-linux-gnueabi-ar
...... 省略了很多输出
-rwxrwxrwx 1 root root  637541 Mar  3  2018 arm-linux-g++
-rwxrwxrwx 1 root root  635091 Mar  3  2018 arm-linux-gcc
-rwxrwxrwx 1 root root  635091 Mar  3  2018 arm-linux-gcc-4.8.5
-rwxrwxrwx 1 root root   26927 Mar  3  2018 arm-linux-gcc-ar
-rwxrwxrwx 1 root root   26863 Mar  3  2018 arm-linux-gcc-nm
-rwxrwxrwx 1 root root   26899 Mar  3  2018 arm-linux-gcc-ranlib
-rwxrwxrwx 1 root root  295397 Mar  3  2018 arm-linux-gcov
-rwxrwxrwx 1 root root  721699 Mar  3  2018 arm-linux-gprof
-rwxrwxrwx 1 root root 1130114 Mar  3  2018 arm-linux-ld
-rwxrwxrwx 1 root root 1130114 Mar  3  2018 arm-linux-ld.bfd
-rwxrwxrwx 1 root root  665465 Mar  3  2018 arm-linux-nm
-rwxrwxrwx 1 root root  827112 Mar  3  2018 arm-linux-objcopy
-rwxrwxrwx 1 root root 1034055 Mar  3  2018 arm-linux-objdump
-rwxrwxrwx 1 root root  684145 Mar  3  2018 arm-linux-ranlib
-rwxrwxrwx 1 root root  440662 Mar  3  2018 arm-linux-readelf
-rwxrwxrwx 1 root root  655978 Mar  3  2018 arm-linux-size
-rwxrwxrwx 1 root root  654252 Mar  3  2018 arm-linux-strings
-rwxrwxrwx 1 root root  827111 Mar  3  2018 arm-linux-strip
-rwxrwxrwx 1 root root    5465 Mar  3  2018 GetSharelib.sh
-rwxrwxrwx 1 root root    9251 Mar  3  2018 so_show.sh
root@ubuntu:one-arm-cross# 

但是include和lib目录下并没有我们需要的头文件和库文件,如下:

root@ubuntu:one-arm-cross# ls -l include/
total 192
-rwxrwxrwx 1 root root 30929 Mar  3  2018 gawkapi.h
-rwxrwxrwx 1 root root 83139 Mar  3  2018 gmp.h
-rwxrwxrwx 1 root root 12733 Mar  3  2018 mpc.h
-rwxrwxrwx 1 root root  6236 Mar  3  2018 mpf2mpfr.h
-rwxrwxrwx 1 root root 51307 Mar  3  2018 mpfr.h
root@ubuntu:one-arm-cross# 
root@ubuntu:one-arm-cross# ls -l lib
total 2892
drwxrwxrwx 2 root root   4096 Mar  3  2018 gawk
drwxrwxrwx 3 root root   4096 Mar  3  2018 gcc
drwxrwxrwx 2 root root   4096 Mar  3  2018 ldscripts
-rwxrwxrwx 1 root root   1095 Mar  3  2018 libgmp.la
-rwxrwxrwx 1 root root 478466 Mar  3  2018 libgmp.so
-rwxrwxrwx 1 root root 478466 Mar  3  2018 libgmp.so.10
-rwxrwxrwx 1 root root 478466 Mar  3  2018 libgmp.so.10.2.0
-rwxrwxrwx 1 root root   1251 Mar  3  2018 libmpc.la
-rwxrwxrwx 1 root root 100581 Mar  3  2018 libmpc.so
-rwxrwxrwx 1 root root 100581 Mar  3  2018 libmpc.so.3
-rwxrwxrwx 1 root root 100581 Mar  3  2018 libmpc.so.3.0.0
-rwxrwxrwx 1 root root   1174 Mar  3  2018 libmpfr.la
-rwxrwxrwx 1 root root 395684 Mar  3  2018 libmpfr.so
-rwxrwxrwx 1 root root 395684 Mar  3  2018 libmpfr.so.4
-rwxrwxrwx 1 root root 395684 Mar  3  2018 libmpfr.so.4.1.3
root@ubuntu:one-arm-cross# 

如何定位正确的include和lib目录呢,我们通过搜索最常见的头文件和库文件可以找到:

root@ubuntu:one-arm-cross# find -name stdio.h
./arm-buildroot-linux-gnueabi/include/c++/4.8.5/tr1/stdio.h
./arm-buildroot-linux-gnueabi/sysroot/usr/include/bits/stdio.h
./arm-buildroot-linux-gnueabi/sysroot/usr/include/stdio.h
root@ubuntu:one-arm-cross# 
root@ubuntu:one-arm-cross# find -name string.h
./arm-buildroot-linux-gnueabi/sysroot/usr/include/bits/string.h
./arm-buildroot-linux-gnueabi/sysroot/usr/include/string.h
./arm-buildroot-linux-gnueabi/sysroot/usr/include/linux/string.h
root@ubuntu:one-arm-cross#
root@ubuntu:one-arm-cross# find -name libc.so
./arm-buildroot-linux-gnueabi/sysroot/usr/lib/libc.so
./arm-buildroot-linux-gnueabi/sysroot/usr/lib32/libc.so
root@ubuntu:one-arm-cross# 
root@ubuntu:one-arm-cross# find -name libpthread.so
./arm-buildroot-linux-gnueabi/sysroot/usr/lib/libpthread.so
./arm-buildroot-linux-gnueabi/sysroot/usr/lib32/libpthread.so
root@ubuntu:one-arm-cross# 

可以看到include目录应该就是 ./arm-buildroot-linux-gnueabi/sysroot/usr/include,但是lib目录是 ./arm-buildroot-linux-gnueabi/sysroot/usr/lib 还是 ./arm-buildroot-linux-gnueabi/sysroot/usr/lib32 呢?
其实再次进行对比,可以发现 ./arm-buildroot-linux-gnueabi/sysroot/usr/lib 和 ./arm-buildroot-linux-gnueabi/sysroot/usr/lib32 目录下的文件是一致的。

root@ubuntu:one-arm-cross# diff ./arm-buildroot-linux-gnueabi/sysroot/usr/lib ./arm-buildroot-linux-gnueabi/sysroot/usr/lib32 -r
root@ubuntu:one-arm-cross#

所以我们重点关注交叉编译链相关的几个配置参数就已经确定了:

--with-cc=/home/sdks/one-arm-cross/bin/arm-linux-gcc 
--with-cpp=/home/sdks/one-arm-cross/bin/arm-linux-g++ 
--with-cc-opt="-I/home/sdks/ruijieh10g/arm-buildroot-linux-gnueabi/sysroot/usr/include" 
--with-ld-opt="-L/home/sdks/ruijieh10g/arm-buildroot-linux-gnueabi/sysroot/usr/lib"

最后,配置命令如下:

./configure --prefix=/tmp/_install --with-cc=/home/sdks/one-arm-cross/bin/arm-linux-gcc --with-cpp=/home/sdks/one-arm-cross/bin/arm-linux-g++ --with-cc-opt="-I/home/sdks/ruijieh10g/arm-buildroot-linux-gnueabi/sysroot/usr/include" --with-ld-opt="-L/home/sdks/ruijieh10g/arm-buildroot-linux-gnueabi/sysroot/usr/lib" --without-http_rewrite_module --without-http_gzip_module --without-http_upstream_zone_module --without-http_charset_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_proxy_module --without-http_uwsgi_module --without-http_scgi_module --without-http_memcached_module --without-http_limit_conn_module --without-http_limit_req_module --without-http_empty_gif_module --without-http_upstream_hash_module --without-http_upstream_ip_hash_module --without-http_upstream_least_conn_module --without-http_upstream_keepalive_module --without-mail_pop3_module --without-mail_imap_module --without-mail_smtp_module  --without-stream_limit_conn_module --without-stream_access_module --without-stream_upstream_hash_module --without-stream_upstream_least_conn_module --without-stream_upstream_zone_module

其中配置的时候会遇到几个错误和解决方法分别如下,具体解释可以参考前一篇文章。

编译器找不到错误

报错现象:

./configure: error: C compiler /home/sdks/one-arm-cross/bin/arm-linux-gcc is not found

解决办法:
修改 auto/feature 大概 42行,把 $CC 修改成 gcc.

无法检测int的大小

报错现象:

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

./configure: error: can not detect int size

解决办法:
修改 auto/cc/sizeof 大概 36 行,把 $CC 修改成 gcc.
另外根据目标机的实际情况,要修改变量 ngx_size 的值,比如我的系统中目标机器是32位的,则大概 46 行左右,设置:ngx_size=4

大小端的设定

这个地方configure本身并不会报错,但是这个地方是要根据实际情况手动调整的,原因分析和调整方法参考附录

mips

交叉编译链的根目录如下:

root@ubuntu:OpenWrt-SDK-ar71xx-generic_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-i686# ls -l
total 124
drwxr-xr-x 3 root root  4096 Jun  7 12:27 build_dir
-rw-r--r-- 1 root root 40823 Jun  7 12:27 Config-build.in
-rw-r--r-- 1 root root    57 Jul 18  2017 Config.in
drwxr-xr-x 2 root root  4096 Jun  7 12:26 dl
drwxr-xr-x 2 root root  4096 Jul 18  2017 docs
-rw-r--r-- 1 root root   900 Jun  7 12:27 feeds.conf.default
drwxr-xr-x 3 root root  4096 Jun  7 12:27 include
-rw-r--r-- 1 root root 17992 Jul 18  2017 LICENSE
-rw-r--r-- 1 root root  1208 Jul 18  2017 Makefile
drwxr-xr-x 2 root root  4096 Jun  7 12:27 package
-rw-r--r-- 1 root root   374 Jul 18  2017 prepare.mk
-rw-r--r-- 1 root root   337 Jul 18  2017 README.SDK
-rw-r--r-- 1 root root 10649 Jul 18  2017 rules.mk
drwxr-xr-x 4 root root  4096 Jul 18  2017 scripts
drwxr-xr-x 5 root root  4096 Jun  7 12:27 staging_dir
drwxr-xr-x 3 root root  4096 Jun  7 12:27 target
root@ubuntu:OpenWrt-SDK-ar71xx-generic_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-i686# 
root@ubuntu:OpenWrt-SDK-ar71xx-generic_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-i686# ls -l staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/bin/
total 26928
-rwxr-xr-x 1 root root   31899 Jun  7 11:46 ldd
lrwxrwxrwx 1 root root      35 Jun  7 11:46 mips-openwrt-linux-addr2line -> mips-openwrt-linux-uclibc-addr2line
lrwxrwxrwx 1 root root      28 Jun  7 11:46 mips-openwrt-linux-ar -> mips-openwrt-linux-uclibc-ar
lrwxrwxrwx 1 root root      28 Jun  7 11:46 mips-openwrt-linux-as -> mips-openwrt-linux-uclibc-as
lrwxrwxrwx 1 root root      29 Jun  7 11:46 mips-openwrt-linux-c++ -> mips-openwrt-linux-uclibc-c++
lrwxrwxrwx 1 root root      33 Jun  7 11:46 mips-openwrt-linux-c++filt -> mips-openwrt-linux-uclibc-c++filt
lrwxrwxrwx 1 root root      29 Jun  7 11:46 mips-openwrt-linux-cpp -> mips-openwrt-linux-uclibc-cpp
lrwxrwxrwx 1 root root      33 Jun  7 11:46 mips-openwrt-linux-elfedit -> mips-openwrt-linux-uclibc-elfedit
lrwxrwxrwx 1 root root      29 Jun  7 11:46 mips-openwrt-linux-g++ -> mips-openwrt-linux-uclibc-g++
lrwxrwxrwx 1 root root      29 Jun  7 11:46 mips-openwrt-linux-gcc -> mips-openwrt-linux-uclibc-gcc
lrwxrwxrwx 1 root root      35 Jun  7 11:46 mips-openwrt-linux-gcc-4.8.3 -> mips-openwrt-linux-uclibc-gcc-4.8.3
lrwxrwxrwx 1 root root      32 Jun  7 11:46 mips-openwrt-linux-gcc-ar -> mips-openwrt-linux-uclibc-gcc-ar
lrwxrwxrwx 1 root root      32 Jun  7 11:46 mips-openwrt-linux-gcc-nm -> mips-openwrt-linux-uclibc-gcc-nm
lrwxrwxrwx 1 root root      36 Jun  7 11:46 mips-openwrt-linux-gcc-ranlib -> mips-openwrt-linux-uclibc-gcc-ranlib
lrwxrwxrwx 1 root root      30 Jun  7 11:46 mips-openwrt-linux-gcov -> mips-openwrt-linux-uclibc-gcov
lrwxrwxrwx 1 root root      29 Jun  7 11:46 mips-openwrt-linux-gdb -> mips-openwrt-linux-uclibc-gdb
lrwxrwxrwx 1 root root      31 Jun  7 11:46 mips-openwrt-linux-gprof -> mips-openwrt-linux-uclibc-gprof
lrwxrwxrwx 1 root root      28 Jun  7 11:46 mips-openwrt-linux-ld -> mips-openwrt-linux-uclibc-ld
lrwxrwxrwx 1 root root      32 Jun  7 11:46 mips-openwrt-linux-ld.bfd -> mips-openwrt-linux-uclibc-ld.bfd
lrwxrwxrwx 1 root root      28 Jun  7 11:46 mips-openwrt-linux-nm -> mips-openwrt-linux-uclibc-nm
lrwxrwxrwx 1 root root      33 Jun  7 11:46 mips-openwrt-linux-objcopy -> mips-openwrt-linux-uclibc-objcopy
lrwxrwxrwx 1 root root      33 Jun  7 11:46 mips-openwrt-linux-objdump -> mips-openwrt-linux-uclibc-objdump
lrwxrwxrwx 1 root root      32 Jun  7 11:46 mips-openwrt-linux-ranlib -> mips-openwrt-linux-uclibc-ranlib
lrwxrwxrwx 1 root root      33 Jun  7 11:46 mips-openwrt-linux-readelf -> mips-openwrt-linux-uclibc-readelf
lrwxrwxrwx 1 root root      30 Jun  7 11:46 mips-openwrt-linux-size -> mips-openwrt-linux-uclibc-size
lrwxrwxrwx 1 root root      33 Jun  7 11:46 mips-openwrt-linux-strings -> mips-openwrt-linux-uclibc-strings
lrwxrwxrwx 1 root root      31 Jun  7 11:46 mips-openwrt-linux-strip -> mips-openwrt-linux-uclibc-strip
-rwxr-xr-x 1 root root 1070344 Jun  7 12:27 mips-openwrt-linux-uclibc-addr2line
-rwxr-xr-x 2 root root 1103084 Jun  7 12:27 mips-openwrt-linux-uclibc-ar
-rwxr-xr-x 2 root root 1703852 Jun  7 12:27 mips-openwrt-linux-uclibc-as
-rwxr-xr-x 2 root root  613692 Jun  7 12:27 mips-openwrt-linux-uclibc-c++
-rwxr-xr-x 1 root root 1070120 Jun  7 12:27 mips-openwrt-linux-uclibc-c++filt
-rwxr-xr-x 1 root root  613692 Jun  7 12:27 mips-openwrt-linux-uclibc-cpp
-rwxr-xr-x 1 root root   30488 Jun  7 12:27 mips-openwrt-linux-uclibc-elfedit
-rwxr-xr-x 2 root root  613692 Jun  7 12:27 mips-openwrt-linux-uclibc-g++
-rwxr-xr-x 2 root root  613692 Jun  7 12:27 mips-openwrt-linux-uclibc-gcc
-rwxr-xr-x 2 root root  613692 Jun  7 12:27 mips-openwrt-linux-uclibc-gcc-4.8.3
-rwxr-xr-x 1 root root   26204 Jun  7 12:27 mips-openwrt-linux-uclibc-gcc-ar
-rwxr-xr-x 1 root root   22108 Jun  7 12:27 mips-openwrt-linux-uclibc-gcc-nm
-rwxr-xr-x 1 root root   22108 Jun  7 12:27 mips-openwrt-linux-uclibc-gcc-ranlib
-rwxr-xr-x 1 root root  288608 Jun  7 12:27 mips-openwrt-linux-uclibc-gcov
-rwxr-xr-x 1 root root 4616868 Jun  7 12:27 mips-openwrt-linux-uclibc-gdb
-rwxr-xr-x 1 root root 1148904 Jun  7 12:27 mips-openwrt-linux-uclibc-gprof
-rwxr-xr-x 4 root root 2182316 Jun  7 12:27 mips-openwrt-linux-uclibc-ld
-rwxr-xr-x 4 root root 2182316 Jun  7 12:27 mips-openwrt-linux-uclibc-ld.bfd
-rwxr-xr-x 2 root root 1082984 Jun  7 12:27 mips-openwrt-linux-uclibc-nm
-rwxr-xr-x 2 root root 1289288 Jun  7 12:27 mips-openwrt-linux-uclibc-objcopy
-rwxr-xr-x 2 root root 1593160 Jun  7 12:27 mips-openwrt-linux-uclibc-objdump
-rwxr-xr-x 2 root root 1103084 Jun  7 12:27 mips-openwrt-linux-uclibc-ranlib
-rwxr-xr-x 1 root root  460108 Jun  7 12:27 mips-openwrt-linux-uclibc-readelf
-rwxr-xr-x 1 root root 1070312 Jun  7 12:27 mips-openwrt-linux-uclibc-size
-rwxr-xr-x 1 root root 1070280 Jun  7 12:27 mips-openwrt-linux-uclibc-strings
-rwxr-xr-x 2 root root 1289288 Jun  7 12:27 mips-openwrt-linux-uclibc-strip
root@ubuntu:OpenWrt-SDK-ar71xx-generic_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-i686# 
root@ubuntu:OpenWrt-SDK-ar71xx-generic_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-i686# find -name stdio.h
./staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/include/bits/stdio.h
./staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/include/stdio.h
./staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/mips-openwrt-linux-uclibc/include/c++/4.8.3/tr1/stdio.h
root@ubuntu:OpenWrt-SDK-ar71xx-generic_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-i686#
root@ubuntu:OpenWrt-SDK-ar71xx-generic_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-i686# find -name libpthread.so
./staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/lib/libpthread.so
root@ubuntu:OpenWrt-SDK-ar71xx-generic_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-i686#

同样的,我们重点关注交叉编译链相关的几个配置参数:

--with-cc=/home/sdks/OpenWrt-SDK-ar71xx-generic_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-i686/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/bin/mips-openwrt-linux-gcc
--with-cpp=/home/sdks/OpenWrt-SDK-ar71xx-generic_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-i686/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/bin/mips-openwrt-linux-g++
--with-cc-opt="-I/home/sdks/OpenWrt-SDK-ar71xx-generic_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-i686/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/include" 
--with-ld-opt="-L/home/sdks/OpenWrt-SDK-ar71xx-generic_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-i686/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/lib"

最后,配置命令如下:

./configure --prefix=/tmp/_install --with-cc=/home/sdks/OpenWrt-SDK-ar71xx-generic_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-i686/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/bin/mips-openwrt-linux-gcc --with-cpp=/home/sdks/OpenWrt-SDK-ar71xx-generic_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-i686/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/bin/mips-openwrt-linux-g++ --with-cc-opt="-I/home/sdks/OpenWrt-SDK-ar71xx-generic_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-i686/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/include" --with-ld-opt="-L/home/sdks/OpenWrt-SDK-ar71xx-generic_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-i686/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/lib" --without-http_rewrite_module --without-http_gzip_module --without-http_upstream_zone_module --without-http_charset_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_proxy_module --without-http_uwsgi_module --without-http_scgi_module --without-http_memcached_module --without-http_limit_conn_module --without-http_limit_req_module --without-http_empty_gif_module --without-http_upstream_hash_module --without-http_upstream_ip_hash_module --without-http_upstream_least_conn_module --without-http_upstream_keepalive_module --without-mail_pop3_module --without-mail_imap_module --without-mail_smtp_module  --without-stream_limit_conn_module --without-stream_access_module --without-stream_upstream_hash_module --without-stream_upstream_least_conn_module --without-stream_upstream_zone_module
./configure --prefix=/tmp/_install --with-cc=/home/sdks/OpenWrt-SDK-ar71xx-generic_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-i686/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/bin/mips-openwrt-linux-gcc --with-cpp=/home/sdks/OpenWrt-SDK-ar71xx-generic_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-i686/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/bin/mips-openwrt-linux-g++ --with-cc-opt="-I/home/sdks/OpenWrt-SDK-ar71xx-generic_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-i686/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/include" --without-http_rewrite_module --without-http_gzip_module --without-http_upstream_zone_module --without-http_charset_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_proxy_module --without-http_uwsgi_module --without-http_scgi_module --without-http_memcached_module --without-http_limit_conn_module --without-http_limit_req_module --without-http_empty_gif_module --without-http_upstream_hash_module --without-http_upstream_ip_hash_module --without-http_upstream_least_conn_module --without-http_upstream_keepalive_module --without-mail_pop3_module --without-mail_imap_module --without-mail_smtp_module  --without-stream_limit_conn_module --without-stream_access_module --without-stream_upstream_hash_module --without-stream_upstream_least_conn_module --without-stream_upstream_zone_module

总结

针对不同的交叉编译链,我们要做的事情都很类似:

  • 观察交叉编译链
  • 找到gcc、g++和ld,分配设置给 –with-cc, –with-cpp, –with-ld
  • 找到include目录和lib目录,分别设置给 –with-cc-opt和 –with-ld-opt
  • 注意观察cpu的位数(即int的长度)、以及大小端(big endian、little endian)的设置

增加模块

nginx的很多模块都依赖于第三方库,对于centos、ubuntu这类成熟系统来说,第三方库的安装都比较简单,直接用命令行即可。但对于交叉编译链来说,第三方库往往都是不完整的、或者版本不匹配的。这里笔者针对常用的几个模块做一些交叉编译的说明。

zip

rewrite

ssl

宿主机不同

笔者之前文章中,没有提及一件事情,即:宿主机和目标机都是32位的系统,如果宿主机是64位的系统,是否会有问题呢?这里记录笔者遇到过的一些现象。

附录

关于大小端


如果我们不修改 auto/endian 文件,configure过程并不会报错,原因是我这个文件有bug,无法正确识别大小端。

先打开该文件观察一下:

# Copyright (C) Igor Sysoev
# Copyright (C) Nginx, Inc.


echo $ngx_n "checking for system byte ordering ...$ngx_c"

cat << END >> $NGX_AUTOCONF_ERR

----------------------------------------
checking for system byte ordering

END


cat << END > $NGX_AUTOTEST.c

int main(void) {
    int i = 0x11223344;
    char *p;

    p = (char *) &i;
    if (*p == 0x44) return 0;
    return 1;
}

END

ngx_test="$CC $CC_TEST_FLAGS $CC_AUX_FLAGS \
          -o $NGX_AUTOTEST $NGX_AUTOTEST.c $NGX_LD_OPT $ngx_feature_libs"

eval "$ngx_test >> $NGX_AUTOCONF_ERR 2>&1"

if [ -x $NGX_AUTOTEST ]; then
    if $NGX_AUTOTEST >/dev/null 2>&1; then
        echo " little endian"
        have=NGX_HAVE_LITTLE_ENDIAN . auto/have
    else
        echo " big endian"
    fi

    rm -rf $NGX_AUTOTEST*

else
    rm -rf $NGX_AUTOTEST*

    echo
    echo "$0: error: cannot detect system byte ordering"
    exit 1
fi

重点关注如下几行:

if [ -x $NGX_AUTOTEST ]; then
    if $NGX_AUTOTEST >/dev/null 2>&1; then
        echo " little endian"
        have=NGX_HAVE_LITTLE_ENDIAN . auto/have
    else
        echo " big endian"
    fi

    rm -rf $NGX_AUTOTEST*

else
    rm -rf $NGX_AUTOTEST*

    echo
    echo "$0: error: cannot detect system byte ordering"
    exit 1
fi

如果存在一个文件,其具备可执行的属性,即使这个文件的格式并不能在当前系统下运行,系统也会认为该文件可执行。
结合这个脚本,如果用交叉编译链编译出一个可执行文件,系统就会认为该文件可执行,所以判断并不能说明问题。
下面是实验过程和结果:

root@ubuntu:tmp# cat main.c 
int main(void) {
    int i = 0x11223344;
    char *p;

    p = (char *) &i;
    if (*p == 0x44) return 0;
    return 1;
}
root@ubuntu:tmp# 
root@ubuntu:tmp# cat check.sh 
#!/bin/sh

NGX_AUTOTEST=/tmp/test
if [ -x $NGX_AUTOTEST ]; then
    if $NGX_AUTOTEST >/dev/null 2>&1; then
        echo " little endian"
    else
        echo " big endian"
    fi
else
    echo "$0: error: cannot detect system byte ordering"
fi
rm -rf $NGX_AUTOTEST*
root@ubuntu:tmp# 
root@ubuntu:tmp# /home/sdks/OpenWrt-SDK-ar71xx-generic_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-i686/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/bin/mips-openwrt-linux-gcc -o test main.c
root@ubuntu:tmp# 
root@ubuntu:tmp# ./test 
-bash: ./test: cannot execute binary file: Exec format error
root@ubuntu:tmp#
root@ubuntu:tmp# ./check.sh 
 big endian
root@ubuntu:tmp# 
root@ubuntu:tmp# /home/sdks/one-arm-cross/bin/arm-linux-gcc -o test main.c
root@ubuntu:tmp# 
root@ubuntu:tmp# ./test 
-bash: ./test: cannot execute binary file: Exec format error
root@ubuntu:tmp#
root@ubuntu:tmp# ./check.sh 
 big endian
root@ubuntu:tmp# 
root@ubuntu:tmp# gcc -o test main.c
root@ubuntu:tmp# 
root@ubuntu:tmp# ./check.sh 
 little endian
root@ubuntu:tmp# 

可以看到用arp、mips编译器编译的结果,脚本都判定为big endian,其实这两个编译链编译出来的test文件并不能在host上执行的。

所以在交叉编译的情况下,这个脚本目前只能手动设定大小端,则:

# Copyright (C) Igor Sysoev
# Copyright (C) Nginx, Inc.


echo $ngx_n "checking for system byte ordering ...$ngx_c"

cat << END >> $NGX_AUTOCONF_ERR

----------------------------------------
checking for system byte ordering

END


cat << END > $NGX_AUTOTEST.c

#include 

int main(void) {
    int i = 0x11223344;
    char *p;

    p = (char *) &i;
    printf("%d", *p);

    return 0;
}

END

ngx_test="$CC $CC_TEST_FLAGS $CC_AUX_FLAGS \
          -o $NGX_AUTOTEST $NGX_AUTOTEST.c $NGX_LD_OPT $ngx_feature_libs"

eval "$ngx_test >> $NGX_AUTOCONF_ERR 2>&1"

if [ -x $NGX_AUTOTEST ]; then
    ngx_value=`$NGX_AUTOTEST`
fi

rm -rf $NGX_AUTOTEST*

#ngx_value=68    # for little endian
#ngx_value=17    # for big endian
case $ngx_value in
    68)
        echo " little endian"
        have=NGX_HAVE_LITTLE_ENDIAN . auto/have
    ;;

    17)
        echo " big endian"
    ;;

    *)

        echo
        echo "$0: error: cannot detect system byte ordering"
        exit 1

esac