# 4.6.使用 Poudriere 构建软件包

poudriere 是一个采用 `BSD` 许可证的实用工具，用于创建和测试 FreeBSD 软件包。它通过 FreeBSD jail 创建隔离的编译环境。这些 jail 可用于为与当前系统版本不同的 FreeBSD 构建软件包，也可以在 amd64 主机上为 i386 构建软件包。构建完成后，生成的软件包布局与 FreeBSD 官方镜像相同，能被 [pkg(8)](https://man.freebsd.org/cgi/man.cgi?query=pkg\&sektion=8\&format=html) 及其他包管理工具使用。

poudriere 可通过 [ports-mgmt/poudriere](https://cgit.freebsd.org/ports/tree/ports-mgmt/poudriere/) 软件包或 port 安装。安装后会附带一个示例配置文件 `/usr/local/etc/poudriere.conf.sample`，可将其复制为 `/usr/local/etc/poudriere.conf` 并根据本地系统进行编辑。

虽然运行 poudriere 的系统不要求使用 `ZFS`，但使用 ZFS 有助于提升性能。启用 ZFS 时，需要在 `/usr/local/etc/poudriere.conf` 中设置 `ZPOOL`，并将 `FREEBSD_HOST` 设为附近的镜像站。定义 `CCACHE_DIR` 可启用 [devel/ccache](https://cgit.freebsd.org/ports/tree/devel/ccache/)，对重复编译的代码进行缓存，加快构建速度。建议将 poudriere 的数据集挂载到一个独立的目录（如 `/poudriere`）。大多数默认配置项通常已经足够。

系统会根据可用处理器核心数决定并行构建的数量。请确保系统具有足够的虚拟内存（`RAM` 或交换空间），否则 jail 会在构建时中止并被销毁，可能导致莫名其妙的错误信息。

## 4.6.1. 初始化 Jail 和 Ports 树

完成配置后，需要初始化 poudriere，使其安装所需的 FreeBSD jail 和 Ports 树。使用 `-j` 指定 jail 名称，`-v` 指定 FreeBSD 版本。在 FreeBSD/amd64 系统上，也可使用 `-a` 指定架构（`i386` 或 `amd64`），默认使用 `uname` 输出的架构：

```sh
# poudriere jail -c -j 13amd64 -v 13.1-RELEASE
```

然后拉取并初始化一个 ports 树：

```sh
# poudriere ports -c -p local -m git+https
```

poudriere 支持在单机上构建多个配置的 ports，分别使用不同的 jail、ports 树和配置集合（*sets*）。关于 set 的详细内容，请参阅 [poudriere(8)](https://man.freebsd.org/cgi/man.cgi?query=poudriere\&sektion=8\&format=html) 中的 CUSTOMIZATION 部分。

以下是基本配置示例：为每一个 jail/ports/set 组合提供一个专用的 `make.conf` 文件，命名规则为 `<jail>-<ports>-<set>-make.conf`。该文件与系统的 `make.conf` 合并后，将用于构建。

要构建的软件包列表写入 `13amd64-local-workstation-pkglist` 文件（带有 [FLAVORS](https://docs.freebsd.org/en/books/porters-handbook/flavors) 的 ports 使用 @FLAVOR 指定）：

```sh
editors/emacs
devel/git
devel/php-composer2@php82
ports-mgmt/pkg
...
```

配置这些 port 的选项与依赖：

```sh
# poudriere options -j 13amd64 -p local -z workstation -f 13amd64-local-workstation-pkglist
```

开始构建并生成软件包仓库：

```sh
# poudriere bulk -j 13amd64 -p local -z workstation -f 13amd64-local-workstation-pkglist
```

构建过程中按下 <kbd>Ctrl</kbd>+<kbd>t</kbd> 可查看当前构建状态。构建日志会保存于 `/poudriere/logs/bulk/jailname`，可通过 Web 服务器查看构建详情。

构建完成后，新生成的软件包可通过 poudriere 提供的软件仓库进行安装。

如需了解更多内容，请参阅 [poudriere(8)](https://man.freebsd.org/cgi/man.cgi?query=poudriere\&sektion=8\&format=html) 和 poudriere 官方页面 <https://github.com/freebsd/poudriere/wiki>。

## 4.6.2. 配置 pkg 客户端使用 poudriere 仓库

虽然可以同时使用自定义软件包仓库与官方仓库，但有时更希望禁用官方仓库。这可以通过创建一个覆盖官方配置的文件来实现。创建 `/usr/local/etc/pkg/repos/FreeBSD.conf`，内容如下：

```ini
FreeBSD: {
	enabled: no
}
```

通常最方便的做法是通过 HTTP 将 poudriere 软件包仓库提供给客户端访问。可以通过 Web 服务器提供仓库目录，例如 `/usr/local/poudriere/data/packages/13amd64`，其中 `13amd64` 是构建名。

假设软件包仓库的 URL 是 [`http://pkg.example.com/13amd64`](http://pkg.example.com/13amd64)，那么应在 `/usr/local/etc/pkg/repos/custom.conf` 中创建如下配置文件：

```ini
custom: {
	url: "http://pkg.example.com/13amd64",
	enabled: yes,
}
```

如果不希望将软件包仓库暴露在互联网中，可以使用 `file://` 协议直接指向本地路径，例如：

```ini
custom: {
	url: "file:///usr/local/poudriere/data/packages/11amd64",
	enabled: yes,
}
```
