Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
159 changes: 126 additions & 33 deletions docs/packaging-guidelines/rpmspecification.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,43 @@ The top of every Spec file MUST feature SPDX-compliant copyright and license dec

A Spec MUST include the following tags and sections, and they SHOULD appear in the specified order:

```specfile
Name:
Version:
Release:
Summary:
License:

%description

%files

%changelog
```

A package MAY have an empty `%files` section when it intentionally produces an empty package, such as a dependency-only meta-package.

The absence of a conditional tag or section does not by itself make a Spec non-compliant.

Common conditional tags and sections include:

| Tag or section | When it is required |
| --------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| `URL` | When the upstream project provides a meaningful homepage or public source repository |
| `VCS` | When a usable upstream source repository exists and `URL` does not already point to it |
| `Source` / `SourceN` / `%sourcelist` | When the package consumes source files or other source inputs |
| `BuildArch` | When the package needs to override the default target architecture behavior |
| `BuildSystem` | When the Spec uses the declarative build system mechanism |
| `Patch` / `%patchlist` | When the package applies downstream or backported patches |
| `BuildOption` | When a declarative build system needs additional stage-specific options |
| `BuildRequires` | When the build needs dependencies that the openRuyi basic build environment does not guarantee |
| `Requires` | When the package needs explicit runtime dependencies |
| `Provides` / `Conflicts` / `Obsoletes` / `Recommends` / `Supplements` | When package relationships require them |
| `%package` | When the Spec creates subpackages |
| `%prep` / `%build` / `%install` / `%check` | When the package needs explicit actions in the corresponding stage |

When the following tags are present, they SHOULD appear in the following relative order:

```specfile
Name:
Version:
Expand All @@ -78,26 +115,55 @@ License:
URL:
VCS:
Source:
BuildArch:
BuildSystem:

Patch:

BuildOption:

BuildRequires:

Provides:
Conflicts:
Obsoletes:

Recommends:

Requires:

Supplements:

%description
```

%files
The example above defines relative ordering, not a mandatory complete header. A Spec does not need to reserve a position for an omitted conditional tag. `Source`, `Source0`, `Source1`, and similar numbered forms belong to the same position. Equivalent source declarations such as `%sourcelist` also belong to the source declaration block.

%changelog
```
Package-specific supplementary specifications MAY define additional tags or more specific ordering rules. When a supplementary specification defines such a rule, that rule takes precedence.

Other tags MAY be ordered alphabetically from A to Z, unless a specific order is required.
For tags that have no specific ordering rule, maintainers SHOULD keep related tags together and MAY order them alphabetically.

Blank lines MUST be used to separate sections.

### Minimal Skeleton Example

TODO
The following example shows a valid minimal structure for a package that does not need upstream source input, a build system, build dependencies, or explicit runtime dependencies:

```specfile

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

字段顺序要考虑子包,是不是可以递归适用

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

子包也适用,但是为了美观可以不进行空行。

Name: <package-name>
Version: <version>
Release: %autorelease
Summary: <summary>
License: <SPDX-license-expression>

%description
<package-description>

%files

%changelog
%autochangelog
```

### Formatting and readability

Expand Down Expand Up @@ -174,7 +240,15 @@ For detailed licensing rules, see the [Licenses](/docs/guide/packaging-guideline

1. `URL` MUST point to the upstream project's official homepage; if one does not exist, it MAY point to the source code repository.

2. The `URL` tag MUST NOT dynamically construct its value using macros such as `%{name}`.
2. When the upstream project does not provide an official homepage but provides a public source repository, the Spec MUST set `URL` to a meaningful project location, normally the source repository.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 和 2 逻辑有一定模糊, 在相同条件描述最终指向源码仓,但是 1 是 MAY 2 是 MUST ,建议 第一条 说 如果没有,就 MUST 什么,第二条解释 第二个 must 具体主要是指 source repository.(注意中文一起改)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个应该是我的编辑疏忽,第一点后半句不应该存在。


3. When no meaningful upstream project URL exists, the Spec MAY omit `URL`. Distribution-specific meta-packages, configuration packages, or similar packages may fall into this category. The Spec MUST include the following exact comment in place of the `URL` tag (the `# URL:` prefix MUST remain intact):

```specfile
# URL: No URL link available
```

4. The `URL` tag MUST NOT dynamically construct its value using macros such as `%{name}`.

### VCS

Expand All @@ -196,18 +270,22 @@ VCS: git:https://git.example.org/project.git

### Source

1. `Source` MUST specify the URI for downloading the upstream source archive (or a mathematically equivalent, reproducible archive).
1. A Spec that consumes source files or other source inputs MUST declare those inputs using RPM source declarations such as `Source`, `SourceN`, or `%sourcelist`, as appropriate. It MUST specify the URI for downloading the upstream source archive (or a mathematically equivalent, reproducible archive). But if a package that does not consume any source input MAY omit source declarations entirely. Dependency-only meta-packages are a common example.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Source 的来源不一定是上游,也可以是本地输入, 本地输入是需要做简单注释来辅助维持长期维护的

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It MAY specifiy... 可能好一点?毕竟前面有提及 %sourcelist


2. If the `URL` tag value can serve as a valid prefix for the source link, `Source` MAY leverage the `%{url}` macro.
2. When a Spec contains one `Source` entry, it MAY use either `Source` or `Source0`. Both forms refer to source index `0`.

3. For any network-fetched `Source`, a `#!RemoteAsset` comment MUST immediately precede the `Source` declaration. If multiple external sources exist, each MUST be individually annotated.
3. When a Spec uses numbered `SourceN` tags, source indexes SHOULD start at `0` and increase sequentially unless a package-specific reason requires otherwise.

4. For any `Source` fetched using the HTTP or HTTPS protocol, the SHA-256 checksum of the source archive MUST be documented on the line following the `#!RemoteAsset` comment.
4. If the `URL` tag value can serve as a valid prefix for the source link, `Source` MAY leverage the `%{url}` macro.

5. For any network-fetched `Source`, a `#!RemoteAsset` comment MUST immediately precede the `Source` declaration. If multiple external sources exist, each MUST be individually annotated.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里少了一个 #!CreateArchive 标签的情况


6. For any `Source` fetched using the HTTP or HTTPS protocol, the SHA-256 checksum of the source archive MUST be documented on the line following the `#!RemoteAsset` comment.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

有歧义,表达的是行中,但是断句是 on ,the line following xxx , 还是 on the line, following..

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

确实会理解成另起一行。

For conveience, it can be generated automatically with [remoteassetify](/docs/guide/remoteassetify-usage-guide).

5. If the tarball filename is obscured or cannot be algorithmically inferred from the URL, `Source` SHOULD explicitly dictate the desired tarball name via a URL fragment (e.g., `#/name.tar.gz`) to guarantee predictable local file naming.
7. If the tarball filename is obscured or cannot be algorithmically inferred from the URL, `Source` SHOULD explicitly dictate the desired tarball name via a URL fragment (e.g., `#/name.tar.gz`) to guarantee predictable local file naming.

6. `Source` Indexing Rules:
8. `Source` Indexing Rules:
1. The base index defaults to `0` and increments by 1 for each subsequent source.
2. If the Spec specifies only a single-source archive, the index MAY be omitted entirely.

Expand All @@ -220,6 +298,15 @@ Source0: https://example.org/example-%{version}.tar.gz
Source1: https://example.org/example-%{version}-additional.tar.gz
```

A Spec MAY also use an RPM source-list mechanism when it better represents a set of local source inputs:

```specfile
%sourcelist
file1.conf
file2.conf
file3.conf
```

For details regarding source URLs, see the [Source Packages](/docs/guide/packaging-guidelines/SourceURL) supplementary specification.

### BuildArch (optional)
Expand All @@ -232,17 +319,15 @@ For details regarding source URLs, see the [Source Packages](/docs/guide/packagi

### BuildSystem

1. Every Spec MUST declare a `BuildSystem` tag.
1. A Spec that uses the RPM declarative build system mechanism MUST declare the corresponding build system with `BuildSystem`.

2. A Spec that does not use the declarative build system mechanism MAY omit `BuildSystem`. Examples include source-less meta-packages, data-only packages, and packages that implement their required stages explicitly.

2. `BuildSystem` values SHOULD be restricted to the following supported systems (or formally introduced future systems):
- `autotools`
- `cmake`
- `meson`
- `golang`
- `golangmodules`
- `pyproject`
3. A Spec MUST NOT add an empty `BuildSystem` tag only to indicate that no declarative build system applies.

3. If the package utilizes an unsupported build system, or requires no configuration phase whatsoever, `BuildSystem` MAY be left blank. However, the Spec MUST include an adjacent comment explicitly justifying this omission.
4. When present, the `BuildSystem` value MUST identify a supported declarative build system. The [Declarative Build Systems](/docs/guide/packaging-guidelines/BuildSystems) supplementary specification defines the available build systems and their requirements.

The main packaging specification does not maintain a separate list of `BuildSystem` values.

When supplementary pre- or post-stage interventions are required, the Spec MAY deploy modifier tags. For example:

Expand Down Expand Up @@ -270,13 +355,6 @@ For system-specific build patterns, see the [Declarative Build Systems](/docs/gu

- If `BuildOption` is absent, patches SHOULD be located between `BuildSystem` and `BuildRequires`.

5. `BuildOption` entries SHOULD be written in the same order as the RPM build process, namely:
```specfile
%build
%install
%check
```

For the comprehensive patch strategy, see the [Patches](/docs/guide/packaging-guidelines/Patch) supplementary specification.

### BuildOption (optional)
Expand All @@ -289,27 +367,42 @@ For the comprehensive patch strategy, see the [Patches](/docs/guide/packaging-gu

4. When utilized, `BuildOption` SHOULD reside between the `BuildSystem` and `BuildRequires` blocks.

5. `BuildOption` entries SHOULD be written in the same order as the RPM build process, for example:

```specfile
BuildOption(conf): <configuration-option>
BuildOption(build): <build-option>
BuildOption(install): <installation-option>
BuildOption(check): <test-option>
```

### BuildRequires

1. `BuildRequires` MUST list all build-time dependencies exhaustively.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

可能补充一句 只有动态机制没有覆盖的依赖才需要静态补充


2. These dependencies MUST adhere to the "one dependency per line" formatting rule.

3. For standard C/C++ applications, it is generally unnecessary to explicitly specify a compiler like `gcc`.
3. When a package requires no additional build-time dependencies beyond the guaranteed basic build environment, the Spec MAY omit `BuildRequires`. For example, for standard C/C++ applications, it is generally unnecessary to explicitly specify a compiler like `gcc`.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里不能说默认不要 gcc 之类,建议是形成一个引用清单,有个 basic build environment 什么的注释 和引用链接,目标是尽量一份 spec 能自动推导出完整相关上下文,减少约定俗成

@misaka00251 misaka00251 Sep 4, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Z572 这个清单如何维护?总不可能让开发者直接来看 Open Build Service 上的 Project Config,但一旦我们修改了 Project Config 内的 Preinstall: 也应该同步到对应的清单(如有)上。
这样顺便能解决上面的第一条问题。


4. If a dependency is dynamically resolved via `pkg-config`, `BuildRequires` SHOULD utilize the `pkgconfig(xxx)` syntax rather than hardcoding the `xxx-devel` package name.

5. The Spec MUST guarantee absolute completeness of build dependencies; it MUST NOT omit required packages under the assumption that the build root happens to have them pre-installed.

For strategies on resolving dependencies, see the [Using pkgconfig(xxx)](/docs/guide/packaging-guidelines/PkgConfigBuildRequires) supplementary specification.

### Requires / Provides / Conflicts / Obsoletes (optional)
### Requires / Provides / Conflicts / Obsoletes / Recommends / Supplements (optional)

1. `Requires` dictates runtime dependencies; these MUST also follow the "one dependency per line" rule.

2. During package renaming, logical splitting, or major migrations, the Spec MUST guarantee a seamless upgrade path using Provides and Obsoletes (see the [Package Splitting](/docs/guide/packaging-guidelines/SplitPackage) supplementary specification).
2. When a package does not need any explicit runtime dependency, the Spec MAY omit `Requires`.

3. The absence of an explicit `Requires` tag does not exempt a package from having correct runtime dependencies. Maintainers MUST ensure that automatic and explicit dependency mechanisms together describe the package's runtime requirements correctly.

4. A Spec MAY use `Provides`, `Recommends`, and `Supplements` when the package needs to express the corresponding package relationship.

5. During package renaming, logical splitting, or major migrations, the Spec MUST guarantee a seamless upgrade path using `Provides` and `Obsoletes` (see the [Package Splitting](/docs/guide/packaging-guidelines/SplitPackage) supplementary specification).

3. If strict incompatibilities exist, `Conflicts` MAY be utilized. However, it SHOULD be applied with extreme caution to prevent creating unresolvable dependency graphs.
6. If strict incompatibilities exist, `Conflicts` MAY be utilized. However, it SHOULD be applied with extreme caution to prevent creating unresolvable dependency graphs.

## Section Requirements

Expand All @@ -325,7 +418,7 @@ The `%description` section MUST provide a comprehensive, informative overview of

### %files

The `%files` section MUST inventory all artifacts bundled into the resulting binary package, adhering to the following constraints:
Every Spec MUST contain a `%files` section for the main package. The `%files` section MUST inventory all artifacts bundled into the resulting binary package, adhering to the following constraints:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

有没有只有子包的 spec,有的话这样就一定有一个空主包,是必要的吗

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for example: SPECS/stb/stb.spec

@misaka00251 misaka00251 Sep 4, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

如果主包确实没有任何文件被放入的话,空主包是没有问题的: rpm-software-management/rpm#3584
我觉得我们可以不省略。


1. Licensing documents MUST be tagged with `%license`; standard documentation SHOULD be tagged with `%doc`.

Expand Down
Loading