SPEC file writing - Best Practices

这篇是 SPEC 系列的“最佳实践清单”。 目标不是再讲语法,而是减少线上踩坑、提升包的可维护性。

1. 头部字段不要留空

SummaryLicenseURL%description 等信息必须完整。
这些信息会直接体现在 rpm -qi 输出里,也是排障和审计的第一入口。

2. 头部字段对齐,降低阅读成本

推荐统一列宽对齐:

1
2
3
4
5
6
Name:           mydaemon
Version: 1.2.0
Release: 1%{?dist}
Summary: My daemon service
License: MIT
URL: https://example.com/mydaemon

团队协作里,这种“无功能变化但提升可读性”的规范非常值。

3. 分段清晰,段内紧凑

建议:

  1. 段与段之间空一行。
  2. 段内不要插入无意义空行。
  3. 注释聚焦“为什么”,不要重复“做了什么”。

4. 能用宏就不要写死路径

避免硬编码 /usr/etc/usr/lib64,优先使用宏:

  1. %{_bindir}
  2. %{_libdir}
  3. %{_sysconfdir}
  4. %{_unitdir}

好处:跨发行版、跨架构更稳,路径迁移成本更低。

5. %install 尽量只做“安装动作”

不推荐在 %install 里手写大量 mkdir/cp
更推荐把文件安装逻辑放到上游构建系统(Makefile/Makefile.am/CMake install)里,再用:

1
2
3
%install
rm -rf %{buildroot}
make install DESTDIR=%{buildroot}

这样可以让“构建”和“打包”职责清晰分层。

6. %files 不要重复列目录和子文件

规则:

  1. 如果已列目录,子项通常会递归包含。
  2. 不要同一文件在多个子包重复声明。
  3. 主包不要塞测试文件,测试内容拆到独立包。

7. 文件权限优先在 %files%attr 控制

不要在 %postchmod/chown 兜底。
优先在 %files 声明:

1
2
3
%files
%attr(0755,root,root) %{_bindir}/mydaemon
%config(noreplace) %attr(0640,root,root) %{_sysconfdir}/mydaemon/mydaemon.conf

这样升级行为更可预测。

8. 目录归属必须唯一

同一个目录不应被多个 RPM 同时“拥有”。
否则升级/卸载顺序变化时,容易出现目录被误删或文件归属冲突。

原则:

  1. 谁创建目录,谁拥有目录。
  2. 共享目录尽量由基础包统一拥有。

9. 子包拆分要服务于依赖治理

当主包依赖越来越重时,优先拆分:

  1. -libs
  2. -devel
  3. -tests / -integration
  4. -sudoers / -systemd 这类可选能力包

子包拆分的目的不是“包越多越好”,而是“安装最小化 + 依赖清晰化”。

10. 特殊构建开关要显式声明

例如容器专用组件、关闭 debug 子包等,都建议在 SPEC 顶部显式写清:

1
2
%global include_in_build no
%global debug_package %{nil}

并配注释说明“为什么”。

11. 养成宏检查与静态检查习惯

高频命令:

1
2
3
4
5
6
7
8
# 查看所有宏
rpm --showrc

# 查看单个宏
rpm --eval '%{_sysconfdir}'

# 解析 spec,查看会生成哪些包
rpmspec -q path/to/pkg.spec

rpmspec 对发现未展开宏、子包命名异常特别有用。

12. 交付前做“三查一装”

每次发版前至少做:

1
2
3
rpm -qpi xxx.rpm            # 包头
rpm -qpl xxx.rpm # 文件列表
rpm --scripts -qp xxx.rpm # 脚本钩子

然后做一次本机安装验证(建议在干净环境):

  1. 新装
  2. 升级
  3. 卸载

重点观察:配置文件覆盖策略、systemd 行为、依赖是否完整。

13. 我的补充看法

写 SPEC 的核心不是“语法背得多熟”,而是“行为可预测”。
你只要把下面三件事做到位,质量就会明显提升:

  1. %install%files 严格对应。
  2. 主包与子包边界稳定。
  3. 升级路径(配置、脚本、依赖)可重复验证。

做到这三点,SPEC 基本就从“能打包”升级到了“能长期维护”。