# port test /usr/ports/net/csup
第 10 章:测试端口
目录
10.1. 运行 make describe
许多 FreeBSD 端口维护工具,例如 portupgrade(1),依赖于一个名为 /usr/ports/INDEX 的数据库,该数据库跟踪端口依赖关系等信息。 INDEX 由顶层 ports/Makefile 通过 make index
命令创建,该命令会进入每个端口子目录并执行 make describe
。 因此,如果在任何端口中 make describe
失败,则没有人能够生成 INDEX,并且许多人会很快变得不高兴。
无论 make.conf 中存在哪些选项,都必须能够生成此文件,因此请避免在(例如)依赖关系未满足时使用 |
如果 make describe
生成一个字符串而不是错误消息,则一切都可能安全。有关生成字符串的含义,请参见 bsd.port.mk。
另请注意,运行最新版本的 portlint
(如下一节所述)将导致自动运行 make describe
。
10.2. 运行 make test
即使端口构建正常,也建议确保软件能够正确地完成其预期功能。如果原始上游项目随软件一起提供测试,则建议运行这些测试并检查一切按预期工作。
端口可以通过使用 TEST_TARGET
变量自动启用测试。设置后,此变量包含端口测试目标的名称。这通常只是 test
,但其他名称包括 tests
、check
或针对特定情况的名称,例如 run_tests.py
。
除了 TEST_TARGET
变量之外,框架还提供以下变量来控制测试执行
TEST_WRKSRC
是执行测试的目录。TEST_ENV
包含传递到测试阶段的额外变量。TEST_ARGS
包含传递到测试阶段的任何额外参数。
在 cad/xyce、www/libjwt 等中可以找到这些变量的使用示例。
请确保测试在更新端口时不会中断。 |
10.3. Portclippy / Portfmt
这些工具来自 ports-mgmt/portfmt。
Portclippy 是一个 linter,它检查 Makefile 中的变量是否按 端口 Makefile 中变量的顺序 排列。
Portfmt 是一个用于自动格式化 Makefile 的工具。
10.4. Portlint
在提交或提交端口之前,请使用 portlint
检查该端口。portlint
会警告许多常见的错误,包括功能性和样式性错误。对于新端口,portlint -A
是最彻底的;对于现有端口,portlint -C
就足够了。
由于 portlint
使用启发式方法来尝试找出错误,因此它可能会产生误报。此外,有时被标记为问题的某些内容实际上由于端口框架的限制,无法以其他方式完成。如有疑问,最好的做法是在 FreeBSD 端口邮件列表 上咨询。
10.5. 端口工具
ports-mgmt/porttools 程序是 Ports Collection 的一部分。
port
是前端脚本,它可以帮助简化测试工作。每当需要测试新端口或对现有端口进行更新时,请使用 port test
测试该端口,包括 portlint
检查。此命令还会检测并列出 pkg-plist 中未列出的任何文件。例如
10.6. PREFIX
和 DESTDIR
PREFIX
决定端口将安装的位置。它默认设置为 /usr/local,但用户可以将其设置为自定义路径,例如 /opt。端口必须尊重此变量的值。
如果用户设置了 DESTDIR
,则它会确定完整的替代环境,通常是 jail 或安装在 / 以外位置的系统。端口实际上会安装到 DESTDIR/PREFIX 中,并在 DESTDIR/var/db/pkg 中向软件包数据库进行注册。端口基础架构会使用 chroot(8) 自动处理 DESTDIR
。无需修改或任何额外注意来编写与 DESTDIR
兼容的端口。
PREFIX
的值将设置为 LOCALBASE
(默认为 /usr/local)。如果设置了 USE_LINUX_PREFIX
,则 PREFIX
将为 LINUXBASE
(默认为 /compat/linux)。
在源代码中避免硬编码 /usr/local 路径,可以使端口更加灵活,并能够满足其他站点的需求。通常,这可以通过在端口的各种 Makefile 中用 ${PREFIX}
替换 /usr/local 的出现来实现。此变量会自动传递到构建和安装过程的每个阶段。
确保应用程序没有将东西安装到 /usr/local 而不是 PREFIX
中。对于此类硬编码路径的快速测试是
% make clean; make package PREFIX=/var/tmp/`make -V PORTNAME`
如果任何东西安装在 PREFIX
以外的位置,则软件包创建过程将抱怨它找不到文件。
此外,值得使用暂存目录支持检查相同的內容(参见 暂存)
% make stage && make check-plist && make stage-qa && make package
check-plist
检查 plist 中缺少的文件以及 plist 中未由端口安装的文件。stage-qa
检查常见的错误,例如错误的 shebang、指向暂存目录外部的符号链接、setuid 文件和未剥离的库……
这些测试不会查找端口文件内部的硬编码路径,也不会验证 LOCALBASE
是否被用来正确引用来自其他端口的文件。必须测试 /var/tmp/make -V PORTNAME
中临时安装的端口的正常运行情况,以确保路径没有问题。
PREFIX
必须不能在端口的 Makefile 中显式设置。安装端口的用户可能已将 PREFIX
设置为自定义位置,而端口必须尊重该设置。
使用上面提到的变量,而不是显式路径名,来引用来自其他端口的程序和文件。例如,如果端口需要一个宏 PAGER
来获取 less
的完整路径名,请不要使用 /usr/local/bin/less 的文字路径。而是使用 ${LOCALBASE}
-DPAGER=\"${LOCALBASE}/bin/less\"
使用 LOCALBASE
的路径更有可能在系统管理员将整个 /usr/local 树移动到其他位置时仍然有效。
运行 |
10.7. poudriere
对于端口贡献者来说,poudriere 是最重要的和最有帮助的测试和构建工具之一。它的主要功能包括
批量构建整个端口树、端口树的特定子集或单个端口及其依赖关系
自动打包构建结果
生成每个端口的构建日志文件
提供签名 pkg(8) 仓库
在向 FreeBSD 错误跟踪器提交补丁或提交到端口树之前测试端口构建
测试使用不同选项成功构建端口
不会污染主机环境:没有残留文件、没有意外删除、没有更改现有配置文件。
验证 pkg-plist 中缺少或多余的条目
端口提交者有时会要求在提交补丁时附带 poudriere 日志,以评估补丁是否已准备好集成到端口树中。
它也相当容易设置和使用,没有依赖关系,并且可以在任何支持的 FreeBSD 版本上运行。本节展示了如何在端口贡献者的正常工作流程中安装、配置和运行 poudriere。
本节中的示例显示了默认的文件布局,这是 FreeBSD 的标准。请根据任何本地更改进行相应的替换。端口树(由 ${PORTSDIR}
表示)位于 /usr/ports 中。默认情况下,${LOCALBASE}
和 ${PREFIX}
都是 /usr/local。
10.7.1. 安装 poudriere
poudriere 在端口树的 ports-mgmt/poudriere 中可用。可以使用 pkg(8) 或从端口中安装它
# pkg install poudriere
或
# make -C /usr/ports/ports-mgmt/poudriere install clean
还存在一个正在开发的 poudriere 版本,它最终将成为下一个版本。它在 ports-mgmt/poudriere-devel 中可用。此开发版本用于官方 FreeBSD 软件包构建,因此经过了充分的测试。它经常具有更新的有趣功能。端口提交者将希望使用开发版本,因为它是在生产中使用的,并且具有所有新功能,以确保一切都是完全正确的。贡献者不一定需要这些功能,因为最重要的修复程序会被移植到已发布的版本中。使用开发版本构建官方软件包的主要原因是它更快,在使用高端 32 CPU 服务器和 128GB RAM 时,可以将完整的构建时间从 18 小时缩短到 17 小时。在台式机上构建端口时,这些优化不会很重要。
10.7.2. 设置 poudriere
该端口安装了一个默认的配置文件 /usr/local/etc/poudriere.conf。每个参数都在配置文件中进行了说明。
以下是一个最小的配置文件示例
ZPOOL=zroot BASEFS=/usr/local/poudriere DISTFILES_CACHE=/usr/ports/distfiles RESOLV_CONF=/etc/resolv.conf
ZPOOL
poudriere 将使用的 ZFS 存储池的名称。必须在
zpool status
的输出中列出。BASEFS
poudriere 文件系统的根挂载点。此条目将导致 poudriere 将
tank/poudriere
挂载到/poudriere
。DISTFILES_CACHE
定义 distfiles 的存储位置。在此示例中,poudriere 和主机共享 distfiles 存储目录。这避免了下载系统上已存在的 tarballs。如果此目录尚不存在,请创建它,以便 poudriere 可以找到它。
RESOLV_CONF
在 jail 内使用主机 /etc/resolv.conf 进行 DNS 解析。这需要 jail 在下载 distfiles 时能够解析它们的 URL。使用代理时不需要它。有关代理配置,请参阅默认配置文件。
10.7.3. 创建 poudriere Jails
创建 poudriere 将用于构建的基本 jail
# poudriere jail -c -j 131Ramd64 -v 13.1-RELEASE -a amd64
从 poudriere.conf 中的 FREEBSD_HOST
给定的 FTP 服务器获取 13.1-RELEASE
(适用于 amd64
),创建 zfs 文件系统 tank/poudriere/jails/131Ramd64
,将其挂载到 /poudriere/jails/131Ramd64 上,并将 13.1-RELEASE
tarballs 提取到此文件系统中。
# poudriere jail -c -j 12i386 -v stable/12 -a i386 -m git+https
创建 tank/poudriere/jails/12i386
,将其挂载到 /poudriere/jails/12i386 上,然后从 poudriere.conf 中的 GIT_HOST
(或默认的 git.freebsd.org
)检出 FreeBSD-12-STABLE
的 Git 分支的顶端,检出到 /poudriere/jails/12i386/usr/src 中,然后完成 buildworld
并将其安装到 /poudriere/jails/12i386 中。
虽然可以在旧版本 FreeBSD 上构建新版本,但大多数情况下它无法运行。例如,如果需要一个 |
要为
为了运行一个 |
可以使用 poudriere jail -l
查看 poudriere 当前已知的 jail 列表。
# poudriere jail -l
JAILNAME VERSION ARCH METHOD
131Ramd64 13.1-RELEASE amd64 ftp
12i386 12.4-STABLE i386 git+https
10.7.4. 保持 poudriere Jails 更新
管理更新非常简单。命令
# poudriere jail -u -j JAILNAME
将指定的 jail 更新到可用的最新版本。对于 FreeBSD 发布版,使用 freebsd-update(8) 更新到最新的补丁级别。对于从源代码构建的 FreeBSD 版本,更新到分支中的最新 git 版本。
对于使用
|
10.7.5. 为 poudriere 设置 Ports 树
在 poudriere 中有多种使用 ports 树的方法。最简单的方法是让 poudriere 使用 Git 为自己创建一个默认的 ports 树
# poudriere ports -c -m git+https -B main
这些命令创建了 tank/poudriere/ports/default
,将其挂载到 /poudriere/ports/default 上,并使用 Git 填充它。之后,它将被包含在已知 ports 树的列表中。
# poudriere ports -l
PORTSTREE METHOD TIMESTAMP PATH
default git+https 2020-07-20 04:23:56 /poudriere/ports/default
请注意,“default” ports 树是特殊的。每个后面介绍的构建命令都将隐式地使用此 ports 树,除非明确指定了其他选项。要使用另一个树,请在命令中添加 |
对于 ports 贡献者来说,处理本地修改的最佳方法是使用 Git。与创建 jail 一样,也可以使用其他方法创建 ports 树。要添加另一个 ports 树来测试本地修改和 ports 开发,建议通过 git(如上所述)检出树。
10.7.6. 在 poudriere 中使用手动管理的 Ports 树
根据工作流程,使用手动维护的 ports 树可能非常有用。例如,如果在 /work/ports 中有一个 ports 树的本地副本,则将 poudriere 指向该位置
# poudriere ports -c -m null -M /work/ports -p development
这将在已知树的表格中列出。
# poudriere ports -l
PORTSTREE METHOD TIMESTAMP PATH
development null 2020-07-20 05:06:33 /work/ports
|
10.7.7. 保持 poudriere Ports 树更新
与前面介绍的 jail 一样简单
# poudriere ports -u -p PORTSTREE
将给定的 PORTSTREE(由 poudriere -l
输出的单个树)更新到官方服务器上的最新版本。
没有方法的 ports 树(参见 在 poudriere 中使用手动管理的 Ports 树)无法通过这种方式更新,必须由 porter 手动更新。 |
10.7.8. 测试 Ports
设置好 jail 和 ports 树后,就可以测试贡献者对 ports 树所做的修改结果。
例如,可以测试之前在 /work/ports/www/firefox 中创建的 13.1-RELEASE jail 中对 www/firefox port 的本地修改
# poudriere testport -j 131Ramd64 -p development -o www/firefox
这将构建 Firefox 的所有依赖项。如果之前构建过某个依赖项并且它仍然是最新的,则将安装预构建的软件包。如果某个依赖项没有最新的软件包,则将在一个 jail 中使用默认选项构建一个新的软件包。然后构建 Firefox 本身。
每个 port 的完整构建日志记录在 /poudriere/data/logs/bulk/131Ri386-development/build-time/logs 中。
目录名称 131Ri386-development
来自 -j
和 -p
的参数。为了方便起见,还维护了一个符号链接 /poudriere/data/logs/bulk/131Ri386-development/latest。该链接指向最新的 build-time 目录。该目录中还有一个 index.html,用于在 Web 浏览器中观察构建过程。
默认情况下,poudriere 会清理 jail 并将日志文件保留在上面提到的目录中。为了便于调查,可以通过在 testport
中添加 -i
来保持 jail 在构建完成后继续运行。
# poudriere testport -j 131Ramd64 -p development -i -o www/firefox
构建完成后,无论成功与否,都将在 jail 中提供一个 shell。该 shell 用于进一步调查。可以使用 -I
告诉 poudriere 在构建完成后保持 jail 运行。poudriere 将显示在不再需要 jail 时运行的命令。然后就可以 jexec(8) 到其中。
# poudriere testport -j 131Ramd64 -p development -I -o www/firefox
[...]
====>> Installing local Pkg repository to /usr/local/etc/pkg/repos
====>> Leaving jail 131Ramd64-development-n running, mounted at /poudriere/data/.m/131Ramd64-development/ref for interactive run testing
====>> To enter jail: jexec 131Ramd64-development-n env -i TERM=$TERM /usr/bin/login -fp root
====>> To stop jail: poudriere jail -k -j 131Ramd64 -p development
# jexec 131Ramd64-development-n env -i TERM=$TERM /usr/bin/login -fp root
# [do some stuff in the jail]
# exit
# poudriere jail -k -j 131Ramd64 -p development
====>> Umounting file systems
FreeBSD ports 构建基础设施的一个重要组成部分是能够使用选项调整 ports 以满足个人喜好。这些也可以在 poudriere 中进行测试。添加 -c
# poudriere testport -c -o www/firefox
在构建 port 之前显示 port 配置对话框。在 -o
后面的 port(格式为 category/portname
)将使用指定的选项,所有依赖项都将使用默认选项。可以使用集合测试具有非默认选项的依赖项,参见 使用集合。
在测试 pkg-plist 在构建过程中根据所选选项而改变的 ports 时,建议进行一次选择所有选项的测试运行,以及一次取消选择所有选项的测试运行。 |
10.7.9. 使用集合
对于所有涉及构建的操作,可以使用 -z setname
指定一个所谓的 集合。集合指的是一个完全独立的构建。例如,这允许使用 testport
为依赖项使用非标准选项。
要使用集合,poudriere 期望有一个类似于 PORT_DBDIR
的现有目录结构(在配置目录中默认为 /var/db/ports)。然后,此目录将被 nullfs(5) 挂载到构建 ports 及其依赖项的 jail 中。通常,可以通过递归地将现有的 PORT_DBDIR
复制到 /usr/local/etc/poudriere.d/jailname-portname-setname-options 来获得一个合适的起点。这在 poudriere(8) 中有详细介绍。例如,要测试名为 devset
的特定集合中的 www/firefox,请在 testport
命令中添加 -z devset
参数
# poudriere testport -j 131Ramd64 -p development -z devset -o www/firefox
这将按以下顺序查找这些目录的存在
/usr/local/etc/poudriere.d/131Ramd64-development-devset-options
/usr/local/etc/poudriere.d/131Ramd64-devset-options
/usr/local/etc/poudriere.d/131Ramd64-development-options
/usr/local/etc/poudriere.d/devset-options
/usr/local/etc/poudriere.d/development-options
/usr/local/etc/poudriere.d/131Ramd64-options
/usr/local/etc/poudriere.d/options
从这个列表中,poudriere 将 nullfs(5) 挂载 第一个存在的 目录树到构建 jail 的 /var/db/ports 目录中。因此,在这次 testport
运行期间,所有自定义选项都将用于所有 ports。
提供集合的目录结构后,可以更改特定 port 的选项。例如
# poudriere options -c www/firefox -z devset
将显示 www/firefox 的配置对话框,可以编辑选项。所选选项将保存到 devset
集合中。
poudriere 在选项配置方面非常灵活。poudriere 可以为特定 jail、ports 树以及多个 ports 设置,所有操作都可以通过一个命令完成。有关详细信息,请参阅 poudriere(8)。 |
10.7.10. 提供自定义的 make.conf 文件
与使用集合类似,如果提供了自定义的 make.conf 文件,poudriere 也会使用它。不需要任何特殊的命令行参数。相反,poudriere 会查找与从命令行派生的名称方案匹配的现有文件。例如
# poudriere testport -j 131Ramd64 -p development -z devset -o www/firefox
将导致 poudriere 按以下顺序检查这些文件是否存在
/usr/local/etc/poudriere.d/make.conf
/usr/local/etc/poudriere.d/devset-make.conf
/usr/local/etc/poudriere.d/development-make.conf
/usr/local/etc/poudriere.d/131Ramd64-make.conf
/usr/local/etc/poudriere.d/131Ramd64-development-make.conf
/usr/local/etc/poudriere.d/131Ramd64-devset-make.conf
/usr/local/etc/poudriere.d/131Ramd64-development-devset-make.conf
与集合不同的是,所有找到的文件都将按 该顺序 追加到构建 jail 中的一个 make.conf 中。因此,可以在 /usr/local/etc/poudriere.d/make.conf 中设置一般的 make 变量,以影响所有构建。旨在仅影响某些 jail 或集合的特殊变量可以设置在专门的 make.conf 文件中,例如 /usr/local/etc/poudriere.d/131Ramd64-development-devset-make.conf。
要使用名为 perl5-20
的集合构建使用非默认 Perl 版本(例如 5.20
)的集合,请创建一个包含以下行的 perl5-20-make.conf 文件
DEFAULT_VERSIONS+= perl=5.20
10.8. 调试端口
有时事情会出错,端口在运行时失败。 该框架提供了一些工具来帮助调试端口。 这些助手功能有限,因为调试端口的方式很大程度上取决于所使用的技术。 以下变量有助于调试端口
WITH_DEBUG
。 如果设置,则端口将使用调试符号进行构建。WITH_DEBUG_PORTS
。 指定要使用WITH_DEBUG
设置进行构建的端口列表。DEBUG_FLAGS
。 用于指定CFLAGS
的附加标志。 默认值为-g
。
当设置 WITH_DEBUG
(全局或针对端口列表)时,生成的二进制文件不会被剥离。
这些变量可以在 make.conf 中或在命令行中指定。
# cd category/port && make -DWITH_DEBUG DEBUG_FLAGSS="-g -O0"
如果端口使用 ports-mgmt/poudriere 构建,则调试变量必须在 poudriere 的 make.conf 中指定,而不是在 /etc/make.conf 中。 有关详细信息,请参阅 ports-mgmt/poudriere 文档。 |
有关可用调试工具的更多详细信息,请参阅 开发者手册 中的调试信息。
最后修改时间:2024 年 9 月 20 日,由 Fernando Apesteguía 修改