RPM包制作理论基础篇



我将通过两篇博客来说明rpm包制作,分为《RPM包制作理论基础篇》和《RPM包制作实战进阶篇》;本篇将从学习RPM包制作目的、原理以及基本的命令进行讲解:

准备工作

rpm 包制作需要rpmbuild 命令工具,因此我们需要先安装好该工具包,但是在这里我们不直接安装rpm-build,而是通过安装rpmdevtools(该工具包依赖rpm-build 包)将rpm-build 自动给安装上;安装rpmdevtools包执行如下命令:

[root@localhost ~]# yum install rpmdevtools

我们可以从中看到它依赖包其中就包括了rpm-build,如下:

在这里插入图片描述

为什么要学习RPM包制作

通常一般Linux用户在使用过程中需要安装/更新某个软件(如telnet、ssh等)都是通过rpm包来进行的,而获取rpm包的方式大都是通过配置yum源进行自动下载安装/升级,另一种方式则是直接到官网或其它网站手动下载到本地后再执行安装/升级命令;当然,作为Linux开发人员您还可以下载该软件对应的源代码,进行本地编译、安装。

第一种方式: 需要配置yum源,一般情况下你可以配置官方源(国外的,相对慢点)、阿里源、清华源等地址,但是这些都要求你的机器能够上外网;当然你也可以配置本地源(公司源或自己搭建),这个就可能存在本地源中没有你想要安装的rpm包,这个时候你就需要通过第二种方式去找各个rpm包放到你的本地源中。

第二种方式: 需要自己花一定的时间和经历去找到你想要安装的rpm包,需要考虑rpm适用平台架构(32位还是64位或是都可以),即使你找到需要安装的rpm包,但是再执行命令安装时你可能会发现有时你还需要去下载一系列的依赖包,这个过程可能是令你非常不爽的。注:这个在Debain系列(deb包)可能你会感触更深;

第三种方式: 无论是第一种还是第二种,都有可能找不到你需要的软件包;如,你需要更新某个软件来实现最新功能或是修复最新漏洞;这个时候就需要通过第三种方式:去软件官网下载最新代码进行编译、安装;但是该方法同样存在弊端,即编译、安装必须搭建编译环境(安装gcc/g++、make、autoconf等工具)且有时整个编译、安装过程也是非常的耗时;


  作为一名Linux开发/维护人员,你会发现以上三种方式都是有一定的局限性:很多时候我们结合上面的三种方式都能将问题给解决掉,但是往往就会存在一些通过上面三种方式都解决不了或是达不到预期值,下面举个本人实际工作中遇到的例子:

案例: 我司的一款终端产品,该终端产品安装了OpenSSH提供SSH服务,由于早期安装的OpenSSH版本较低存在漏洞问题,有的漏洞修复时间较早(可以通过安装新的rpm包进行升级),但有的漏洞当年(如今年2019)才修复的,即使升级镜像源(官网源、清华源等)上最新的rpm,也无法修复该漏洞问题。这个时候能想到的就是看看最新源码是否已经修改,如果已经修复,那我们就可以通过第三种方式进行升级,如果没有修复,就需要我们研究代码,进行修复(难度通常比较大)。幸运的是实际最新源码已经修复,但是现场众我司终端产品众多,如果每个终端都先安装编译环境,再通过源码编译、安装,那工作量可想而知;如果客户了解这种方式,可能也会提出疑意甚至拒绝;那我们能不能利用最新源代码修复漏洞的同时,又不需要在用户终端产品上搭建编译环境进行软件升级,答案是可以,这也是我在接下来将重点介绍的内容:利用源码制作RPM包,在介绍具体实施之前,我觉得有必要介绍一下原理和概念性的东西。


原理介绍

源码制作RPM包的时候需要编译源码,还需要把编译好的二进制命令文件、文档以及安装后执行需要的配置文件等东西按照安装好的样子放到合适的位置,还要根据需要对RPM的包进行测试,这些都需要先有一个“工作空间”。rpmbuild 命令使用一套标准化的“工作空间”,执行 rpmdev-setuptree 命令可以看到默认在用户~目录下会生成该标准的“工作空间rpmbuild”;
过tree 命令我们来看看该目录构成,如下:
在这里插入图片描述
从上图中我们看到该目录(RPM 包制作工作空间)下面又有5个空目录,实际打包过程中还会生成一个BUILDROOT目录,下面通过一张表格来说说这些目录的用途。

默认位置宏代码名称用途
~/rpmbuild/SPEC%_specdirspec文件目录保存制作rpm包核心文件
~/rpmbuild/SOURCES%_sourcedir源文件目录保存源代码(如.tar包)和所有patch补丁包
~/rpmbuild/BUILD%_builddir构建目录源代码会被加压至此,并在该目录下完成编译
~/rpmbuild/BUILDROOT%_buildrootdir安装目录保存%install 阶段安装的文件,最后生成rpm包后,该目录一般会被清空
~/rpmbuild/RPMS%_rpmdir二进制rpm包存放目录生成/保存二进制RPM包
~/rpmbuild/SRPMS%_srcrpmdir源码包存放目录生成/保存源码RPM包

用源码制作RPM包相比通过源码编译、安装最复杂的地方就是SPEC文件的编写,也是整个RPM包制作的核心。既然spec文件是核心,那我们如何去编写或者获取spec文件呢?一般可以通过下面几种方式得到:

第一种: 自己手动从无到有进行编写:spec文件是有的语法和结构要求,如果你对结构比较熟悉,完全可以自己编写;

第二种: 通过如下命令生成spec模板,如下:

[root@localhost ~]# rpmdev-newspec testsample.spec //也可以不指定文件名,默认模板文件名为newpackage.spec 

下面具体看一下该文件的构成和字段说明:

      1 Name:           testsample 软件包的名称,后面可使用%{name}的方式引用
      2 Version:        软件的实际版本号,例如:1.0.1等,后面可使用%{version}引用
      3 Release:        1%{?dist},发布序列号,标明第几次打包,后面可使用%{release}引用
      4 Summary:        软件包的内容概要
      5
      6 License:  软件授权方式,通常就是GPL
      7 URL:      软件的主页
      8 Source0:  源代码包,可以带多个用Source1、Source2等源,后面也可以用%{source1}、%{source2}引用。
      9
     10 BuildRequires: 编译依赖
     11 Requires: 运行依赖,该rpm包所依赖的软件包名称,可以用>=或<=表示大于或小于某一特定版本
     12
     13 %description 对该软件包的说明
     14
     15
     16 %prep 预处理脚本,这个段是预处理段,通常用来执行一些解开源程序包的命令,为下一步的编译安装作准备。%prep和下面的%build,%install段一样,除了可以执行RPM所定义的宏命令(以%开头)以外,还可以执行SHELL命令,命令可以有很多行,如我们常写的tar解包命令。
     17 %setup -q 把源码包解压并放好,一般用%setup -q就可以了,但有两种情况:一就是同时编译多个源码包,二就是源码的tar包的名称与解压出来的目录不一致,此时,就需要使用-n参数指定一下了。如:%setup -n newdir 将软件包解压到newdir目录。
     18
     19
     20 %build  开始编译源码构建包,相当于configure以及make部分
     21 %configure 这个不是关键字,而是rpm定义的标准宏命令。意思是执行源代码的configure配置,
     22 make %{?_smp_mflags} 相当于执行make -jn
     23
     24
     25 %install 开始把软件安装到虚拟的根目录中,本段是安装段,其中的命令在安装软件包时将执行,这里的%install主要就是为了后面的%file服务的
     26 rm -rf $RPM_BUILD_ROOT
     27 %make_install 这不是关键字,而是rpm定义的标准宏命令,相当于执行make install命令那一步。
     28
     29
     30 %files  本段是文件段,用于定义构成软件包的文件列表,那些文件或目录会放入rpm中,分为三类-说明文档(doc),配置文件(config)及执行程序,还可定义文件存取权限,拥有者及组别。
这里会在虚拟根目录下进行,千万不要写绝对路径,而应用宏或变量表示相对路径。
     31 %doc 表示这是文档文件
     32
     33
     34
     35 %changelog 变更日志,本段是修改日志段。你可以将软件的每次修改记录到这里,保存到发布的软件包中,以便查询之用。每一个修改日志都有这样一种格式:第一行是:* 星期月日 年 修改人电子信箱。
        其中:星期、月份均用英文形式的前3个字母,用中文会报错。接下来的行写的是修改了什么地方,可写多行。一般以-开始,便于后续的查 阅。

得到spec模板以后,就可以根据需要自己填写内容了,当然这个你也需要对你安装或更新的软件比较熟悉才行。如软件运行需要哪些配置文件和依赖库等;其实这些信息通常我们可以从旧的rpm 包中查看到;如通过rpm -qpi 查看之前安装的rpmdevtool 安装信息如下:
在这里插入图片描述
注: 这里要rpm -qpi 参数是具体rpm包,因此需要配置采用yum安装软件的时候保留rpm包,具体配置就是修改/etc/yum.conf 文件,将keepcache值设为1,默认值为0。

通过rpm -ql 查看已安装包中包含的文件信息如下:
在这里插入图片描述注: 包含文件较多,截图有省略。

通过rpm -q – changelog , 查看该软件的更新日志如下:在这里插入图片描述
注: 截图有省略。

第三种: RPM 包 一般分二进制包.rpm以及源码包src.rpm两种;***.src.rpm 包中会包含该软件对应的.spec 文件,如有必要我们可以对其进行修改即可。这种方式可能也是比较常用的,因为再获取到spec文件的同时,我们还能获取到该软件需要的一些配置文件信息。

第四种: 有的时候我们下载的源代码中就会包含spec文件或者通过执行configure能够生成相应的spec文件(下一篇我会通过一个实操进行讲解)。


当我们通过上面任何一种方式获取到spec文件后,就可以通过命令rpmbuild制作rpm包,其命令参数如下:

-bp  #只执行spec的%pre 段(解开源码包并打补丁,即只做准备)

-bc  #执行spec的%pre和%build 段(准备并编译)

-bi  #执行spec中%pre,%build与%install(准备,编译并安装)

-bl  #检查spec中的%file段(查看文件是否齐全)

-ba  #建立源码与二进制包(常用) 

-bb  #只建立二进制包(常用)

-bs  #只建立源码包

rpmbuild -bb openssh.spec 表示只生成OpenSSH 的二进制rpm包;注:前提是需要将源代码放到合适的位置,下一篇会举例介绍。

在这里也顺便补充一点常用的 rpm 命令,其主要参数形式有:

-ivh ***.rpm 安装rpm包,加上参数--test 还可以用来只测试依赖关系,不实际安装

-Uvh ***.rpm 升级rpm包,加上参数--oldpackage 还可以实现降级

-qpi ***.rpm 查看rpm包安装信息

-ql  *** 查看已经安装过的rpm包里面的内容

-qpl ***.rpm 查看rpm包里面的内容

-e   *** 删除已经安装的软件包,可以加上参数--nodeps 来强制删除

-qa  *** 查看是否安装了该软件包

rpm -qpl openssh-8.0p1-1.el7.x86_64.rpm 查看openssh包里面的内容;


最后在介绍一个从rpm包中到导出内容的命令:
rpm2cpio xxxx.rpm | cpio -ivd 导出rpm内容到当前目录

如:rpm2cpio openssh-8.0p1-1.el7.x86_64.rpm | cpio -ivd 将openssh包中的内容进行导出。

好了,本篇就简单介绍到这里,至于获取到spec文件后,如何利用 spec+源代码 进行打包生成我们需要的rpm包呢?这个具体我将在下一篇博客中进行介绍,谢谢阅读~

  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值