跳到主要内容

软件包拆分

这个文档讲述了 openRuyi 软件包的软件包拆分策略。

通常,要拆分的情况为,同一份软件包源码编译出了两个或多个基于 RPM Spec 的软件包。拆分软件包通常出于多种原因,例如提供不同类型的功能或者文档。

以下是编写 RPM Spec 时必须要遵守的规则:

以功能大类拆分

如果软件包提供了多种不同的功能,那么必须按照不同的功能大类进行拆分,而不按每个小模块/插件拆分。子包命名必须以 %{name}-<feature> (feature 为功能简称,如 client/server等) 的格式命名。

这旨在减少碎片化、降低维护成本、让用户从包名就能推断用途。

命名

以功能拆分为子包的时候,命名应明确用途、避免按实现细节命名 (例如 %{name}-featureX-moduleY 这种"代码结构导向"的命名)。

一旦引入某个子包名,应尽量长期保持,避免修改;如必须重命名/拆分迁移,必须使用 Obsoletes/Provides 等机制提供平滑升级路径。

分隔符

包名的各部分必须用短横线 - 分隔,不得用 _+. 等作为分隔符 (特殊情况除外)。

开发文件

如果软件包提供了开发所需文件,则相关文件应该放入一个子软件包中,并必须以 %{name}-devel 的格式命名。

什么库文件应该纳入开发文件包

对 "系统共享库" (安装在 %{_libdir} 且会进入动态链接器搜索范围) 应按下面三类区分归属:

  1. 真实库文件 (实体): 属于运行时,不得放入 -devel,应放入主包。

例:%{_libdir}/libfoo.so.3.2.0

  1. SONAME 链接: 属于运行时,不得放入 -devel,应放入主包。

例:%{_libdir}/libfoo.so.3 -> libfoo.so.3.2.0

动态链接器按 SONAME 查找库,因此应确保存在该链接 (通常由上游安装产生)。

  1. 无版本链接: 属于开发文件,必须放入 -devel

例:%{_libdir}/libfoo.so -> libfoo.so.3.2.0

该文件仅用于编译/链接,不是运行所必需。

开发文件应包含的内容

开发文件一般指(非穷举):

  • headers (*.h,通常在 /usr/include)

  • pkgconfig/*.pc、CMake package config

  • 无版本的 libfoo.so (见上)

插件/私有 .so 的处理

有些软件会生成"非系统库"的 unversioned .so(常见于插件/模块),它们不放在系统 ld 搜索路径里,只在运行时由主程序从私有目录加载。这类 .so 不需要放入开发文件子包,应随主包/对应功能包走。

另外,若这些"私有 .so"触发了 RPM 自动生成的全局 Provides/Requires,必须进行过滤,避免把私有能力当成全局能力发布。

文档

如果软件包提供了文档,且文档的总大小过大的情况下,则相关文件必须放入一个子软件包中,并必须以 %{name}-doc 的格式命名。 "大型"的定义留给打包者自行判断,但并不仅限于大小。"大型"可以指文件的大小或数量。

推荐规则

运行时库

如果软件包需要运行时库,相关文件不应放入单独的子软件包 (例如 %{name}-libs)。目前可以将相关文件先放至主包,并在主包内显式声明对应的依赖:

Provides:       %{name}-libs = %{name}-%{version}

同时,需要在 %files 字段以注释的方式声明哪些文件为运行时库,方便 Review 或后续迁移,例如:

%files
# ...
# samba libs
%{_libdir}/libdcerpc-samr.so.*
# ...
# client libs
%{_libdir}/libdcerpc-binding.so.*
# ...

注:安装带共享库的软件包时通常不需要在脚本中显式调用 ldconfig

例外拆库包的情况

当满足以下任一情况时,建议拆出独立的运行时库包:

  • 该库会被多个不相关的软件依赖 (即成为 "平台库/通用库"的时候)

  • 希望库的安全更新/ABI 变更能独立于主程序交付时 (例如运维需要)

  • 存在 ABI 并行需求时

子包依赖

子包如需依赖主包,必须严格依赖主包版本,这可以避免头文件/链接文件与运行时库不匹配:

Requires:       %{name}%{?_isa} = %{version}-%{release}

同时,建议在主包名称后加上 %{?_isa},让依赖变成架构特定,避免多架构环境下依赖解析器拉错包。

语言包

翻译/语言资源须拆成单独的子包,详见语言包