makepkg

出自 Arch Linux 中文维基

makepkg是一個軟體包自動編譯腳本。使用時需要一個 Unix 環境和 PKGBUILD.

makepkg 是由 pacman 包提供的。

配置[編輯 | 編輯原始碼]

makepkg 的詳細配置選項可以通過 makepkg.conf(5) 查詢。

/etc/makepkg.conf 是 makepkg 的主配置文件。用戶的自定義配置位於 $XDG_CONFIG_HOME/pacman/makepkg.conf~/.makepkg.conf. 建議用戶在編譯軟體包之前檢查 makepkg 配置。

打包人信息[編輯 | 編輯原始碼]

每個軟體包都會有元數據信息,其中就包含 packager. 默認情況下,用戶自己打包的軟體標記為 Unknown Packager. 如果多個用戶會在系統上編譯,或者需要發布軟體包給其他人,最好提供真實的聯繫人。可以通過 makepkg.conf 中的 PACKAGER 變量設置。

檢查安裝軟體包的打包人:

pacman -Qi package
...
Packager       : Unknown Packager
...

修改之後:

pacman -Qi package
...
Packager       : John Doe <john@doe.com>
...

要自動簽名過程,請同時在 makepkg.conf 中設置 GPGKEY 變量.

包輸出[編輯 | 編輯原始碼]

makepkg 默認會在工作目錄創建軟體包,並把原始碼下載到 src/ 目錄。可以配置到自定義的路徑,比如所有安裝的軟體包放到 ~/build/packages/,所有原始碼放到 ~/build/sources/.

配置以下makepkg.conf,如果需要配置變量:

  • PKGDEST - 目錄中存儲產生的包
  • SRCDEST - 目錄中存儲的source 數據 (符號連結將被放置到 src/ 如果點其他地方)
  • SRCPKGDEST - 目錄存儲產生的原始碼包 (構建用 makepkg -S)
提示:可以用 paccache -c ~/build/packages/ 清理 PKGDEST 目錄。

驗證簽名[編輯 | 編輯原始碼]

注意: makepkg 中的簽名驗證並不使用 pacman 的密鑰環, 而是使用用戶的密鑰[1]

如果簽名文件是以 .sig.asc 形式作為 PKGBUILD 代碼的一部分,makepkg 會自動驗證 軟體包. 如果用戶未提供需要的簽名公鑰,makepkg 會停止安裝過程並提示用戶說無法驗證 PGP 密鑰。

如果缺少公鑰或希望其他開發者進行簽名,可以手動 導入或通過 密鑰伺服器 導入。要臨時禁用簽名檢查請在執行 makepkg 命令時加上 --skippgpcheck 選項。

使用[編輯 | 編輯原始碼]

繼續之前,確保 base-devel包組 軟體組已經安裝。屬於這個組的軟體包不會列在 PKGBUILD 文件的依賴中。

注意:
  • Make sure sudo is configured properly for commands passed to pacman.
  • Running makepkg itself as root is disallowed.[2] Besides how a PKGBUILD may contain arbitrary commands, building as root is generally considered unsafe.[3] Users who have no access to a regular user account should run makepkg as the nobody user.

要編譯軟體包,用戶必須首先建立一個 PKGBUILD,或者編譯腳本(在 創建軟體包 中有詳細描述),或者從 ABS 編譯系統Arch User Repository 或其他來源獲取。

警告: 只從信任的來源編譯和/或安裝軟體包。

擁有一個 PKGBUILD 之後,切換到存放這個文件的目錄,輸入下面的命令編譯 PKGBUILD 描述的軟體包:

$ makepkg

如果需要的依賴不滿足,makepkg 會輸出一個警告然後失敗。想要編譯軟體包然後自動安裝必須的依賴,只需要輸入以下命令:

$ makepkg --syncdeps

注意這些依賴必須在已配置的軟體源之中。另外,用戶也可以在編譯前手動安裝需要的依賴(pacman -S --asdeps dep1 dep2)。如果添加了 -r/--rmdeps 選項,makepkg 會在結束前刪除不再需要的編譯依賴,如果需要持續編譯軟體包,請考慮使用 刪除未使用軟體包 的方式處理。

一旦所有的依賴都滿足並且軟體包成功編譯,一個軟體包文件 (pkgname-pkgver.pkg.tar.zst) 會在工作目錄下創建。想安裝,運行

$ makepkg --install

要清空殘餘的文件和目錄,例如解壓到 $srcdir 的文件,輸入下面的選項。這對於在使用同一個文件夾多次編譯同一個軟體包或者升級軟體包版本時很有用。它防止過期的或殘餘的文件呈遞到新的編譯任務中。

$ makepkg --clean

更多信息請閱讀makepkg(8).

使用技巧[編輯 | 編輯原始碼]

減少下載和解壓時間[編輯 | 編輯原始碼]

編譯 VCS 軟體包時,使用 SRCDEST 可以縮短獲取和解壓原始碼的時間。

編譯結果優化[編輯 | 編輯原始碼]

在使用 makepkg 編譯軟體時,make, gccg++ 會使用 CFLAGSCXXFLAGS 選項。默認情況下,這些選項產生的是通用的包,可以在不同的機器上安裝。使用針對目標機器的設置,可以獲得性能提升,但編譯出的包也許無法在其他機器上運行。

注意: 記住不是所有的包創建系統都會使用你設置的變量。一些包的 Makefiles 或者 PKGBUILD文件會覆蓋設置。
/etc/makepkg.conf
...

#########################################################################
# ARCHITECTURE, COMPILE FLAGS
#########################################################################
#
CARCH="x86_64"
CHOST="x86_64-unknown-linux-gnu"

#-- Exclusive: will only run on x86_64
# -march (or -mcpu) builds exclusively for an architecture
# -mtune optimizes for an architecture, but builds for whole processor family
CFLAGS="-march=x86-64 -mtune=generic -O2 -pipe -fstack-protector --param=ssp-buffer-size=4 -D_FORTIFY_SOURCE=2"
CXXFLAGS="-march=x86-64 -mtune=generic -O2 -pipe -fstack-protector --param=ssp-buffer-size=4 -D_FORTIFY_SOURCE=2"
LDFLAGS="-Wl,-O1,--sort-common,--as-needed,-z,relro"
#-- Make Flags: change this for DistCC/SMP systems
#MAKEFLAGS="-j2"

...

默認的 makepkg.conf CFLAGSCXXFLAGS 是與所有機器各自的體系結構兼容的。

並不是所有的編譯系統都使用 makepkg.conf 中定義的變量。例如, cmake 不會遵循 CPPFLAGS。所以 PKGBUILD 中會直接指定需要的配置。

原始碼 Makefile 或編譯命令行中指定的選項優先級更高,會取代 makepkg.conf 中的設置。

在 x86_64 機器上,不要花費時間進行編譯選項優化,絕大部分情況下優化效果都不明顯。使用非標準的 CFLAGS 非常容易降低性能,因為編譯器傾向於快速增大生成的文件,例如解開循環、錯誤的向量化和非理性的內聯函數。除非通過測評得出性能提升的結論,否則最好不要做優化。

GCC 的手冊頁面有完整的選項列表。GCC optimizationSafe CFLAGS wiki 文章提供了深入信息。

GCC 可以進行 CPU 自動檢測,可以在編譯時自動選擇本地機器支持的優化。要使用它,刪除所有 -march-mtune,然後添加 -march=native. 例如:

/etc/makepkg.conf
CFLAGS="-march=native -O2 -pipe -fno-plt"
CXXFLAGS="${CFLAGS}"

要查看march=native啟用的選項,運行:

 $ gcc -march=native -v -Q --help=target
  • 如果沒有指定 -march=native, -Q --help=target不會 起作用。[4] 需要通過一個編譯過程確定真正使用的選項是哪個,請參考 Gentoo:Safe CFLAGS#Manual

生成新 md5sums[編輯 | 編輯原始碼]

pacman 4.1 pacman-contrib 和其中的 updpkgsums 已經 合併 進入 pacman,生成和替換 PKGBUILD 中的校驗和:

$ updpkgsums

Starting in pacman version 5.2.2, makepkg.conf also includes overrides for the RUSTFLAGS environment variable, for flags given to the Rust compiler. The Rust compiler can also detect and enable architecture-specific optimizations by adding -C target-cpu=native to the given RUSTFLAGS value:

/etc/makepkg.conf
RUSTFLAGS="-C opt-level=2 -C target-cpu=native"

To see which CPU features this will enable, run:

$ rustc -C target-cpu=native --print cfg

Running --print cfg without -C target-cpu=native will print the default configuration. The opt-level parameter can be changed to 3, s, or z as desired. See The Rust compiler's documentation for details.

減少編譯時間[編輯 | 編輯原始碼]

並行編譯[編輯 | 編輯原始碼]

make 編譯系統使用 MAKEFLAGS 環境變量 指定 make 的額外選項。這個值也可以在 makepkg.conf 中進行設置。

使用多核系統的用戶可以設定同時運行的任務數。可以用nproc獲得可用處理器的個數,如果結果是 4, 則使用-j4. 有些 PKGBUILD 強制使用 -j1,因為某些版本會產生衝突或者軟體包並不支持。如果出現軟體包因為此原因無法編譯,請在 bug 系統中報告

完整的選項請閱讀 make(1)

使用內存文件系統進行編譯[編輯 | 編輯原始碼]

編譯過程需要大量的讀寫操作,要處理很多小文件。將工作目錄移動到 tmpfs 可以減少編譯時間。

使用BUILDDIR變量可以臨時將 makepkg 的編譯目錄設置到 tmpfs:

$ BUILDDIR=/tmp/makepkg makepkg

修改 makepkg.confBUILDDIR 選項可以永久變更編譯目錄。設置此變量為BUILDDIR=/tmp/makepkg可以利用 Arch 默認臨時文件系統的/tmp

注意:
  • tmpfs 中構建大型軟體包時可能會內存不足。
  • tmpfs 目錄掛載時不能使用 noexec 選項,否則編譯命令無法執行。
  • tmpfs 中編譯的文件重啟後會消失,設置 PKGDEST 選項可以將構建結果保存到其它目錄。

ccache[編輯 | 編輯原始碼]

ccache 可以將編譯結果緩存起來供下次編譯使用,減少編譯時間。

生成新校驗和[編輯 | 編輯原始碼]

安裝 pacman-contrib,然後用下面命令生成新校驗和並替換 PKGBUILD 中的內容,只需要執行:

$ updpkgsums

updpkgsums uses makepkg --geninteg to generate the checksums. See this forum discussion for more details.

可以用 sha256sum 命令生成校驗和並手動加入 sha256sums

使用其它壓縮算法[編輯 | 編輯原始碼]

為了加快打包和安裝速度,您可以更改 PKGEXT ,代價是生成的軟體包文件更大。例如,以下命令可以讓此次調用生成不壓縮的軟體包:

$ PKGEXT='.pkg.tar' makepkg

另一個使用 lz4 算法的例子:

$ PKGEXT='.pkg.tar.lz4' makepkg

要使這些設置之一永久生效,請在 /etc/makepkg.conf 中設置 PKGEXT

在壓縮時使用多個CPU核心[編輯 | 編輯原始碼]

zstd supports symmetric multiprocessing (SMP) via the --threads flag to speed up compression. For example, to let makepkg use as many CPU cores as possible to compress packages, edit COMPRESSZST array in /etc/makepkg.conf:

COMPRESSZST=(zstd -c -z -q --threads=0 -)

xz supports symmetric multiprocessing (SMP) via the --threads flag to speed up compression. For example, to let makepkg use as many CPU cores as possible to compress packages, edit COMPRESSXZ array in /etc/makepkg.conf:

COMPRESSXZ=(xz -c -z --threads=0 -)

pigz is a drop-in, parallel implementation for gzip which by default uses all available CPU cores (the -p/--processes flag can be used to employ less cores):

COMPRESSGZ=(pigz -c -f -n)

pbzip2 is a drop-in, parallel implementation for bzip2 which also uses all available CPU cores by default. The -p# flag can be used to employ less cores (note: no space between the -p and number of cores).

COMPRESSBZ2=(pbzip2 -c -f)

lbzip2 is another drop-in, parallel implementation for bzip2 which also uses all available CPU cores by default. The -n flag can be used to employ less cores.

COMPRESSBZ2=(lbzip2 -c -f)

plzipAUR is a multithreaded implementation for lzip which also uses all available CPU cores by default. The -n/--threads flag can be used to employ less cores.

COMPERSSLZ=(plzip -c -f)

Show packages with specific packager[編輯 | 編輯原始碼]

expac is a pacman database extraction utility. This command shows all packages installed on the system with the packager named packagername:

$ expac "%n %p" | grep "packagername" | column -t

This shows all packages installed on the system with the packager set in the /etc/makepkg variable PACKAGER. This shows only packages that are in a repository defined in /etc/pacman.conf.

$ . /etc/makepkg.conf; grep -xvFf <(pacman -Qqm) <(expac "%n\t%p" | grep "$PACKAGER$" | cut -f1)

Build 32-bit packages on a 64-bit system[編輯 | 編輯原始碼]

See 32-bit package guidelines.

Unattended package signing[編輯 | 編輯原始碼]

本文或本章節可能需要合併到GnuPG#Unattended_passphrase

附註: This is not specific to makepkg(在 Talk:Makepkg 中討論)

這篇文章的某些內容需要擴充。

原因: Another option is gnupg-set-passphrase(1)[失效連結 2022-06-25] (在 Talk:Makepkg 中討論)

A person may not be available to provide the passphrase for the gpg private key used to sign with in automated build environments such as Jenkins. It is ill-advised to store a private gpg key on a system without a passphrase.

A resulting zst package made with makepkg can still be be signed after creation:

$ gpg --detach-sign --pinentry-mode loopback --passphrase --passphrase-fd 0 --output NewlyBuilt.pkg.tar.zst.sig --sign NewlyBuilt.pkg.tar.zst 

where the GPG passphrase is securely provided and obscured by your automation suite of choice.

The resulting zst and sig file can be referenced by pacman clients expecting a valid signature and repositories created with repo-add --sign when hosting your own repo.

Magnet URIs[編輯 | 編輯原始碼]

Support for magnet URIs resources (with magnet:// prefix) in the source field can be added using the transmission-dlagentAUR download agent.

問題處理[編輯 | 編輯原始碼]

Specifying install directory for QMAKE based packages[編輯 | 編輯原始碼]

The makefile generated by qmake uses the environment variable INSTALL_ROOT to specify where the program should be installed. Thus this package function should work:

PKGBUILD
...
package() {
	cd "$srcdir/${pkgname%-git}"
	make INSTALL_ROOT="$pkgdir" install
}
...

Note, that qmake also has to be configured appropriately. For example put this in the corresponding .pro file:

YourProject.pro
...
target.path = /usr/local/bin
INSTALLS += target
...

WARNING: Package contains reference to $srcdir[編輯 | 編輯原始碼]

有時 $pkgdir$srcdir 進入了軟體包中的文件,用下面命令檢查:

grep -R "$(pwd)/src" pkg/

一個可能是 C/++ 代碼使用了 __FILE__ 宏並將完整路徑傳遞給了編譯器。

Makepkg fails to download dependencies when behind proxy[編輯 | 編輯原始碼]

When makepkg calls dependencies, it calls pacman to install the packages, which requires administrative privileges via sudo. However, sudo does not pass any environment variables to the privileged environment, and includes the proxy-related variables ftp_proxy, http_proxy, https_proxy, and no_proxy.

In order to have makepkg working behind a proxy, invoke one of the following methods.

Enable proxy by setting its URL in XferCommand[編輯 | 編輯原始碼]

The XferCommand can be set to use the desired proxy URL in /etc/pacman.conf. Add or uncomment the following line in pacman.conf[5]:

/etc/pacman.conf
...
XferCommand = /usr/bin/curl --proxy
http://username:password@proxy.proxyhost.com:80 --location --continue-at - --fail --output %o %u
...

Enable proxy via sudoer's env_keep[編輯 | 編輯原始碼]

Alternatively, one may want to use sudoer's env_keep option, which enables preserving given variables the privileged environment. See Pacman#Pacman does not honor proxy settings for more details.

Makepkg fails, but make succeeds[編輯 | 編輯原始碼]

If something successfully compiles using make, but fails through makepkg, it is almost certainly because /etc/makepkg.conf sets an incompatible compilation variable. Try adding these flags to the PKGBUILD options array:

!buildflags, to prevent its default CPPFLAGS, CFLAGS, CXXFLAGS, and LDFLAGS.

!makeflags, to prevent its default MAKEFLAGS.

!debug, to prevent its default DEBUG_CFLAGS, and DEBUG_CXXFLAGS, in case the PKGBUILD is a debug build.

If any of these fix the problem, this could warrant an upstream bug report assuming the offending flag has been identified.

參閱[編輯 | 編輯原始碼]