# makepkg (简体中文)

相关文章

- Creating packages
- PKGBUILD (简体中文)
- Arch User Repository (简体中文)
- pacman (简体中文)
- Official Repositories (简体中文)
- Arch Build System (简体中文)

翻译状态： 本文是英文页面 Makepkg 的翻译，最后翻译时间：2013-04-08，点击这里可以查看翻译后英文页面的改动。

makepkg用来编译和创建可以用 pacman(Arch Linux 的包管理器)安装的软件包。makepkg 是一个脚本，可以自动化包的创建过程。它可以下载和校验源文件，检查依赖，配置编译时设置，编译源代码，安装到一个临时的 root，个性化修改，生成元数据，然后把所有文件打包到一起。

makepkg 是由 pacman 包提供的。

## 配置

`/etc/makepkg.conf` 是 makepkg 的主配置文件。大多数用户希望在编译任何包之前有一个仔细调节好的 makepkg 配置。

### 体系结构，编译标志

在使用 makepkg 编译软件时，make, gcc 和 `g++` 会使用 `MAKEFLAGS`, `CFLAGS` 和 `CXXFLAGS` 选项。默认情况下，这些选项产生的是通用的包，可以在不同的机器上安装。使用针对目标机器的设置，可以获得性能提升，但编译出的包也许无法在其他机器上运行。

注意: 记住不是所有的包创建系统都会使用你设置的变量。一些包的 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 `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}"

Tip: 要查看`march=native`启用的选项，运行：

    $ gcc -march=native -E -v - </dev/null 2>&1 | sed -n 's/.* -v - //p'

理论上，根据 CPU 做进一步优化可以提高性能，因为 `-march=native` 启用了所有的指令集，提高了某些 CPU 的调度效率。特别是重新编译比较依赖 Arch Linux 默认没有打开指令集的程序，音频视频编码、科学计算和具有大量运算的程序等。

然而，使用非标准的 CFLAGS 非常容易降低性能，因为编译器倾向于快速增大生成的文件，例如解开循环、错误的向量化和非理性的内联函数。除非通过测评得出性能提升的结论，否则最好不要做优化。

GCC 的手册页面有完整的选项列表。Gentoo 编译器优化指南 和 安全 Cflags wiki 文章提供了深入信息。

#### MAKEFLAGS

`MAKEFLAGS` 选项可以用来指定 make 的额外选项。使用多核系统的用户可以设定同时运行的任务数。可以用`nproc`获得可用处理器的个数，如果结果是 4， 则使用`-j4`. 有些 PKGBUILD 强制使用 `-j1`，因为某些版本会产生冲突或者软件包并不支持。如果出现软件包因为此原因无法编译，请在 bug 系统中报告。

完整的选项请阅读 `man make`。

### 包输出

下一步，你可以配置源文件和包的输出路径，以及打包者的信息。这一步是可选的；默认情况下包会在 makepkg 运行的工作路径下创建。

    /etc/makepkg.conf

    ...

    #########################################################################
    # PACKAGE OUTPUT
    #########################################################################
    #
    # Default: put built package and cached source in build directory
    #
    #-- Destination: specify a fixed directory where all packages will be placed
    #PKGDEST=/home/packages
    #-- Source cache: specify a fixed directory where source files will be cached
    #SRCDEST=/home/sources
    #-- Source packages: specify a fixed directory where all src packages will be placed
    #SRCPKGDEST=/home/srcpackages
    #-- Packager: name/email of the person or organization building packages
    #PACKAGER="John Doe <john@doe.com>"

    ...

例如，创建目录：

    $ 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 代码的一部分，会验证源代码。例如 pkgname-pkgver.tar.gz.sig 会被 gpg 用来验证 pkgname-pkgver.tar.gz 的完整性。如果需要，其它开发者的签名也能手动添加到 gpg 密钥环，方法参阅GnuPG。

注意: makepkg 中的签名验证并不使用 pacman 的密钥环。用如下方法配置 makepkg 就可以读取 pacman 的密钥环。

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

注意: 在抱怨丢失(编译)依赖之前，记得 base 组是被视为在所有的 Arch Linux 系统中安装的。在使用 makepkg 编译时，base-devel 组默认假设安装过。

要编译软件包，用户必须首先建立一个 PKGBUILD，或者编译脚本(在 创建软件包 中有详细描述)，或者从 ABS tree、 Arch User Repository 或其他来源获取。

警告: 只从信任的来源编译和/或安装软件包。

拥有一个 `PKGBUILD` 之后，切换到存放这个文件的目录，输入下面的命令编译 `PKGBUILD` 描述的软件包：

    $ makepkg

想要让 makepkg 清空残余的文件和目录，例如解压到 $srcdir 的文件，输入下面的选项。这对于在使用同一个文件夹多次编译同一个软件包或者升级软件包版本时很有用。它防止过期的或残余的文件呈递到新的编译任务中。

    $ makepkg -c

如果需要的依赖不满足，makepkg 会输出一个警告然后失败。想要编译软件包然后自动安装必须的依赖，只需要输入以下命令：

    $ makepkg -s

注意这些依赖必须在已配置的软件源之中。参见 pacman#Repositories 获取更多细节。另外，用户也可以在编译前手动安装需要的依赖(`pacman -S --asdeps dep1 dep2`)。

一旦所有的依赖都满足并且软件包成功编译，一个软件包文件 (`pkgname-pkgver.pkg.tar.xz`) 会在工作目录下创建。想安装，运行 (作为 root)：

    # pacman -U pkgname-pkgver.pkg.tar.xz

另外，想要安装的话，使用 `-i` 标识是一个比运行 `pacman -U pkgname-pkgver.pkg.tar.xz` 更简单的方法，即：

    $ makepkg -i

## 使用技巧

### Generate new md5sums

从 pacman 4.1 pacman-contrib 和其中的 `updpkgsums` 已经 合并 进入 pacman，生成和替换 PKGBUILD 中的校验和:

    $ updpkgsums

### Makepkg 两次引用 PKGBUILD

Makepkg 会引用 PKGBUILD 两次：一次是初始运行时，一次是位于 fakeroot 时，所有 PKGBUILD 中的非标准函数都会被执行两次。

### WARNING:Referencing $srcdir in PKGBUILD

有时 `$pkgdir` 或 `$srcdir` 进入了软件包中的文件，用下面命令检查：

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

讨论此问题的[链接]。

## 参阅

- gcccpuopt: 一个根据当前 CPU，输出 cpu 专有选项的脚本

Categories:

- Package development (简体中文)
- About Arch (简体中文)