定制RPM包(FPM和原生rpmbuild)

article/2025/10/16 8:57:24

例子:
Redis打包(FPM工具)
Nginx打包RPM(FPM工具)
Nginx(SPEC文件打包)
Redis(SPEC文件打包)

一、FPM工具进行打包

1. 更新yum软件源

yum update

2. 安装fpm模块依赖

yum -y install ruby rubygems ruby-devel

请添加图片描述

3. 更换rubygems仓库

  1. 查看当前源
gem source list


2. 更换阿里源

gem sources -a  http://mirrors.aliyun.com/rubygems/


3. 移除原生源

gem sources --remove https://rubygems.org/

请添加图片描述

4. 安装fpm工具

gem install fpm

可能会出现的问题:

请添加图片描述
原因:ruby在centos7中yum最高支持到2.0.0,而fpm安装需要ruby支持到2.3.0
解决办法:

  1. 安装RAM密钥(二选一,失败重复尝试)

命令一:

gpg2 --keyserver hkp://pool.sks-keyservers.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB

命令二:

command curl -sSL https://rvm.io/mpapis.asc | gpg2 --import -

image.png

command curl -sSL https://rvm.io/pkuczynski.asc | gpg2 --import -

image.png

  1. 安装RAM(经常会失败,重复尝试直到成功)
curl -L get.rvm.io | bash -s stable

image.png

  1. 更新配置文件
source /etc/profile.d/rvm.sh
  1. 查看可安装脚本
rvm list known | grep ruby

image.png

  1. 安装ruby 2.6
rvm install 2.6

image.png

  1. 查看当前ruby版本
ruby -v

image.png

5. 检查是否正确安装

fpm --help

6. fpm参数

常用参数

1.-s 指定源类型
2.-t 指定目标类型,即想要制作为什么包
3.-n 指定包的名字
4.-v 指定包的版本号
5.-C 指定打包的相对路径 Change directory to here before searchingforfiles
6.-d 指定依赖于哪些包
7.-f 第二次打包时目录下如果有同名安装包存在,则覆盖它
8.-p 输出的安装包的目录,不想放在当前目录下就需要指定
9.–before-install 软件包安装之前所要运行的脚本;同–pre-install(已弃用)
10.–after-install 软件包安装完成之后所要运行的脚本;同–post-install(已弃用)
11.–before-remove 软件包卸载完成之后所要运行的脚本;同–pre-uninstall(已弃用)
12.–after-remove 软件包卸载完成之后所要运行的脚本;同–post-uninstall(已弃用)

更多参数详情可前往FPM官网查看:https://fpm.readthedocs.io/en/latest/cli-reference.html

7. 安装软件

将源代码软件进行编译安装。具体看软件。建议将一个编译后的软件存放到指定地方。

8. 编写shell脚本

以Nginx为例子:

#!/bin/bash# 源码编译一般都要添加执行用户
useradd nginx -M -s /sbin/nologin

9.打包

打包格式:
fpm -s 源文件类型 -t 目标文件类型 -n 打包后名称 -v 打包后版本号 -d 所需要依赖 --post-install 安装完后执行的脚本 -f 源文件地址
以Nginx为例子:

fpm -s dir -t rpm -n nginx -v 1.20.1 -d 'pcre-devel,openssl-devel' --post-install /root/rpm_building/ngnix_rpm.sh -f /opt/nginx/

参数说明:

1.-s 指定源类型
2.-t 指定目标类型,即想要制作为什么包
3.-n 指定包的名字
4.-v 指定包的版本号
5.-d 指定依赖于哪些包
6.-f 第二次打包时目录下如果有同名安装包存在,则覆盖它
7.–post-install 软件包安装完成之后所要运行的脚本;同–after-install

可能会出现的错误:

  • Need executable ‘rpmbuild’ to convert dir to rpm {:level=>:error}

解决办法:安装rpm-build

yum install rpm-build -y

10.安装rpm包

方法一:rpm命令安装(离线麻烦)

使用rpm命令安装

rpm -ivh nginx-1.20.1-1.x86_64.rpm

这种方法直接安装会出现依赖错误,需要先 yum 或手动安装依赖才能安装 rpm 包。

方法二:yum命令安装(在线简单)

yum -y localinstall nginx-1.20.1-1.x86_64.rpm

这种方法会先安装依赖,再安装rpm包

11.注意点

  1. 测试centos7环境下编译的软件,在centos8下能运行;centos8下编译软件无法在centos7上运行。

二、原生rpmbuild打包rpm包

1.打包流程

  1. 源代码放到%_sourcedir中
  2. 源代码解压到%_builddir中,并进行编译
  3. 将编译好的软件安装到%_buildrootdir中
  4. 编写SPEC文件,并存放到其他目录
  5. 执行打包程序,将打包好的二进制rpm包存放在%_rpmdir中,源码rpm包文件存放在%_srcrpmdir中。
默认位置宏代码名称用途
~/rpmbuild%_topdir工作空间目录保存rpmbuild时的相关文件
~/rpmbuild/SPECS%_specdirSpec 文件目录保存 RPM 包配置(.spec)文件
~/rpmbuild/SOURCES%_sourcedir源代码目录保存源码包(如 .tar 包)和所有 patch 补丁
~/rpmbuild/BUILD%_builddir构建目录源码包被解压至此,并在该目录的子目录完成编译
~/rpmbuild/BUILDROOT%_buildrootdir最终安装目录保存 %install 阶段安装的文件
~/rpmbuild/RPMS%_rpmdir标准 RPM 包目录生成/保存二进制 RPM 包
~/rpmbuild/SRPMS%_srcrpmdir源代码 RPM 包目录生成/保存源码 RPM 包(SRPM)

源码rpm包和二进制rpm包区别:

  • 源码rpm包运行后是出现源码文件,要运行程序还要进行make进行编译。打包原理:压缩源码文件目录,跟压缩包一样。
  • 二进制rpm包解压后直接就可以运行文件。打包原理:先进行源码包的编译和安装,然后将安装好的文件进行打包。

2.SPEC文件

SPEC文件说明:

阶段读取的目录写入的目录具体动作
%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%_srcrpmdirb创建源码 RPM 包(简称 SRPM,以.src.rpm作为后缀名),并保存至%_srcrpmdir目录。SRPM 包通常用于审核和升级软件包。

3.宏定义文件

宏定义:
宏的格式–> %_topdir
宏表示一个变量,如环境变量。这个变量指向一个路径或者其他含义。

查找rpmbuild定义文件

rpmbuild --showrc | grep Macro

image.png
从这张图中看出很多地方都可以定义宏。

查询宏命令路径

rpmbuild --showrc | grep _mandir

常用宏文件的定义

%{_sysconfdir} /etc
%{_prefix} /usr
%{_exec_prefix} %{_prefix}
%{_bindir} %{_exec_prefix}/bin
%{_libdir} %{_exec_prefix}/%{_lib}
%{_libexecdir} %{_exec_prefix}/libexec
%{_sbindir} %{_exec_prefix}/sbin
%{_sharedstatedir} /var/lib
%{_datarootdir} %{_prefix}/share
%{_datadir} %{_datarootdir}
%{_includedir} %{_prefix}/include
%{_infodir} /usr/share/info
%{_mandir} /usr/share/man
%{_localstatedir} /var
%{_initddir} %{_sysconfdir}/rc.d/init.d
%{_var} /var
%{_tmppath} %{_var}/tmp
%{_usr} /usr
%{_usrsrc} %{_usr}/src
%{_lib} lib (lib64 on 64bit multilib systems)
%{_docdir} %{_datadir}/doc
%{buildroot} %{_buildrootdir}/%{name}-%{version}-%{release}.%{_arch}
$RPM_BUILD_ROOT %{buildroot}

4.安装rpmbuild工具

yum install rpm-build -y

5.建立工作路径

在家目录下分别创建rpmbuild/BUILD、rpmbuild/RPMS、rpmbuild/SOURCES、rpmbuild/SPECS、rpmbuild/SRPMS目录。

mkdir -p ~/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}

image.png
文件夹含义:

默认位置宏代码名称用途
~/rpmbuild%_topdir工作空间目录保存rpmbuild时的相关文件
~/rpmbuild/SPECS%_specdirSpec 文件目录保存 RPM 包配置(.spec)文件
~/rpmbuild/SOURCES%_sourcedir源代码目录保存源码包(如 .tar 包)和所有 patch 补丁
~/rpmbuild/BUILD%_builddir构建目录源码包被解压至此,并在该目录的子目录完成编译
~/rpmbuild/BUILDROOT%_buildrootdir最终安装目录保存 %install 阶段安装的文件
~/rpmbuild/RPMS%_rpmdir标准 RPM 包目录生成/保存二进制 RPM 包
~/rpmbuild/SRPMS%_srcrpmdir源代码 RPM 包目录生成/保存源码 RPM 包(SRPM)

6.下载源码

cd ~/rpmbuild/SOURCES
wget http://ftp.gnu.org/gnu/hello/hello-2.10.tar.gz

image.png

7.编写SPEC文件

cd ~/rpmbuild/SPECS
vim hello.spec

spec文件进去后会自动加载模板,模板初始样子如下:
image.png
编写好的文件如下:

# 软件名
Name:           hello
# 版本号
Version:        2.10
# 发布编号
Release:        1%{?dist}
# 软件说明
Summary:        The "Hello World" program from GNU
Summary(zh_CN): GUN "Hello Word" 程序
# 包所属类别,但目前基本已经被弃用,直接删除即可
Group:          Applications/Productivity
# 软件包的版权协议
License:        GPLv3+URL:            http://ftp.gnu.org/gnu/hello
Source0:        http://ftp.gnu.org/gnu/hello/%{name}-%{version}.tar.gz# 编译需要的依赖
BuildRequires: gettext
# 本软件需要的依赖
#Requires:      
# 安装后的依赖
Requires(post): info
# 卸载前的依赖
Requires(preun): info# 描述
%description
The "Hello World" program, done with all bells and whistles of a proper FOSS
project, including configuration, build, internationalization, help files, etc.%description -l zh_CN
"Hello World" 程序, 包含 FOSS 项目所需的所有部分, 包括配置, 构建, 国际化, 帮助文件等.%prep
%setup -q# 编译阶段执行的命令
%build
%configure
make %{?_smp_mflags}# 安装阶段执行的命令
%install
make install DESTDIR=%{buildroot}
# 查找 install 中的语言文件
%find_lang %{name}
rm -f %{buildroot}/%{_infodir}/dir# 安装后执行的命令
%post
/sbin/install-info %{_infodir}/%{name}.info %{_infodir}/dir || :# 卸载前执行的命令
%preun
if [ $1 = 0 ] ; then
/sbin/install-info --delete %{_infodir}/%{name}.info %{_infodir}/dir || :
fi# 将所需要打包的文件都存放到这边中;-f %{name}.lang 加上后的意思为声明找到的文件
%files -f %{name}.lang
# doc添加的是说明文档
%doc AUTHORS ChangeLog NEWS README THANKS TODO
%license COPYING
%{_mandir}/man1/hello.1.*
%{_infodir}/hello.info.*
%{_bindir}/hello# 软件更新说明
%changelog
* Sun Dec 4 2016 Your Name <youremail@xxx.xxx> - 2.10-1
- Update to 2.10
* Sat Dec 3 2016 Your Name <youremail@xxx.xxx> - 2.9-1
- Update to 2.9

8.检查SPEC文件正确性

rpmlint hello.spec

9.构建rpm包

cd ~/rpmbuild/SPECS
rpmbuild -ba hello.spec

image.png
查看下输出的内容:

tree ~/rpmbuild/*RPMS

image.png


http://chatgpt.dhexx.cn/article/iEWyW3L1.shtml

相关文章

12.4 RPMB

UFS里&#xff0c;有这么一个LU&#xff0c;主机往该LU写数据时&#xff0c;UFS设备会校验数据的合法性&#xff0c;只有特定的主机才能写入&#xff1b;同时&#xff0c;主机在读取数据时&#xff0c;也提供了校验机制&#xff0c;保证了主机读取到的数据是从该LU上读的数据&a…

rpmbuild编译安装制作rpm包

什么是rpm包? rpm 相当于windows中的安装文件,它会自动处理软件包之间的依赖关系。 rpm优点: 包管理系统简单,通过几个命令就可以实现包的安装、升级、卸载。 安装速度比源码包快的多。 缺点: 经过编译,不能看到源代码,功能选择不如源码灵活。依赖性强。 首先说一下流程…

Linux下软件部署安装管理----rpmbuild打包rpm包部署安装

来源&#xff1a;微信公众号「编程学习基地」 文章目录 1.安装rpmbuild2.rpm包制作打包rpm包 3.rpm包安装4.rpm包卸载 1.安装rpmbuild yum install rpmbuild yum install rpmdevtools创建rpm包管理路径&#xff0c;生成rpm相关目录 RPM打包的时候需要编译源码&#xff0c;还…

rpmbuild打包rpm

一、rpmbuild及rpm rpm rpm命令 是RPM软件包的管理工具。rpm原本是Red Hat Linux发行版专门用来管理Linux各项套件的程序&#xff0c;由于它遵循GPL规则且功能强大方便&#xff0c;因而广受欢迎。逐渐受到其他发行版的采用。RPM套件管理方式的出现&#xff0c;让Linux易于安…

RPMB详解

这里写自定义目录标题 RPMB详解1. 简介1.1. 概述1.2. 基本原理 2. 命令需求3. 用于RPMB访问的数据帧4. RPMB的组成5. mac计算6. 访问流程6.1. 写认证密钥&#xff08;write Authentication Key&#xff09;6.2. 读计数器值&#xff08;Reading of the Counter Value&#xff09…

python项目使用setuptools和rpmbuild构建rpm包

python项目使用setuptools和rpmbuild构建rpm包 文章目录 python项目使用setuptools和rpmbuild构建rpm包一、setuptools二、使用rpmbuild&#xff0c;编写.spec文件构建rpm包三、使用pyinstaller四、参考文献&#xff1a; 一、setuptools 作为 Python 标准的打包及分发工具&…

rpm(基本命令、Makefile、建立rpmbuild编包)

文章目录 一、rpm基本命令介绍1.安装软件2、升级软件3、查询软件包的详细信息4、查询某个文件是属于那个rpm包的5、查该软件包所包含的文件6、查看软件包所依赖的软件7、查看某个包是否被安装8、卸载 二、rpm命令实践三、把c语言程序和makefile内容&#xff0c;编译情况和执行情…

rpmbuild制作rpm 包

什么是rpm包&#xff1f; rpm 相当于windows中的安装文件&#xff0c;它会自动处理软件包之间的依赖关系。 rpm优点&#xff1a; 包管理系统简单&#xff0c;通过几个命令就可以实现包的安装、升级、卸载。 安装速度比源码包快的多。缺点&#xff1a; 经过编译&#xff0c…

项目打包rpm包(rpmbuild)

这里以python项目为例&#xff0c;通过rpmbuild工具打包成rpm包&#xff0c;并进行安装验证 rpmbuild打包 rpm流程 构建rpmbuild打包目录 rpmbuild 默认变量配置文件 将我们的python项目和依赖包压缩成xx.tar.gz格式&#xff0c;并copy到SOURCE目录 我们这里以datalake-demo…

前向星和链式前向星

链接&#xff1a;https://blog.csdn.net/ACdreamers/article/details/16902023 我们首先来看一下什么是前向星. 前向星是一种特殊的边集数组,我们把边集数组中的每一条边按照起点从小到大排序,如果起点相同就按照终点从小到大排序, 并记录下以某个点为起点的所有边在数组中的…

关于链式前向星

最近看了许多题目都用了比较奇怪的东西… 后面才发现是神奇的链式前向星….. 听名字就觉得很牛啊&#xff01; 然而其实很简单…… 组成:begin,next,to,w,与一个用来标记的e begin[n]数组&#xff1a;代表编号为n的点,最后一条边的储存位置 next[n]:是用来保存从同一个点…

链式前向星(加快图的搜索)

存储一个图通常有两种方式&#xff1a;邻接矩阵和邻接表。如果一个图中的边非常少&#xff0c;那么邻接矩阵就比较稀疏&#xff0c;浪费空间&#xff0c;如果点非常多&#xff0c;则矩阵的内存有可能会爆掉。用向量实现的邻接表在点非常多的时候同样比较慢&#xff0c;在一些题…

链式前向星存储图

第七天链式前向星存图 图片如下所示 本代码存的是有向图&#xff0c;图示为无向图。 #include<iostream> using namespace std; const int maxn 100; struct node//to 边的终点编号&#xff0c;w 权值&#xff0c; next 以 x 为起点的上一条边的编号 {int to,w,next;…

链式前向星存图 详细解析

文章目录 链式前向星完整代码 链式前向星 链式前向星是一种图的存储方式&#xff0c;相比于 邻接矩阵和邻接表 &#xff0c;链式前向星是一种静态链表存储&#xff0c;用边集数组和邻接表相结合&#xff0c;可以快速访问一个顶点的所有邻接点。 在某些算法题中使用还很频繁&a…

C++之链式前向星

链式前向星 基本定义以及实现链式前向星实现DFSBFS 基本定义以及实现 (若果有一定了解&#xff0c;可以跳过第一部分&#xff0c;直接看第二部分) 我们首先来看一下什么是前向星. 前向星是一种特殊的边集数组,我们把边集数组中的每一条边按照起点从小到大排序,如果起点相同就按…

图的存储 —— 链式前向星

图的存储 —— 链式前向星 链式前向星采用了一种静态链表存储方式&#xff0c;将边集数组和邻接表相结合&#xff0c;可以快速访问一个节点的所有邻接点&#xff0c;在算法竞赛中被广泛应用。 链式前向星有如下两种存储结构。 边集数组&#xff1a;edge[]&#xff0c;edge[i…

简述链式前向星

一、前言 我们常见的存图数据结构有两种&#xff0c;一种是邻接矩阵&#xff0c;另一种是邻接表。而在邻接矩阵中&#xff0c;空间复杂度为 O ( n 2 ) O(n^2) O(n2)&#xff0c;在稀疏图的情况下&#xff0c;相较于邻接表浪费了许多空间。而常规的邻接表是用链表进行操作&…

链式前向星 详解

链式前向星 链式前向星是一种类似于邻接表的存图方式&#xff0c;同样适用于有向 图和无向图。 他建立的是边与边之间的联系 它将边里的所有边都进行编号 int cnt; //边的编号 struct edge{ //边的结构体int from,to,w,next; //from是边的起点&#xff08;这个可有可无&a…

用链式前向星存储图

图最常用的存储结构主要是邻接矩阵和邻接表。当顶点数太大时&#xff0c;用二维数组表示的邻接矩阵可能超内存&#xff08;MLE&#xff09;&#xff0c;而用邻接表的编码工作量较大&#xff0c;此时&#xff0c;使用vector数组或链式前向星模拟邻接表是不错的选择。因vector数组…

链表、链式前向星

讲链表的时候就卡在这里了&#xff0c;最短路又卡在链式前向星上了&#xff0c;毕竟是图论基础&#xff0c;觉得还是有必要写一写防止下次再懵。 链表都是头插法&#xff01;&#xff01;即每次我们给他插一个头。 普通链表 先初始化令head-1,idx-1. void add_tohead(int x…