# openRuyi 软件包样式指南 ## 基础包字段 > TL;DR: 想要一个简单的视觉效果,可以在源码仓内搜索 `libpwquality` 或 `graphite2`。 openRuyi 默认打包时应带上以下所有字段: ```rpmspec Name: Version: Release: Summary: License: URL: VCS: Source: BuildSystem: BuildRequires: Requires: %description %files %changelog ``` 在所有字段之前,应包含显式声明 Spec 文件的版权信息: ```rpmspec # SPDX-FileCopyrightText: (C) 2025 Institute of Software, Chinese Academy of Sciences (ISCAS) # SPDX-FileCopyrightText: (C) 2025 openRuyi Project Contributors # SPDX-FileContributor: Your Name # # SPDX-License-Identifier: MulanPSL-2.0 ``` 但请注意,这类版权信息会由 REUSE 自动生成,所以在贡献时可不手动编写。其中,SPDX-FileContributor 为自愿填写的内容。 ### Name 定义软件包的名称。默认软件包名称应为小写。详情请查阅 [命名规则](./Naming.md)。 ### Version 定义软件包的版本。不同的上游可能有不同的版本号策略,打包时应该遵守下列规则: | 情形 | 应当采取的措施 | 举例 | | -------------------------------- | ---------------------------------------------------- | ------------------------------------------------------------------------------- | | 版本号只带有半角句号 | 可直接使用上游的版本号 | zstd: 1.5.7 `Version: 1.5.7` | | 版本号带有发布阶段标记(`alpha`、`beta`、`rc`) | 将字母转为小写,并在字母前加波浪号 (`~`) | libffi: v3.5.0-rc1 `Version: 3.5.0~rc1` | | 版本号本身带有短横线 | 将短横线替换为小数点 (`.`) | ImageMagick: 7.1.1-44 `Version: 7.1.1.44` | | 版本号本身带有下划线 | 将下划线替换为小数点 (`.`) | postgres: 17\_6 `Version: 17.6` | | 版本号为格式化后带有半角句号的日期 | 可直接使用上游的版本号 | u-boot: 2025.07 `Version: 2025.07` | | 版本号为基于版本控制系统的提交哈希值 | 由数字 `0` 作为开头,而后接上 `+`、版本控制器名称、打包日期 (`YYYYMMDD`) ,及哈希值的前 7 位 | gn: ee5b7e32b961a9da1933e9f46a018ba6cac8ef60 `Version: 0+git20250808.ee5b7e3` | 详情请查阅 [版本号](./Versioning.md)。 ### Release 定义软件包的发布号。此变量默认应为 `%autorelease`。该宏展开后(举例)为 `1%{?dist}`,每次修订时应为数字递增 1。 更新软件包时,应该将数字复位为 1。 对于`%{?dist}` 标签,详情请查阅 [%{?dist} 标签](./DistTag.md)。 ### Summary 定义软件包功能的简短描述。简介应只包含必要的英文介绍,并且末尾不能加英文句号标点。 ### License 定义软件包的许可证类型。开源许可证的编写应严格按照 [SPDX License](https://spdx.org/licenses/) 内的 Identifier 编写。如遇到一个软件包内有多个许可证,则 Identifier 之间应该用 `AND` 连接。 对于许可证字段,详情请参阅 [许可证](./LicensingGuidelines.md)。如果想了解更多关于 SPDX 许可证的信息,请参阅 [SPDX 许可证表达式](./spdx.md)。 ### URL 定义软件包的官方网站链接。为了清晰明了,请不要在这里使用 `%{name}` 宏。 如果软件包没有官方网站,则可以使用源代码仓库链接。 ### VCS 定义软件包的源代码仓库链接。这个链接主要为了方便用户和开发者找到软件包的源代码位置。为了清晰明了,请不要在这里使用 `%{name}` 宏。 如果在 `URL` 中定义的链接为源代码仓库链接,则可以省略 `VCS` 字段。 如果软件包没有可用的源代码仓库链接,那么请在 VCS 字段的位置编写以下注释: ```rpmspec # VCS: No VCS link available ``` 后面的注释可以是任意的,但前方的 # VCS: 格式是必须的。 #### Git 如果软件包的源代码托管在 Git 仓库中,则 `VCS` 字段的值应为该仓库的克隆链接。例如: ```rpmspec VCS: git:https://git.netfilter.org/iptables ``` ### Source 定义软件包的源代码文件。通常来讲,你必须需要提供软件包的源代码文件位置。 如果软件包下载地址页面提供了检验和文件的话,则需要新增加一条,内容为该检验和文件的下载地址。 如果官方有镜像网址的话,那么可以在这里使用镜像网址。例如 gnu 的 `ftpmirror.gnu.org` 镜像。 如果引用的 Source 地址来源于网络,则需要在该地址前添加 `#!RemoteAsset` 注释,引用多条的,请在每条前都添加该注释。 此变量默认数字值应为 0,每增加一条应为该值递增 1。如果只有一个源代码文件,则可以省略数字。 对于源码包字段,详情请参阅 [源码包](./SourceURL.md)。 ### BuildSystem 定义指定构建系统的类型。对于该字段,详情请参阅 [声明式构建系统](./BuildSystem.md)。 `BuildSystem` 目前有以下值: * `autotools`: 适用于 conf 时使用 `%configure`,build 时使用 `%make_build` 的软件包。 * `cmake`: 适用于 conf 时使用 `%cmake`,build 时使用 `%make_build` 的软件包。 * `meson`: 适用于 conf 时使用 `%meson`,build 时使用 `%meson_build` 的软件包。 在必要的情况下,你可以对构建过程进行更改,通过添加特定的标签来执行自定义命令。这些标签可以让你在自动化的构建步骤前后插入自己的逻辑: * `%prep -a`: 在系统自动执行 `%prep` 阶段 之后 添加自定义命令。 * `%conf -p`: 在系统自动执行 `configure` 阶段 之前 添加自定义命令。 当然,你也可以留空。例如某个软件包打包时不需要 `configure`,则直接编写单 `%conf` 即可,内容可留空,但请用注释说明原因。 ### BuildRequires 定义构建软件包时所需的依赖包。对于 C 程序,默认不需要写 `gcc` 和 `gcc-c++`。 请按照一行一个依赖包的形式进行编写。 我们推荐在 BuildRequires 字段使用 `pkgconfig(xxx)` 来声明开发库名称,详情请参阅 [使用 pkgconfig(xxx)](./PkgConfigBuildRequires.md)。 ### Requires 定义软件包运行时所需的依赖包。 请按照一行一个依赖包的形式进行编写。 ### %description 定义软件包的详细描述。 ### %files 定义安装的软件包包含哪些文件。 ### %changelog 定义软件包的更新日志。 ## 可选包字段 openRuyi 打包时也可带上一些可选字段: ```rpmspec Epoch: BuildOption: %patchlist Provides: Conflicts: %prep %build %install ``` ### Epoch Epoch 通常用来解决版本号歧义的问题。因为这个 tag 的特殊性,一旦使用则不能再被移除,所以能不用就不要使用。 ### BuildArch 用于声明软件包是给哪种架构使用的。`BuildArch` 字段应该放在最后一个 `Source` 字段和 `BuildSystem` 字段之间。 如果该字段的值为 `noarch`,代表该软件包和 CPU 架构无关。 ### BuildOption 用于显式声明构建选项。例如,你需要增加 configure 时的参数: ```rpmspec BuildOption(conf): --disable-static ``` 遇到多个参数时请按行添加。或者,你需要同时修改 build 和 install 时的参数: ```rpmspec BuildOption(build): -f unix/Makefile unzips CF_NOOPT="$RPM_OPT_FLAGS" BuildOption(install): -f unix/Makefile prefix=$RPM_BUILD_ROOT%{_prefix} MANDIR=$RPM_BUILD_ROOT%{_mandir}/man1 ``` 参数应该跟标签空两格。`BuildOption` 字段应该放在 `BuildSystem` 字段和`BuildRequires` 字段之间。 ### %patchlist / Patch 定义补丁文件列表,用于修补源代码文件。以下是一个概括版本,详情请参阅 [补丁](./Patch.md)。 我们希望补丁能按照统一且可排序的规则命名,第一个 patch 的文件名从 0001 编号开始,每新增一个 patch 则为该编号加 1。 所有的 Patch 都应该附带必要的说明。如果 Patch 内没有任何说明信息,则应该在 patch 文件名的上方用简短的一句话或者链接代表 patch 的用途,例如: ```rpmspec # Fix executable space protection patch, upstream plans to do this Patch0: 0001-unzip-6.0-exec-shield.patch ``` 在 Spec 文件内存在有 `BuildOption` 字段的情况下,Patch 应该放在 `BuildSystem` 字段和 `BuildOption` 字段之间。如果 `BuildOption` 字段不存在,则 Patch 应该放在 `BuildSystem` 字段和`BuildRequires` 字段之间。 如果有大于 3 个 patch,则不宜使用 `Patch0:` 这样的命名格式,直接定义 `%patchlist` 即可。如果定义 `%patchlist`,需要将列表放置于 `%description` 的上方。 详见[这里](https://github.com/rpm-software-management/rpm/issues/752)。 ```rpmspec %patchlist # Fix executable space protection patch, upstream plans to do this 0001-unzip-6.0-exec-shield.patch # http://www.info-zip.org/board/board.pl?m-1259575993/ 0002-unzip-6.0-attribs-overflow.patch # ... # covscan issues 0020-unzip-6.0-COVSCAN-fix-unterminated-string.patch ``` ### Provides 声明软件包提供的功能或文件,以便其他软件包依赖。 ### Conflicts 定义与当前软件包冲突的其他软件包。 ## 路径宏标签 在 Spec 文件中,路径宏标签用于定义和引用文件系统中的标准路径。这些宏有助于确保软件包在不同的系统环境中具有一致的文件路径结构。以下是一些常用的路径宏标签及其含义: | %{\_lib} | lib64 | | | ----------------- | -------------------------- | ---------------------------- | | %{\_bindir} | %{\_exec\_prefix}/bin | 可执行文件的目录,通常为 /usr/bin | | %{\_docdir} | %{\_datadir}/doc | 文档目录,通常为 /usr/share/doc | | %{\_libdir} | %{\_exec\_prefix}/%{\_lib} | 库文件目录,通常为 /usr/%{\_lib} | | %{\_libexecdir} | %{\_exec\_prefix}/libexec | 可执行程序的目录,通常为 /usr/libexec | | %{\_datadir} | %{\_datarootdir} | 共享数据文件的目录,通常为 /usr/share | | %{\_mandir} | %{\_datarootdir}/man | 手册页文件的目录,通常为 /usr/share/man | | %{\_prefix} | /usr | 顶级安装前缀 | | %{\_sysconfdir} | /etc | 系统配置文件的目录 | | %{\_exec\_prefix} | %{\_prefix} | 可执行文件路径前缀,通常为 /usr | | %{\_includedir} | %{\_prefix}/include | C/C++ 头文件目录,通常为 /usr/include | 我们还有一些其他的路径宏标签,可以根据需要使用: ### Bash | 宏标签 | 含义 | 注释 | | ------------------------- | ---------------------------------------- | --------------- | | %{bash\_completions\_dir} | %{\_datadir}/bash-completion/completions | 存放 bash 的自动补全脚本 | ### Python | 宏标签 | 含义 | 注释 | | ------------------- | ------------------- | -- | | %{\_\_python} | Python 解释器 | | | %{python\_sitelib} | Python 第三方库安装目录 | | | %{python\_sitearch} | Python 第三方架构相关库安装目录 | | ### Perl | 宏标签 | 含义 | 注释 | | ------------------- | ----------------- | -- | | %{\_\_perl} | Perl 解释器 | | | %{perl\_vendorlib} | Perl 第三方库安装目录 | | | %{perl\_vendorarch} | Perl 第三方架构相关库安装目录 | | ## 拆包规则 如果打包的时候会生成 Development files,那么需要将这些组件拆成单独的 devel 子包。 对于 Documentation 和 test files (test suite),如果体积不大,可不需要拆成子包。 详情请参阅[软件包拆分](./SplitPackage.md)。 ## 其它宏使用规则 ### 条件宏 `%bcond` 是 RPM spec 文件中的条件宏(Build Condition Macro),用来定义编译时的可选开关。以下为示例: ```rpmspec %bcond bootstrap 0 # 相当于 %bcond_with foo,禁用 bootstrap %bcond bootstrap 1 # 相当于 %bcond_without foo,启用 bootstrap %if %{with bootstrap} # 启用 bootstrap 时生效的内容 %endif %if %{without bootstrap} # 禁用 bootstrap 时生效的内容 %endif ``` 注意:我们在打包时尽量避免使用 `%bcond_with` 和 `%bcond_without`。 ## 其它 SPEC 文件编写规则 ### 本地化文件查找 对于 `%find_lang` 宏的使用,我们希望能统一使用 `--generate-subpackages` 参数来自动生成子包。这样,也不需要在 `%files` 中手动列出语言文件。 ```rpmspec %find_lang %{name} --generate-subpackages %files # Normal files here ``` 详情请参阅 [语言包](./LangPacks.md)。 ## 贡献规则 ### commit message 规则 在提交 PR 的时候,我们希望贡献者遵守以下的模版来编写 commit message: ```rpmspec 文件夹: 包名: <操作>. ``` 例如,对某个包做出了更改: ```rpmspec library-python: python-rpm-macros: Fix %python_provide. ``` 创建新包时为例外: ```rpmspec core: Add systemd. ``` 一个 PR 里可以包含多个 commit,但每个 commit 应该只包含一类更改。例如,Formatting 和 Bug Fixing 应该分成两个 commit。