Arm64架構下編譯便攜Python

DrunkCat90發表於2022-01-01

這段時間,我一直忙於將 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

相關文章