rpm包制作流程

什么是rpm包?

rpm 相当于windows中的安装文件,它会自动处理软件包之间的依赖关系。

rpm优点:
包管理系统简单,通过几个命令就可以实现包的安装、升级、卸载。
安装速度比源码包快的多。
缺点:
经过编译,不能看到源代码,功能选择不如源码灵活。依赖性强。

包名称

一个rpm包的名称分为包全名和包名,包全名如httpd-2.2.15-39.el6.centos.x86_64.rpm,包全名中各部分的意义如下:

1
2
3
4
5
6
httpd       包名
2.2.15 版本号,版本号格式[ 主版本号.[ 次版本号.[ 修正号 ] ] ]
39 软件发布次数
el6.centos 适合的操作系统平台以及适合的操作系统版本
x86_64 适合的硬件平台,硬件平台根据cpu来决定,有i386、i586、i686、x86_64、noarch或者省略,noarch或省略表示不区分硬件平台
rpm 软件包后缀扩展名

使用rpm工具管理包时,如果要操作未安装的包,则使用包全名,如安装包,查看未安装包的信息等;如果要操作已安装的rpm包,则只需要给定其包名即可,如查询已装包生成了哪些文件,查看已装包的信息等。

而对于yum工具来说,只需给定其包名即可,若有需要,再指定版本号,如明确指明要安装1.6.10版本的tree工具,yum install tree-1.6.10。

rpm管理包

rpm包被安装后,会在/var/lib/rpm下会建立已装rpm数据库,以后有任何rpm的升级、查询、版本比较等包的操作都是从这个目录下获取信息并完成相应操作的。

1
2
3
4
5
root@xuexi ~]# ls /var/lib/rpm/ 
Basenames __db.003 Group Packages Requirename Triggername
Conflictname __db.004 Installtid Providename Requireversion
__db.001 Dirnames Name Provideversion Sha1header
__db.002 Filedigests Obsoletename Pubkeys Sigmd5

rpm安装完成后,相关的文件会复制到多个目录下(具体复制的路径是在制作rpm包时指定的)。一般来说,分布形式差不多如下表。

1
2
3
4
5
6
/etc 放置配置文件的目录
/bin、/sbin、/usr/bin或/usr/sbin 一些可执行文件
/lib、/lib64、/usr/lib(/usr/lib64) 一些库文件
/usr/include 一些头文件
/usr/share/doc 一些基本的软件使用手册与帮助文件
/usr/share/man 一些 man page 档案

rpm安装、升级、卸载

1
2
3
4
5
6
7
8
9
10
11
12
13
rpm -ivhUe --nodeps --test --force --prefix
选项说明:
-i 表示安装,install的意思
-v 显示安装信息,还可以"-vv"、"-vvv",v提供的越多显示信息越多
-h 显示安装进度,以#显示安装的进度
-U 升级或升级包
-F 只升级已安装的包
-e 卸载包,卸载也有依赖性,"--erase"
--nodeps 忽略依赖性强制安装或卸载(no dependencies)
--test 测试是否能够成功安装指定的rpm包
--prefix 新路径 自行指定安装路径而不是使用默认路径,基本上都不支持该功能,功能极其简单的软件估计才支持重定位安装路径
--force 强制动作
--replacepkgs 替换安装,即重新覆盖安装。

rpm查询功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
-q[p] -q查询已安装的包,-qp查询未安装的包。它们都可接下面的参数
-a 查询所有已安装的包,也可以指定通配符名称进行查询
-i 查询指定包的信息(版本、开发商、安装时间等)。从这里面可以查看到软件包属于哪个包组。
-l 查询包的文件列表和目录(包在生产的时候就指定了文件路径,因此可查未装包)
-R 查询包的依赖性(Required)
-c 查询安装后包生成的配置文件
-d 查询安装后包生成的帮助文档
-f 查询系统文件属于哪个已安装的包(接的是文件而不是包)
--scripts 查询包相关的脚本文档。脚本文档分四类:安装前运行、安装后运行、卸载前运行、卸载后运行

(1).查询文件/etc/yum.conf是通过哪个包安装的。
[root@xuexi cdrom]# rpm -qf /etc/yum.conf
yum-3.2.29-60.el6.centos.noarch

(2).查询安装httpd时生成了哪些目录和文件,还可以过滤出提供了哪些命令行工具。
rpm -ql httpd
rpm -ql httpd | grep 'bin/'

(3).查询某个未安装包的依赖性如zip-3.0-1.el6.x86_64.rpm的依赖性。
[root@xuexi cdrom]# rpm -qRp zip-3.0-1.el6.x86_64.rpm
libc.so.6()(64bit)
libc.so.6(GLIBC_2.2.5)(64bit)
libc.so.6(GLIBC_2.3)(64bit)
libc.so.6(GLIBC_2.3.4)(64bit)
libc.so.6(GLIBC_2.4)(64bit)
libc.so.6(GLIBC_2.7)(64bit)
rpmlib(CompressedFileNames) <= 3.0.4-1
rpmlib(FileDigests) <= 4.6.0-1
rpmlib(PayloadFilesHavePrefix) <= 4.0-1
rtld(GNU_HASH)
rpmlib(PayloadIsXz) <= 5.2-1

yum管理包

/etc/yum.conf是yum的默认文件,里面配置的也是全局默认项。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@server2 ~]# cat /etc/yum.conf

[main]
cachedir=/var/cache/yum/$basearch/$releasever # 缓存目录
keepcache=0 # 是否保留缓存,设置为1时,安装包时所下载的包将不会被删除
debuglevel=2 # 调试信息的级别
logfile=/var/log/yum.log # 日志文件位置
exactarch=1 # 设置为1将只会安装和系统架构完全匹配的包
obsoletes=1 # 是否允许更新旧的包
gpgcheck=1 # 是否要进行gpg check
plugins=1 # 是否允许使用yum插件
installonly_limit=5
bugtracker_url=http://bugs.centos.org/set_project.php?project_id=23&ref=http://bugs.centos.org/bug_report_page.php?category=yum
distroverpkg=centos-release # 指定基准包,yum会根据这个包判断发行版本

配置yum仓库

首先配置yum仓库,配置文件为/etc/yum.conf和/etc/yum.repos.d/中的”.repo”文件,其中/etc/yum.conf配置的是仓库的默认项,一般配置yum源都是在/etc/yum.repos.d/*.repo中配置。注意,该目录中任意repo文件都会被读取。

默认/etc/yum.repos.d/下会有以下几个仓库文件,除了CentOS-Base.repo,其他的都可以删掉,基本没用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@xuexi yum.repos.d]# vim CentOS-Base.repo

[base] # 仓库ID,ID必须保证唯一性
name # 仓库名称,可随意命名
mirrorlist # 该地址下包含了仓库地址列表,包含一个或多个镜像站点,和baseurl使用一个就可以了
#baseurl # 仓库地址。网络上的地址则写网络地址,本地地址则写本地地址,格式为“file://”后接路径,如file:///mnt/cdrom
gpgcheck=1 # 指定是否需要签名,1表示需要,0表示不需要
gpgkey= # 签名文件的路径
enable # 该仓库是否生效,enable=1表示生效,enable=0表示不生效
cost= # 开销越高,优先级越低

【repo配置文件中可用的宏:】
$releasever:程序的版本,对Yum而言指的是redhat-relrase版本。只替换为主版本号,如Redhat6.5 则替换为6
$arch:系统架构
$basharch:系统基本架构,如i686,i586等的基本架构为i386
$YUM0-9:在系统定义的环境变量,可以在yum中使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
安装epel-release-noarch.rpm
rpm -ivh epel-release-latest-6.noarch.rpm

方法二:直接增加epel仓库
在/etc/yum.repos.d/下任意一个repo文件中添加上epel的仓库即可。
[epel]
name=epel
baseurl=http://mirrors.sohu.com/fedora-epel/6Server/$basearch/
enabled=1
gpgcheck=0

然后清除缓存再建立缓存即可。

shell> yum clean all ; yum makecache

yum命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
Usage: yum [options] COMMAND

List of Commands:
help 命令的帮助信息,用法:yum help command,如yum help install则查看install命令的用法说明
clean 清除缓存数据,如yum clean all
makecache 生成元数据缓存数据,yum makecache
deplist 列出包的依赖关系
erase 卸载包
fs 为当前文件系统创建快照,或者列出或删除当前已有快照。快照是非常有用的,升级或打补丁前拍个快照,就能放心地升级或打补丁了
fssnapshot 同fs一样
groups 操作包组
history 查看yum事务信息,yum是独占模式的进程,所以有时候查看事务信息还是有用的
info 输出包或包组的信息,例如该包是谁制作的,大概是干什么用的,来源于哪个包组等信息
install 包安装命令
list 列出包名,一般会结合grep来搜索包,如yum list all | grep -i zabbix
provides 搜索给定的内容是谁提供的,可用来搜索来源于个包,如CentOS 7上mysql被mariadb替代,搜索Mysql提供者时就能找出包mariadb
reinstall 重新安装包
repolist 列出可用的仓库列表
search 给定字符串搜索相关包,并给出相关包较为详细的信息
update 更新包

Options:

-R [minutes], --randomwait=[minutes]:最多等待时间
-q, --quiet 安静模式
-v, --verbose 详细模式
-y, --assumeyes 对所有问题回答yes
--assumeno 对所有问题回答no
--enablerepo=[repo] 启用一个或多个仓库,可用通配符通配仓库ID
--disablerepo=[repo] 禁用一个或多个仓库,可用通配符通配仓库ID
-x [package], --exclude=[package] 通配要排除的包
--nogpgcheck 禁用gpgcheck
--color=COLOR 带颜色
--downloadonly 仅下载包,不安装或升级。默认下载在yum的缓存目录中,默认为/var/cache/yum/$basearch/$releasever
--downloaddir=DLDIR 指定下载目录

制作rpm 包

安装rpmbuild

1
2
3
4
5
6
7
$yum install rpmbuild
$yum install rpmdevtools
$rpmdev-setuptree

此时rpmbuild已经安装好了,可以查看一下

rpmbuild --showrc | grep topdir

进入rpmbuild 目录文件夹如下:
avatar

各个文件夹的用途:
avatar

整理源码

rpmbuild安装完成以后我门就需要将我们的源码放到 SOURCE 文件夹下。我门的源码可能是一个tar.gz 的包、也可能是几个文件。

tar.gz源码包的名字格式应该为 helloword-1.0.0.tar.gz (其实就是名字-版本号.tar.gz)

编写spec文件

在SPECS文件夹下新建 xxx.spec 打包脚本,其实也就是把我门的源码编译打包成rpm 的一个过程。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
vi  xxx.spec 

Name: hellorpm #名字为源码tar.gz 包的名字
Version: 1.0.0 #版本号,一定要与tar.gz包的一致哦
Release: 1%{?dist} #释出号,也就是第几次制作rpm
Summary: helloword #软件包简介,最好不要超过50字符

License: GPL #许可,GPL还是BSD等
URL: #可以写一个网址
Packager: abel
Source0: %{name}-%{version}.tar.gz
#定义用到的source,也就是你的源码

BuildRoot: %_topdir/BUILDROOT
#这个是软件make install 的测试安装目录.

BuildRequires: gcc,make #制作过程中用到的软件包
Requires: python-apscheduler >= 2.1.2-1.el7,python-daemon >= 1.6-1.el7 #软件运行依赖的软件包,也可以指定最低版本如 bash >= 1.1.1
%description #描述,随便写
%prep #打包开始
%setup -q #这个作用静默模式解压并cd


%build #编译制作阶段,主要目的就是编译,如果不用编译就为空
./configure \
%{?_smp_mflags} #make后面的意思是:如果就多处理器的话make时并行编译

%install #安装阶段
rm -rf %{buildroot} #先删除原来的安装的,如果你不是第一次安装的话
cp -rp %_topdir/BUILD/%{name}-%{version}/* $RPM_BUILD_ROOT
#将需要需要打包的文件从BUILD 文件夹中拷贝到BUILDROOT文件夹下。

#下面的几步pre、post、preun、postun 没必要可以不写
%pre #rpm安装前制行的脚本

%post #安装后执行的脚本

%preun #卸载前执行的脚本

%postun #卸载后执行的脚本

%clean #清理段,删除buildroot
rm -rf %{buildroot}


%files #rpm要包含的文件
%defattr (-,root,root,-) #设定默认权限,如果下面没有指定权限,则继承默认
/etc/hello/word/helloword.c #将你需要打包的文件或目录写下来

### 7.chagelog section 改变日志段
%changelog

注意:
以上阶段如果没有操作的话,为空,但是不能有空行,例如build阶段为空应写为

1
2
3
4
5
6
7
8
9
%build              
%install
xxxxxxxx

错误示例:
%build

%install
xxxxxxxx

rpm包制作阶段
avatar

打包

spec 文件编写好以后就可以进行打包了。
在SPECS文件夹下执行命令:

1
rpmbuild -bb xxx.spec

如果出错了可以通过 不同的命令来看是在打包的那一步出了问题。

1
2
3
4
5
6
7
8
rpmbuild  
-ba 既生成src.rpm又生成二进制rpm
-bs 只生成src的rpm
-bb 只生二进制的rpm
-bp 执行到pre
-bc 执行到 build段
-bi 执行install段
-bl 检测有文件没包含

参考文件

  1. https://blog.csdn.net/u012373815/article/details/73257754
  2. https://www.cnblogs.com/f-ck-need-u/p/7049750.html