AUR 套件的安裝是在本機從原始碼編譯,這讓它的失敗面比官方 repo 套件多出一整層:官方套件的失敗集中在「抓不抓得到」(網路、資料庫、簽章,見 安裝期套件與網路故障排除),AUR 套件在抓到之後還要在你的機器上 build 成功——編譯環境、函式庫版本、架構宣告都可能讓它斷在半路。本篇把一輪 ARM VM 實測踩到的建置失敗分層整理成判讀路由:每一層有不同的權威檢查,判對層就能避免「build 失敗就懷疑軟體不支援這平台」這種昂貴的誤判。

先排資源層:build 中斷優先查磁碟

一次大型編譯(上百步的 C++ 專案)停在中途,最廉價也最常見的解釋是資源耗盡。實測案例:一次 build 停在第 120/227 步,同一份原始碼在清出磁碟空間後接著編就過——中斷的根因是宿主磁碟寫滿,跟 aarch64 相容性完全無關。df -hfree 是 build 中斷後的第一組檢查,先排除掉廉價解釋再往下懷疑,完整的判讀紀律見 診斷心法

型態一:預編二進位的版本半衰期(-bin 套件)

AUR 的 -bin 套件是別人在某個時間點編好的二進位,它對「當時的系統函式庫」連結。rolling 發行版的函式庫 soname 輪替快,一次 pacman -Syu 之後,預編二進位依賴的舊版函式庫可能已經被換掉——二進位還在、但載入直接失敗。實測案例:paru-bin 的 aarch64 二進位連結 libalpm.so.15,系統升級後 libalpm 已是 .so.16,helper 自己就起不來。

判讀訊號是 error while loading shared libraries: libxxx.so.N: cannot open shared object file——注意這是「工具自己壞了」,跟它要裝的套件無關。兩條修法對應不同取捨:

  • 改用原始碼建置的 helperyay 從 AUR 以 makepkg 建置(Go 專案、編譯快),建置當下就對系統現有的 libalpm 連結,對這類 soname 漂移免疫。長期用 rolling 發行版時這條比較划算。
  • 重建 -bin:重跑一次該 -bin 套件的安裝讓它抓新版二進位。前提是上游已經對新 soname 重新發布,時效上受制於維護者。

這條機制對所有 -bin 後綴的 AUR 套件成立:-bin 換到的是「省編譯時間」,付出的是「跟系統函式庫版本綁定的半衰期」。系統更新頻繁、或架構冷門(上游重發慢)時,半衰期會明顯縮短。

型態二:建置設定烤入發行版套件(makepkg.conf 管不到的路徑)

編譯期叫到一個不存在的工具時,直覺是去 /etc/makepkg.conf 找設定,但有一類路徑是烤入發行版套件本身的:發行版建置自家套件時使用的工具鏈路徑,被序列化進了套件的建置中繼資料,之後所有透過該套件觸發的編譯都會沿用。實測案例:Arch Linux ARM 官方的 python 套件是用 distcc(分散式編譯)建的,CXX=/usr/lib/distcc/bin/g++ 被烤進 python 的 sysconfig;本機編任何 Python C++ extension(AUR 的 python-materialyoucolor)都會去叫這個不存在的路徑,而 makepkg.conf!distcc 完全管不到它——那個設定管的是 makepkg 自己的行為,管不了 python 轉手發起的編譯。

權威判讀是直接問那個工具鏈自己記了什麼:

1python -c "import sysconfig; print(sysconfig.get_config_var('CXX'))"
2# /usr/lib/distcc/bin/g++  ← 烤入的路徑,不是 makepkg.conf 給的

修法是在建置指令前用環境變數覆寫:CXX=g++ paru -S <套件>。這層的通用判讀:編譯叫錯工具時,先查路徑是誰給的——makepkg 設定、環境變數、還是烤入語言 runtime 的建置中繼資料,三個來源的修法各不相同。

型態三:PKGBUILD 架構宣告缺失

makepkg 建置前會比對 PKGBUILD 的 arch 陣列跟當前機器架構,沒列就拒建。這是 metadata 層的宣告缺失,跟「軟體真的不支援這個架構」是兩件事——很多 AUR 維護者只在 x86_64 測過、就只宣告 x86_64,程式本身可能完全可移植。判讀訊號是錯誤訊息明講架構不在清單(doesn't support the 'aarch64' architecture),此時用 --mflags "-A"(傳 --ignorearch 給 makepkg)繞過宣告、讓它實際嘗試編譯:編得過且跑得動,就是純宣告缺失(值得回報維護者補宣告);編譯在架構相關的程式碼上真的失敗,才是存在性層的問題——這條跟「工具打包了、依賴的專有二進位沒有這個架構」的判讀合流,見 平台與發行版差異的判讀地圖 的套件存在性段。

建置成功之後:-git 版本與既有套件的衝突

AUR 鏈還有一類失敗發生在建置成功、安裝階段:PKGBUILD 把依賴指名到 -git 開發版(例如 depends 列 quickshell-git),跟系統已裝的官方 repo 穩定版同名衝突。互動模式下 helper 會問你要不要移除舊版;--noconfirm 的非互動流程則直接失敗、且已建好的包留在快取裡。修法是手動換裝:pacman -R <穩定版>pacman -U <快取裡建好的包>。自動化腳本要把「AUR 依賴可能指名 -git 版」納入預期,先查 PKGBUILD 的 depends 再決定要不要預先移除穩定版。

判讀總表

症狀權威檢查修法
build 跑一半停住資源df -hfree(宿主與 guest 兩側)清空間後同一份原始碼續編
helper 報 error while loading shared libraries二進位漂移ldd $(which <helper>) 看斷的 soname換原始碼建置的 helper 或重建 -bin
編譯叫不存在的編譯器路徑烤入路徑sysconfig.get_config_var('CXX') 之類環境變數覆寫(CXX=g++
doesn't support the '...' architecture宣告缺失--mflags "-A" 實編驗證編過即宣告問題、編不過才是存在性問題
建好了、安裝時跟穩定版衝突依賴衝突PKGBUILD 的 depends 是否指名 -git手動 -R 舊版再 -U 裝建好的包

下一步路由