註:本文使用情境為桌面版Linux,適用把Linux當主力系統使用的人群。
很多人想要穩定的系統,卻又想要最新版的軟體。
用Linux發行版的術語來說,就是固定發行版 (stable release) 的用戶組總會想要安裝滾動發行版 (rolling release) 的軟體。
其中一個例子就是Ubuntu了!Ubuntu基於Debian開發,是標準的固定發行版系統,常常遇到軟體版本太舊的問題,導致使用者有時得從原始碼編譯軟體(compiling from source),通常安裝的最後一步就是make install或ninja install指令。
當你看到軟體要你執行make install的時候,請勿必三思而後行。看看企鵝的眼睛,思考它是什麼樣的軟體,確認你是否真的有必要這樣安裝,想想這樣會不會影響你未來正常使用Linux桌面的體驗。
Ubuntu的爸爸,Debian在 Don’t Break Debian一文中指出,Linux使用者應當好好愛護你的系統,不要盲目複製貼上網路部落格的指令(包括我這篇:P),不要隨便在你的系統make install安裝軟體。Ubuntu使用跟Debian一樣的APT套件管理器,所以Debian的話也在理。
下面表述為何不要用make install,以及解決方案。
Ubuntu的軟體太舊的問題#
相信你不只一次遇過Ubuntu套件庫軟體版本太舊的問題
好一點的開發者會維護自己的PPA,自動給舊版Ubuntu編譯對應軟體套件,例如Wine、Kdenlive。
但總會遇到更慘的,沒人維護PPA,或是PPA更新慢半拍,連開發者都叫你手動make install才能取得最新版本軟體的情景吧!比如Gamescope、Scrcpy等等。
再以glibc版本問題為例子,拿我最近遇到的這個編譯錯誤來說: /lib/x86_64-linux-gnu/libc.so.6: version GLIBC_2.38' not found (required by
我的系統是Ubuntu 22.04,用strings指令查看
strings /lib/x86_64-linux-gnu/libc.so.6 | grep GLIBC_
可見glibc最多只提供到2.35,2.38要Ubuntu 23.10以後才有。
應當迴避的解決方法#
在不升級系統的情況下,如何上述問題?取得最新版的軟體?
加PPA?看不到有大型組織維護的PPA呀。
自己configure make新版軟體?太麻煩了。你知道make install一條指令下去,沒有其他軟體輔助下,要反安裝你剛剛裝的東西有多複雜嗎。
pkg.orgs上面有很多新版Ubuntu的deb套件,載下來用dpkg設定一下問題就解決了吧?否,千萬不要。
別自作聰明的找新版本的deb套件,替換掉系統套件,尤其是libc這種系統關鍵的核心套件,就為了取得新版本的.so檔或lib什麼,這樣系統會炸掉。很多程式依賴GLIBC版本一旦錯誤就會產生毀滅後果。此外,亂裝新版本的deb檔的後果就是,未來apt upgrade會出現大量"you have held broken packages"的依賴錯誤,夠你受的了。
因此,不要幹這種事情。
較為妥善的解決之道#
參考我之前寫過的 Linux應該用何種方法安裝應用程式,我認為每個軟體都應該被套件管理器納入管理,如果不行,那就用容器隔離。
GLIBC的問題,我後來用 Distrobox指令臨時開個Ubuntu 22.04的Docker容器,GLIBC版本問題就解決了,軟體也順利編譯了。
Distrobox真的很便利呀,需要某個Ubuntu版本的環境一行指令就能切換。
啊如果軟體編譯還得依賴到系統套件,甚至限定Linux核心版本,那你就只能開完全隔離系統的 KVM虛擬機來編譯了~
關於軟體版本太舊的問題,很多時候,不一定要編譯軟體,可多用容器技術跑軟體!例如: Flatpak、 AppImage、 Snap、 Docker 以上技術都把軟體的依賴套件與宿主機隔離,不會互相干擾。
如果非得make install不可,那麼至少編譯的時候,放在Docker容器裡面執行,才不會為了編譯軟體給系統裝一堆QT、舊版libncurses5之類的依賴套件。
make install所產出的二進位檔,你可以進入build目錄先行測試,等到測試好了之後再從容器取出來安裝到系統。
另外, Distrobox也可以協助你整合容器裡的軟體到宿主機,又不至於污染環境。