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 是正常的。