
統信UOS專業版1070arm64裝Python3.8.0這件事我在本地折騰了一整天中間踩了不少坑也把整套流程理順了。這篇文章就是把當時實際操作的過程完整復盤一遍包括為什么非要源碼編譯、怎么處理依賴、configure參數怎么選、編完以后怎么避免把系統搞壞以及幾個反復出現的報錯怎么排查。手上正好有arm64設備飛騰、麒麟或者鯤鵬主板的機器又需要在上面用Python3.8做開發的可以直接照著做。先說結論統信UOS V20專業版1070基于Debian 10體系系統自帶的Python是3.7系列并不自帶Python3.8。如果項目依賴鎖定了3.8。x最穩妥的辦法不是折騰軟件源而是下載官方源碼在本地編譯安裝。整個流程對硬件性能有一些要求建議內存4GB以上、磁盤空余空間至少2GB。下面進入正題。1. 為什么在UOS arm64上裝Python3.8這么特殊1.1 統信UOS專業版1070的系統基礎統信UOS V20專業版1070是面向政企辦公和行業應用的操作系統底層基于Debian 10Buster但并不是原生Debian而是做了大量國產化適配的發行版本。換句話說它繼承了Debian的包管理機制可以用apt安裝軟件但軟件源、內核、圖形桌面層都做了深度調整。正因為是基于Debian 10所以軟件倉庫里的Python默認版本是3.7系列。python3指向/usr/bin/python3而/usr/bin/python3的實際版本是3.7.3。這是整個系統的基礎組件很多桌面工具、系統管理腳本、軟件中心都依賴這個Python解釋器。這就引出了第一個關鍵原則不能覆蓋系統自帶的Python3。如果你貿然把/usr/bin/python3指向了3.8版本后果可能是桌面組件起不來、控制中心異常、軟件包管理器崩潰——這類問題在國產化操作系統里非常常見。正確做法是讓Python3.8以獨立身份安裝與系統Python3.7共存。1.2 arm64和amd64的區別在哪里標題里特意提到arm64說明這不是普通的x86環境。arm64也叫aarch64是ARM公司推出的64位指令集架構與Intel/AMD主導的amd64x86-64在指令集上是完全不同的兩套體系。這意味著x86平臺上編譯出來的二進制包不能直接在arm64上運行pip安裝純Python包沒有問題因為純Python包是跨平臺的源碼但包含C擴展的包必須要有aarch64版本的wheel包或者本機編譯最典型的例子是numpy、pandas、Pillow、lxml這些常用科學計算庫雖然PyPI上已經提供了arm64的wheel但有些偏門庫沒有預編譯包只能靠本機下載源碼后編譯在UOS這樣的國產化系統上還多一層復雜性部分ARM平臺是飛騰、鯤鵬、麒麟等國產芯片它們的處理器微架構和編譯優化參數都不一樣。雖然都是aarch64指令集但用同一份源碼編譯出來的性能表現會有差異個別特殊指令的啟用情況也不同。1.3 為什么不能直接雙擊安裝包或者用商店安裝很多剛接觸統信UOS的人會習慣性地以為可以像Windows一樣下載一個安裝包然后下一步到底。但Linux系統裝Python不是這么玩的。統信應用商店里并沒有提供Python3.8安裝包就算有也不一定針對arm64進行了適配。從軟件安裝方式上看Linux下安裝Python大致有三條路apt從官方源安裝簡單但UOS官方源大概率沒有python3.8這個包下載預編譯二進制包對arm64支持不友好官方并不提供Linux arm64的獨立二進制包源碼編譯安裝最可靠也是本次采用的方式源碼編譯是解決“官方源里沒有、又沒有現成二進制包”這種情況的標準方案。這也是為什么網上幾乎所有關于在國產系統安裝指定Python版本的教程最后都指向了源碼編譯這條路。2. 安裝前的準備工作與方案取舍2.1 版本選型為什么是3.8.0而不是別的版本項目標題指定了Python3.8.0這是2019年10月發布的版本。實際生產里如果對版本號沒有嚴格鎖定我更建議安裝同系列的補丁版本比如3.8.20或3.8.18因為補丁版本修復了很多安全和兼容性問題。不過既然項目鎖定了3.8.0就按3.8.0來部署流程是通用的。你只要把下載鏈接里的版本號替換掉其他步驟完全一致。有一點要注意Python 3.8.x各小版本之間的源碼在依賴上有細微差別特別是libffi和OpenSSL版本檢測那一塊所以如果你換版本編譯遇到報錯優先看看依賴庫版本是否過舊。2.2 方案對比apt安裝vs源碼編譯vs容器方案在UOS上裝Python3.8還有一個思路用Docker。如果目標機器上已經跑著Docker那么拉一個python:3.8的鏡像是最省事的因為鏡像內部已經有編譯好的Python環境。但桌面系統的使用場景和服務器不一樣很多應用需要直接調用宿主機上的Python解釋器Docker方案對桌面場景不太友好而且有些政企內網環境并沒有配置Docker鏡像源。另外用虛擬化方案比如qemu模擬arm64也是一個思路。如果你手上只有x86電腦但是要驗證arm64上能不能跑通Python3.8可以先用qemu-system-aarch64啟動一個UOS arm64虛擬機做測試。這個思路在開發階段很好用性能損耗比較大但優點是可以避免頻繁重裝系統。qemu的安裝和使用方法這里不展開只說一點UOS arm64的鏡像文件可以直接作為虛擬機的磁盤鏡像加載加上-machine virt -cpu cortex-a57這樣的參數就能跑起來。測試完畢確認沒問題再到實機上操作這是最穩妥的工作流。2.3 下載Python3.8.0源碼與校驗第一步是去Python官網下載源碼包。建議使用wget或者curl在命令行直接下載避免圖形界面下載文件后路徑找不到的問題。Python官方提供了GPG簽名文件可以下載后校驗一下完整性尤其是在政企內網環境這一步不能省。cd ~/Downloads wget https://www.python.org/ftp/python/3.8.0/Python-3.8.0.tgz wget https://www.python.org/ftp/python/3.8.0/Python-3.8.0.tgz.asc如果官網下載速度太慢可以使用國內鏡像源下載比如華為云鏡像、淘寶npm鏡像等。這里我用的是華為云鏡像站wget https://mirrors.huaweicloud.com/python/3.8.0/Python-3.8.0.tgz下載完成后解壓tar xzf Python-3.8.0.tgz cd Python-3.8.0注意不要用dpkg或alien去轉換Python的RPM包來安裝統信UOS雖然能兼容部分rpm包轉deb但Python這種多文件分派到不同目錄的軟件轉換安裝后鏈接經常會出現問題。2.4 安裝編譯工具鏈和依賴庫這一步是整個流程里最容易出問題的環節。Python源碼編譯需要gcc、g、make等基礎工具同時還依賴多個系統開發庫。缺少任何一個編譯過程都可能報錯或者編譯出來的Python功能不全。在UOS專業版1070上你需要安裝的依賴大致如下sudo apt update sudo apt install -y \ gcc \ g \ make \ zlib1g-dev \ libssl-dev \ libffi-dev \ libsqlite3-dev \ libreadline-dev \ libbz2-dev \ libncurses5-dev \ libncursesw5-dev \ tk-dev \ liblzma-dev \ uuid-dev \ libdb-dev \ libgdbm-dev逐個解釋一下為什么要裝這些gcc/g/makeC語言/ C編譯器Python解釋器源碼主要用C寫成編譯過程必須的。zlib1g-devPython的zipimport模塊以及ensurepip安裝pip都依賴zlib缺了它pip直接裝不了。libssl-dev提供OpenSSL開發庫編譯Python時需要用它的頭文件啟用_ssl模塊。如果缺這個模塊后面pip安裝任何需要HTTPS的包都會失敗。libffi-dev外部函數接口庫CFFIctypes模塊依賴它。在arm64平臺尤其重要因為很多科學計算庫會調用CTypes特別是新版Python的_ctypes模塊。libsqlite3-devsqlite3模塊。可能很多人覺得用不到但Django項目的開發模式對sqlite有強依賴而且新版pip也依賴sqlite。libreadline-dev交互模式下命令行編輯功能。沒有它Python解釋器里按方向鍵會出現奇怪的轉義字符。liblzma-devPython標準庫里的lzma模塊依賴主要是壓縮文件處理。提示在統信UOS上apt源的地址可能指向了官方源或者內網鏡像源。如果執行apt update時提示找不到某些包先檢查/etc/apt/sources.list和/etc/apt/sources.list.d/下的源配置確保源URL是正確的。3. 源碼編譯完整實操過程3.1 configure參數的選擇與含義進入到解壓后的源碼目錄第一步運行configure腳本。這是整個編譯過程的核心參數決定了編譯出來的Python安裝到哪里、優化程度如何、哪些功能會被啟用。我推薦使用的configure命令是./configure \ --prefix/usr/local/python3.8 \ --enable-optimizations \ --with-ensurepipinstall \ --with-ssl-default-suitesopenssl逐個參數說明參數作用--prefix/usr/local/python3.8指定安裝路徑。將Python3.8獨立安裝在/usr/local/python3.8目錄下與系統默認Python完全隔離。后面不用了直接刪掉這個目錄就能干凈卸載--enable-optimizations啟用編譯器優化會做Profile-Guided OptimizationPGO編譯出的Python解釋器運行速度更快。代價是編譯時間翻倍arm64設備上可能要等很久--with-ensurepipinstall安裝時自動安裝pip和setuptools。如果不加這個參數裝完Python后還得手動去裝pip容易出問題--with-ssl-default-suitesopenssl指定使用系統OpenSSL配置的TLS套件與系統集成更緊密還有兩個參數可以根據實際情況調整--enable-shared編譯成共享庫libpython3.8.so。如果你后續要用mod_wsgi或者某些嵌入式場景需要加這個參數。普通使用不建議加因為加了之后如果不配置LD_LIBRARY_PATHPython啟動時會找不到libpython3.8.so反而多出一條麻煩事。--with-system-ffi使用系統的libffi。有些系統的libffi版本過舊可能導致ctypes模塊編譯失敗。UOS 1070使用的libffi版本不算舊如果編譯報錯再考慮關閉這個參數。configure腳本運行結束后會生成一個Makefile。同時輸出一個摘要信息列出檢測到的模塊可以在這里檢查一下_ssl、_ctypes、sqlite3等關鍵模塊是否為“enabled”。3.2 編譯與安裝make與make installconfigure通過后開始編譯make -j4-j4是指用4個并行任務編譯。這個參數要根據CPU核心數調整。arm64設備常見的處理器核心數是4核或8核。并行編譯能大幅縮短時間但內存緊張的設備比如只有2GB內存的機器建議不要設置過大的并行數否則會因內存不足卡死。如果不需要PGO優化可以跳過了--enable-optimizations編譯速度會快很多。但照我實測同一個Python3.8.0在飛騰FT-20004核平臺開啟優化后編譯大約要50分鐘不開的話大概15分鐘就能完成。編譯完成后執行安裝sudo make install這一步會把Python安裝到/usr/local/python3.8目錄下并且自動創建pip和setuptools。安裝完成后驗證一下/usr/local/python3.8/bin/python3.8 -V正常會輸出Python 3.8.0。3.3 配置環境變量與軟鏈接R安裝完成只是第一步接下來要把Python3.8接入到用戶環境中。我不建議把/usr/bin/python3替換成3.8版本因為系統很多工具依賴自帶Python尤其是桌面環境下替換了可能導致日志收集組件、軟件管理模塊崩潰。建議用軟鏈接加PATH的方式sudo ln -s /usr/local/python3.8/bin/python3.8 /usr/local/bin/python3.8 sudo ln -s /usr/local/python3.8/bin/pip3.8 /usr/local/bin/pip3.8把/usr/local/bin加入PATH一般默認已經在PATH里了這樣用戶執行python3.8就能直接啟動新裝的Python。執行一下驗證which python3.8 python3.8 -V這里要說一下為什么是軟鏈接到/usr/local/bin而不是直接設置PATH環境變量。/usr/local/bin幾乎在所有的現代Linux發行版里默認都在PATH中而/usr/local/python3.8/bin則不在。通過軟鏈接方式可以避免修改/etc/profile從而避免對環境變量的全局修改。還可以在~/.bashrc里追加別名設置echo alias python/usr/local/python3.8/bin/python3.8 ~/.bashrc echo alias pip/usr/local/python3.8/bin/pip3.8 ~/.bashrc source ~/.bashrc提示這個別名只對當前用戶生效。如果每次執行python都要加上3.8這個后綴會讓你覺得不習慣可以用別名把python指向3.8。但要注意系統內已有的.bashrc別名可能會沖突先看下原有配置。3.4 創建虛擬環境與pip配置Python3.8安裝完成后建議為項目創建一個虛擬環境避免污染全局環境。arm64平臺上同樣可以使用venv模塊cd ~/project /usr/local/python3.8/bin/python3.8 -m venv myenv source myenv/bin/activate python -V虛擬環境創建之后可以順手把pip升級到最新版本并配置國內鏡像源pip install --upgrade pip pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/pip換源這一步在很多時候能救命。政企內網訪問PyPI可能非常慢甚至超時配置國內鏡像后下載速度提升非常明顯。如果你使用清華源或阿里源注意鏡像站的證書是否正常如果證書有問題還需要執行pip config set global.trusted-host mirrors.aliyun.com來信任該源。4. 常見問題與排查技巧實錄4.1 編譯后pip無法使用HTTPS提款No module named _ssl這是UOS上編譯Python最常見的報錯之一。現象是pip安裝包時報錯ModuleNotFoundError: No module named _ssl或者Could not fetch URL https://pypi.org/...。原因通常是configure階段沒有檢測到OpenSSL開發庫或者編譯時OpenSSL版本過低。Python3.8.0需要OpenSSL 1.0.2或1.1.x版本。檢查方法openssl version如果版本正常說明問題出在configure階段沒找到頭文件。檢查是否安裝了libssl-devdpkg -l | grep libssl-dev如果沒有安裝執行安裝后再重新編譯。我已經把libssl-dev列入了依賴清單如果你在安裝依賴時漏掉了這一步編譯出的Python就會出現這種功能缺失問題。解決之后需要重新編譯make clean ./configure --prefix/usr/local/python3.8 --enable-optimizations --with-ensurepipinstall make -j4 sudo make install4.2 缺少_ctypes模塊導致第三方庫安裝失敗另一個高頻報錯是ModuleNotFoundError: No module named _ctypes。這個模塊在Python3.8中扮演的角色是提供C語言接口調用能力。很多第三方庫在安裝時會檢測_ctypes模塊一旦缺失直接拒絕安裝。原因是缺少libffi開發庫。剛才依賴清單里有libffi-dev如果你跳過或者apt源里沒有這個包就會遇到這個報錯。解決辦法sudo apt install libffi-dev然后重新編譯一遍。注意make install并不會重新生成_modules你需要先make clean再重新編譯。4.3 編譯時內存不足導致卡死或直接被killarm64設備很多是嵌入式主板內存可能只有2GB或者4GB。執行make -j4時如果內存不足編譯進程會被系統OOM Killer殺掉或者整個系統都卡住無法操作。這種情況建議把并行數降低make -j1雖然編譯耗時增加但勝在穩定。另外如果開啟了--enable-optimizationsPGO階段會更吃內存。如果你發現這個階段反復崩潰建議取消優化參數改成./configure --prefix/usr/local/python3.8 --with-ensurepipinstall性能差距在日常開發中感知不明顯穩定性最重要。4.4 軟鏈接沖突覆蓋系統Python的風險我在一開始強調過不要動系統自帶的Python。但實際操作中還是有人會執行sudo ln -s /usr/local/python3.8/bin/python3.8 /usr/bin/python3這種做法非常危險。統信UOS的桌面端很多組件啟動器、控制中心、軟件包管理器都調用系統Python3.7。一旦替換輕則軟件中心閃退重則整個桌面無法加載。不要用軟鏈接去覆蓋/usr/bin/python3用前面提到的/usr/local/bin軟鏈接或別名即可。4.5 Python包安裝成功但import報錯依賴庫兼容問題arm64平臺下部分包含C擴展的Python包沒有提供aarch64的預編譯wheelpip會嘗試從源碼編譯此時編譯過程中會調用系統gcc如果缺了該庫的系統開發依賴就會報錯。比如安裝Pillow時報錯Could not find zlib、安裝lxml時報錯need libxml2。解決思路是安裝對應的系統依賴庫。常用包的依賴對應關系Python包需要安裝的系統依賴Pillowlibjpeg-dev, zlib1g-dev, libfreetype6-devlxmllibxml2-dev, libxslt1-devpsycopg2libpq-devmysqlclientdefault-libmysqlclient-devnumpy/pandasgfortran, libopenblas-devmatplotliblibpng-dev, libfreetype6-dev一般來說把這些裝上以后絕大多數pip包都能順利編譯。4.6 一個容易忽略的問題locale相關的警告編譯后在終端輸入python3.8時可能會看到類似Unable to get locale encoding或者Could not find platform independent libraries prefix之類的警告。前者通常是系統locale配置不完整造成的。可以在終端先執行export LANGen_US.UTF-8 export LC_ALLen_US.UTF-8確認問題消失后再把這兩行寫入~/.bashrc。4.7 安裝問題速查表把前幾次調試中遇到的問題整理成一張速查表方便按圖索驥報錯信息原因解決辦法No module named _ssl缺libssl-dev或OpenSSL版本過低安裝libssl-dev重新編譯配置No module named _ctypes缺libffi-dev安裝libffi-dev重新編譯Ignoring ensurepip failure: pip requires SSL/TLS缺少zlib開發庫或SSL庫安裝zlib1g-dev與libssl-dev后重編make: gcc: Command not foundgcc未安裝apt install gccCould not find platform independent libraries編譯時configure參數異常make clean后重新configurefatal error: Python.h: No such file or directory編譯第三方C擴展時缺Python開發頭文件對virtualenv而言是缺少python3-dev頭文件重新安裝python3.8開發環境zipimport.ZipImportError: cant decompress data缺少zlib安裝zlib1g-dev重新編譯5. 編譯完成后的驗證與使用體驗5.1 一條命令驗證核心模塊是否齊全Python編譯安裝最大的風險是模塊缺失。因此裝完以后建議做一次快速驗證。命令行直接執行/usr/local/python3.8/bin/python3.8 -c import ssl, sqlite3, ctypes, lzma, bz2; print(所有核心模塊導入正常)如果不報錯說明SSL、SQLite、CTypes、壓縮模塊都正常工作了。再測試一下pip/usr/local/python3.8/bin/pip3.8 -V驗證通過后創建虛擬環境把pandas、requests等常用包安裝一下實測pip install requests pandas python -c import requests, pandas; print(requests.__version__, pandas.__version__)5.2 arm64平臺使用Python的性能體驗在arm64設備上運行Python性能表現與x86設備有一定差異。Python本身是解釋型語言純Python代碼的性能差距主要看CPU頻率和IPC效率。飛騰、鯤鵬這些芯片的單核性能與同世代x86相比有一定差距純計算密集的Python任務可能會慢20%-40%。但實際使用中大部分Python項目瓶頸在I/O和網絡請求上這部分arm64與amd64的差距并不明顯。啟用--enable-optimizations以后解釋器本身的執行速度確實有提升直觀感受是啟動速度和簡單循環運算變快了。5.3 實用技巧多版本共存時如何快速切換裝完Python3.8后系統里會有至少兩個Python系統自帶3.7和編譯安裝的3.8。我建議為每個項目創建獨立的虛擬環境這樣就不需要頻繁切換全局版本。如果確實有多個項目分別要求不同版本可以用virtualenv或者conda來管理但conda在arm64平臺上的支持需要額外注意Miniforge比Anaconda更適合ARM設備。或者在shell里寫一個簡單的切換函數alias py3.8source ~/py38venv/bin/activate這樣每當需要用到Python3.8的環境時直接輸入py3.8就能切進虛擬環境和系統環境互不干擾。5.4 小技巧如何徹底卸載Python3.8如果哪天不需要Python3.8了卸載非常簡單。由于全部安裝在/usr/local/python3.8目錄下直接刪除該目錄即可sudo rm -rf /usr/local/python3.8 sudo rm /usr/local/bin/python3.8 /usr/local/bin/pip3.8同時清理掉對應的虛擬環境和軟鏈接。系統的Python3.7完全不受影響。6. 一點個人經驗總結在統信UOS arm64上編譯安裝Python3.8.0核心其實就是一個詞“隔離”。把自定義版本的Python與系統自帶的Python隔離開互不干擾這是Linux多版本共存的關鍵思路。跑通這一套流程之后后面哪怕要在同樣的環境裝Python3.9、3.10甚至更老的版本套路完全一樣先裝依賴庫再configure指定prefix接著make和make install最后用軟鏈接或者虛擬環境接入項目。最大的坑從來都不是編譯過程而是依賴缺失和默認路徑覆蓋這兩點只要有了意識遇到的概率就大大降低了。還有一點要說一下編譯前一定要確認源碼包的完整性和來源。有條件的話下載后在本地做一次sha256校驗尤其在生產環境下源碼被篡改的風險是真實存在的。用官方渠道下載的包相對可靠但安裝之后馬上執行模塊驗證這一步不能省。我在這臺UOS arm64機器上編譯完Python3.8.0之后順帶把一套Django項目跑了起來數據庫連接、Celery任務調度、Redis緩存全部正常運行連續運行兩周沒有出現異常。這個環境現在還在服役穩定性是經過驗證的。最后再分享一個小細節編譯時如果你用的飛騰CPU可以在configure之前設置環境變量CFLAGS-marcharmv8-acrc這樣編譯出來的Python會對飛騰處理器做微架構優化判斷是否生效可以在編譯完成后執行python3.8 -c import sysconfig; print(sysconfig.get_config_var(CFLAGS))查看。不過這個優化對日常開發感知不強追求極致的可以試一下不折騰也沒問題。