RPM 打包技术与典型 SPEC 文件分析
一 、rpm 介绍
1. 概述
RPM全称是 Red Hat Package Manager(Red Hat包管理器)。几乎所有的 Linux 发行版本都使用这种形式的软件包管理安装、更新和卸载软件。
RPM是一个开放的软件包管理系统。它工作于Red Hat Linux以及其它Linux和UNIX 系统,可被任何人使用。redhat软件公司鼓励其它厂商来了解RPM并在自己的产品中使用它。RPM的发布基于GPL协议。对于最终用户来说,使用RPM所提供的功能来维护系统是比较容易和轻松的。安装、卸载和升级RPM软件包只需一条命令就可以搞定。RPM维护了一个所有已安装的软件包和文件的数据库,可以让用户进行查询和验证工作。在软件包升级过程中,RPM会对配置文件进行特别处理,绝对不会丢失以往的定制信息。对于程序员RPM可以让我们连同软件的源代码打包成源代码和二进制软件包供最终用户使用。
RPM拥有功能强大的查询选项。我们可以搜索数据库来查询软件包或文件。也可以查出某个文件属于哪个软件包或出自哪儿。RPM软件包中的文件是以压缩格式存放的,拥有一个定制的二进制头文件,其中包含有关包和内容的信息,可以让我们对单个软件包的查询简便又快速。
RPM另一个强大的功能是进行软件包的验证。如果我们担心误删了某个软件包中的某个文件,我们就可以对它进行验证。任何非正常现象将会被通知。如果需要的话还可以重新安装该软件包。在重新安装过程中,所有被修改过的配置文件将被保留。
RPM设计目标之一就是要保持软件包的原始特征, 就象该软件的原始发布者发布软件时那样。通过使用RPM我们可以拥有最初的软件和最新的补丁程序,还有详细的软件构建信息。
概括的说:RPM有五种基本的操作功能(不包括创建软件包):安装、卸载、升级、查询、和验证。关于rpm命令的使用我们可以用以下命令:
[root@hostname root]rpm -help
来获的。
2.RPM工具功能
1) 安装
rpm -i ( or --install) options file1.rpm ... fileN.rpm 通过rpm -ivh可以把rpm软件包安装到系统中,当然也可以使用不同的参数选项,笔者建议使用-ivh ,使用该选项可以解决大部分rpm软件包的安装,至于详细的参数说明可用查看rpm的man 文档。
2 )删除
rpm -e ( or --erase) options pkg1 ... pkgN 如果某个软件包你再也不想使用了,那就用以上这个命令彻底的把你指定的rpm软件包清除掉把。
3 )升级
rpm -U ( or --upgrade) options file1.rpm ... fileN.rpm 由于开源软件更新速度快,用户当然要使用最新版本的软件包,此时最合适的就是rpm升级功能,当然最理想的参数选项就是-Uvh。
4 )查询
rpm -q ( or --query) options 实际上我们通常使用rpm工具最多的功能还是它的查询功能,比如查看软件包的版本、依赖关系等软件包的详细说明都要用到。最有用的参数选项是-qpi。
5 )校验已安装的软件包
rpm -V ( or --verify, or -y) options 一般我们可用通过该命令来验证已安装软件包,根据笔者的经验该命令一般没什么用途,只做一个了解就ok了。
3.spec文件规范
能熟练掌握以上命令以及部分参数含义,管理日常的rpm软件包就不成问题了。然而随着Linux风靡全球,越来越多的开发者喜欢采用RPM格式来发布自己的软件包。那么RPM软件包是怎样制作的呢?对大多数Linux开发工程师来说是比较陌生的。
其实,制作RPM软件包并不是一件复杂的工作,其中的关键在于编写SPEC软件包描述文件。要想制作一个rpm软件包就必须写一个软件包描述文件(SPEC)。这个文件中包含了软件包的诸多信息,如软件包的名字、版本、类别、说明摘要、创建时要执行什么指令、安装时要执行什么操作、以及软件包所要包含的文件列表等等。
描述文件说明如下:
(1) 文件头
一般的spec文件头包含以下几个域:
Summary:
用一句话概括该软件包尽量多的信息。
Name:
软件包的名字,最终RPM软件包是用该名字与版本号,释出号及体系号来命名软件包的。
Version:
软件版本号。仅当软件包比以前有较大改变时才增加版本号。
Release:
软件包释出号。一般我们对该软件包做了一些小的补丁的时候就应该把释出号加1。
Vendor:
软件开发者的名字。
Copyright:
软件包所采用的版权规则。具体有:GPL(自由软件),BSD,MIT,Public Domain(公共域),Distributable(贡献),commercial(商业),Share(共享)等,一般的开发都写GPL。
Group:
软件包所属类别,具体类别有:
Amusements/Games (娱乐/游戏)
Amusements/Graphics(娱乐/图形)
Applications/Archiving (应用/文档)
Applications/Communications(应用/通讯)
Applications/Databases (应用/数据库)
Applications/Editors (应用/编辑器)
Applications/Emulators (应用/仿真器)
Applications/Engineering (应用/工程)
Applications/File (应用/文件)
Applications/Internet (应用/因特网)
Applications/Multimedia(应用/多媒体)
Applications/Productivity (应用/产品)
Applications/Publishing(应用/印刷)
Applications/System(应用/系统)
Applications/Text (应用/文本)
Development/Debuggers (开发/调试器)
Development/Languages (开发/语言)
Development/Libraries (开发/函数库)
Development/System (开发/系统)
Development/Tools (开发/工具)
Documentation (文档)
System Environment/Base(系统环境/基础)
System Environment/Daemons (系统环境/守护)
System Environment/Kernel (系统环境/内核)
System Environment/Libraries (系统环境/函数库)
System Environment/Shells (系统环境/接口)
User Interface/Desktops(用户界面/桌面)
User Interface/X (用户界面/X窗口)
User Interface/X Hardware Support (用户界面/X硬件支持)
Source:
源程序软件包的名字。如 stardict-2.0.tar.gz。
%description:
软件包详细说明,可写在多个行上。
(2)%prep段
这个段是预处理段,通常用来执行一些解开源程序包的命令,为下一步的编译安装作准备。%prep和下面的%build,%install段一样,除了可以执行RPM所定义的宏命令(以%开头)以外,还可以执行SHELL命令,命令可以有很多行,如我们常写的tar解包命令。
(3)build段
本段是建立段,所要执行的命令为生成软件包服务,如make 命令。
(4)%install段
本段是安装段,其中的命令在安装软件包时将执行,如make install命令。
(5)%files段
本段是文件段,用于定义软件包所包含的文件,分为三类--说明文档(doc),配置文件(config)及执行程序,还可定义文件存取权限,拥有者及组别。
(6)%changelog段
本段是修改日志段。你可以将软件的每次修改记录到这里,保存到发布的软件包中,以便查询之用。每一个修改日志都有这样一种格式:第一行是:* 星期 月 日 年 修改人 电子信箱。其中:星期、月份均用英文形式的前3个字母,用中文会报错。接下来的行写的是修改了什么地方,可写多行。一般以减号开始,便于后续的查阅。
4.打包
如果想发布rpm格式的源码包或者是二进制包,就要使用rpmbuild工具(rpm最新打包工具)。如果我们已经根据本地源码包的成功编译安装而写了spec文件(该文件要以.spec结束),那我们就可以建立一个打包环境,也就是目录树的建立,一般是在/usr/src/redhat/目录下建立5个目录。它门分别是BUILD、SOURCE、SPEC、SRPM、RPM。其中BUILD目录用来存放打包过程中的源文件,SOURCE用来存放打包是要用到的源文件和patch,SPEC用来存放spec文件,SRPM、RPM分别存放打包生成的rpm格式的源文件和二进制文件。当然我们可以根据需要来选用不同的参数打包文件,笔者总结如下3条。
1) 只生成二进制格式的rpm包
rpmbuild -bb xxx.spec
用此命令生成软件包,执行后屏幕将显示如下信息:(每行开头为行号)
1 Executing: %prep
2 + umask 022
3 + cd /usr/src/dist/BUILD
4 + exit 0
5 Executing: %build
6 + umask 022
7 + cd /usr/src/dist/BUILD
生成的文件会在刚才建立的RPM目录下存在。
2)只生成src格式的rpm包
rpmbuild -bs xxx.spec
生成的文件会在刚才建立的SRPM目录下存在。
3) 只需要生成完整的源文件
rpmbuild -bp xxx.spec
源文件存在目录BUILD下。
读者朋友可能对这个命令不太明白,这个命令的作用就是把tar包解开然后把所有的补丁文件合并而生成一个完整的具最新功能的源文件。
4) 完全打包
rpmbuild -ba xxx.spec
产生以上3个过程分别生成的包。存放在相应的目录下。
软件包制作完成后可用rpm命令查询,看看效果。如果不满意的话可以再次修改软件包描述文件,重新运行以上命令产生新的RPM软件包。
二.典型spec文件分析
通过第一部分的介绍,我们对软件包的管理以及spec文件的一些细节应该掌握的差不多了,接下来通过分析kaffeine.spec(kaffeine是linux平台下的媒体播放器)文件来让读者朋友实践一回spec文件的规范和书写。
Kaffeine.spec文件内容如下:
%define debug_package %{nil}
Name: kaffeine
Version: 0.4.3
Release: 25
Summary: A xine-based Media Player for KDE
Group: Applications/Multimedia
License: GPL
URL: http://kaffeine.sourceforge.net/
Source0: kaffeine-0.4.3.tar.bz2
Source1: logo.png
Source2: icon.tgz
Source3: kaffeine.desktop
Source4: codecs.tgz
Patch: kaffeine-0.4.3-fix-hide-crash.patch
Patch1:kaffeine-0.4.3-without-wizard.patch
BuildRoot: /var/tmp/kaffeine-root
%description
Kaffeine is a xine based media player for KDE3. It plays back CDs,
DVDs, and VCDs. It also decodes multimedia files like AVI, MOV, WMV,
and MP3 from local disk drives, and displays multimedia streamed over
the Internet. It interprets many of the most common multimedia formats
available - and some of the most uncommon formats, too. Additionally,
Kaffeine is fully integrated in KDE3, it supports Drag and Drop and
provides an editable playlist, a bookmark system, a Konqueror plugin,
a Mozilla plugin, OSD an much more.
以上这部分就是我们第一部分所说的文件头。这一部分主要包括软件包的名称、版本、源代码和patch等信息,通过这些关键字我们可以一目了然。查看以上内容,我们会全面了解该软件包。
接下来的这一个段就是核心部分,涉及到解包、补丁、编译、安装的过程。
%prep
%setup -q
%patch -p1
%patch1 -p1
%Build
make -f admin/Makefile.common cvs
./configure --prefix=/usr
make
#for mo files
pushd po
rm *.gmo
make
popd
%install
mkdir -p $RPM_BUILD_ROOT
make install DESTDIR=$RPM_BUILD_ROOT
mkdir -p $RPM_BUILD_ROOT/usr/share/services
cp $RPM_BUILD_ROOT/usr/share/apps/kaffeine/mms.protocol
$RPM_BUILD_ROOT/usr/share/services
cp $RPM_BUILD_ROOT/usr/share/apps/kaffeine/rtsp.protocol
$RPM_BUILD_ROOT/usr/share/services
#mkdir -p $RPM_BUILD_ROOT/usr/lib/firefox/plugins
#cp $RPM_BUILD_ROOT/usr/lib/kaffeineplugin/kaffeineplugin.so
$RPM_BUILD_ROOT/usr/lib/firefox/plugins
cp %{SOURCE1} $RPM_BUILD_ROOT/usr/share/apps/kaffeine
rm -rf $RPM_BUILD_ROOT/usr/share/icons/hicolor/*/apps/kaffeine.png
rm -rf $RPM_BUILD_ROOT/usr/share/icons/hicolor/*/apps/kaffeine-pause.png
rm -rf $RPM_BUILD_ROOT/usr/share/icons/hicolor/*/apps/kaffeine-play.png
rm -rf $RPM_BUILD_ROOT/usr/share/icons/hicolor/*/apps/kaffeine-record.png
mkdir -p $RPM_BUILD_ROOT/usr/share/icons/crystalsvg
tar zxvf %{SOURCE2} -C $RPM_BUILD_ROOT/usr/share/icons/crystalsvg
mkdir -p $RPM_BUILD_ROOT/usr/share/applnk/App/Multimedia
cp -r %{SOURCE3} $RPM_BUILD_ROOT/usr/share/applnk/App/Multimedia
mkdir -p $RPM_BUILD_ROOT/usr/lib/win32
tar zxvf %{SOURCE4} -C $RPM_BUILD_ROOT/usr/lib/win32
%clean
rm -rf $RPM_BUILD_ROOT
%post
ln -s /dev/cdrom /dev/dvd
ln -s /dev/cdrom /dev/rdvd
%files
%defattr(-,root,root)
/usr
这部分内容与所要打的包有关系,我们要根据具体情况来写出编译过程。这部分内容是最复杂的内容,当然,我们也可以看出,这样的写法其实就是在写一种规范化的脚本,说到脚本,读者朋友门就应该领会到这部分内容的灵活性了。
%changelog
* Fri Jul 1 2005 AiLin Yang <alyang@redflag-linux.com> -0.4.3-25
- modified the fullscreen bottom control panel
* Fri Jun 17 2005 xxx <xxx@redflag-linux.com> -0.4.3-24
- Modified to use xshm as video driver.
* Thu Jun 16 2005 AiLin Yang <alyang@redflag-linux.com>
- delete the option of Embed in system tray in configwidget
* Tue Jun 14 2005 AiLin Yang <alyang@redflag-linux.com>
- add fullscreen bottom control panel
- update kaffine to support my fullscreen bottom control panel
这部分内容可以说是spec文件的最后内容了,它对团队软件开发以及后续的软件维护至关重要,它相当于一个日志,记录了所有的基于该软件包的修改、更新信息。
小结
在Linux下RPM软件包的管理与RPM软件包的制作关键在rpm工具的使用和spec描述文件的起草。要想制作一个RPM格式的软件包必须编写软件包描述文件。其标准命名格式为:软件名-版本号-释出号.spec,这个文件详细描述了有关该软件包的诸多信息,如软件名,版本,类别,说明摘要,创建时要执行什么指令,安装时要执行什么操作,以及软件包所要包含的文件等等。有了这个文件RPM就可以制作出相应的rpm软件包。
RPM 打包技术与典型 SPEC 文件分析的更多相关文章
- RPM打包原理、示例、详解及备查
原文地址:https://blog.csdn.net/qq_16542775/article/details/80961213 RPM(Redhat Package Manager)是用于Redhat ...
- RPM打包原理、示例、详解及备查( 转)
RPM(Redhat Package Manager)是用于Redhat.CentOS.Fedora等Linux 分发版(distribution)的常见的软件包管理器.因为它允许分发已编译的软件,所 ...
- 以libfuse为例介绍rpm打包工具rpmbuild的使用和SPEC文件的编写
一.rpmbuild命令的安装 yum install rpm-build 二.用法 rpmbuild -bb XXXX.spec或者rpmbuild -ba XXX.tar.gz 三.目录概述 rp ...
- RPM安装包-Spec文件參数具体解释与演示样例分析
spec文件是整个RPM包建立过程的中心,它的作用就如同编译程序时的Makefile文件. 1.Spec文件參数 spec文件包括建立一个RPM包必需的信息,包括哪些文件是包的一部分以及它们安装在哪个 ...
- 使用spec文件语法创建一个rpm
How to create an RPM package/zh-hk < How to create an RPM package 此页面包含 Packaging:ScriptletSnippe ...
- CS4.1 RPM打包函数分析
shell举例说明:脚本名称叫test.sh 入参三个: 1 2 3运行test.sh 1 2 3后$*为"1 2 3"(一起被引号包住)$@为"1" &quo ...
- Pyinstaller通过spec文件打包py程序(多个py脚本)
Pyinstaller pyinstaller是python的一个第三方模块,使用它可以将python程序打包为可执行文件,实现打包后的程序在没有python环境的机器上也可以运行.pyinstall ...
- linux 版本控制及rpm打包
版本控制 subversion:是一个自由/开源的版本控制系统,在subversion管理下,文件和目录可以超越时空subversion允许你数据恢复到早期版本,或者是检查数据修改历史许多人将版本控制 ...
- 用 RPM 打包软件,第 1 部分
http://www.ibm.com/developerworks/cn/linux/management/package/rpm/part1/ RPM(Red Hat Package Manager ...
随机推荐
- 命令行执行Django脚本
命令行执行Django脚本 - #效仿manage.py加入的环境变量在脚本的文件加入 - #手动注册django所有的APP import sys,os ---------------------- ...
- IntelliJ IDEA 建空包合并问题。
举例:我想在一个包下,创建2个空子包,这个时候,却无法再IDE里完成. 老是这样子,如果选中dff.sfsdf再右键 创建包的话,结局是再sfsdf下 又创建一个文件夹. 如果右键创建类的话,实际上在 ...
- Linux下的堆伪造漏洞利用技术(new unlink)
感觉markdown的文件格式看起来更清晰一些就写成附加的形式了.Download 更正:这种利用方式不叫House of Mind,是我搞混了.
- 阿里云宝塔Linux服务器管理面版初始化地址不能登入(原创)
宝塔面板是一款可以让Linux服务器实现图形可视化操作的集成系统. 安装好以后,页面初始化登录地址http://{您的服务器IP}:888不能登入. 不能登入通常是我们没有权限访问,需要更改安全组赋予 ...
- FlumeNG介绍及安装部署
本节内容: Flume简介 Flume NG核心组件 Flume部署种类 Flume单机安装 一.Flume简介 Flume是一个分布式.可靠.高可用的海量日志聚合系统,支持在系统中定制各类数据发送方 ...
- day6 SYS模块
SYS模块 用于提供对Python解释器相关的操作: (1)sys.argv 命令行参数List,第一个元素是程序本身路径 >>> sys.argv [' ...
- 站点的安全防范都是后端的职责?非也,Web前端安全同样不可忽视
前言 随着网络的快速普及,网络安全问题的受害者不再只是政府.企业等集体,每一个接触网络的普通人都有可能成为网络攻击的受害者.随着网络的普及,黑客进行网络攻击的手段越来也多,越来越复杂.以网站的攻击为例 ...
- Bridge 桥接
意图 将抽象部分与它的实现部分分离,使它们都可以独立地变化. 动机 当一个抽象可能有多个实现时,通常用继承来协调它们.抽象类定义对该抽象的接口,而具体的子类则用不同方式加以实现.但是此方法有时不够灵活 ...
- 修改linux下默认的python版本
首先在终端输入:python --verison 查看本机默认采用的python 版本 接着进入/usr/local/lib 目录查看当前系统中安装了多少个python版本 如果只有一个,就安装你需要 ...
- Java 中常见数据类型的相互转换
1.将String 转化成 long , 转化成 double String 转化成 long : long i = Long.parseLong(String s); 或 long i = L ...