插槽
软件包可以支持同时安装多个版本。这对于接口可能在不同版本之间发生变化的库很有用 - 例如,gtk+
软件包可以同时安装 2.24
和 3.6
版本。此功能称为插槽。
大多数软件包不需要插槽。这些软件包在 ebuild 中指定 SLOT="0"
。这纯粹是一种约定;包管理器不会将 0
与其他插槽值区别对待。
SLOT
是一个必填变量,不能为空。Portage 允许每个 SLOT
值最多安装一个软件包实例。例如,假设我们有以下内容
-
foo-1.1
具有SLOT="1"
-
foo-1.2
具有SLOT="1"
-
foo-2.0
具有SLOT="2"
-
foo-2.1
具有SLOT="2"
那么用户可以同时安装 foo-1.2
和 foo-2.0
,但不能同时安装 foo-1.1
和 foo-1.2
。请注意,用户完全有可能安装 foo-2.0
,但没有安装任何 foo-1.x
。
要对特定插槽中的软件包进行 DEPEND
,请参阅 插槽依赖项。
子插槽
有时,软件包会安装一个库,该库在不同版本之间改变接口,但同时允许安装其中一些版本是不希望的或不方便的。在 EAPI=5
及更高版本中,这种情况可以通过使用子插槽来处理,子插槽通过 /
字符与常规插槽分隔,如 SLOT="slot/subslot"
。软件包可以在 运行时依赖项的子插槽更改时请求自动重建。
如果 ebuild 未显式声明子插槽,则默认情况下常规插槽用作子插槽的值。
您可能希望查看 QA 团队关于子插槽的文档。
media-libs/libpng
中的 SLOT="0" 切换为 SLOT="0/14",而软件包 foo
依赖于 libpng:0=
)。因此,最好在库接口发生更改时开始在库中使用子插槽。ABI 损坏
库有两种方式会破坏与使用者的兼容性。
- ABI(应用程序二进制接口):这会影响在更改之前构建的二进制文件。链接到更改前库的应用程序在更改后可能无法正常工作。这些更改与内部结构相关,例如
struct
的大小或参数的类型(例如整数宽度)。修复此问题需要重建所有使用者。 - API(应用程序编程接口):这会影响编译时的使用者,通常发生在库已弃用并删除函数时。修复此问题需要对使用者进行代码更改。
请注意,子插槽并非专门用于此目的。虽然它们在 Gentoo 树中占大多数使用,但子插槽可能具有与 SONAME 或 ABI 损坏完全无关的含义。在使用子插槽运算符之前,请检查相关软件包中的使用情况!
在意识到 ABI 损坏后,请更改子插槽。请注意,子插槽不必严格等于 SONAME,因此可以是任意字符串(遵循命名规则)。
请注意,某些上游可能在未验证次要版本中是否破坏了二进制兼容性的情况下进行发布。您应该使用 dev-util/libabigail
或ABI 实验室(如果您喜欢非网络版本,可在 Gentoo 中使用 dev-util/abi-compliance-checker
)之类的工具进行检查。
通常,链接到具有表示 SONAME 或二进制兼容性的子插槽的库的使用者应该使用 :=
订阅它(在子插槽更改时请求重建)。此外,请参阅 QA 策略指南以了解有关 在定义子插槽之前主动订阅子插槽 的信息。
子插槽的一般命名
作为简单规则,SONAME 通常是库链接文件名 libfoo.so
和其第一个版本组件的函数。剩余的版本组件对于确保使用者的单调升级路径很有用,但不会包含在库的 SONAME 中,在本例中 SONAME 将是 libfoo.so.1
。
SONAME 递增意味着库的 ABI 已损坏。
由于上述约定,ebuild 通常将当前 ABI 版本作为子插槽公开。对于此libfoo 示例,如果库是 libfoo.so.1.2
,ebuild 可能会设置
SLOT="0/1"
此外,假设软件包 foo
安装了一个库,该库的不同版本具有不同的 SONAME。使用 SONAME 版本作为子插槽名称是合理的
-
foo-1.1
安装libfoo.so.5
-SLOT="1/5"
-
foo-1.2
安装libfoo.so.6
-SLOT="1/6"
-
foo-2.0
安装libfoo-2.so.0
-SLOT="2/0"
-
foo-2.1
安装libfoo-2.so.1
-SLOT="2/1"
然后,其他安装链接到 libfoo-2
(或 libfoo
)的二进制文件的 ebuild 可以请求在安装的 foo:2
或 foo:1
版本更改子插槽时自动重建 - 例如,当用户从 foo-2.0
升级到 foo-2.1
时。
单个软件包中的多个库
软件包可能需要安装多个库。这方面的典型例子是 media-video/ffmpeg
# Subslot: <libavutil_major>.<libavcodec_major>.<libavformat_major>
# Since FFmpeg ships several libraries, subslot is kind of limited here.
# Most consumers will use those three libraries, if a "less used" library
# changes its soname, consumers will have to be rebuilt the old way
# (preserve-libs) - which should not be relied upon.
# If, for example, a package does not link to libavformat and only libavformat
# changes its ABI then this package will be rebuilt needlessly. Hence, such a
# package is free _not_ to := depend on FFmpeg but I would strongly encourage
# doing so since such a case is unlikely.
SLOT="0/56.58.58"
在这种情况下,使子插槽成为每个安装库的主要 SONAME 的组合。这强调了上面提到的一个观点 - 子插槽不必等于安装库的精确 SONAME,它们只需要以某种方式表示 ABI 兼容性。