ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

RPM包制作理论基础篇

2021-02-21 10:35:28  阅读:209  来源: 互联网

标签:安装 RPM 理论 编译 源码 rpm 制作 spec


转载:https://blog.csdn.net/zhaihaibo168/article/details/100128551

我将通过两篇博客来说明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 %_specdir spec文件目录 保存制作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个字母,用中文会报错。接下来的行写的是修改了什么地方,可写多行。一般以-开始,便于后续的查 阅。
12345678910111213141516171819202122232425262728293031323334353637

得到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  #只建立源码包123456789101112

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  *** 查看是否安装了该软件包123456789101112

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包呢?这个具体我将在下一篇博客中进行介绍,谢谢阅读~

注:
.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个字母,用中文会报错。接下来的行写的是修改了什么地方,可写多行。一般以-开始,便于后续的查 阅。

标签:安装,RPM,理论,编译,源码,rpm,制作,spec
来源: https://www.cnblogs.com/kribee/p/14424345.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有