制作 rpm 包

一、安装和构建项目

  • 安装
$ yum install -y rpm-build rpmdevtools
  • 构建项目
$ rpmdev-setuptree
$ tree rpmbuild/
rpmbuild/
├── BUILD                源码解压并编译的临时目录
├── BUILDROOT            最终安装目录,保存 %install 阶段安装的文件
├── RPMS                 最终生成二进制 RPM 安装包
├── SOURCES              所有源码包(.tar.gz)及需要的补丁文件
├── SPECS                配置文件,定义 rpmbuild 在构建时的所有操作
└── SRPMS                最终生成的源码rpm包

二、spec 说明

  • rpmbuild 每个文件对应的宏
名称 默认位置 用途
%{_specdir} Spec 文件目录 ~/rpmbuild/SPECS 保存 RPM 包配置(.spec)文件
%{_sourcedir} 源代码目录 ~/rpmbuild/SOURCES 保存源码包(如 .tar 包)和所有 patch 补丁
%{_builddir} 构建目录 ~/rpmbuild/BUILD 源码包被解压至此,并在该目录的子目录完成编译
%{_buildrootdir} 最终安装目录 ~/rpmbuild/BUILDROOT 保存 %install 阶段安装的文件
%{_rpmdir} 标准 RPM 包目录 ~/rpmbuild/RPMS 生成/保存二进制 RPM 包
%{_srcrpmdir} 源代码 RPM 包目录 ~/rpmbuild/SRPMS 生成/保存源码 RPM 包(SRPM)
  • spec 文件中标签
名称 说明
Name %{name} 软件包名,与spec的文件名保持相同。
Version %{version} 版本号
Release %{release} 发行编号,初始值为 1%{?dist},后期制作新版本时,递增该值。若Version发布新版本,该值重新设置为1。
Summary 软件包介绍(简洁)。
License 软件授权协议。
URL 该软件包的项目主页
Sources %{source} 源码包名称,若有多个源码包,增加标签Sources1、Sources2...
BuildRequires 编译软件包所需的依赖包列表,以逗号分隔
Requires 安装软件包时所需的依赖包列表,以逗号分隔
  • spec 文件中预定义宏
对应目录 说明
%{_bindir} /usr/bin 二进制目录:保存可执行文件
%{_builddir} ~/rpmbuild/BUILD 构建目录:软件在 build 的子目录被编译。参考 %buildsubdir
%{buildroot} ~/rpmbuild/BUILDROOT Build root:%install 阶段中,将 %{_builddir} 子目录下的文件复制到 %{buildroot} 的子目录(之前,%{buildroot} 使用的位置为 "/var/tmp/")
%{buildsubdir} %{_builddir}/%{name} 构建子目录:%build 阶段中,文件会在 %{_builddir} 的子目录中编译。此宏在 %autosetup 之后设置
%{_datadir} /usr/share 共享数据目录
%{_defaultdocdir} /usr/share/doc 默认文档目录
%{dist} .fcNUMBER 发行版名称+版本号(例如 ".fc33")
%{fedora} NUMBER Fedora 发行版本号(例如 "33")
%{_includedir} /usr/include 程序头文件目录
%{_infodir} /usr/share/info info 手册目录
%{_initrddir} /etc/rc.d/init.d init 脚本目录
%{_libdir} /usr/lib 共享库目录
%{_libexecdir} /usr/libexec 仅由系统调用执行该目录中的命令
%{_localstatedir} /var 保存缓存/日志/lock等信息的目录
%{_mandir} /usr/share/man man 手册目录
%{name} 软件包名称,通过 Name: tag 设置
%{_sbindir} /usr/sbin 保存管理员可执行命令
%{_sharedstatedir} /var/lib 保存程序运行所处理的文件
%{_sysconfdir} /etc 配置文件目录
%{version} 软件包版本,通过 Version: tag 设置
  • spec 文件执行阶段
阶段 说明
%prep 读取位于 %_sourcedir 目录的源代码和 patch 。之后,解压源代码至 %_builddir 的子目录并应用所有 patch。
%build 编译位于 %_builddir 构建目录下的文件。通过执行类似 "./configure && make" 的命令实现。
%install 读取位于 %_builddir 构建目录下的文件并将其安装至 %_buildrootdir 目录。这些文件就是用户安装 RPM 后,最终得到的文件。注意一个奇怪的地方: 最终安装目录 不是 构建目录。通过执行类似 "make install" 的命令实现。
%pre rpm 安装前执行
%post rpm 安装完成后执行
%preun rpm 卸载前执行的脚本
%postun rpm 卸载后执行的脚本
%check 检查软件是否正常运行。通过执行类似 "make test" 的命令实现。很多软件包都不需要此步。
%files 表示为所有要被打包的文件清单
  • %files 中的宏
说明
%doc 文档
%config 配置文件
%attr 文件属性,包括许可、用户和用户组
%defattr 文件默认属性分别(文件权限,属主,属组,目录权限)
例如 %defattr (-,root,root,-) : - 表示默认值,由umask决定,通常对文本文件是0644,可执行文件是0755
%ghost 文件包含在包中,但不进行安装
%verify 验证文件的各种属性以保证完整性

三、打包命令 rpmbuild

  • 打包参数
参数 说明
-bp 只作准备 (解压与打补丁)
-bc 准备并编译
-bi 编译并安装
-bl 检验文件是否齐全
-ba 编译后做成*.rpm和src.rpm
-bb 编译后做成*.rpm
-bs 只做成*.src.rpm
  • 其他参数
参数 说明
--buildroot <root> 构建包时,以值 root 覆盖标签 BuildRoot 的值。
--clean 清除软件包构建目录。
--nobuild 不执行任何构建阶段,用于测试 spec 文件。
--noprep 不执行 %prep 构建阶段。
--noclean 不执行 %clean 构建阶段。
--nodebuginfo 不产生调试信息包。
--nodeps 不验证构建依赖。
--rmsource 构建后移除源码包,也可以单独使用,比如 rpmbuild --rmsource foo.spec。
--rmspec 构建后移除 spec 文件,同 --rmsource。
--with <option> 使能选项 option。
--without <option> 禁止选项 option。
--showrc 显示 rpmbuild 当前使用的所有的宏。

四、rpm 常用命令

  • 安装 rpm 显示详细过程
$ rpm -ivvh 包
  • 参看已安装的所有包
$ rpm -qa
  • 查看已安装的包
$ rpm -q 包名
  • 删除包
$ rpm -e  包名
  • 查看某包的依赖
$ rpm -qR 包名

五、示例 将 Python 打包成 rpm

1. 打包 python 为可执行脚本

使用 PyInstaller 工具
注意:打包不同操作系统的可执行文件,需要到对应的操作系统中进行打包

# 安装
$ pip install PyInstaller

# 打包
$ Python -m PyInstaller -F test.py
$ cd disk
$ ls
test      打包后的可执行程序
2. 打包 rpm

创建 rpm 工作目录

$ rpmdev-setuptree
$ cd SPECS
$ vim test.spec

test.spec

Name:     test
Version:  1.0
Release:  0%{?dist}
Summary:  Configure the kvm environment and install pylon and drone
License:  GPLv3+
URL:      http://www.cetccloud.com
Source0:  test-1.0.tar.gz

BuildRequires:  gettext
# 在 %post 中执行命令时使用 bash 
Requires(post): bash

%description
描述

%prep
# 主要作用是解压 %{source} 指定的源码包
# 参数
# -n <dir>    指定自动进入目录名称。用于当源码解压后目录名不规范。
# -c  解压之前先创建默认目录,用于压缩文件未包含在一个顶层目录下。
# -q  抑制输出,可以减少日志的输出。
# -D  解压前不删除目录。
# -T  不执行默认解压动作。
# -b <num>    切换目录前,解压 %{source<num>} 指定的包。
# -a <num>    切换目录后,解压 %{source<num>} 指定的包。
%setup -c n test

# 编译源码包
%build
echo "aaaaaaaa"

# 在构建rpm包时执行。注意这个不会再安装rpm包时执行
%install
# 在根据路创建保存脚本的目录
mkdir -p %{buildroot}/pytest/
# 将可执行文件放入到创建的目录中
install %{name}-%{version}/test %{buildroot}/pytest/test1.0

# rpm 包安装完成后执行
%post
# 执行python可执行文件
/pytest/test1.0

# 为所有要被打包的文件清单
%files
# 文档
%doc
/pytest/install_rpm/*
/pytest/test1.0

%changelog
* Thu Dec 23 2021 Ma Chao <machao_ma@qq.com> - 1.0
- asdf
3. 打包 rpm
$ rpmbuild -bb SPEC/test.spec
4. 安装 rpm
$ rpm -ivvh test-1.0-0.rpm
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容