《LinuxFromScratch》第三部分:構建LFS系統第六章:安裝基本的系統軟體-6.3.軟體包管理

行者武松發表於2017-11-07

軟體包管理是我們經常收到希望新增到 LFS
手冊裡的需求。一個軟體包管理器可以追蹤安裝的檔案,這樣可以在移除或升級軟體包時輕鬆地清理。不僅是二進位制執行檔案和庫檔案,包管理器還會處理配置檔案的安裝。在你遐想之前提醒一下,不!——本節不涉及也不建議任何一個特定的包管理器,而是關於軟體包管理的更一般的技術的綜合概述。最適合你的包管理器可能就在這些技術裡,或者可能是兩個或更多的組合。本節還會簡要提到升級軟體包可能碰到的問題。

關於為什麼 LFS 或 BLFS 手冊裡不採用任何軟體包管理器的一些原因:

  • 軟體包管理偏離了本手冊的主要目標——教大家 Linux 系統是如何構建出來的。

  • 存在很多軟體包管理的解決方案,每一個都有自己的長處和缺點。很難選擇一種適合所有人的方式。

關於軟體包管理有很多資料,請訪問 Hints Project 看看是否有一個能適合你的需求。

6.3.1. 升級問題

軟體包管理器可以在軟體新版本釋出後輕鬆升級。一般來說 LFS 和 BLFS 手冊裡的指令可以用來升級到新版本。下面是一些在你準備升級軟體包時需要注意的事情,特別是在一個執行中的系統。

  • 如果需要升級 Glibc 到新版本(比如,從 glibc-2.19 升級到 glibc-2.20),重新構建整個 LFS 會比較安全。雖然你也許能夠按依賴關係重新編譯所有的軟體包,不過我們不建議這樣做。

  • 如果某個包含的動態庫的軟體包升級了,而且庫名字有改變,那麼所有動態連結到這個庫的軟體包都需要重新連結新的庫。(請注意軟體包版本和庫名字並不存在相關性。)舉個例子,某個軟體包 foo-1.2.3 安裝了一個名叫 libfoo.so.1 的動態庫。然後假設你把這個軟體包升級到了新版本 foo-1.2.4,而新版本會安裝名叫 libfoo.so.2的動態庫。在這種情況下,所有動態連結到 libfoo.so.1 的軟體包都需要重新編譯連結到 libfoo.so.2。注意在所有依賴軟體包重新編譯完成之前,請不要刪除舊版的庫檔案。

6.3.2. 軟體包管理技術

下面介紹一些常見的軟體包管理技術。在決定用哪種包管理方式之前,先研究一下各種不同的技術,特別是瞭解特定體系下的不足。

6.3.2.1. 所有一切都在我腦袋裡!

是的,這也算一種軟體包管理技術。有些人覺得不需要管理軟體包,是因為他們非常熟悉軟體包,知道每個包都安裝了哪些檔案。也有些使用者不需要管理軟體包,是因為他們會在某個軟體包有更改後重建整個系統。

6.3.2.2. 在獨立目錄裡安裝

這是一種簡單的軟體包管理方式,不需要其他額外的軟體來管理軟體的安裝。每一個軟體包都被裝到一個獨立的目錄裡。例如,軟體包 foo-1.1 安裝到目錄 /usr/pkg/foo-1.1 裡並建立一個軟連結 /usr/pkg/foo 指向 /usr/pkg/foo-1.1。在安裝新版本 foo-1.2 的時候,它會被裝到目錄 /usr/pkg/foo-1.2 裡,然後將之前的軟連結替換成指向新版本軟體的位置。

類似 PATHLD_LIBRARY_PATHMANPATHINFOPATHCPPFLAGS 之類的環境變數需要包含 /usr/pkg/foo 目錄。在管理大量軟體包時,這種方式就不可行了。

6.3.2.3. 軟連結方式軟體包管理

這是前一種軟體包管理技術的變種。每個軟體包都和之前方式一樣的安裝。但不是建立目錄的軟連結,而是把每個檔案都連結到 /usr 目錄結構裡。這樣就不需要擴充套件環境變數了。通過自動建立這些可由使用者自己建立的連結,許多軟體包管理器都採用了這種方式。幾個比較流行的有 Stow、Epkg、Graft 和 Depot。

這種安裝方式需要偽裝,這樣軟體包會認為自己被裝到了 /usr 目錄下,而實際上它被裝到了 /usr/pkg 目錄結構中。在這種方式下,安裝並不是一件瑣碎的小事。例如,假如你準備安裝一個軟體包 libfoo-1.1。下面的指令可能不會正確地安裝:

./configure --prefix=/usr/pkg/libfoo/1.1
make
make install

安裝本身倒是沒有問題,但是可能一些依賴包不會像你期望的那樣連結 libfoo 庫。如果要編譯一個連結 libfoo 的軟體,你可能會注意到它實際上鍊接的是 /usr/pkg/libfoo/1.1/lib/libfoo.so.1 而不是你所期望的 /usr/lib/libfoo.so.1。正確的方式是使用 DESTDIR 策略來偽裝軟體包的安裝過程。這種方式需要像下面這樣操作:

./configure --prefix=/usr
make
make DESTDIR=/usr/pkg/libfoo/1.1 install

大多數軟體包支援這種方式,但也有一些例外。對於不相容的軟體包,你可能需要自己手動安裝,或許你會發現將這些有問題的包安裝到 /opt 目錄下會更簡單些。

6.3.2.4. 基於時間戳

在這種方式裡,在安裝之前會建立一個時間戳檔案。在安裝之後,用一行簡單的 find 命令加上合適的引數就可以生成在時間戳檔案建立之後所安裝的所有檔案列表。有一個採用這種方式的包管理器叫做 install-log。

這種方式的優點是非常簡單,但是它有兩個缺陷。比如,在安裝過程中,所安裝檔案採用的是其它時間戳而不是當前時間,那這些檔案將不能被軟體包管理器跟蹤到。還有,這種方式只能在一次安裝一個軟體包的情況下使用。如果在不同的終端裡同時安裝兩個不同的軟體包,此時的安裝日誌就不可靠了。

6.3.2.5. 追蹤安裝指令碼

在這種方式裡,安裝指令碼所使用的命令都會被記錄下來。有兩種技術,一種技術是:

設定環境變數 LD_PRELOAD 指向一個在安裝前預載入的庫。在安裝過程中,這個庫會追蹤軟體包安裝指令碼里所包含的各種執行檔案比如 cpinstallmv,以及追蹤會修改檔案系統的系統呼叫。要讓這種方式有效的話,所有的執行檔案需要動態連結到沒有 suid 或 sgid 標誌位的庫。預載入這個庫可能會引起安裝過程中一些意外的副作用。不過,建議做一些測試以保證軟體包管理器不會造成破壞並且記錄了所有適當的檔案。

第二種技術是使用 strace 命令,它會記錄下安裝指令碼執行過程中所有的系統呼叫。

6.3.2.6. 建立軟體包存檔

在這種方式裡,像之前的軟連結軟體包管理方式裡所描述的那樣,軟體包被偽裝安裝到一個獨立的目錄樹裡。在安裝完成後,會將已安裝檔案打包成一個軟體包存檔。然後這個存檔會用來在本地機器或其他機器上安裝軟體包。

這種方式為商業發行版中的大多數包管理器所採用。一些例子是 RPM(它順便也是 Linux 標準規範 裡所要求的)、pkg-utils、Debian 的 apt、以及 Gentoo 的 Portage 系統。該頁面描述瞭如何在 LFS 系統裡採用這種包管理方式: http://www.linuxfromscratch.org/hints/downloads/files/fakeroot.txt

建立帶有依賴關係的軟體包存檔非常複雜,已經超出 LFS 手冊範圍了。

Slackware 使用一個基於 tar 的系統來建立軟體包存檔。這套系統不像那些更復雜的包管理器,有意地不處理包依賴關係。關於 Slackware 包管理器的詳細資訊,請參看 http://www.slackbook.org/html/package-management.html

6.3.2.7. 基於使用者的軟體包管理

在這種方式,是 LFS 特有的,由 Matthias Benkmann 所設計,可以在 Hints Project 裡能找到。在這種方式裡,每個軟體包都由一個單獨的使用者安裝到標準的位置。屬於某個軟體包的檔案可以通過檢查使用者 ID 輕鬆識別出來。關於這種方式的特性和短處非常複雜,在本節裡說不清楚。詳細的資訊請參看 http://www.linuxfromscratch.org/hints/downloads/files/more_control_and_pkg_man.txt

6.3.3. 在多個系統上佈置 LFS

LFS 系統的一個優點是沒有會依賴磁碟系統裡檔案位置的檔案。克隆一份 LFS 到和宿主機器相似配置的機器上,簡單到只要對包含根目錄的 LFS 分割槽(對於一個基本的 LFS 構建不壓縮的話大概有 250MB)使用 tar命令打包,然後通過網路傳輸或光碟拷貝到新機器上展開即可。在這之後,還需要調整一些配置檔案,包括:/etc/hosts/etc/fstab/etc/passwd/etc/group/etc/shadow/etc/ld.so.conf

根據系統硬體和原始核心配置檔案的差異,可能還需要重新編譯一下核心。

最後,需要使用 8.4 “用 GRUB 設定引導過程”裡所介紹的方法讓新系統可引導。      

建立者:Gerard Beekmans

編輯者:Matthew Burgess 和 Armin K.

翻譯團隊:LCTT

譯者/校對:zpl1025,wxy

原文連結   


相關文章