openEuler RPM Packaging

🚨 openEuler 专项 RPM 打包规范。任何涉及 openEuler 打包的场景,都必须读取此技能。**openEuler 规则与通用 RPM 不同**:5 包拆分规则、专用 changelog 格式(Type/ID/SUG/DESC)、openEuler 专用宏、检视原则。不适用于其他发行版。

Audits

Pass

Install

openclaw skills install openeuler-rpm

openEuler RPM 打包技能 — openEuler 打包规范的唯一来源

⚠️ 核心规则:

openEuler 的打包规则与通用 RPM 有显著差异。通用 RPM 知识不够用。

差异包括:5 包拆分规则、专用 changelog 格式(Type/ID/SUG/DESC 四字段)、openEuler 专用宏(%disable_rpath, %delete_la_and_a 等)、检视原则。这些在通用 RPM 文档中都不存在。

因此:任何 openEuler 打包场景,都必须读取此技能。绝不能用通用 RPM 知识代替。

🚨 触发规则 — 遇到以下任何情况,立即读取此技能

如果你要做…你应该…禁止行为
为 openEuler 编写/修改 spec✅ 读取此技能❌ 用通用 RPM 模板
拆分 openEuler 子包(libs/devel/static/help)✅ 读取此技能❌ 按 Fedora/CentOS 方式拆分
写 openEuler changelog✅ 读取此技能❌ 用通用 changelog 格式(必须用 Type/ID/SUG/DESC)
使用 openEuler 专用宏✅ 读取此技能❌ 凭记忆写 %disable_rpath 等宏
openEuler 包检视/审查✅ 读取此技能❌ 用通用标准检查
处理 openEuler 补丁命名✅ 读取此技能❌ 用其他发行版的补丁命名规则
判断 openEuler 架构支持✅ 读取此技能❌ 凭记忆写 ExcludeArch
openEuler 包升级✅ 读取此技能❌ 直接改版本号不更新 changelog

如何判断该读哪个技能?

发行版读取技能
openEuleropeneuler-rpm(同时自动获得 rpm 能力)
Fedora / CentOS / RHELrpm(通用 RPM)
不确定是哪个发行版两个都读

快速自检

当你要为 openEuler 编写或修改 任何 spec 文件、changelog、子包拆分、宏使用 时,问自己:

"openEuler 的 changelog 格式是什么?包拆分规则是什么?专用宏怎么用?"

如果不确定 → 读取此技能


🎯 核心原则

openEuler 打包原则:不做复杂的拆分,将软件拆分为基本固定的 5 个 RPM 包,保持包的简洁。

📦 包拆分规则

openEuler 标准包结构(5 个):

包类型包名内容关键点
主包mypackage命令、配置、so、license、copyright、readme、man/info可通过 Provides/Obsoletes 兼容其他 OS
libs 包mypackage-libs对外提供的动态库、命令分离功能与能力,避免循环依赖
devel 包mypackage-devel头文件、Example、tests、开发内容devel 包需 Requires 主包
static 包mypackage-static静态库.a、静态版本可使用宏控制
help 包mypackage-help二次开发文档、手册文档大时才拆分

特殊拆分

  • for-language 包:python2-mypackagepython3-mypackageperl-mypackage
  • 本地化支持:mypackage-lang(复杂国际化相关软件)
  • 其他复杂包:gcc、python2、python3 等

📝 Spec 文件结构

标准模板(主包)

Name:           mypackage
Version:        1.0.0
Release:        1%{?dist}
Summary:        Package summary

License:        MIT
URL:            https://example.com
Source0:        https://github.com/%{url}/releases/download/%{version}/%{name}-%{version}.tar.gz

BuildRequires:  gcc
BuildRequires:  make
Requires:       glibc >= 2.17

# openEuler 补丁命名:PATCH-(BUGFIX|CVE|FEATURE)-内容
# Patch0:       PATCH-BUGFIX-fix-build.patch

%description
Detailed package description.

%prep
%autosetup -p1

%build
%configure
%make_build

%install
%make_install

%check
%make_test

%files
%license LICENSE
%doc README.md
%{_bindir}/%{name}

%changelog
* Tue Apr 7 2020 openEuler Buildteam <buildteam@openeuler.org> - 10.33-3
- Type: CVES
- ID: CVE-2019-20454
- SUG: NA
- DESC: fix CVE-2019-20454

* Wed Apr 15 2026 zhangsan <zhangsan@example.com> - 1.0.0-1
- Type: Feature
- ID: NA
- SUG: NA
- DESC: Initial packaging for openEuler

multi-package 模板

# ——— 主包 ——————————————————————————————————————

Name:           mypackage
Version:        1.0.0
Release:        1%{?dist}
Summary:        Main package

License:        MIT
URL:            https://example.com
Source0:        https://github.com/%{url}/releases/download/%{version}/%{name}-%{version}.tar.gz

BuildRequires:  gcc
BuildRequires:  make
Requires:       %{name}-libs = %{version}-%{release}

%description
Main package containing commands, configs, and runtime libraries.

%files
%license LICENSE
%doc README.md
%{_bindir}/%{name}
%{_libdir}/lib%{name}.so.*

# ——— libs 包 ——————————————————————————————————————

%package -n libs
Summary:        Libraries for %{name}
Requires:       %{name} = %{version}-%{release}

%description -n libs
Runtime libraries for %{name}.

%files -n libs
%{_libdir}/lib%{name}.so.*

# ——— devel 包 ——————————————————————————————————————

%package -n devel
Summary:        Development files for %{name}
Requires:       %{name}-libs = %{version}-%{release}
Requires:       %{name} = %{version}-%{release}

%description -n devel
Development files for %{name}.

%files -n devel
%{_includedir}/%{name}/
%{_libdir}/lib%{name}.so
%{_libdir}/pkgconfig/%{name}.pc

# ——— static 包(可选) ——————————————————————————

%package -n static
Summary:        Static libraries for %{name}
Requires:       %{name}-devel = %{version}-%{release}

%description -n static
Static libraries for %{name}.

%files -n static
%{_libdir}/lib%{name}.a

# ——— help 包(可选,文档大时) ——————————————

%package -n help
Summary:        Documents for %{name}
BuildArch:      noarch
Requires:       man info

%description -n help
Man pages and other related documents for %{name}.

%files -n help
%{_datadir}/%{name}/doc/

🔧 openEuler 专用宏

# 删除 rpath
%disable_rpath
sed -i 's|^hardcode_libdir_flag_spec=.*|hardcode_libdir_flag_spec=""|g' libtool \
sed -i 's|^runpath_var=LD_RUN_PATH|runpath_var=DIE_RPATH_DIE|g' libtool

# 删除 .la 和 .a 文件
%delete_la_and_a
find $RPM_BUILD_ROOT -type f -name "*.la" -delete \
find $RPM_BUILD_ROOT -type f -name "*.a" -delete

# 删除 .la 文件
%delete_la
find $RPM_BUILD_ROOT -type f -name "*.la" -delete

# 删除 chrpath
%chrpath_delete
find $RPM_BUILD_ROOT/ -type f -exec file {} ';' | grep "<ELF>" | awk -F ':' '{print $1}' | xargs chrpath --delete {}

# help 子包定义
%package_help
%package        help \
Summary:        Documents for %{name} \
Buildarch:      noarch \
Requires:               man info

%description help \
Man pages and other related documents for %{name}.

# info 工具
%install_info()
/sbin/install-info %1 %{_infodir}/dir || :

%install_info_rm()
/sbin/install-info --remove %1 %{_infodir}/dir || :

📋 openEuler 专用规范

1. 来源可靠

  • ❌ 不要内嵌预编译的二进制文件或库文件
  • ❌ 避免多个上游项目捆绑到一个软件包
  • ✅ 软件应该是开源软件
  • ✅ spec 文件要适配 openEuler
  • ❌ 黑名单软件必须不能引入

2. 架构支持

  • 尽量支持 aarch64 和 x86_64 架构
  • 架构强相关内容通过 %ifarch 宏控制
  • 无架构内容构建成 noarch 包
  • 使用 ExcludeArch:ExclusiveArch: 控制

3. changelog 格式

openEuler 要求 changelog 使用特定格式(必须严格遵守):

3.1 标题行格式(必须)

* Day Mon DD YYYY 提交人 <邮箱> - [Epoch:]Version-Release
部分说明示例
日期格式 * 星期 月 日 年* Wed Apr 15 2026
提交人姓名(不带括号)zhangsanlisi
邮箱必须用尖括号包裹<user@example.com>
Epoch可选,取决于 spec 是否定义了 Epoch 字段。若定义了必须写,否则不写1:
Version与 spec Version 一致2.4.7
Release修改后的 release 值14

完整示例:

# 有 Epoch 的包(如 cups: Epoch: 1)
* Wed Apr 15 2026 zhangsan <zhangsan@example.com> - 1:2.4.7-13

# 没有 Epoch 的包(大多数)
* Tue Apr 7 2020 openEuler Buildteam <buildteam@openeuler.org> - 10.33-3

3.2 内容行格式(CVES 类型必须包含 4 个字段)

Type 字段取值:CVES / Bugfix / Feature

CVES(多个 CVE 修复):

* Wed Apr 15 2026 zhangsan <zhangsan@example.com> - 1:2.4.7-13
- Type: CVES
- ID: CVE-2026-27447 CVE-2026-34978 CVE-2026-34979
- SUG: NA
- DESC: fix CVE-2026-27447 CVE-2026-34978 CVE-2026-34979

Bugfix(普通缺陷修复):

* Mon Mar 10 2026 lisi <lisi@example.com> - 1:2.4.7-12
- Type: Bugfix
- ID: NA
- SUG: NA
- DESC: fix build failure with gcc-15

Feature(新增功能/版本升级):

* Sat Apr 25 2026 wangwu <wangwu@example.com> - 2.0.0-1
- Type: Feature
- ID: NA
- SUG: NA
- DESC: Update to 2.0.0
字段取值说明
TypeCVES / Bugfix / FeatureCVES=多个CVE,Bugfix=普通修复,Feature=新功能
IDCVE-XXXX-XXXX 或 Bugzilla 编号CVE 修复必须写完整 CVE 编号
SUGNA 或具体建议无特殊建议写 NA
DESC简短描述说明做了什么

3.3 常见错误(必须避免)

错误正确
* Sat Apr 25 2026 zhangsan - 2.4.7-14(缺 <email>、缺 epoch)* Sat Apr 25 2026 zhangsan <zhangsan@example.com> - 1:2.4.7-14
- fix CVE-2026-41079(缺少 Type/ID/SUG/DESC)- Type: CVES\n- ID: CVE-2026-41079\n- SUG: NA\n- DESC: fix CVE-2026-41079
- Type: CVES/Bugfix/Feature(不要写多个类型)每条 changelog 只写一个 Type 值(CVES 或 Bugfix 或 Feature)
your@email.com 等占位邮箱用实际邮箱,从 git config 或已有 changelog 获取

3.4 修改 changelog 的标准流程(必须遵守)

  1. 先查看 spec 是否定义了 Epochgrep "^Epoch" xxx.spec
  2. 参考 spec 已有 changelog 条目的格式 — 看最新一条的写法(日期格式、邮箱格式、Epoch 有无)
  3. 按已有格式风格写入新条目 — 不凭记忆,不自行编造格式

4. 命名规则

  • 主包名称与软件名称同名
  • 如多个版本:mypackage2mypackage-stable
  • 语言模块:python-mypackageperl-mypackage
  • 补丁命名:PATCH-BUGFIX-fix-build.patch

5. 依赖关系

  • Requires: - 软件正常工作所需
  • Recommends: / Suggests: - 非必需但推荐
  • Supplements: / Enhances: - 补充完整性
  • devel 包必须写完整依赖Requires: %{name} = %{version}-%{release}

✅ openEuler 检视原则(必须项)

检查项说明
✅ rpmlint 检查使用 rpmlint 工具检查
✅ 包命名符合 openEuler 命名规则
✅ License 字段必须与实际许可证匹配
✅ spec 文件英语必须用英语撰写且清晰可读
✅ 源代码匹配spec 中 URL 必须与上游源码一致
✅ ExcludeArch未支持的架构必须列出
✅ 构建依赖完整BuildRequires 包含所有依赖
✅ 处理 locale使用 %find_lang
✅ 单一文件不重复原则上不能将单一文件打包到多个 rpm
✅ 文件权限必须正确设置文件权限
✅ UTF-8 文件名rpm 包中的文件名必须是 UTF-8

🔍 常见问题

Q1: 如何使用 openEuler 专用宏?

见上方 🔧 openEuler 专用宏 章节。

Q2: 如何写 changelog?

见上方 ### 3. changelog 格式 章节。必须包含标题行(日期+姓名+邮箱+Epoch可选+Version-Release)和内容行(Type/ID/SUG/DESC)。

Q3: 如何处理多版本包?

openEuler 一般只集成一个版本。如需多版本,需 TC 同意:

# 使用后缀版本号
Name: mypackage2

# 或描述性后缀
Name: mypackage-stable

🔄 依赖技能

本技能依赖:

技能用途
rpm基础 RPM 功能(继承所有 rpm 能力)

版本: 2.0.0 | 作者: openEuler Build Agent