Arm64架构下编译便携Python

时间:2024-10-31 21:35:44

这段时间,我一直忙于将 Rainbond 源码构建模块移植到 Arm64/aarch64 架构中。对于 Python 项目而言,可以直接通过源代码编译成为可运行在各种容器平台之上的容器镜像。这个过程不需要使用者掌握任何容器化知识。在 Rainbond 源码构建适配 Arm64 架构之后,用户可以直接利用编译完成的容器镜像交付到 Arm64 环境下,比如华为的鲲鹏系列服务器中。

Python源码编译简介

在当前场景下,我要探索如何在 Arm64 架构下,通过 builder 这一 Rainbond 源码编译模块,完成 Python 项目的编译与容器化。

Python 是一种解释型的脚本语言,所有的运行介质都是脚本。从这一特性出发,我只需要将 Python 自身的解释器在 Arm64 环境中编译运行起来,任务就已经完成了一大半。Python 官方支持在各种平台上由包管理器安装 Python 解释器,但是这不符合 builder 的需求。builder 构建完成的最终产物最终需要转移到 runner 运行模块中进行最终的镜像打包,这要求 builder 中安装的 Python 解释器是便携式 (portable) 的预编译安装包。

接下来,我要开始在具有 M1 芯片的 MacBookPro 上编译Python。

这台 MacBookPro 上预装了 Docker Desktop 为我提供容器环境。

编译过程

为了保证最终环境的一致性,我选择使用 builder 项目所用的基础镜像进行编译。这一基础镜像已经推送了 Arm64 版本到 DockerHub 中

docker run -ti --name=compiler rainbond/cedar14:20211224 bash

进入容器环境后,生成专门用于构建的目录,下载并解压 Python 源码包。当前选择的版本是 Python-3.7.10

mkdir -p /app/src && cd /app
wget https://www.python.org/ftp/python/3.7.10/Python-3.7.10.tgz
tar xzf Python-3.7.10.tgz -C src
cd src/Python-3.7.10/

执行编译

./configure --prefix=/app/python
make && make install
  • --prefix=/app/python 指定了编译后生成文件的路径

编译完成后,检查编译产物

ls -l /app/python/

得到以下返回

total 16
drwxr-xr-x 2 root root 4096 Dec 31 15:46 bin
drwxr-xr-x 3 root root 4096 Dec 31 15:46 include
drwxr-xr-x 4 root root 4096 Dec 31 15:46 lib
drwxr-xr-x 3 root root 4096 Dec 31 15:46 share

打包

在进行打包之前,还有两处可以做的优化。

首先,可以删除一些专门用于测试的编译产物。

下面的代码,来自于官方 Python 容器镜像的 Dockerfile https://github.com/docker-library/python/blob/master/Dockerfile-alpine.template

执行后,编译产物的总大小,缩小了100MB左右

find /app/python -depth \
\( \
\( -type d -a \( -name test -o -name tests -o -name idle_test \) \) \
-o \
\( -type f -a \( -name '*.pyc' -o -name '*.pyo' \) \) \
\) -exec rm -rf '{}' +;

其次,编译而来的可执行文件 /app/python/bin/python3.7 并不是我们常用的 python 命令,所以可以为它改个名字,便于以后使用

mv /app/python/bin/python3.7 /app/python/bin/python

最终,可以在 python 目录下进行打包操作

cd  /app/python
tar czf python-3.7.10-arm64.tar.gz ./*

最终的压缩包尺寸为 28M,非常便携。

验证

为了验证 python-3.7.10-arm64.tar.gz 可以在 buider 环境中插之即用,我重新启动了一个容器来验证其功能。

下载并解压预编译安装包

docker run -ti --name=test rainbond/cedar14:20211224 bash
mkdir /python
curl https://buildpack.oss-cn-shanghai.aliyuncs.com/python/cedar-14/runtimes/python-3.7.10-arm64.tar.gz | tar xz -C /python

验证功能

/python/bin/python --version
Python 3.7.10