makepkg (简体中文)
相关文章
makepkg是一个软件包自动编译脚本。使用时需要一个 Unix 环境和 PKGBUILD.
makepkg 是由 pacman 包提供的。
配置
makepkg 的详细配置选项可以通过 man makepkg.conf
查询。
/etc/makepkg.conf
是 makepkg 的主配置文件。用户的自定义配置位于 $XDG_CONFIG_HOME/pacman/makepkg.conf
或 ~/.makepkg.conf
. 建议用户在编译软件包之前检查 makepkg 配置。
包输出
配置源文件和包的输出路径,以及打包者的信息。这一步是可选的;默认情况下包会在 makepkg 运行的工作路径下创建。
例如,创建目录:
$ mkdir /home/$USER/packages
然后照此修改 /etc/makepkg.conf
中的PKGDEST
变量。
PACKAGER
变量会设置包的.PKGINFO
元数据文件中的 packager
值。默认情况下,用户编译的包会显示:
pacman -Qi package
... Packager : Unknown Packager ...
修改之后:
pacman -Qi package
... Packager : John Doe <john@doe.com> ...
这对于多个用户在一个系统上编译软件包时,以及将包给其他用户时很有用。
验证签名
编译时并不需要下面操作,首次配置,请查看用法部分。要临时禁用签名检查请在执行 makepkg 命令时加上 --skippgpcheck
选项。
如果 .sig 签名文件是 PKGBUILD 代码的一部分,makepkg 会验证源代码。例如 pkgname-pkgver.tar.gz.sig 会被 gpg 用来验证 pkgname-pkgver.tar.gz 的完整性。如果需要,其它开发者的签名也能手动添加到 gpg 密钥环,方法参阅GnuPG。
gpg 密钥应该保存在~/.gnupg/pubring.gpg
文件中,如果其中不包含需要的签名,makepkg 会显示警告.
$ makepkg
... ==> Verifying source file signatures with gpg... pkgname-pkgver.tar.gz ... FAILED (unknown public key 1234567890) ==> WARNING: Warnings have occurred while verifying the signatures. Please make sure you really trust them. ...
要显示当前使用的密钥:
$ gpg --list-keys
如果 pubring.gpg 文件不存在,会被立即创建。
要让 gpg 验证 Arch 开发者提交的 AUR 软件包。将如下内容加到 gpg 配置文件的末尾:
~/.gnupg/gpg.conf
... keyring /etc/pacman.d/gnupg/pubring.gpg
gpg --list-keys
的输出就会包含开发者的密钥。
使用方法
继续之前,确保 base-devel 软件组已经安装。属于这个组的软件包不会列在 PKGBUILD 文件的依赖中。输入以下命令安装 base-devel 软件包组 (用 root 运行):
# pacman -S base-devel
要编译软件包,用户必须首先建立一个 PKGBUILD,或者编译脚本(在 创建软件包 中有详细描述),或者从 ABS tree、 Arch User Repository 或其他来源获取。
拥有一个 PKGBUILD
之后,切换到存放这个文件的目录,输入下面的命令编译 PKGBUILD
描述的软件包:
$ makepkg
如果需要的依赖不满足,makepkg 会输出一个警告然后失败。想要编译软件包然后自动安装必须的依赖,只需要输入以下命令:
$ makepkg -s
注意这些依赖必须在已配置的软件源之中。参见 pacman#Repositories 获取更多细节。另外,用户也可以在编译前手动安装需要的依赖(pacman -S --asdeps dep1 dep2
)。
一旦所有的依赖都满足并且软件包成功编译,一个软件包文件 (pkgname-pkgver.pkg.tar.xz
) 会在工作目录下创建。想安装,运行
$ makepkg -i
要清空残余的文件和目录,例如解压到 $srcdir 的文件,输入下面的选项。这对于在使用同一个文件夹多次编译同一个软件包或者升级软件包版本时很有用。它防止过期的或残余的文件呈递到新的编译任务中。
$ makepkg -c
Arch Linux 软件包可以通过 makepkg 自动签名:
$ makepkg --sign --key <key-id>
更多信息请阅读makepkg(8).
使用技巧
体系结构,编译标志
在使用 makepkg 编译软件时,make, gcc 和 g++
会使用 MAKEFLAGS
, 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
是与所有机器各自的体系结构兼容的。
在 x86_64 机器上,不要花费时间进行编译选项优化,绝大部分情况下优化效果都不明显。
从 4.3.0 版本开始, GCC 提供了 -march=native
开关,可以进行 CPU 自动检测,可以在编译时自动选择本地机器支持的优化。要使用它,只需修改默认设置,将 CFLAGS
和 CXXFLAGS
修改为:
# -march=native also sets the correct -mtune= CFLAGS="-march=native -O2 -pipe -fstack-protector --param=ssp-buffer-size=4 -D_FORTIFY_SOURCE=2" CXXFLAGS="${CFLAGS}"
理论上,根据 CPU 做进一步优化可以提高性能,因为 -march=native
启用了所有的指令集,提高了某些 CPU 的调度效率。特别是重新编译比较依赖 Arch Linux 默认没有打开指令集的程序,音频视频编码、科学计算和具有大量运算的程序等。
然而,使用非标准的 CFLAGS 非常容易降低性能,因为编译器倾向于快速增大生成的文件,例如解开循环、错误的向量化和非理性的内联函数。除非通过测评得出性能提升的结论,否则最好不要做优化。
GCC 的手册页面有完整的选项列表。Gentoo 编译器优化指南 和 安全 Cflags wiki 文章提供了深入信息。
MAKEFLAGS
MAKEFLAGS
选项可以用来指定 make 的额外选项。使用多核系统的用户可以设定同时运行的任务数。可以用nproc
获得可用处理器的个数,如果结果是 4, 则使用-j4
. 有些 PKGBUILD 强制使用 -j1
,因为某些版本会产生冲突或者软件包并不支持。如果出现软件包因为此原因无法编译,请在 bug 系统中报告。
完整的选项请阅读 man make
。
生成新 md5sums
从 pacman 4.1 pacman-contrib 和其中的 updpkgsums
已经 合并 进入 pacman,生成和替换 PKGBUILD 中的校验和:
$ updpkgsums
减少编译时间
tmpfs
编译过程需要大量的读写操作,要处理很多小文件。将工作目录移动到 tmpfs 可以减少编译时间。
使用BUILDDIR
变量可以临时将 makepkg 的编译目录设置到 tmpfs:
$ BUILDDIR=/tmp/makepkg makepkg
修改 makepkg.conf
的 BUILDDIR
选项可以永久变更编译目录。Arch 的默认 tmpfs 目录是 /tmp
. 此变量可以设置为:BUILDDIR=/tmp/makepkg
。
ccache
ccache 可以将编译结果缓存起来,减少编译时间。
生成新校验和
Pacman 包含了 updpkgsums
脚本,可以生成新校验和并替换 PKGBUILD 中的内容,只需要执行:
$ updpkgsums
创建非压缩软件包
如果只是本地安装,可以用下面设置跳过 LZMA2 压缩和解压缩:
/etc/makepkg.conf
[...] #PKGEXT='.pkg.tar.xz' PKGEXT='.pkg.tar' [...]
Utilizing multiple cores on compression
xz supports symmetric multiprocessing (SMP) on compression. This can be done by using the -T 0
/--threads=0
flag, which makes xz use as many threads as there are cores on the system:
/etc/makepkg.conf
[...] COMPRESSXZ=(xz -T 0 -c -z -) [...]
问题处理
Makepkg sometimes fails to sign a package without asking for signature passphrase
With gnupg 2.1, gpg-agent no longer has to be started manually and will be started automatically on the first invokation of gpg. Thus if you do not manually start gpg-agent, makepkg will start it.
The problem is that makepkg runs gpg inside a fakeroot, so gpg-agent is also started in that same environment. This leads to bad behavior. The obvious remedy is to manually start the gpg-agent, either on boot or by command, before you run makepkg.
See GnuPG#gpg-agent for ways to do this.
CFLAGS/CXXFLAGS/CPPFLAGS in makepkg.conf do not work for QMAKE based packages
Qmake automatically sets the variable CFLAGS
and CXXFLAGS
according to what it thinks should be the right configuration. In order to let qmake use the variables defined in the makepkg configuration file, you must edit the PKGBUILD and pass the variables QMAKE_CFLAGS_RELEASE and QMAKE_CXXFLAGS_RELEASE to qmake. For example:
PKGBUILD
... build() { cd "$srcdir/$_pkgname-$pkgver-src" qmake-qt4 "$srcdir/$_pkgname-$pkgver-src/$_pkgname.pro" \ PREFIX=/usr \ CONFIG+=LINUX_INTEGRATED \ INSTALL_ROOT_PATH="$pkgdir"\ QMAKE_CFLAGS_RELEASE="${CFLAGS}"\ QMAKE_CXXFLAGS_RELEASE="${CXXFLAGS}" make } ...
Alternatively, for a system wide configuration, you can create your own qmake.conf
and set the QMAKESPEC environment variable.
WARNING:Referencing $srcdir in PKGBUILD
有时 $pkgdir
或 $srcdir
进入了软件包中的文件,用下面命令检查:
grep -R "$(pwd)/src" pkg/
讨论此问题的[链接]。
See also
参阅
- gcccpuopt: 一个根据当前 CPU,输出 cpu 专有选项的脚本