軟體包補丁
本文涵蓋了如何在 Arch Build System (ABS) 中為軟體包創建和應用補丁。
補丁描述了一個或多個文件的行更改。補丁通常用於自動更改原始碼。
diff 工具逐行比較文件。將它的輸出保存下來你就得到了一個補丁,如 diff --unified --recursive --text foo bar > patch, 如果你傳遞了目錄, diff 會比較它們包含的文件。
- 如果你已將構建了軟體包,請刪除
src目錄。 - 運行
makepkg --nobuild會下載並提取,但不會構建PKGBUILD中聲明的源文件。如果你正在創建補丁的系統上沒有必要的依賴,你可能需要運行makepkg --nobuild --nodeps作為替代。 - 在
src目錄中創建兩份提取的目錄的副本,一個作為原始版本,一個作為你修改過的版本,將他們稱為package.orig和package.new。 - 在
package.new目錄中進行你的更改。 - 運行
diff --unified --recursive --text package.orig package.new --color並檢查補丁是否看起來良好。 - 運行
diff --unified --recursive --text package.orig package.new > package.patch來生成補丁。 - 進入
package.orig目錄並使用patch --strip=1 < ../package.patch命令來應用補丁。運行makepkg --noextract --install命令構建並安裝更改後的軟體包來驗證補丁是否正常工作。
更多信息參見 diff(1) 和 git-diff(1)。
本節概述如何在 PKGBUILD 的 prepare() 函數中應用你創建或從網絡下載的補丁。請遵循以下步驟:
- 為補丁文件在
PKGBUILD的source數組中添加一個條目,將該條目與原始源 url 之間用空格隔開。如果該文件可在網上獲得,你可以提供完整的 URL ,它將被自動下載並放在src目錄中。如果它是你自己創建的補丁,則應將補丁文件與PKGBUILD文件放在同一目錄中,並只需將文件名添加到source數組中,以便將其複製到src目錄中。如果你重新發布PKGBUILD,你應該在PKGBUILD中包含補丁。 - 然後使用
makepkg -g >> PKGBUILD或者updpkgsums(來自於 pacman-contrib包) 來更新sha512sums數組。 或者手動添加一個條目到sha512sums數組; 你可以使用 sha512sum 工具來生成你的補丁的校驗和。 - 如果
PKGBUILD還沒有prepare()函數就創建它。 - 第一步是進入到需要被打補丁的目錄(在
prepare()函數中,不是你的終端!你希望自動化打補丁這一過程)。 也可以通過cd "$srcdir/$pkgname-$pkgver"完成。$pkgname-$pkgver通常是解包一個下載源文件的目錄名,但並不總是這樣。 - 現在你只需要從這個目錄裡面應用補丁。這可以通過添加
patch --strip=1 --input=pkgname.patch到你的prepare()函數就能簡單完成。 將pkgname.patch改成包含 diff 的文件的名字(因為在PKGBUILD的source數組中而被自動複製到src的文件)。
一個 prepare 函數示例:
prepare() {
cd "$pkgname-$pkgver"
patch --forward --strip=1 --input="${srcdir}/eject.patch"
}
或者不先 cd,直接使用 patch 的 --directory 參數:
prepare() {
patch --directory="$pkgname-$pkgver" --forward --strip=1 --input="${srcdir}/eject.patch"
}
從終端運行 makepkg, 如果一切順利,補丁會被自動應用,並且你的新軟體包會包含補丁中的更改。如果不是這樣的話,你可能需要試驗一下補丁的 --strip 選項。 在試驗的時候,你會發現 --dry-run, --reverse 或者 --verbose 選項會有用。更多信息參見 patch(1)。
基本上它的工作原理如下。如果 diff 文件被創建來將補丁應用到 myversion/ 中的文件,那麼 diff 文件將被應用於 myversion/file。你正在 yourversion/ 目錄中運行它(因為你會 cd 到 PKGBUILD 中的目錄),因此當補丁應用該文件時,你希望它將其應用到 file 文件,並從 myversion/ 部分中取出。 --strip=1 通過從路徑中刪除一個目錄來實現這一點。但是,如果開發者在 myfiles/myversion 中修補,則需要刪除兩個目錄,因此你使用 --strip=2。
如果你不應用一個 --strip 選項,它將會去掉所有目錄結構。如果所有文件都在基礎目錄中的時候是可以的。但是如果補丁是在 myversion/ 上創建的,並且有一個被編輯的文件是 myversion/src/file,當你從 yourversion 目錄以不帶 --strip 參數的方式運行補丁的時候,它會嘗試為一個名為 yourversion/file 的文件打補丁。
大多數開發者從被打補丁的目錄的父目錄創建補丁,因此 --strip=1 通常是正確的。
一個更簡單的創建補丁的方法是使用 quilt包,它為管理許多補丁提供了更好的支持,例如應用補丁,刷新補丁和將打補丁的文件回退到原始狀態。Debian 使用 quilt包 來管理他們的補丁。quilt 生成和應用補丁、回退打補丁的文件的基本用法的基本信息可參考使用 Quilt。
- http://www.kegel.com/academy/opensource.html — 有關修補文件的有用信息