rpmbuild打包rpm

article/2025/10/16 9:05:54

一、rpmbuild及rpm

  1. rpm 
        rpm命令 是RPM软件包的管理工具。rpm原本是Red Hat Linux发行版专门用来管理Linux各项套件的程序,由于它遵循GPL规则且功能强大方便,因而广受欢迎。逐渐受到其他发行版的采用。RPM套件管理方式的出现,让Linux易于安装,升级,间接提升了Linux的适用度。 
  1. rpm优点:

    • 包管理系统简单,通过几个命令就可以实现包的安装、升级、卸载。
      安装速度比源码包快的多。
    • 缺点:
      经过编译,不能看到源代码,功能选择不如源码灵活。依赖性强。
  2. rpmbuild
         rpmbuild用于构建二进制和源代码软件包。


二、rpmbuild安装

$ yum install rpmbuild

如果上述方法无法找到该系统对应的rpmbuild版本导致安装失败,可使用下面方法

$ yum list |grep rpm-build 查找合适的rpm-build包
$ yum install -y rpm-build.x86_64

然后还需要安装rpmdevtools

$ yum install rpmdevtools 
$ rpmdev-setuptree

此时rpmbuild就安装完毕了,可以查看rpmbuild工作目录

$ rpmbuild --showrc | grep topdir


目录名作用
BUILD你要打包的文件将会在这里编译(编译rpm包的临时目录)
BUILDROOT在虚拟安装(make install)的目录(编译后生成的软件临时安装目录)
RPMS存放生成的二进制的rpm包(生成的可安装的rpm安装包所在目录)
SOURCES你要编译的源码包会被copy到这里(所有源代码和补丁文件的存在目录)
SPECS你执行的spec文件会被copy到这里(存放SOEC文件的目录)
SRPMS软件最终的rpm源码格式存放路径

三、rpmbuild详解

-bp 只作准备 (解压与打补丁)
-bc 准备并编译
-bi 编译并安装
-bl 检验文件是否齐全
-ba 编译后做成*.rpm和src.rpm
-bb 编译后做成*.rpm

-bs 只做成*.src.rpm

更具体的用法说明

Build options with [ <specfile> | <tarball> | <source package> ]:
*建立包的选项有:[ 从文件<specfile>建立 |从 <tarball>包建立 |从 <source package>包建立]
*从文件<specfile>建立

-bp build through %prep (unpack sources and apply patches) from <specfile>
* -bp 从<specfile>文件的%prep段开始建立(解开源码包并打补丁)
-bc build through %build (%prep, then compile) from <specfile>
*-bc 从<specfile>文件的%build
-bi build through %install (%prep, %build, then install) from <specfile>

-bl verify %files section from <specfile>
*检查<specfile>文件的%files段
-ba build source and binary packages from <specfile>
*建立源码和二进制包
-bb build binary package only from <specfile>
*只建立二进制包
-bs build source package only from <specfile>
*只建立源码包
 
*rpmbuild的其他使用项

--buildroot=DIRECTORY override build root
*确定以root目录建立包
--clean remove build tree when done
*完成打包后清除BUILD下的文件目录
--nobuild do not execute any stages of the build
*不进行BUILD的阶段
--nodeps do not verify build dependencies
*不检查建立包时的关联文件
--nodirtokens
generate package header(s) compatible with (legacy) rpm[23] packaging

--rmsource remove sources when done
*完成打包后清除sources
--rmspec remove specfile when done
*完成打包后清除specfile
--short-circuit skip straight to specified stage (only for c,i)
*跳过
--target=CPU-VENDOR-OS override target platform
                 *确定包的最终使用平台


四、spec文件详解

生成rpm除了源码外,最重要的就是懂得编写.spec脚本。rpm建包的原理其实并不复杂,可以理解为按照标准的格式整理一些信息,包括:软件基础信息,以及安装、卸载前后执行的脚本,对源码包解压、打补丁、编译,安装路径和文件等。########################## 关键字 ##############################
Summary:   ELK(elasticsearch+logstash+kibana+filebeat) Server	#软件包的内容概要
Name:      elk          			#软件包的名称,后面可使用%{name}的方式引用 
Version:   1.0.0				#版本号
Release:   1 					#发布序列号,也就是第几次制作rpm后面可使用%{release}引用
License:   GPL					#许可,GPL还是BSD等(一般为GPL)
Packager:  RPMBuild			#打包者的信息
Group:     Applications/System	#软件分组,建议使用标准分组
BuildRoot: /					#这个是安装或编译时使用的“虚拟目录”,该参数非常重要,因为在生成rpm的过程中,执行make install时就会把软件安装到上述的路径中,在打包的时候,同样依赖“虚拟目录”为“根目录”进行操作(即%files段)。后面可使用$RPM_BUILD_ROOT 方式引用。
BuildRequires:  gcc,make                        #制作过程中用到的软件包
URL:						#软件的主页
PATCH						#补丁源码,可使用Patch1、Patch2等标识多个补丁,使用%patch0或%{patch0}引用
Provides:  src					#指明本软件一些特定的功能,以便其他rpm识别
Prefix: %{_prefix} 				#这个主要是为了解决今后安装rpm包时,并不一定把软件安装到rpm中打包的目录的情况。这样,必须在这里定义该标识,并在编写%install脚本的时候引用,才能实现rpm安装时重新指定位置的功能
Prefix: %{_sysconfdir} 			#这个原因和上面的一样,但由于%{_prefix}指/usr,而对于其他的文件,例如/etc下的配置文件,则需要用%{_sysconfdir}标识
Build Arch:					#指编译的目标处理器架构,noarch标识不指定,但通常都是以/usr/lib/rpm/marcros中的内容为默认值
Requires:  /bin/sh  /usr/bin/getent /usr/sbin/useradd /usr/sbin/userdel#该rpm包所依赖的软件包名称,可以用>=或<=表示大于或小于某一特定版本
Source0:        %{name}-%{version}.tar.gz   #定义用到的source,也就是你的源码,如果没有源码,则不需要声明词宏变量
%define _rpmfilename %%{NAME}-%%{VERSION}.%%{ARCH}.rpm########################## spec脚本主体 ##############################
%prep 			          #预处理脚本
%setup -n %{name}-%{version}      #把源码包解压并放好,通常是从/usr/src/asianux/SOURCES里的包解压到/usr/src/asianux/BUILD/%{name}-%{version}中。一般用%setup -c就可以了,但有两种情况:一就是同时编译多个源码包,二就是源码的tar包的名称与解压出来的目录不一致,此时,就需要使用-n参数指定一下了。%patch 				  #打补丁, 通常补丁都会一起在源码tar.gz包中,或放到SOURCES目录下。一般参数为:%patch -p1 使用前面定义的Patch补丁进行,-p1是忽略patch的第一层目录%Patch2 -p1 -b xxx.patch 打上指定的补丁,-b是指生成备份文件#将需要需要打包的文件从BUILD 文件夹中拷贝到BUILDROOT文件夹下。◎补充一下 
引用
%setup 不加任何选项,仅将软件包打开。 
%setup -n newdir 将软件包解压在newdir目录。 
%setup -c 解压缩之前先产生目录。 
%setup -b num 将第num个source文件解压缩。 
%setup -T 不使用default的解压缩操作。 
%setup -T -b 0 将第0个源代码文件解压缩。 
%setup -c -n newdir 指定目录名称newdir,并在此目录产生rpm套件。 
%patch 最简单的补丁方式,自动指定patch level。 
%patch 0 使用第0个补丁文件,相当于%patch ?p 0。 
%patch -s 不显示打补丁时的信息。 
%patch -T 将所有打补丁时产生的输出文件删除。%configure 			  #这个不是关键字,而是rpm定义的标准宏命令。意思是执行源代码的configure配置
在/usr/src/asianux/BUILD/%{name}-%{version}目录中进行 ,使用标准写法,会引用/usr/lib/rpm/marcros中定义的参数。
另一种不标准的写法是,可参考源码中的参数自定义,例如:
引用
CFLAGS="$RPM_OPT_FLAGS" CXXFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%{_prefix}%build 				  #开始构建包
在/usr/src/asianux/BUILD/%{name}-%{version}目录中进行make的工作 ,常见写法:
引用
make %{?_smp_mflags} OPTIMIZE="%{optflags}"
都是一些优化参数,定义在/usr/lib/rpm/marcros中%install 			  #开始把软件安装到虚拟的根目录中
在/usr/src/asianux/BUILD/%{name}-%{version}目录中进行make install的操作。这个很重要,因为如果这里的路径不对的话,则下面%file中寻找文件的时候就会失败。 常见内容有:
%makeinstall 这不是关键字,而是rpm定义的标准宏命令。也可以使用非标准写法:
引用
make DESTDIR=$RPM_BUILD_ROOT install
或
引用
make prefix=$RPM_BUILD_ROOT install需要说明的是,这里的%install主要就是为了后面的%file服务的。所以,还可以使用常规的系统命令:
引用
install -d $RPM_BUILD_ROOT/
cp -a * $RPM_BUILD_ROOT/%clean 				  #清理临时文件
通常内容为:
引用
[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf "$RPM_BUILD_ROOT"
rm -rf $RPM_BUILD_DIR/%{name}-%{version}※注意区分$RPM_BUILD_ROOT和$RPM_BUILD_DIR:
$RPM_BUILD_ROOT是指开头定义的BuildRoot,而$RPM_BUILD_DIR通常就是指/usr/src/asianux/BUILD,其中,前面的才是%file需要的。 %pre 				  #rpm安装前执行的脚本%post 				  #rpm安装后执行的脚本%preun 				  #rpm卸载前执行的脚本%postun 			  #rpm卸载后执行的脚本%files 				  #定义那些文件或目录会放入rpm中
这里会在虚拟根目录下进行,千万不要写绝对路径,而应用宏或变量表示相对路径。 如果描述为目录,表示目录中除%exclude外的所有文件。
%defattr (-,root,root) 指定包装文件的属性,分别是(mode,owner,group),-表示默认值,对文本文件是0644,可执行文件是0755%exclude 			  #列出不想打包到rpm中的文件
※小心,如果%exclude指定的文件不存在,也会出错的。 
%changelog 			  #变更日志

    注:关于上述的spec详解参(chao偷笑)考(xi偷笑)了前辈的血汗之作   https://www.cnblogs.com/SQL888/p/5776442.html 膜拜!!!!


五、spec实例

    下面是我在实战中编写的.spec , 上述中的大部分其实并没有用到 , 整体来讲比较简单,如果有错误的地方望大佬不吝赐教.

     大概思路就是:将ELKF的四个rpm包整合为一个rpm包,并且覆盖一些初始配置文件,在卸载@postrun中卸载四个rpm包并且删除相关数据目录.

Summary:   ELK(elasticsearch+logstash+kibana+filebeat) Server
Name:      ELK
Version:   1.0.0
Release:   1
License:   GPL
Packager:  RPMBuild
Group:     Applications/System          
BuildRoot: /
Provides:  src
Requires:  /bin/sh  /usr/bin/getent /usr/sbin/useradd /usr/sbin/userdel
AutoReqProv: no%define _rpmfilename %%{NAME}-%%{VERSION}.%%{ARCH}.rpm%description
Boog ELK Log analysis system.%post            #rpm安装后执行的脚本
echo "after rpm install(update)..."
install_elasticsearch(){echo "########### begin installing elasticsearch ###########"rm -f /var/lib/rpm/.rpm.lockes=`rpm -qa | grep elasticsearch`if [ `rpm -qa | grep elasticsearch |wc -l` -ne 0 ];thenecho -e "ERROR: elasticsearch has been installed on this server,the packet_list: $es"else# install beginrpm -ivh /home/elk_install_temp/rpms/elasticsearch-6.1.1.rpm # 设置elasticsearch java环境变量配置sed -i "s%\#JAVA_HOME=%JAVA_HOME=$JAVA_HOME%g" /etc/sysconfig/elasticsearch# 更改数据目录cp -f /home/elk_install_temp/template/elasticsearch.yml /etc/elasticsearch/chown -R elasticsearch:elasticsearch /etc/elasticsearch/elasticsearch.ymlchown -R elasticsearch:elasticsearch /data/logchown -R elasticsearch:elasticsearch /data/lib#设置开机自启动/sbin/chkconfig --add elasticsearchfiecho "Run 'service elasticsearch start' to start the elasticsearch service"echo "###########If the elasticsearch startup failed,Please read '/etc/elasticsearch/remark.txt' for help!!###########"
}
install_kibana(){echo "############## begin installing kibana ###############"kb=`rpm -qa | grep kibana`if [ `rpm -qa | grep kibana |wc -l` -ne 0 ];thenecho -e "ERROR: kibana has been installed on this server,the packet_list: $kb"else# install beginrpm -ivh /home/elk_install_temp/rpms/kibana-6.1.1-x86_64.rpmcp -f /home/elk_install_temp/template/kibana.yml /etc/kibana/#设置开机自启动/sbin/chkconfig --add kibanafiecho "Run 'service kibana start' to start the kibana service"
}
install_filebeat(){echo "############# begin installing filebeat ##############"fb=`rpm -qa | grep filebeat`if [ `rpm -qa | grep filebeat |wc -l` -ne 0 ];thenecho -e "ERROR: filebeat has been installed on this server,the packet_list: $fb"else# install beginrpm -ivh /home/elk_install_temp/rpms/filebeat-6.1.1-x86_64.rpmcp -f /home/elk_install_temp/template/filebeat.yml /etc/filebeat/#设置开机自启动/sbin/chkconfig --add filebeatfiecho "Run 'service filebeat start' to start the filebeat service"
}
install_logstash(){echo "############## begin installing logstash #############"lt=`rpm -qa | grep logstash`if [ `rpm -qa | grep logstash |wc -l` -ne 0 ];thenecho -e "ERROR: logstash has been installed on this server,the packet_list: $lt"else# install beginrpm -ivh /home/elk_install_temp/rpms/logstash-6.1.1.rpm#覆盖配置文件cp -f /home/elk_install_temp/template/logstash-simple.conf /etc/logstash/conf.d/#生成logstash启动脚本/usr/share/logstash/bin/system-install /etc/logstash/startup.options sysv#设置开机自启动/sbin/chkconfig --add logstashfi#服务启动/etc/init.d/logstash startinitctl stop logstashecho "Run 'initctl start logstash' to start the logstash service"
}
#执行安装
install_elasticsearch
install_kibana
install_filebeat
install_logstash
################### remove elk install temp ####################
rm -rf /home/elk_install_temp
rm -rf /var/elk_install_temp%clean
rm -rf %{BuildRoot} %preun
%postun           #rpm安装后执行的脚本
if [ $1 = 0 ]; thenrm -f /var/lib/rpm/.rpm.lock##################### begin uninstall elasticsearch ######################echo "begin uninstall elk"es=`rpm -qa elasticsearch`if [ $es ];thenservice elasticsearch stoprpm -e $esrm -rf /data/lib/elasticsearchrm -rf /data/log/elasticsearchrm -rf /usr/share/elasticsearchfiecho 'elasticsearch has been uninstall!'######################## begin uninstall logstash ########################ls=`rpm -qa logstash`if [ $ls ];thenecho $ls/etc/init.d/logstash stop#防止logstash 未被成功关闭导致用户无法删除以至于logstash卸载失败lsid=`ps aux | grep  logstash | grep -v grep| awk '{print $2}'`if [ ! $lsid ]; then  echo "logstash is stop!"  else kill -9 $lsid echo 'logstash is about to be closed.....'fi rpm -e $lsrm -rf /etc/init.d/logstash /etc/rc.d/init.d/logstash /etc/logstash /etc/default/logstashrm -rf /var/log/logstash /var/log/logstash-std* /var/lib/logstashrm -rf /usr/share/logstashfiecho 'logstash has been uninstall!'######################### begin uninstall filebeat #######################fb=`rpm -qa filebeat`if [ $fb ];thenecho $fbservice filebeat stoprpm -e $fbfiecho 'filebeat has been uninstall!'######################### begin uninstall kibana #########################ki=`rpm -qa kibana`if [ $ki ];thenecho $kiservice kibana stoprpm -e $kifiecho 'kibana has been uninstall!'###################### remove elk install temp ############################rm -rf /home/elk_install_temp#rm -rf /var/elk_install_temp
fi%pre
echo $JAVA_HOME
if [ ! $JAVA_HOME ];thenecho 'ERROR:请先安装java并配置java相关环境'exit 0
fi
mkdir -p /data/lib/elasticsearch /data/log/elasticsearch%files           #定义那些文件或目录会放入rpm中(这里是BUILDOROOT/name-version/下的源码和配置文件)
/home/elk_install_temp/.elk-release
/home/elk_install_temp/rpms/*
/home/elk_install_temp/template/*
/etc/elasticsearch/remark.txt
%defattr(-,root,root)



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

相关文章

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…

链式前向星(详细讲述)

在dalao的压迫下本蒟蒻发个博客&#xff0c;给大家讲一下链式前向星&#xff08;新手&#xff0c;写错了轻喷&#xff09; 首先说明一点链式前向星适合于稀疏图&#xff0c;而邻接矩阵则更适合稠密图&#xff0c;所以最好看好数据范围再决策使用哪个方法&#xff0c;当然有些题…

链式前向星与邻接表对比

本文图片及数据 对于这样一张有向图&#xff1a; 输入边的顺序如下&#xff1a; 1 2 2 3 3 4 1 3 4 1 1 5 4 5 对于邻接表来说是这样的&#xff1a; 1 -> 2 -> 3 -> 5 2 -> 3 3 -> 4 4 -> 1 -> 5 5 ->^ 对于链式前向星来说是这样的&…

链式前向星存图(有图详解)

链式前向星:既然是链式那么肯定和链表相关,前向星是每次指向都向前 链式前向星存图是以边为中心,并不是以结点为中心,它记录的是边的一些属性,包括边边的id、头节点、尾结点、权值、边的指向! 边的指向是遍历图的时候需要按照一定顺序去遍历,而不能胡乱的去遍历,那么就需要这些…

链式前向星的详解

目录 1&#xff1a;链式前向星的概念解释 2&#xff1a;代码展现 链式前向星是一种非常好用的有向图存储方式&#xff0c;但是它的代码难度却有点大。作者在这上面花了很长的时间才弄懂。虽然有其他的博客大佬写的很好&#xff0c;但总感觉不太适合小白选手&#xff08;比如说…