这段时间,我一直忙于将 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 模块需要它。pcre-8.44.tar.gz

  • zlib:小而美的压缩库,Nginx 的 Gzip 模块需要它。zlib-1.2.11.tar.gz

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

我已经把它们的安装包上传到 Rainbond 官方对象存储上,读者若有需求,可以点击下载。

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

编译过程

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

# 解压已经下载好的依赖软件包
$ tar xzf pcre-8.44.tar.gz
$ tar xzf zlib-1.2.11.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 /usr/local/nginx/sbin/nginx
/usr/local/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

Arm64架构下静态编译Nginx的更多相关文章

  1. Arm64架构下编译便携Python

    这段时间,我一直忙于将 Rainbond 源码构建模块移植到 Arm64/aarch64 架构中.对于 Python 项目而言,可以直接通过源代码编译成为可运行在各种容器平台之上的容器镜像.这个过程不 ...

  2. ARM64架构下,OpenJDK的官方Docker镜像为何没有8版本

    为什么需要ARM64架构的OpenJDK8的Docker镜像 对现有的Java应用,之前一直运行在x86处理器环境下,编译和运行都是JDK8,如今在树莓派的Docker环境运行(也可能是其他ARM环境 ...

  3. Linux下静态编译Qt

    Qt采用编译的方式安装的时候,配置中默认的编译方式是动态编译的,但是有时候你编写的程序要发布出去,带很多动态库文件是很繁琐的,此时就需要静态编译你的程序,Qt要实现静态编译必须库文件也是静态编译的,所 ...

  4. Linux/Ubuntu下 静态编译Qt程序

    一般情况下,我们用Qt编译出来的程序是要依赖于系统Qt库的,也就是这个程序移到别的没有安装Qt库的系统上是不能使用的.会提示缺少……库文件之类的错误.这就是动态编译的结果. 但是如果我们想编译一个程序 ...

  5. Linux下静态编译Qt程序

    一般情况下,我们用Qt编译出来的程序是要依赖于系统Qt库的,也就是这个程序移到别的没有安装Qt库的系统上是不能使用的.会提示缺少……库文件之类的错误.这就是动态编译的结果. 但是如果我们想编译一个程序 ...

  6. Win7下静态编译QT5.12源码

    官方参考文档:https://doc.qt.io/qt-5/build-sources.html CSDN博客:https://blog.csdn.net/GG_SiMiDa/article/deta ...

  7. Windows下静态编译Qt4

    既然是静态编译,那就要编译出来的程序不信赖于任何dll文件.首先下载qt-win-opensource-4.7.4-mingw.exe: http://get.qt.nokia.com/qt/sour ...

  8. Qt5.5.0在Windows下静态编译(修改参数以后才能支持XP)good

    测试系统环境: windows 7 编译软件环境: vs2013 + QT5.5.0 [源码地址:http://download.qt.io/official_releases/qt/5.5/5.5. ...

  9. Qt5.5.0在Linux下静态编译(加上-fontconfig编译项才能显示中文) good

    测试系统环境:Ubuntu12.04 (32bit/64bit)编译软件环境:QT5.5.0   本文章主要介绍Linux下QT静态编译环境的搭建,以及如何编译我们的程序board_driver. 1 ...

随机推荐

  1. Demo04分解质因数

    package 习题集1;import java.util.Scanner;//将一个正整数分解质因数.例如输入90,打印出90=2*3*3*5public class Demo04 { public ...

  2. javaSE高级篇7 — 设计原则和设计模式 — 设计模式慢慢更( 这是思想层次篇 )

    1.什么是设计原则? 设计原则就是面向对象的原则嘛,即:OOP原则 换句话说:就是为了处理类与类之间的关系( 包括接口.类中的方法 ) 2.OOP设计原则有哪些? 1).开闭原则:就是指对拓展开放.对 ...

  3. C语言中的字符和整数之间的转换

    首先对照ascal表,查找字符和整数之间的规律: ascall 控制字符  48  0  49  1  50  2  51  3  52  4  53  5  54  6  55  7  56  8 ...

  4. 为 Rainbond Ingress Controller 设置负载均衡

    Rainbond 作为一款云原生应用管理平台,天生带有引导南北向网络流量的分布式网关 rbd-gateway.rbd-gateway 组件,实际上是好雨科技团队开发的一种 Ingress Contro ...

  5. 网易云信 集成UI库登录dologin没有回调

    感谢github上的两位大佬指出问题的解决方法. 解决方法: 在进行ui初始化要在主进程中进行,初始化前进行主进程判断. 若还收不到回调,可尝试将uikit中的base包去掉而在build.gradl ...

  6. 常见排序——Java实现

    1 package struct; 2 3 /** 4 * 5 * @作者:dyy 6 * @公司:陕西科技大学 7 * @修改日期: 8 * @邮箱:1101632375@qq.com 9 * @描 ...

  7. Mysql的索引调优详解:如何去创建索引以及避免索引失效

    在正式介绍Mysql调优之前,先补充mysql的两种引擎 mysql逻辑分层 InnoDB:事务优先(适合高并发操作,行锁) MyISAM:性能优先(表锁) 查看使用的引擎: show variabl ...

  8. 图书管理系统总结——JAVA Swing控件简介

    断断续续学习JAVA语言,写了一个多月数据库大作业,终于在五一过后写完了.由于第一次使用JAVA和数据库,遇到了许多问题,记录下来,以备以后查看. 我使用的JAVA SE,说实话,在开发后期,觉得JA ...

  9. 【Java 基础】Java Enum

    概览 在本文中,我们将看到什么是 Java 枚举,它们解决了哪些问题以及如何在实践中使用 Java 枚举实现一些设计模式. enum关键字在 java5 中引入,表示一种特殊类型的类,其总是继承jav ...

  10. JavaEE复习三

    Http协议是基于请求/响应模式.无状态的协议:所有请求时相互独立的.无连续的:服务器无法记住与识别用户. 对于简单的页面浏览或信息获取,http协议可以完全胜任:对于需要提供客户端和服务器端交互的网 ...