GLEP 64: 导出 PMS 缓存的 VDB 信息
作者 | Anthony G. Basile <blueness@gentoo.org> |
---|---|
类型 | 标准跟踪 |
状态 | 最终 |
版本 | 1 |
创建 | 2014-07-31 |
最后修改 | 2017-10-12 |
发布历史 | 2014-08-30 |
GLEP 源代码 | glep-0064.rst |
摘要
在构建期间,包管理器 (PM) 会生成关于正在构建的包的重要信息。当使用 Portage 作为 PM 时,此信息会按包为单位缓存到 /var/db/pkg/<cat>/<pkg>(VDB)下的目录中。虽然此信息可以动态重新生成,但这样做可能会很昂贵或不切实际。此类信息的示例包括已安装特定包的所有文件的完整列表,或包的可执行文件和/或共享对象的动态链接信息。为了避免不必要的重新生成成本,并促进所有 PM 与其他可能使用此信息的工具之间的互操作性,所有 PM 应缓存一组标准信息,并提供一个通用的 API 来导出这些信息。在本 GLEP 中,我们指定应缓存和导出的信息。 [1]
动机
PM 在构建时生成的信息范围从易于重新生成到难以重新生成。某些信息,例如包的 HOMEPAGE,可以通过简单地 grep Portage 树中的包的 ebuild 来轻松重新生成。然而,尽管如此简单,但即使此信息也需要缓存,以防从树中删除 ebuild,但该包仍安装在系统上。但是,即使已安装的包和树中的 ebuild 不“不同步”,仍然有另一个理由在构建时缓存 PM 生成的信息。某些信息,例如属于特定包的所有已安装文件的列表,无法轻松重新生成。如果未缓存此类列表,PM 将不得不重新构建该包以重新生成它,即使这样,重新生成的列表也无法保证代表已安装包的实际状态,因为系统其余部分的环境可能在构建之间发生了变化。除了 PM 本身在卸载时需要此列表,因此必须为此自己缓存之外,列出包的文件对于其他实用程序很有用。例如,在撰写本文时,sys-apps/elfix、app-portage/gentoolkit、app-portage/portage-utils 和 app-portage/eix 就是一些使用 Portage 的 VDB 来获取此缓存列表的实用程序示例。
另一个有用且昂贵但可能不如上例明显的重新生成信息示例是链接信息,例如运行readelf或scanelf在 ELF 对象上,或类似的工具用于其他可执行文件格式,如 Mach-O 或 COFF。在“滚动发布”系统(如 Gentoo)中,跟踪可执行对象与其库之间的正向和反向依赖关系对于在升级期间避免损坏至关重要。对跟踪这些依赖关系的需求在 PMS 特性(如子插槽)中很明显,这些特性旨在确保可执行文件始终与库一致地构建:升级破坏了向后兼容性的库会自动触发其依赖的可执行文件 (s) 的重新构建 [2] [3]。虽然它们在其自身范围内足够,但这些 PMS 特性存在局限性:1) 此信息是为确保构建时的一致性而计算的,但之后不会缓存和导出供其他工具使用,例如revdep-pax它使用相同的信息在可执行对象和库之间一致地应用 PaX 标记 [4];并且,2) 这种信息对于需要根据 ABI、SONAME、库路径名等进行区分的工具来说不够精细。通过缓存和导出这种形式,可以构建系统的可执行对象和库的整个“链接图” [5],以方便快速遍历正向和反向依赖关系。诸如“此系统上链接到 libssl.so.1.0.0 的所有可执行文件(对于 ABI=x32)的路径名是什么?” 之类的问题可以快速得到解答,而无需在系统上读取每个对象的动态部分以搜索那些需要 libssl.so 的 x32 对象。
以上示例促使我们为任何希望使用此生成信息的实用程序创建一个统一的标准。下面,我们指定了一个应由任何 PM 在构建时生成、缓存,然后由通用 API 导出的一组标准最小信息。
规格
对于每个安装的包,应在构建时生成以下信息,将其缓存,然后导出
- 所有 Portage 变量,如 PMS 13.2 中定义的元数据缓存的一部分所指定 [6]。请注意,与元数据缓存一样,这些变量应存储所有已评估的条件。
- 包的所有文件的列表,以及文件类型的指定(常规、目录、符号链接、管道等)、MD5SUM 或其他校验和以及 mtime 时间。
- 每个包的所有可执行文件或共享对象的列表,以及相应的链接信息,包括对象到对象的完整路径,其体系结构和 ABI、SONAME、RPATH 以及它们链接到的任何 NEEDED 对象,如readelf在 ELF 系统上,或类似的工具用于其他可执行文件格式。目前,Portage 在 NEEDED.ELF.2、NEEDED.MACHO.3、NEEDED.XCOFF、NEEDED.PECOFF 等中缓存此信息。
- 影响包构建系统行为的标志,包括至少 CHOST、CBUILD、CTARGET、CFLAGS、CXXFLAGS、CPPFLAGS 和 LDFLAGS。如果使用了 Fortran 编译器,也应包含 FFLAGS。在不需要编译/链接的包的情况下,这些标志可能为空。
- 影响 PM 行为的标志,这些标志尚未在 PMS 13.2 中指定,包括至少 USE 和 KEYWORDS。
- 由 PM 计算的包之间的依赖关系,包括至少 DEPEND、RDEPEND 和 PDEPEND。
- 杂项信息,包括包构建时间、存储库名称、DEFINED_PHASES、EAPI、INHERITED eclasses 和 SLOT。
实现说明
本 GLEP 的目的不是指定导出上述信息的通用 API 的详细信息。更不用说界定每个 PM 的实现细节了。但是,应由 PM 团队开发和指定用于导出上述信息的通用 API,并将其包含在未来的 PMS 文档中。对 API 的任何更改都应进行版本控制,以允许随着时间的推移保持一致性。
作为指南,我们建议使用一个简单的 CLI API,它可以回答以下问题
- webkit-gtk 的特定版本的 SLOT 号是多少?
query-installed metadata =net-libs/webkit-gtk-2.4.4-r200 SLOT
- 特定文件的 ABI 和它链接到的库是什么?
query-installed file /usr/bin/timeout ABI NEEDED
向后兼容性
- Portage 自 v2.2_pre7 2008-05-21 起已缓存所有上述信息;但是,它不是通过一致的 API 导出的。实现了上述指定 API 的 Portage 版本可以使用早在 2008 年就构建的缓存。
- 对于不缓存任何上述信息的 PM,应实施迁移方案以生成缓存,而无需重新构建世界。
参考资料
[1] | 此已由理事会批准。参见 https://gentoolinux.cn/proj/en/council/meeting-logs/20130910-summary.txt |
[2] | 此在 PMS 中指定。参见 http://dev.gentoo.org/~zmedico/portage/doc/portage.html#package-ebuild-eapi-4-slot-abi-metadata-slot-sub-slot-abi |
[3] | 子插槽和插槽运算符 https://wiki.gentoo.org/wiki/Sub-slots_and_Slot-Operators |
[4] | http://git.overlays.gentoo.org/gitweb/?p=proj/elfix.git;a=blob;f=scripts/revdep-pax 手册页可以在 http://www.linuxhowtos.org/manpages/1/revdep-pax.htm 上查看 |
[5] | 此类类的示例位于 http://git.overlays.gentoo.org/gitweb/?p=proj/elfix.git;a=blob;f=pocs/link-maps/link_map.py。Portage 本身在评估 emerge @preserved-rebuild 时会在内部构建这样的图。 |
[6] | https://projects.gentoo.org/pms/6/pms.html#x1-16300013 |
版权
此作品根据知识共享署名-相同方式共享 3.0 未经修改版许可授权。要查看此许可的副本,请访问 https://creativecommons.org/licenses/by-sa/3.0/。