Rpm打包原理详解
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Rpm打包原理详解
为什么要打包?
制作rpm 不仅仅是打包,更可以解决菜单创建、打补丁、完成大量预配置、与其他软件包互动等操作。使用源代码安装要求用户了解基本的编译过程、能够应付各种不能编译的意外、必须自己完成抽象的配置、甚至懂得软件开发,能够自己打补丁,……对非计算机专业的用户而言简直就是天方夜谭。这是把软件开发的最后一步抛给了用户,作为发行版,这是极不负责任的!也是不现实的,除非用lfs,但那是一本菜谱,不是真正的发行版。
软件作者发布源代码是正确的,负责的作者一般都同时提供rpm 和deb 包以及它们的源代码包。除非他们不会制作。愿意使用什么,那是个人的自由,但对外就不能只想到自己。GNU 精神是一种公益精神,没有奉献精神,在自由软件领域是要遭唾弃的!
直接使用其他发行版的rpm 常常是不行的。不知道大家看没看“恼人的依赖关系”这个帖子。可以在技术支持区搜索一下。任何两个发行版本在二进制上都是不能兼容的!他们实际是不同的操作系统。不仅使用的库文件不同,配置也迥异。特别是同一个发行版的不同版本更不兼容。任何包都必须在本地重新编译,而且不一定通得过,因为还有spec 宏的兼容问题!如果要在别的发行版上使用,必须用源码编译,这是常识。考虑文件布局和配置问题,有时直接编译也是不够的,必须修改spec,甚至自己打补丁。
如何创建rpm 包?
rpm 建包原理其实不复杂。写spec 相当于一种脚本编程,主要是在spec 里提供一些软件相关信息,以及安装、卸载前后要执行的脚本,然后展开压缩的源代码包,打上补丁,执行编译,然后利用make install 可以重新指定安装目的地的特性,把编译好的文件安装到指定的虚拟根目录下的指定位置里,一般是虚拟的/usr 里,然后把这些目录、信息和脚本打成一个压缩包,即rpm 包。同时可选地生成源码包src.rpm。当然有很多具体细节问题。您应该首先阅读软件的readme 和INSTALL 文件。
打包原则
1. 任何人都应该在系统现有src.rpm 的spec 基础上修改更新,除非没有这样的包。这可以省去很多麻烦,少走弯路。
2. 任何人都无权删除别人的changelog 和原始打包者的信息,这是对别人的不尊重。但你可以追加自己的信息。
3. 尽可能在spec 里使用系统的标准宏定义,而不要用非标准写法。
4. 任何人都不应该直接提供修改后的源代码,而应该以补丁形式发布你的修改,在spec 里完成打补丁操作。务必做到一个补丁只解决一个问题,这样才能确保补丁的可重用性,否则
版本升级后补丁很容易失效。如果你确信自己的补丁是清洁补丁,尽可能发给上游开发者,这样才能一劳永逸。你所打的任何补丁,其授权方式必须和被修改源代码保持一致。
预备知识:
首先我们观察一下rpm 文件名的特点。一个rpm 包文件名通常由 5 段组成:
%{name}-%{version}-%{release}.ix86.rpm
cutedict-1.1-1mgc.i686.rpm
这里%{name}=cutedict,%{version}=1.1,%{release}=1mgc,ix86=i686,如果是为athlon 芯片家族编译的包,这里就是athlon,依此类推。
注意:
下面是一个spec 模板。
1. 凡是行首加上# 的都被注释掉了,实际运行时不起作用,如要使其生效,请去掉注释符#。
2. 凡是以%{***} 和%*** 形式出现的符号都是“宏”,很多宏都是系统预定义的[注2],也可以是自己定义的。
3. 下面的黑体字是spec 文件的关键字,不能写错。
4. 有不明白的地方可以参见跟帖里的参考文献。
5. 如果软件没有使用GNU autotool 创建,而是自己写的Makefile,这就导致不能按照常规方法打包,非常麻烦。
6. 服务器软件通常都需要大量预配置工作,spec 打包绝非一两天能解决,需要深入研究很多东西和反复实践,建议初学者不要尝试。
7. 其他发行版的spec 与src.rpm 是很好的教材,建议打包前先找找Fedora 或SuSE 的文件学习,能借鉴最好,但不应该不修改照搬过来或使用Mandrake 的文件,因为它使用的大量宏定义和我们不兼容,甚至src.rpm 直接编译都通不过。
------------------------------------------------------------------
[spec 文件头部]
# Initial spec file created by autospec #这里是一些注释
%define _noautoreq perl(Plot) perl(WidgetDemo) #这里用%define 自定义一个系统里没有的叫做_noautoreq 的宏,后面可以用%{_noautoreq} 引用。
Name: software #这是软件包名称,后面可以用%{name} 引用
Summary: a software #这是软件包的内容提要
#Summary(zh_CN): #这里写入中文内容提要(如果有必要。不建议使用,因为如果系统里的默认编码与此处不符,会导致显示乱码。例如:我们使用GBK,如果这里的中文是UTF-8 编码,在kpackage 里就会显示乱码,但是synaptic 可能能够正确显示,但需要把zh_CN 改为zh_CN.UTF-8 )
Version: number #这是软件的实际版本号,例如2.1.6、2.2final 等,后面可以用%{version} 引用
Release: number #发布序列号,我们用1mgc、2mgc 等等,标明这是第几次打包。如果软件本身是预览版,比如pre6 版,则写成pre6_1mgc、pre6_2mgc,后面可以用%{release} 引用
Group: Applications/Multimedia #这是软件分组,建议使用标准分组,参见下面:[注1]
#Group(zh_CN): #中文软件分组(如果有必要)
License: GPL #这是软件版权证书,通常是GPL
Source: %{name}-%{version}.tar.gz #这是源代码(通常是压缩包),可以带有完整的网址,可以用正整数标识多个源Source0 Source4 Source5 Source100,数字不必连续排列,后面可以用%{SOURCE0}、%{SOURCE4}、%{SOURCE5}、%{SOURCE100} 引用。例如/src/%{name}-%{version}.tar.gz
BuildRoo t: %{_tmppath}/%{name}-%{version}-%{release}-buildroot #这是make install 时使用的“虚拟”根目录也称为“构建根”目录,通常是/var/tmp/软件名称-版本号-发布序列号-buildroot,make install 时一般会将软件安装在/var/tmp/软件名称-版本号-发布序列号-buildroot/usr/ 下的bin/ 下(可执行文件)、share/ 下(数据、资源文件)、lib/ 下(共享库文件)等等,例如/var/tmp/cce-0.51-1mgc-buildroot/usr/bin/cce。不过实际不一定都是这样,具体情况具体对待
# 下面是可选的字段
URL: / #这是软件主页地址
#Vendor: Red Hat Co.,ltd. #这是发行商或者打包组织的信息,我们统一写成MGC Group,不过这一行可以省略,把它写入/usr/lib/rpm/macros 标准宏定义文件里,该文件的Vendor 这行定义是空的,而且通常前面用# 注释掉了
#Distribution: Red Hat Linux #这是软件针对的发行版标识,我们是Magic Linux
Patch: src-%{version}.patch #这是补丁源代码(可以是压缩包),可以用正整数标识多个源Patch1 Patch4 Patch6,数字不必连续排列。
Prefix: %{_prefix} #指定make install 时在虚拟根目录里的安装位置,通常用标准的%{_prefix} 宏,它代表/usr。这里指定后,用户可以在rpm 安装阶段重新指定安装到其他位置,如/opt,否则就不能改变安装位置。
Prefix: %{_sysconfdir} #如果软件有些文件并非都安装到%{_prefix},那么你需要指明其他位置。例如你需要把一个配置文件放到/etc 下面,这显然不在/usr 下面,此时你需要前方这种写法。%{_sysconfdir} 宏代表/etc。这里指定后,用户可以在rpm 安装阶段重新指定这些文件安装到其他位置,如/opt/etc,否则就不能改变安装位置。[注3]
#BuildArch: noarch#编译目标处理器架构,就是今后软件运行时的CPU 类型。noarch 是不指定架构,通常标准默认是i386,定义在了系统的标准宏定义文件/usr/lib/rpm/macros 里[注2]。实际编译时可以在rpmbuild 命令行用--target=i686 参数,spec 里通常不写这行。#Requires: XFree86>=4.3 zlib libpng #这里罗列所有安装本包时需要先行安装的包(依赖包),通常软件会依赖这些包里的一部分文件。可以分成多行来写。如果这里不写明依赖包,打包时系统会自动把具体依赖的.so 文件写进rpm 包,而不会注明这些文件属于哪些软件包,这会对用户造成困惑,因为他们很难知道这些文件属于哪些软件包
#Obsoletes: #这里列出的软件包都是“陈旧”的,当安装本包的时候,这里列出的包都会被自动卸载!
NoAutoReq: %{_noautoreq} #这里的意思是禁止自动查找对spec 文件头部预定义的_noautoreq 宏里定义的两个软件包[perl(Plot) 和perl(WidgetDemo)]的依赖关系,通常对于