0. 概述

在 CentOS 中,我已习惯了使用 Yum/RPM,同时平时也会经常 build rpm,所以在这篇文章中,我想介绍一下我制作 RPM 的一些步骤和经验。

1. 创建构建环境

[[email protected]]# yum install -y rpm-build
[[email protected]]# yum install -y redhat-rpm-config
[[email protected]]# mkdir -p ~/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
[[email protected]]# echo '%_topdir %(echo $HOME)/rpmbuild' > ~/.rpmmacros
[[email protected]]#

2. spec 文件

一个 RPM 是如何被构建的需要一个文件指导,这个文件类似于我们构建 Docker Image 的 Dockerfile,描述 RPM 中包含哪些文件,以及这些文件需要怎么被安装等等。spec 文件通常很复杂,毕竟是包含了 RPM 内的所有信息,但是,这里我只是想介绍一些构建 RPM 的通用流程,所以就来个简单的过程,写一个可以简单安装一个二进制文件的 RPM。

[[email protected]]# cat prometheus.spec
%define debug_package %{nil}

Name:    %{_name}
Version: 2.14.0
Release: release.el7.centos
Summary: %{name}
License: MIT
URL:     https://liqiang.io

Source0: %{name}


%description
%{name}


%install
install -d -m 755 %{buildroot}%{_bindir}
install -c -m 755 %{SOURCE0} %{buildroot}%{_bindir}/%{name}

%files
%defattr(-,root,root,-)
%{_bindir}/%{name}

%changelog

可以看到,和 Dockerfile 类似,RPM 的 spec 也是从上到下读的,但是,不同之处在于 rpm 的 spec 是分阶段的,例如这里有 install 阶段,还有很多其他阶段我都隐藏了。

rpm 的各个阶段以及相关操作

阶段 读取的目录 写入的目录 具体动作
%prep %_sourcedir %_builddir 读取位于 %_sourcedir 目录的源代码和 patch 。之后,解压源代码至 %_builddir 的子目录并应用所有 patch。
%build %_builddir %_builddir 编译位于 %_builddir构建目录下的文件。通过执行类似 "./configure && make" 的命令实现。
%install %_builddir %_buildrootdir 读取位于 %_builddir 构建目录下的文件并将其安装至 %_buildrootdir 目录。这些文件就是用户安装 RPM 后,最终得到的文件。注意一个奇怪的地方: 最终安装目录 不是 构建目录。通过执行类似 "make install" 的命令实现。
%check %_builddir %_builddir 检查软件是否正常运行。通过执行类似 "make test" 的命令实现。很多软件包都不需要此步。
bin %_buildrootdir %_rpmdir 读取位于 %_buildrootdir 最终安装目录下的文件,以便最终在 %_rpmdir 目录下创建 RPM 包。在该目录下,不同架构的 RPM 包会分别保存至不同子目录, “noarch” 目录保存适用于所有架构的 RPM 包。这些 RPM 文件就是用户最终安装的 RPM 包。
src %_sourcedir %_srcrpmdir 创建源码 RPM 包(简称 SRPM,以.src.rpm 作为后缀名),并保存至 %_srcrpmdir 目录。SRPM 包通常用于审核和升级软件包。

3. 构建 RPM

在写完 Spec 文件之后,就可以开始尝试构建 RPM 了。这里 spec 的位置不重要,重要的是二进制(或者软件包)的位置,默认情况下一定要放到:/root/rpmbuild/SOURCES 目录下。

当然,Spec 文件通常放在:/root/rpmbuild/SPECS 目录下,然后就可以执行 rpmbuild 命令了:

[[email protected]]# rpmbuild  --define '_name prometheus' -ba prometheus.spec

然后就坐等构建完成。

4. 验证 RPM

在前面的步骤构建完成之后,那么下一步就是查看一下编译的 RPM 是否正常了:

[[email protected]]# cd /root/rpmbuild/RPMS/x86_64
[[email protected]]# rpm -qpi --changelog prometheus-2.14.0-release.el7.centos.x86_64.rpm
Name        : prometheus
Version     : 2.14.0
Release     : release.el7.centos
Architecture: x86_64
Install Date: (not installed)
Group       : Unspecified
Size        : 44816280
License     : MIT
Signature   : (none)
Source RPM  : prometheus-2.14.0-release.el7.centos.src.rpm
Build Date  : Tue 10 Mar 2020 03:38:51 PM CST
Build Host  : china
Relocations : (not relocatable)
URL         : https://liqiang.io
Summary     : prometheus
Description :
prometheus
[[email protected]]# rpm -ivh prometheus-2.14.0-release.el7.centos.x86_64.rpm
Preparing...                          ################################# [100%]
        file /usr/bin/prometheus from install of prometheus-2.14.0-release.el7.centos.x86_64 conflicts with file from package prometheus-2.2.2-14.el7.smartx.x86_64

OK,可以看到,这一份 RPM 是正常的。

5. Ref