> 技术文档 > Nginx交叉编译:Linaro工具链+zlib+openssl+pcre

Nginx交叉编译:Linaro工具链+zlib+openssl+pcre


Nginx交叉编译:Linaro工具链+zlib+openssl+pcre

一、方案一:Poky工具链交叉编译

1.介绍

Poky工具链是Yocto项目的一部分,而Yocto项目专注于嵌入式系统的构建和定制,因此它提供了更完整的工具链,包括常见的依赖库(如zlib、openssl、pcre等)。Yocto的目标是让开发者能快速搭建和定制嵌入式系统,这些库是嵌入式开发中常见的依赖,因此Yocto会默认提供这些工具链和库支持,便于用户直接进行交叉编译而无需额外安装。
编译流程

2.工具链默认路径

/opt/fsl-imx-x11/4.1.15-2.1.0/sysroots/x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi-gcc

3.编译流程

(1)初始化工具链

source /opt/fsl-imx-x11/4.1.15-2.1.0/environment-setup-cortexa7hf-neon-poky-linux-gnueabi

(2)配置Nginx

./configure --prefix=/home/dt/tools/nginx-1.20.0/install \\--with-http_ssl_module \\ --with-http_mp4_module \\ --with-http_v2_module \\--without-http_upstream_zone_module \\--add-module=/home/dt/tools/nginx-rtmp-module

(3)修改Nginx源码

sudo vim objs/ngx_auto_config.h

增加如下内容:

#ifndef NGX_HAVE_SYSVSHM #define NGX_HAVE_SYSVSHM 1 #endif

(4)make && make install

二、方案二:Linaro工具链+第三方库

1.介绍

Linaro是一个专门为ARM架构优化的开源软件工程组织,Linaro工具链提供了一个为ARM架构(包括ARMv7、ARMv8、AArch64等)优化的交叉编译工具链。它包含针对ARM架构优化的GCC编译器、调试器以及其他工具。Linaro工具链在ARM开发领域中使用较为广泛,要额外配置zlib、openssl和pcre环境。需要注意的是:zlib、openssl和pcre环境的配置也是分情况的:Linux本地编译和arm-linux交叉编译。在Nginx交叉编译的过程中,依赖的是交叉编译的zlib、openssl和pcre环境!本文选择zlib-1.3.1,openssl-1.1.1t,pcre-8.45,读者可根据自己的版本自行调整参数路径等设置。

2.工具链默认路径

/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc

3.编译流程

(1)zlib交叉编译

./configure --host=arm-linux-gnueabihf --prefix=/home/zhuchen/linux/tool/pcre-8.45 --enable-static --disable-shared CC=arm-linux-gnueabihf-gcc
make && make install

(2)openssl交叉编译

sudo mkdir .openssl
./Configure linux-armv4 no-asm shared no-async --prefix=/home/zhuchen/linux/tool/openssl-1.1.1t-2/.openssl --cross-compile-prefix=/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-

在这里插入图片描述

注意:在配置Nginx的时候,openssl依赖项的交叉编译最为特殊,需要将openssl安装在.openssl目录中。同时,为了移除后续修改Makefile文件的操作,使用linux-armv4直接指定目标平台。如果不指定目标平台,按照网上的教程,然后将生成的Makefile中-m64删除,openssl编译似乎可以通过,但是在Nginx交叉编译是会发生文件格式识别错误,也就是部分openssl依赖文件的目标平台仍旧是x86_64,Nginx交叉编译无法执行。
在这里插入图片描述

在Nginx 配置构建的objs/Makefile中会自动进行openssl的make && make install操作,包括.openssl目录的由来也是在objs/Makefile中规定的,如果安装目录不选择.openssl,需要修改很多地方的目录,得不偿失。因此,对于Nginx的依赖openssl环境建议只安装在.openssl目录中。

(3)pcre交叉编译

安装路径选择pcre的根目录,指定host参数,指定CC交叉编译器

./configure --host=arm-linux-gnueabihf --prefix=/home/zhuchen/linux/tool/pcre-8.45 --enable-static --disable-shared CC=arm-linux-gnueabihf-gcc

在这里插入图片描述

make && make install

(4)Nginx交叉编译

1. 配置
./configure --prefix=/home/zhuchen/linux/tool/nginx-1.20.0/install \\--with-zlib=/home/zhuchen/linux/tool/zlib-1.3.1 \\--with-pcre \\--with-pcre=/home/zhuchen/linux/tool/pcre-8.45 \\--with-pcre-jit \\--with-openssl=/home/zhuchen/linux/tool/openssl-1.1.1t-2 \\--with-http_ssl_module \\ --with-http_mp4_module \\ --with-http_v2_module \\--without-http_upstream_zone_module \\--add-module=/home/zhuchen/linux/tool/nginx-rtmp-module \\--with-cpp=/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-g++ \\--with-cc=/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc \\--with-ld-opt=-pthread

配置参数说明:–prefix指定Nginx的安装目录,–with-http_ssl_module、–with-http_mp4_module、–with-http_v2_module表示需要支持一些协议或者模块,–without-http_upstream_zone_module表示不需要支持,–add-module表示需要引入第三方的模块,这里是需要引入nginx-rtmp,再后面是指定编译器,最后是pthread参数,只有这样Nginx源码才能索引到部分线程函数比如 pthread_atfork的定义,否则会报部分线程函数实现未定义错误。
在这里插入图片描述

2. 修改源码文件

(1)objs/ngx_auto_config.h添加内容

#ifndef NGX_HAVE_SYSVSHM#define NGX_HAVE_SYSVSHM 1#endif

(2)auto/cc/conf修改内容

case $NGX_CC_NAME IN 下一行将gcc修改为对应的编译链arm-linux-gnueabi-gcc

(3)auto/types/sizeof修改内容
将ngx_size设置为4(说明:32位目标平台是4,64位目标平台是8)

(4)configure修改内容
将NGX开头的三行语句注释掉

(5)src/os/unix/ngx_time.h添加内容

#include 

(6)src/os/unix/ngx_errno.h添加宏定义

#define NGX_SYS_NERR 1

(7)src/event/ngx_event_accept.c添加内容

#define _GNU_SOURCE

(8)src/event/ngx_event_udp.c修改内容

将所有涉及NGX_HAVE_INET6判断的都注释掉共计2处注意事项:在注释的时候,要区分if语句的括号 和 #if #endif ,否则会在编译时产生语法错误。

(9)src/os/unix/ngx_udp_sendmsg_chain.c修改内容

将所有涉及NGX_HAVE_INET6判断的都注释掉共计2处注意事项:在注释的时候,要区分if语句的括号 和 #if #endif ,否则会在编译时产生语法错误。
3. 修改Makefile
sudo vim objs/Makefile
  1. 修改CC、CFLAGS、CPP、LINK,将其变成工具链的对应工具;
    在这里插入图片描述

  2. 去除pcre与openssl编译部分语句,如果不去除会将之前手动编译的部分,重新编译。将文件修改成下图所示即可。
    在这里插入图片描述

4. 编译与安装
make && make install 

在这里插入图片描述
在这里插入图片描述

总结

以上便是Nginx的交叉编译的配置过程,可以根据自己使用的工具链自行选择方案。
本文基于ubuntu16.04,nginx1.20.0,读者若为了避免不必要的报错,可以选择相同的版本和系统。