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