跳至內容

軟體包補丁

出自 Arch Linux 中文维基

本文涵蓋了如何在 Arch 構建系統(ABS)中為軟體包創建和應用補丁。

補丁描述了一個或多個文件的行更改。補丁通常用於自動更改原始碼。

創建補丁

注意:如果你只是想要更改一兩行,你可能會想使用 sed

diff 工具會逐行比較文件。將它的輸出保存下來你就得到了一個補丁,如 diff --unified --recursive --text foo bar > foobar.patch(可以將參數簡寫為 diff -ura)。如果你傳遞了目錄, diff 會比較它們包含的文件。

  1. 如果你已將構建了軟體包,請刪除 src 目錄。
  2. 運行 makepkg --nobuild/makepkg -o 會下載並提取 PKGBUILD 中聲明的源文件,但不會進行構建。如果你正在創建補丁的系統上沒有必要的依賴,你可能需要轉而使用 makepkg --nobuild --nodeps/makepkg -od
  3. src 目錄中創建兩份提取的目錄的副本,一個作為原始版本,一個作為你修改過的版本,下面我們會將他們稱為 package.origpackage.new
  4. package.new 目錄中進行你的更改。
  5. 運行 diff -ura package.orig package.new --color 並檢查補丁是否看起來良好。
  6. 運行 diff -ura package.orig package.new > package.patch 來生成補丁。
  7. 進入 package.orig 目錄並使用 patch --strip=1 --input=../package.patch(可以簡寫為 patch -p1 -i ../package.patch)命令來應用補丁。運行 makepkg --noextract --install/makepkg -ei 命令構建並安裝更改後的軟體包來驗證補丁是否正常工作。
注意:你也可以使用 Gitgit diffgit format-patch 命令 [1]

更多信息參見 diff(1)git-diff(1)

提示:大部分 git 託管平台(例如 GitHub 和 GitLab)支持為特定提交或合併生成補丁,只需在其 URL 結尾添加 .patch。對於 GitHub,請考慮在 URL 最後添加 ?full_index=1 參數,以避免未來對象哈希值長度變更導致的校驗值不匹配錯誤。

應用補丁

本節概述如何在 PKGBUILDprepare() 函數中應用你創建或從網絡下載的補丁。請遵循以下步驟:

  1. 為補丁文件在 PKGBUILDsource 數組中添加一個條目,將該條目與原始源 url 之間用空格隔開。如果該文件可在網上獲得,你可以提供完整的 URL ,它將被自動下載並放在 src 目錄中。如果它是你自己創建的補丁,則應將補丁文件與 PKGBUILD 文件放在同一目錄中,並只需將文件名添加到 source 數組中,以便將其複製到 src 目錄中。如果你要分發 PKGBUILD,就需要將補丁與 PKGBUILD 一同發布。
  2. 然後使用 makepkg -g >> PKGBUILD 或者 updpkgsums(來自於 pacman-contrib)來更新 sha512sums 數組。或者手動添加一個條目到 sha512sums 數組; 你可以使用 sha512sum 工具來生成你的補丁的校驗和。
  3. 如果 PKGBUILD 中還沒有 prepare() 函數,就創建一個。
  4. 第一步是在 prepare() 函數中進入到需要被打補丁的目錄,可以通過 cd $pkgname-$pkgver 來完成。$pkgname-$pkgver 通常是源碼包解包後的目錄名,但並不總是這樣。
  5. 現在你只需要在這個目錄裡面應用補丁。這可以通過在 prepare() 函數中添加 patch -p1 -i pkgname.patch 來完成。將 pkgname.patch 改成包含 diff 的文件的名字(由於其在 PKGBUILDsource 數組中,因此已被自動複製到 src 目錄下)。

一個 prepare 函數示例:

PKGBUILD
prepare() {
    cd $pkgname-$pkgver
    patch -Np1 -i ../eject.patch
}

或者不先 cd,直接使用 patch--directory/-d 參數:

PKGBUILD
prepare() {
    patch -d $pkgname-$pkgver -Np1 -i ../eject.patch
}

從終端運行 makepkg,如果一切順利,補丁會被自動應用,並且你的新軟體包會包含補丁中的更改。如果不是這樣的話,你可能需要試驗一下 patch 的 --strip/-p 選項。在試驗的時候,你會發現 --dry-run, --reverse 或者 --verbose 選項會有用。更多信息參見 patch(1)

基本上它的工作原理如下:如果 diff 文件被用於將補丁應用到 myversion/ 中的文件,那麼 diff 文件將被應用於 myversion/file。你當前的運行目錄為 yourversion/(即 PKGBUILD 中 cd 進的目錄),在將補丁應用到文件時,需要將 myversion/ 部分移除,只應用到 file 文件,所以需要使用 -p1 參數將路徑中的第一個目錄移除。但如果需要修補 myfiles/myversion 中的文件,就需要使用 -p2 移除兩個目錄。

如果你不應用一個 -p 選項,它將會去掉所有目錄結構。如果所有文件都在基目錄中的時候是可以的,但是如果補丁是在 myversion/ 上創建的,並且有一個被編輯的文件是 myversion/src/file,當你從 yourversion 目錄以不帶 -p 參數應用補丁的時候,它會嘗試為一個名為 yourversion/file 的文件打補丁。

大多數開發者從被打補丁的目錄的父目錄創建補丁,因此 -p1 通常是正確的。

使用 quilt

一個更簡單的創建補丁的方法是使用 quilt,它為管理大量補丁提供了更好的支持,例如應用補丁,更新補丁和將被打補丁的文件回退到原始狀態。Debian 使用 quilt 來管理他們的補丁。使用 quilt 生成和應用補丁、回退被打補丁的文件的基本用法和信息可參考使用 Quilt

另見