用 rpmdev-setuptree 一键创建标准 rpm 构建目录结构并配置 ~/.rpmmacros,安装 rpm-build、rpmdevtools、redhat-rpm-config 工具链,确保 name/version 与源包名严格匹配,显式声明 buildarch: noarch,%files 路径以 %{buildroot} 为根,%install 中必须使用 destdir=%{buildroot},调试加 --vv 参数。

怎么搭出干净可用的RPM构建环境
别直接在生产机上搞,也别手动 mkdir 一堆目录应付了事——rpmbuild 对路径结构有强约定,错一个就报 File /root/rpmbuild/SOURCES/xxx.tar.gz: No such file or directory 这类“找不到源”的假错误,实际是环境没建对。
- 用
rpmdev-setuptree一键生成标准结构(~/rpmbuild/{SPECS,SOURCES,RPMS,BUILD,SRPMS}),它比手动创建更可靠,还会自动写好~/.rpmmacros配置 - 必须装全工具链:
yum install -y rpm-build rpmdevtools redhat-rpm-config,缺redhat-rpm-config会导致%{?dist}展开失败、%setup -q报错 - 普通用户就能构建,无需 root;但最终安装测试时要用
sudo rpm -ivh,别用su -c混淆权限上下文
SPEC 文件里哪些字段不能省、不能乱写
.spec 不是配置文件,是构建脚本——漏掉 %install 或写错 %files,包能编出来但安装后文件全丢在 /tmp 或根本没拷过去。
-
Name和Version必须和源码压缩包名严格匹配,比如源是mytool-2.1.0.tar.gz,就得写Name: mytool+Version: 2.1.0,否则%setup -q解压失败 -
BuildArch: noarch要显式声明(尤其脚本类工具),不写默认按主机架构走,x86_64 机器打包的包在 aarch64 上会提示no package available -
%files列的路径必须以%{buildroot}为根,例如写/usr/bin/mytool是错的,得写%{_bindir}/mytool或%{buildroot}/usr/bin/mytool;漏掉%defattr(-,root,root)可能导致安装后文件权限为 000
为什么 rpmbuild -ba 总卡在 %build 或 %install 阶段
不是命令错了,是构建逻辑没对齐源码习惯。rpmbuild 默认不会帮你 cd 进解压目录、也不会自动运行 ./configure,所有编译安装动作都得你白纸黑字写进 %build 和 %install 里。
- 如果源码带
Makefile,%build写make,%install写make install DESTDIR=%{buildroot}——DESTDIR是关键,漏了就真把文件装到宿主机/usr下了 - 纯 shell 工具?跳过
%build,在%install里用install -m 0755 %{_sourcedir}/mytool.sh %{buildroot}%{_bindir}/mytool - 调试时加
-vv参数:rpmbuild -ba --vv mytool.spec,能看到每一步执行的真实命令和当前工作目录,比猜快得多
安装后发现命令找不到或配置不生效
常见于没处理好路径宏或忽略安装脚本语义。RPM 不是复制粘贴,它要协调系统状态。
- 检查
%files是否漏了配置文件,比如/etc/mytool.conf没列进去,安装后当然不存在;用%config(noreplace)标记配置文件,避免升级时被覆盖 - 需要开机启动?别只放 service 文件,得在
%post里写systemctl daemon-reload && systemctl enable mytool.service,否则 rpm 装完服务不自启 - 卸载时想清理数据?
%preun和%postun不是摆设:%preun适合停服务,%postun适合删缓存目录,但别在%postun里删/var/log——日志该留还得留
最麻烦的永远不是打包本身,而是 %files 漏项、DESTDIR 忘写、%{buildroot} 和 %{_prefix} 混用——这三处出错,包能生成,但装上去就是个空壳。










