这段时间,我一直忙于将 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. 学习java的第十二天

    一.今日收获(前两天家里有事,博客都忘了发了,唉) 1.通过看哔哩哔哩看黑马程序员的教学视频,学习了java中的数据类型自动转换.强制转换及注意事项三节 2.简单看了看完全学习手册 二.今日问题 1. ...

  2. 巩固javaweb第十五天

    巩固内容: 单选按钮: 在注册功能中,用户选择学历使用的是单选按钮,并且是多个单选按钮,每个选项对 应一个单选按钮,用户只能选择其中一个,这多个单选按钮的格式相同.如果用户要输入 的信息只有少数几种可 ...

  3. A Child's History of England.27

    Then, the Red King went over to Normandy, where the people suffered greatly under the loose rule of ...

  4. Netty之ByteBuf

    本文内容主要参考<<Netty In Action>>,偏笔记向. 网络编程中,字节缓冲区是一个比较基本的组件.Java NIO提供了ByteBuffer,但是使用过的都知道B ...

  5. Hbase(一)【入门安装及高可用】

    目录 一.Zookeeper正常部署 二.Hadoop正常部署 三.Hbase部署 1.下载 2.解压 3.相关配置 4.分发文件 5.启动.关闭 6.验证 四.HMaster的高可用 一.Zooke ...

  6. 基本类型、引用类型NPE异常

    1.null是Java中的关键字,像public.static.final.它是大小写敏感的,你不能将null写成Null或NULL,编译器将不能识别它们然后报错. 2.就像每种原始类型都有默认值一样 ...

  7. java web 限制同一个用户在不同处登入

    用到的技术:map集合,sessionListener监听器,Fiter过滤器. 实现思路: 一.利用一个全局的map集合来保存每个用户sessionID的值的一个集合.一个用户对应一个session ...

  8. 【Matlab】向图像域添加噪声/高斯/均匀/伽马/指数/椒盐

    [向图像域添加噪声] matlab自带一个函数:imnoise,可以对图像添加噪声. Matlab的说明 https://www.mathworks.com/help/images/ref/imnoi ...

  9. Redis操作命令合集

    目录 一.客户端命令 二.sql命令 一.客户端命令 #读取配置文件启动 redis-server redis.conf #关闭 Redis,Redis服务器将断开与客户端链接,产生持久化文件,平滑关 ...

  10. 解决android studio no debuggable process

    这个问题可能是由多种因素造成的. 一.可能是buildtypes配置或选择错误,在对应module的build.gradle中确认如下配置 debug { debuggable true//一定要配置 ...