Arch 打包準則 - Arch Linux 中文维基

跳至內容

# Arch 打包準則

出自 Arch Linux 中文维基
Arch 打包準則

32 位 – 安全 – CLR – CMake – DKMS – Eclipse – Electron – Free Pascal – GNOME – Go – Haskell – Java – 交叉編譯工具 – KDE – Lisp – Meson – MinGW – 內核模塊 – Node.js – Nonfree – OCaml – Perl – PHP – Python – R – Ruby – Rust – Shell – VCS – Web – Wine – 字體

相關文章

- /安全
- Arch 構建系統
- 創建軟體包
- makepkg
- PKGBUILD

翻譯狀態：

- 本文（或部分內容）譯自 Arch packaging standards，最近一次同步於 2026-01-19，若英文版本有所更改，則您可以幫助同步與翻譯更改的內容。
- 您可以在 ArchWiki 的對應頁面找到本文翻譯的原始修訂歷史。
- 本文可能與英文原文存在出入。

在為 Arch Linux 構建軟體包時，您應該遵循以下的軟體包指導原則，尤其是當打算貢獻新軟體包至 Arch Linux 時。同時需要閱讀 PKGBUILD(5) 和 makepkg(8) man 手冊。

本頁中列出的重要項將不再於其它軟體包指導頁中指出，這些指導頁將作為以下準則的附加內容。

提交到 Arch 用戶軟體倉庫 (AUR) 的軟體包需要額外遵守 AUR 提交準則。

可在 `/usr/share/pacman/` 目錄下的 .proto 文件中查看更多 `PKGBUILD` 示例。

## 打包規則

- 永遠別將軟體包安裝至 `/usr/local/`

- 除非非用不可，否則絕對不要在 `PKGBUILD` 中自定義和使用新的變量，以避免和 makepkg 本身的變量衝突。

- 在非用不可的情況下，需要給自定義變量名前加上下劃線 (`_`)。例如：

      _customvariable=

- 任何情況下都要避免使用 `/usr/libexec/`，應該使用 `/usr/lib/${pkgname}/`。

- 包信息文件中的 `packager` 欄位可以通過修改 `/etc/makepkg.conf` 文件由編譯者進行自定義。使用 `~/.makepkg.conf`也可以達到此目的。

- 不要使用 makepkg 子程序（例如 `error`，`msg`，`msg2`，`plain` 和 `warning`），這些隨時都可能會更改。請使用 `printf` 或 `echo` 來輸出內容。

- 所有安裝過程中所需輸出的重要的信息，都要放到 .install 文件中。比如說如果某軟體包需要擴展的安裝步驟才能正常運行，你可以將這些步驟的介紹包含在 .install 文件中。

- 依賴包是最容易出現錯誤的地方。請花時間仔細核對，例如對動態可執行文件執行 `ldd` 或 `readelf`，檢查腳本需要的工具，查看軟體文檔等。namcap 可以幫助你，它可以解析 PKGBUILD 和生成的打包文件，報告權限錯誤、缺少依賴、過多依賴等常見問題。

- 任何運行該軟體包不需要，或者該軟體包的通用功能不需要的可選依賴不要加入到 depends 中。這些信息應該加入 optdepends 數組，例如：

      optdepends=('cups: printing support'
                  'sane: scanners support'
                  'libgphoto2: digital cameras support'
                  'alsa-lib: sound support'
                  'giflib: GIF images support'
                  'libjpeg: JPEG images support'
                  'libpng: PNG images support')

  例子取自 wine包 軟體包。這些信息在安裝和升級時會自動列印，所以不要將這些信息加入 .install 文件。

- 在填寫軟體包描述（description）時，請不要使用下定義的方式描述包名稱。比如說，「Nedit is a text editor for X11」 應當簡寫為 "A text editor for X11"。順便注意保持描述在 80 個字符以內.

- 儘量保持 `PKGBUILD` 文件中每行不超過100字符。

- 如果可能的話，從 `PKGBUILD` 文件中去掉空行（沒有設置變量值的行）(如 `provides`、`replaces` 等)

- 通常實踐建議按照 PKGBUILD 一文中的示例安排 `PKGBUILD` 各變量順序。當然這不是強制性的，這裡唯一強制要求的是滿足正確的 Bash 語法。

- 變量名可能包含空格時，請使用引號，例如 `"$pkgdir"` 和 `"$srcdir"`。

- 請確保軟體包的完整性，確保校驗變量包含正確的數值，可以通過 `updpkgsums` 工具進行更新。

## 軟體包命名

- 軟體包應當僅包含字母或數字以及 `@`，`.`，`_`，`+`，`-`，不能以 `-` 和 `.` 開頭，所有的字母應當保持小寫。

- 軟體包的名稱不應該包含上游的主版本號，例如如果上游軟體包是 libfoo v2.3.4，不應該命名為 libfoo2。這樣在上游發布新的大版本時，就可以保留軟體包名和依賴可以保持不變。只有個別軟體包是例外，例如圖形庫 GTK 和 Qt。這些軟體升級後，應用程式需要花很長時間和經歷才能移植完成，所以系統需要同時安裝多個版本，軟體包名應該包含大版本號，比如 gtk3、gtk4、qt5、qt6。如果出現大部分軟體包都可以同步升級，只有個別軟體沒有被移植的情況，可以把老的軟體包命名為 libfoo1，而新的軟體包繼續使用 libfoo。

## 軟體包版本號

- 軟體包版本號（即 `pkgver`）應當和作者發行版號保持一致。
- 如果需要的話，版本號可以包含字母（例如 `2.54BETA32`）。
- 版本號裡不能包含連字符，只能允許字母、數字、下劃線、點號。如果上游版本號中出現了連字符，需要將其替換為下劃線。

- 軟體包發行號（即 `pkgrel`）僅和 Arch 相關. 這樣用戶就可以區分不同的編譯版本。發布號從1開始，軟體包被重新（打包）發布時 ，發行號將增加1。
- 當新版本發布的時候，發行號（release）自動回到1。
- 軟體包發布標記和軟體包版本標記遵從同樣的規則。

## 軟體包依賴

- 不要依賴 PKGBUILD#依賴關係 中的傳遞依存關係，因為依賴更新可能會導致關係中斷。
- 列出所有直接依賴庫，可以通過 find-libdeps(1)（devtools包 的組件）來完成。

## 軟體包關聯

- 不要將 `$pkgname` 添加到 PKGBUILD#provides，軟體包無法與自身衝突。
- 在 PKGBUILD#provides 中列出所有外部共享庫（如 `'libsomething.so'`），可通過 find-libprovides(1)（devtools包 的組件）來完成。

## 軟體源

- 儘可能使用 HTTPS 源：壓縮包使用 `https://`，git 源使用 `git+https://`
- 儘可能使用 PGP 簽名對源進行驗證（如果上游對提交進行了簽名，但沒有對壓縮包簽名，可能需要使用 git 標籤而不是源碼壓縮包進行構建。）

本文或本章節的事實準確性存在爭議。

原因： commit# is not required in recent pacman as proper checksum is supported for git sources. See[1]. gitea package also has been updated to use below approach（在 Talk:Arch 打包準則 中討論）

- 使用 git 標籤進行構建時，不要使用標籤名，要使用 `git rev-parse` 獲取到的對象哈希值

      _tag=1234567890123456789012345678901234567890 # git rev-parse "v$pkgver"
      source=(git+https://$url.git?signed#tag=$_tag)

      pkgver() {
          cd "$pkgname"
          git describe
      }

  具體案例可參考 gitea包 包。該操作的原因是，標籤可以被強制推送改變指向到的提交，從而導致構建出的包產生變化。強制推送會改變標籤的哈希值，從而使用標籤的對象哈希值可以確保源的完整性。使用 `pkgver()` 函數可避免在沒有更新 `_tag` 的情況下不小心修改掉 `pkgver`。關於 VCS 源格式的更多信息請參考 VCS 軟體打包準則#VCS 源。

- Do not diminish the security or validity of a package (e.g. by removing a checksum check or by removing PGP signature verification), because an upstream release is broken or suddenly lacks a certain feature (e.g. PGP signature missing for a new release)
- 源在 `srcdir` 下的名稱不能相同（可能需要在下載時進行重命名，例如 `"${pkgname}-${pkgver}.tar.gz::https://${pkgname}.tld/download/${pkgver}.tar.gz"`）
- 避免對如 sourceforge 等平台的連結使用特定鏡像源進行下載，因為它們有可能會變得不可用
- 使用 SSH 密鑰簽名的 Git 對象（例如標籤和提交等）可以使用 git 命令進行驗證，用法為通過 `gpg.ssh.allowedSignersFile` 指定包含可能的簽名密鑰的文件。具體用例請參考 [2]。

## 與上游協作

It is considered best-practice to work closely with upstream wherever possible. This entails reporting problems about building and testing a package.

- Report problems to upstream right away.
- Upstream patches wherever possible.
- Add comments with links to relevant (upstream) bug tracker tickets in the PKGBUILD (this is particularly important, as it ensures, that other packagers can understand changes and work with a package as well).

It is recommended to track upstream with tools such as nvchecker包, nvrsAUR or urlwatch包 to be informed about new stable releases.

## 目錄

- 配置文件應該放置到 `/etc` 目錄。如果有多個配置文件，可以使用子目錄，以保持 `/etc` 簡潔。例如，如果包名是 `pkg`，那就應使用 `/etc/pkg`（或者其他合適的名稱，比如apache使用的就是 `/etc/httpd/`）。

- 軟體包文件應該安裝在下列常用目錄：

  `/etc` | 系統關鍵配置文件
  `/usr/bin` | 二進制文件
  `/usr/lib` | 庫
  `/usr/include` | 頭文件
  `/usr/lib/pkg` | 模塊，插件等
  `/usr/share/doc/pkg` | 應用程式文檔
  `/usr/share/info` | GNU Info 系統文件
  `/usr/share/licenses/pkg` | Application licenses
  `/usr/share/man` | 手冊
  `/usr/share/pkg` | 程序數據
  `/var/lib/pkg` | 應用持久數據
  `/etc/pkg` | pkg 應用的配置文件
  `/opt/pkg` | 大的獨立程序，例如 Java

- 軟體包不應該在下面目錄添加任何文件:
  - `/bin`
  - `/sbin`
  - `/dev`
  - `/home`
  - `/srv`
  - `/media`
  - `/mnt`
  - `/proc`
  - `/root`
  - `/selinux`
  - `/sys`
  - `/tmp`
  - `/var/tmp`
  - `/run`

## Makepkg 的任務

當您使用 makepkg 構建軟體包時，makepkg 會自動執行如下功能:

- 檢查軟體包的依賴和構建依賴是否已安裝
- 從伺服器中下載源文件
- 校驗源文件的完整性
- 解壓源文件
- 打上必要的補丁（patch）
- 構建軟體並安裝到 fake root
- 從可執行文件中去掉符號標記
- 從庫文件中去掉調試標記
- 壓縮手冊頁和/或 info 頁
- 生成包信息文件（包含軟體包的基本信息）
- 壓縮 fake root 成為軟體包文件（*.pkg.tar.xz）
- 生成的軟體包文件保存在指定的目錄中（默認在當前目錄）

## 架構

如果該軟體包是針對特定架構編譯的，那麼 `arch` 數組應該包含 `'x86_64'`，否則使用 `'any'` 生成架構無關的包。

## 授權協議

有兩種與 Arch 軟體包相關的許可證：

### PKGBUILD 的許可證欄位

`PKGBUILD` 中的 `license` 欄位列出了被打包軟體的上游許可證，注意這不是軟體打包代碼的許可證。該欄位必須遵循 SPDX 許可證格式，更多信息請參考 PKGBUILD#license

### 軟體打包代碼許可證

軟體打包代碼的許可證。根據 RFC40，Arch Linux 指定了軟體打包代碼需以 `0BSD` 許可證進行授權，並參照 RFC52 使用 REUSE 來執行這一點。

總結一下就是：

1. 在軟體包源碼的根目錄下添加一個 `LICENSE` 文件，其內容與該文件完全一致，即 Arch Linux 用於軟體包的 `0BSD` 許可證。
2. 在軟體包源碼的根目錄下添加一個 `REUSE.toml` 文件，可以使用 `pkgctl license setup` 生成一個後在其上進行修改。
3. 確保執行 `pkgctl license check` 命令時不會有任何報錯。

如果有其它需要配置授權的文件，你需要為它們選擇一個合理的許可證。方法通常很簡單：

- 如果文件（例如類似 `launcher.sh` 的啟動腳本或類似 `myunit.service` 的 systemd 服務文件）是完全由你或其他 Arch 人員創建的，則需使用 `0BSD` 許可證。
  注意：如果你編寫了該補丁，同時也將其提交到了上游，那可以其針對 Arch 將其以 `0BSD` 許可證分發，並在提交到上游時讓他們應用自己的許可證。

- 如果文件時從上游獲取的（例如類似 `tool.png` 的圖標或類似 `fix.patch` 的補丁），那需要應用上游的許可證。

另請參考介紹了 pkgctl-license(1) 的這篇 Arch Linux 開發博客文章。

## 可復現構建

Arch 正努力使所有軟體包具有可復現性。打包人員可通過 devtools包 的 `makerepropkg` 或 archlinux-repro包 的 `repro` 來檢查包是否有可復現性：

    $ makerepropkg $pkgname-1-1-any.pkg.tar.zst

或

    $ repro -f $pkgname-1-1-any.pkg.tar.zst

如果在構建時需要使用時間戳，可以使用 `SOURCE_DATE_EPOCH` 環境變量，具體格式可參考上游文檔。

分類：​

- Arch 打包準則
- 包管理
- 包開發

隱藏分類：​

- 使用「模板:準確性」標記的頁面或章節

Arch 打包準則
新增話題