如何制作rpm包

Posted redguardtoo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何制作rpm包相关的知识,希望对你有一定的参考价值。

以前写的一篇文档,文章重点在于讲清如何快速上手和会碰到的问题。并不是软件文档的中文翻译,要看大全或faq的见参考文献

1. 概述以及难点
这里的概述仅仅是我的理解。如果要获得准确全面的信息,建议阅读“参考文献”一章。

开发者需要书写一个后缀名为spec的文本文件(简称spec文件),该文件提供了将应用程序打包(package)必须的配置信息。开发者在填写完这个配置文件(就是spec文件)后,只需要运行打包软件rpmbuild(通常是输入命令行"rpmbuild -ba your_application.spec),rpmbuild读入spec文件上的配置信息,自动生成rpm包。书写spec文件的内容是打包者的主要工作。

这里有个关键,理解这个关键是阅读并正确书写spec文件的前提。

关键在于,rpm是为开源软件设计的打包软件,它假设软件的打包者对于要打包的软件并不熟悉,例如打包者对他(她)要打包的软件的熟悉度,只是知道如何获得源代码包并解压缩源代码包,然后“./configure;make;make install”。即使这样,打包者也可以成功地制作rpm包。如果不理解这点,你可能会误会打包过程中的“install”(意义见后文),就是普通用户安装程序中的“安装”。实际上,打包过程中的install仅仅是处理源代码包的一个步骤而已。后文会详细解释这个问题。

和通常商业打包软件不同的是,在spec文件中,你*可以*提供(通过设置Source变量)软件的源代码包的完整文件名(注意:不是完整路径!具体原因见后文)。几乎所有的开源软件都提供源代码包的文件名(例如hello-1.0.0.tar.gz)。打包系统会根据且*仅*根据文件名(和文件名一起提供的路径自动被忽略)在并且*仅仅在*某个特定目录找到这个源代码包。这里的“特定目录”由%{_topdir}/SOURCES指定,_topdir是环境变量,可以输入命令行rpmbuild --showrc查看这个变量,在redhat linux系统中,%{_topdir}的值是/usr/src/redhat,具体细节参考RPM Tutorial和Maximum RPM。

打包系统找到这个源代码包后,它会解压缩源代码包(解压缩至%{_topdir}/BUILD目录中)并且将当前工作目录切换到解压缩后的源代码包根目录里(这个阶段可以认为是prepare阶段,在spec文件中简写为%prep),然后它开始编译源代码包(这个阶段是build阶段,在spec文件中简写为%build),然后它会将编译出的binary文件安装(这个阶段是install阶段,在spec文件中简写为%install)到用户指定的某个目录(可以由$RPM_BUILD_ROOT这个环境变量访问)。接着打包系统进入清理阶段,它会删除一些打包过程中产生的临时文件(这个阶段是clean阶段,在spec文件中简写为%clean)。最后它会输出binary rpm包到%{_topdir}/RPMS/i386中(子目录是i386还是i486,i586,取决于系统的architecture设置),输出source rpm包到%{_topdir}/SRPMS/中。

注意!以上描述中的主语始终是“打包系统”,也就是说,上段中的各个动作都是在打包过程中发生的动作。就是你运行“rpmbuild -ba your_application.spec”后打包系统的一些自动的动作。 即使是install阶段,也只是打包过程中的一个阶段(这个阶段移动了某些临时文件)而已。和最终用户安装rpm包中的“安装”根本是两回事!!!

在cos系统中的spec文件,没有上文所说的“prepare,build”两个阶段,而所谓install阶段,我理解只是例行公事地把编译好的二进制文件移动到$RPM_BUILD_ROOT目录中去。

2. 一个spec文件的例子
spec文件实际上很简单。一个spec文件可以划分为三个部分(我的理解):必要信息,shell脚本(shell scripts),要打包的文件清单(file list,在spec文件中用%files标示)。

所谓必要信息,就是诸如公司名,源代码包名,打包者的名字之类的杂七杂八的信息,为什么要提供这些信息是显而易见的。其中的Source变量指定了源代码包的来源,我的例子给出了源代码包的文件名,有些spec文件会给出源代码包的url,但是结果和我这里没什么区别。对于打包系统来说,它会忽略掉url,提取出源代码包的文件名。BuildRoot变量设定了$RPM_BUILD_ROOT的值。

shell脚本是在打包以及运行安装程序的过程中必须运行的一些脚本程序,例如删除文件,移动文件,创建目录等等。在%prep,%build,%install,%clean各section下(每个section对应打包过程中的一个阶段)都是一些常见的shell脚本或命令。%setup -q是一个宏,对应解压缩源代码包,进入源代码包目录等几个动作,你可以不使用这个宏而自己写脚本命令。但是使用宏显然方便很多。%setup的细节请参考Maximum RPM。

要打包的文件清单部分在spec文件中用%files标示,例如:
%files
#defattr的定义请参阅RPM HOWTO
%defattr(-,root,root)
#hello文件放入最后生成的安装包中,其安装路径为/usr/local/bin
/usr/local/bin/hello

打包者应该在文件清单部分中指定放入于安装包中的二进制文件名,打包者也要指定运行安装包后该文件最终应被安装到哪里。

例如上例中的"/usr/local/bin/hello",说明了hello这个可执行程序(打包系统会在$RPM_BUILD_ROOT下的相应子目录寻找hello)应被放入安装包中,运行安装包后hello将最终被安装到/usr/local/bin目录下。

以下是一个spec文件的例子,完整的源代码,脚本以及spec文件见附件(附件找不着了!) :
#--------------------hello-1.0.0-1.spec----------------begin
Summary: a simple "hello world" app
Name:hello
Version: 1.0.0
Release: 1
Copyright: Commercial
URL: http://www.kodak.com
Source: %{name}-%{version}.tar.gz
Vendor: Kodak Inc.
Packager:  Jerry Chen <jerry.chen@kodak.com>
Group: Applications/Multimedia
#指定了$RPM_BUILD_ROOT的值
BuildRoot:/var/tmp/%{name}-%{version}-%{release}-root


%description
a simple "hello world" app. you can do nothing useful with it.

%prep
#解压缩源代码包,进入源代码包目录
%setup -q

%build
#就是make了
make

%install
rm -rf $RPM_BUILD_ROOT
#编译好的二进制文件安装到环境变量$RPM_BUILD_ROOT所指定的目录中去。
make DESTDIR="$RPM_BUILD_ROOT" install

%clean
rm -rf $RPM_BUILD_ROOT

%files
%defattr(-,root,root)
#hello文件放入最后生成的安装包中,其安装路径为/usr/local/bin
/usr/local/bin/hello

%changelog
#--------------------hello-1.0.0-1.spec----------------end

3. 参考文献
网上关于rpm package的文档,我认为比较有价值的罗列如下:

Packaging software with RPM, Part 1 & Part 2
http://www-128.ibm.com/developerworks/library/l-rpm1/
http://www-128.ibm.com/developerworks/library/l-rpm2/
入门文档,也提供了一些有用的信息。

Maximum RPM
http://www.rpm.org/max-rpm/index.html
大全。

RPM HOWTO
http://www.tldp.org/HOWTO/RPM-HOWTO/
入门文档,相对于"Packaging software with RPM",可读性稍差。

RPM Tutorial
http://genetikayos.com/code/repos/rpm-tutorial/trunk/rpm-tutorial.html
一个操作手册而已,对于没有root权限的打包者有一定的价值。但称为tutorial恐怕有点问题

以上是关于如何制作rpm包的主要内容,如果未能解决你的问题,请参考以下文章

打rpm包步骤

将源码包制作成RPM包

通过nginx源码包制作rpm包

把脚本制作成RPM包

制作rpm包

如何制作rpm包