Arm64架构下静态编译Nginx

这段时间,我一直忙于将 Rainbond 源码构建模块移植到 Arm64/aarch64 架构中。这一源码构建模块可以将指定代码仓库中包含的源码,拉取构建成为容器镜像,在各种容器平台中运行。目前支持的源码类型包括:Java(Maven、Gradle、jar、war)、Nodejs(前端Vue、后端项目)、Golang、Python、PHP、.NetCore、静态Html。

Rainbond源码构建简介

Rainbond 源码构建模块由 builderrunner 两个子模块组成。

builder 负责将源码进行编译,并打包成为 Heroku 风格的 slug.tgz 包。slug.tgz 包中会包含编译完成的产物(比如jar包、二进制等),以及编译产物运行所需要的基础环境(比如 jdk、tomcat、nginx、apache)。

runner 负责提供 slug.tgz 包运行的基础环境。这是一个通用的基础环境,不必再区分语言,无论何种语言生成的 slug.tgz 包都适用。

为何要编译Nginx

Nginx 是静态Html 、 Nodejs前端项目运行所使用的默认 Web-Server。builder 会在这两种语言编译完成后,前往 Rainbond 专用的云端对象存储中拉取 Nginx 安装包。这种预编译的安装包,Nginx 官方只会提供 x86_64 版本。

在源码构建模块移植到 Arm64/aarch64 架构的过程中,我不可避免的要自己重新编译 Arm 架构可用的 Nginx 预编译安装包。

为何要进行静态编译

最开始,我是希望走一些捷径,Nginx 的核心是要有一个可执行二进制文件,那么我是否可以从别处得到这种可执行文件。

Nginx 官方虽不提供我直接需要的 Arm64 预编译安装包,但是却为各大操作系统发行版提供 Arm64 环境下的安装源。对于 builder 所使用的 Ubuntu:14.04 操作系统而言,可以通过 apt install nginx 的方式安装。然后我就可以得到我想要的可执行文件了。但是下面两个问题的出现,阻断了这条思路。

  • Ubuntu:14.04 源提供的 Nginx 版本过低。
  • 使用更高版本的 Ubuntu:18.04 安装的 Nginx 版本可以满足我的要求,但是提取到的可执行文件在 Ubuntu:14.04 无法运行,缺少必要的库文件。

此时我意识到,由源安装而来的 Nginx 是动态编译版本,apt 等包管理工具会自动处理所需的依赖,然而我并不想要一点点尝试我所缺少的库都由哪些包安装,这很耗神。

我希望这个可执行文件可以像 golang 语言编译出的二进制文件一样,将所有需要的库都编译到二进制中去,从而免除对操作系统的要求。理论上,这种方式得到的二进制在运行效率上也会更高。

简单的查询后,我了解到,我所需要的,是进行静态编译。

准备工作

阅读 Nginx 官方提供的 源码编译文档 了解到,我至少需要以下依赖需要处理:

  • PCRE(Perl Compatible Regular Expressions):基于 Perl 的正则表达式函数库,Nginx 的 Core 、Rewrite 模块需要它。

  • zlib:小而美的压缩库,Nginx 的 Gzip 模块需要它。

  • OpenSSL:用于安全通信的工具包,非常著名,Nginx 所有和安全通信相关的模块都需要它,比如Https。

我已经把它们的安装包上传到 Rainbond 官方对象存储上,下载速度会快很多。

进行编译的硬件环境,是位于拥有 M1 芯片的 MacBookPro 笔记本 ,利用 Docker Desktop 启动的 ubuntu:1404 容器。容器中预装了 gccmakeg++ 软件包。

编译过程

解压所有的依赖软件包,以及 Nginx 的源码包,所有源码包都位于同级目录下:

# 下载并解压依赖软件包
$ wget https://buildpack.oss-cn-shanghai.aliyuncs.com/static/r6d/nginx/nginx-compile-lib/pcre-8.44.tar.gz
$ tar xzf pcre-8.44.tar.gz
$ wget https://buildpack.oss-cn-shanghai.aliyuncs.com/static/r6d/nginx/nginx-compile-lib/zlib-1.2.11.tar.gz
$ tar xzf zlib-1.2.11.tar.gz
$ wget https://buildpack.oss-cn-shanghai.aliyuncs.com/static/r6d/nginx/nginx-compile-lib/openssl-1.1.1l.tar.gz
$ tar xzf openssl-1.1.1l.tar.gz
# 下载并解压 nginx stable 源码包
$ wget https://nginx.org/download/nginx-1.18.0.tar.gz
$ tar zxf nginx-1.18.0.tar.gz
$ cd nginx-1.18.0

执行 configure ,并指定静态编译参数:

$ ./configure \
--with-cc-opt='-static -static-libgcc' \
--with-ld-opt=-static \
--prefix=/app/nginx \
--with-http_ssl_module \
--with-openssl=../openssl-1.1.1l \
--with-pcre=../pcre-8.44 \
--with-zlib=../zlib-1.2.11

开始执行编译:

$ make && make install

打包编译出来的 Nginx 目录即可:

$ tar czf nginx-1.18.0-arm64.tar.gz /app/nginx

验证

查看编译后产生的可执行文件,会发现该二进制文件的编译类型为静态类型,这样的文件,可以在 arm64 架构下的任意 Linux 环境下运行。

$ file /app/nginx/sbin/nginx
/app/nginx/sbin/nginx: ELF 64-bit LSB  executable, ARM aarch64, version 1 (SYSV), statically linked, for GNU/Linux 3.7.0, BuildID[sha1]=66e5740a16bdfe6bc2f04c5371fd706ae7ca5395, not stripped

若干问题

CentOS 编译环境的问题

很久之后,我又有一次机会重新静态编译 Nginx,这次的不同之处在于我的构建环境是 CentOS 7 操作系统。执行 ./configure 命令时,遇到了一个问题:

./configure: error: the invalid value in --with-ld-opt="-static"

竟然不识别负责连接的构建参数 --with-ld-opt="-static" ,经过一番搜索,原来在 CentOS 环境中,需要安装以下这个包,来解决这个问题:

yum install glibc-static -y

看到包名就释然了,这个包的功能必然围绕着静态编译 C 语言库。重新执行 ./configure ,问题得以解决。
又是丧气满满的一天。

Pcre 编译问题

承接上个问题,在执行 make && make install 命令的时候,又报了一个和 pcre 相关的问题:

configure: error: Invalid C++ compiler or C++ compiler flags
make[1]: *** [../pcre-8.44/Makefile] Error 1

看起来, pcre 去寻找 C++ 编译器了,然而 CentOS 7 操作系统中并没有预装,那么解决之道应该是执行以下命令:

yum install -y gcc-c++

重新执行 make && make install ,编译过程又欢快的跑动了起来。
由此看来,作为编译环境而言,CentOS 7 相比 Ubuntu 14.04 少了很多必要工具,需要用到时自行安装,累了一点,确更明白了一点。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


学习编程是顺着互联网的发展潮流,是一件好事。新手如何学习编程?其实不难,不过在学习编程之前你得先了解你的目的是什么?这个很重要,因为目的决定你的发展方向、决定你的发展速度。
IT行业是什么工作做什么?IT行业的工作有:产品策划类、页面设计类、前端与移动、开发与测试、营销推广类、数据运营类、运营维护类、游戏相关类等,根据不同的分类下面有细分了不同的岗位。
女生学Java好就业吗?女生适合学Java编程吗?目前有不少女生学习Java开发,但要结合自身的情况,先了解自己适不适合去学习Java,不要盲目的选择不适合自己的Java培训班进行学习。只要肯下功夫钻研,多看、多想、多练
Can’t connect to local MySQL server through socket \'/var/lib/mysql/mysql.sock问题 1.进入mysql路径
oracle基本命令 一、登录操作 1.管理员登录 # 管理员登录 sqlplus / as sysdba 2.普通用户登录
一、背景 因为项目中需要通北京网络,所以需要连vpn,但是服务器有时候会断掉,所以写个shell脚本每五分钟去判断是否连接,于是就有下面的shell脚本。
BETWEEN 操作符选取介于两个值之间的数据范围内的值。这些值可以是数值、文本或者日期。
假如你已经使用过苹果开发者中心上架app,你肯定知道在苹果开发者中心的web界面,无法直接提交ipa文件,而是需要使用第三方工具,将ipa文件上传到构建版本,开...
下面的 SQL 语句指定了两个别名,一个是 name 列的别名,一个是 country 列的别名。**提示:**如果列名称包含空格,要求使用双引号或方括号:
在使用H5混合开发的app打包后,需要将ipa文件上传到appstore进行发布,就需要去苹果开发者中心进行发布。​
+----+--------------+---------------------------+-------+---------+
数组的声明并不是声明一个个单独的变量,比如 number0、number1、...、number99,而是声明一个数组变量,比如 numbers,然后使用 nu...
第一步:到appuploader官网下载辅助工具和iCloud驱动,使用前面创建的AppID登录。
如需删除表中的列,请使用下面的语法(请注意,某些数据库系统不允许这种在数据库表中删除列的方式):
前不久在制作win11pe,制作了一版,1.26GB,太大了,不满意,想再裁剪下,发现这次dism mount正常,commit或discard巨慢,以前都很快...
赛门铁克各个版本概览:https://knowledge.broadcom.com/external/article?legacyId=tech163829
实测Python 3.6.6用pip 21.3.1,再高就报错了,Python 3.10.7用pip 22.3.1是可以的
Broadcom Corporation (博通公司,股票代号AVGO)是全球领先的有线和无线通信半导体公司。其产品实现向家庭、 办公室和移动环境以及在这些环境...
发现个问题,server2016上安装了c4d这些版本,低版本的正常显示窗格,但红色圈出的高版本c4d打开后不显示窗格,
TAT:https://cloud.tencent.com/document/product/1340