makepkg
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
目錄。驗證簽名[編輯 | 編輯原始碼]
如果簽名文件是以 .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包, gcc包 和 g++
會使用 CFLAGS
和 CXXFLAGS
選項。默認情況下,這些選項產生的是通用的包,可以在不同的機器上安裝。使用針對目標機器的設置,可以獲得性能提升,但編譯出的包也許無法在其他機器上運行。
/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 CFLAGS
和 CXXFLAGS
是與所有機器各自的體系結構兼容的。
並不是所有的編譯系統都使用 makepkg.conf
中定義的變量。例如, cmake 不會遵循 CPPFLAGS
。所以 PKGBUILD 中會直接指定需要的配置。
原始碼 Makefile
或編譯命令行中指定的選項優先級更高,會取代 makepkg.conf
中的設置。
在 x86_64 機器上,不要花費時間進行編譯選項優化,絕大部分情況下優化效果都不明顯。使用非標準的 CFLAGS 非常容易降低性能,因為編譯器傾向於快速增大生成的文件,例如解開循環、錯誤的向量化和非理性的內聯函數。除非通過測評得出性能提升的結論,否則最好不要做優化。
GCC 的手冊頁面有完整的選項列表。GCC optimization 和 Safe 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.conf
的 BUILDDIR
選項可以永久變更編譯目錄。設置此變量為BUILDDIR=/tmp/makepkg
可以利用 Arch 默認臨時文件系統的/tmp
。
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[編輯 | 編輯原始碼]
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.