您的位置:首页 > 产品设计 > 产品经理

rpm包制作(一)

2015-10-17 16:57 357 查看
rpm介绍
rpm的全称是RedhatPackage Manager,常见的使用rpm软件包的系统主要有Fedora、CentOS、openSUSE、SUSE企业版、PCLinuxOS等。使用deb软件包后缀的类Debian系统最常见的有Debian、Ubuntu、Finnix等。 从软件运行的结构来说,一个软件主要可以分为三个部分:可执行程序、配置文件和动态库。当然还有可能会有相关文档、手册、供二次开发用的头文件以及一些示例程序等等。可执行文件是必须的,其他部分都是可选的。
制作rpm软件包的方法,使用最多的是rpmbuild这个命令行工具。如果你的rpm的版本<=4.4.x,那么rpmbuid工具其默认的工作路径是/usr/src/redhat,由于权限使得普通用户不能制作rpm包,在制作rpm软件包时必须切换到root身份才可以。所以,rpm从4.5.x版本开始,将rpmbuid的默认工作路径移动到用户家目录下的rpmbuild目录里,即$HOME/rpmbuild。安全起见,建议用户在制作rpm软件包时尽量不要以root身份进行操作。
关于rpmbuild默认工作路径由%_topdir的宏变量来定义,这个变量在/usr/lib/rpm/macros里的定义。也可使用rpmbuild命令查看。
$ rpmbuild --showrc |grep _topdir
……
-14: _topdir    %{getenv:HOME}/rpmbuild


如果用户想更改这个目录,官方不推荐直接更改这个文件,而是在用户家目录下建立一个名为.rpmmacros的隐藏文件,然后在里面重新定义%_topdir,指向一个新的目录名。

定制rpm包工作目录结构
定制rpm包需要在%_topdir下建立以下5个目录
目录名 说明 macros中的宏名
BUILD 编译rpm包的临时目录 %_builddir
RPMS 最终生成的rpm包的所在目录 %_rpmdir
SOURCES 所有源代码和补丁文件的存放目录 %_sourcedir
SPECS 存放SPEC文件的目录(重要) %_specdir
SRPMS 源码格式rpm包存放路径 %_srcrpmdir

以上目录无需手动创建,执行rpmdev-setuptree命令即可在用户家目录下自动创建目录树
$ yum install rpmdevtools   #安装rpmdevtools这个工具,该工具包含rpmbuild,rpmdev-newspec,rpmdev-setuptree等工具
$rpmdev -setuptree
$ tree
.
└── rpmbuild
├── BUILD
├── RPMS
├── SOURCES
├── SPECS
└── SRPMS

rpmbuild命令常用选项
基本格式:rpmbuild  [options]  [spec文档|tarball包|源码包]
1、从spec文档建立rpm包有以下选项:
-bp        #只执行spec的%pre 段(解开源码包并打补丁,属于准备阶段)
-bc        #执行spec的%pre和%build 段(完成准备阶段并编译)
-bi        #执行spec中%pre,%build与%install(准备,编译并安装)
-bl        #检查spec中的%file段(查看文件是否包含完全)
-ba        #二进制的rpm包和源码的rpm包都建立(常用)
-bb        #只建立二进制的rpm包(常用)
-bs        #只建立源码的rpm包

2.  从tarball包建立rpm包有以下选项:
-tp         #对应sepc方式的-bp
-tc         #对应sepc方式的-bc
-ti         #对应sepc方式的-bi
-ta         #对应sepc方式的-ba
-tb         #对应sepc方式的-bb
-ts         #对应sepc方式的-bs

3.  从源码包建立rpm包有以下选项:
--rebuild    #建立二进制包,同sepc方式的-bb
--recompile   #同sepc方式的-bi

4.  其他选项:
--buildroot=DIRECTORY  #确定以root目录建立包
--clean         #完成打包后清除BUILD下的文件目录
--nobuild        #不进行%build的阶段
--nodeps         #不检查建立包时的关联文件
--nodirtokens          #generate packageheader(s) compatible with (legacy) rpm[23] packaging
--rmsource       #完成打包后清除SOURCES
--rmspec        #完成打包后清除SPEC
--short-cricuit     #skip straight tospecified stage (only for c,i)
--target=CPU-VENDOR-OS #确定包的最终使用平台


制作rpm包的几个关键阶段
%prep阶段
这个阶段主要完成对源代码包的解压和打补丁,系统把源码包从SOURCES解压缩到BUILD目录,并切换到BUILD下的压缩包解压生成的目录(可能是%{name}-%{version} )里,完成打补丁等准备工作,最后退回到BUILD 目录下。常用指令如下:
解压常用指令:
%setup              #不加任何选项,仅将软件包打开。
%setup -q            #quiet,静默方式解压,输出少量信息。
%setup -n destdir  #destdir为软件包解压后生成的目录名称,一般用在tar包名称和展开后生成的目录名不一致的情况下。
%setup -c           #解压缩之前先创建目录,目录名称一般为%{name}-%{version}。
%setup -a num        #a表示after,在切换到BUILD目录之后再解压第num个文件,如果有多个文件,会产生多个目录。
%setup -b num    #b表示before,在切换到BUILD目录之前再解压第num个文件。一般同-c一起使用,如果有多个文件,这样可以控制多个文件解压到一个目录下。
%setup -D          #在解压之前不删除原有目录
%setup -T           #不解压,直接把文件复制到BUILD目录即可。
%setup -T -b 0     #将第0个源代码文件解压缩。
%setup -c -n destdir   #指定目录名称destdir,并在此目录产生rpm套件。
打补丁常用指令:
%patch            #最简单的补丁方式,自动指定patch level。
%patch 0           #使用第0个补丁文件,相当于%patch?p 0。
%patch -s          #不显示打补丁时的信息。
%patch -T          #将所有打补丁时产生的输出文件删除。


%build阶段
这个阶段开始构建包,就是执行常见的configure和make操作。%configure是个宏常量,会自动将prefix设置成/usr。另外,这个宏还可以接受额外的参数,如果某些软件有某些高级特性需要开启,可以通过给%configure宏传参数来开启。如果不用 %configure这个宏的话,就需要完全手动指定configure时的配置参数了。如果不指定,它自动将软件安装时的路径自动设置成如下默认目录:可执行程序/usr/bin依赖的动态库/usr/lib或者/usr/lib64视操作系统版本而定。二次开发的头文件/usr/include文档及手册/usr/share/man 在configure执行完成之后系统重新进入BUILD下的压缩包解压出来的目录下执行 make命令,如make %{?_smp_mflags}OPTIMIZE="%{optflags}" 以上这条命令的两个参数的含意为:%{?_smp_mflags}如果系统里定义了make的并行编译参数,则使用这个参数。例如: -j2 表示 make并行执行两个文件的编译操作。如果你使用多个 CPU 或者非单核 CPU,这个参数可以明显提高编译速度,但是这里指定的数字不宜超过你的 CPU 内核数量+1。OPTIMIZE="%{optflags}" 表示如果系统里定义了 gcc的优化参数,则在软件默认优化参数的基础上追加使用这里指定的优化参数。例如: -O2 -g -pipe 表示使用 gcc 第二优化级、为调试工具GDB 提供额外的支持信息、使用管道而不是临时文件以便加快编译速度。这两个参数在/usr/lib/rpm/mBuild/macros文件中定义。
%install阶段
这个阶段就是执行make install操作。这个阶段会在BUILDROOT目录里建好目录结构,然后将需要打包到rpm软件包里的文件从BUILD里拷贝到BUILDROOT里对应的目录里。这个阶段最常见的两条指令是:
rm -rf $RPM_BUILD_ROOT
make install DESTDIR=$RPM_BUILD_ROOT

其中$RPM_BUILD_ROOT也可以换成我们前面定义的BuildRoot变量,不过要写成%{buildroot}才可以,必须全部用小写,不然要报错。
如果软件有配置文件或者脚本之类,需要使用用copy命令或者install命令拷贝到%{buildroot}相应的目录里,推荐用install命令。
install命令相关选项如下:
-b:类似 --backup,但不接受任何参数。
-d,--directory:所有参数都作为目录处理,而且会创建指定目录的所有主目录。
-D:创建<目的地>前的所有主目录,然后将<来源>复制至 <目的地>;在第一种使用格式中有用。
-g,--group=组:自行设定所属组,而不是进程目前的所属组。
-m,--mode=模式:自行设定权限模式 (像chmod),而不是rwxr-xr-x。
-o,--owner=所有者:自行设定所有者 (只适用于超级用户)。
-p,--preserve-timestamps:保留文件原有时间戳。
-S,--suffix=后缀:自行指定备份文件的<后缀>。


%clean阶段
执行编译完成后一些清理工作,主要包括对%{buildroot}目录的清空(不是必须),通常执行诸如make clean之类的命令。 通常执行以下命令:
%clean
rm -rf $RPM_BUILD_ROOT
rm -rf $RPM_BUILD_DIR/%{name}-%{version}
也可以写成
%clean
%{__rm}-rf %{buildroot}
%{__rm}-rf %{_builddir}/%{name}-%{version}


%files阶段
这里是包含制作rpm包文件的阶段,它主要用来说明会将%{buildroot}目录下的哪些文件和目录最终打包到rpm包里。
在%files阶段的第一条命令的语法是:%defattr(文件权限,用户名,组名,目录权限)
如果不需要改变文件、目录权限则一般用%defattr(-,root,root,-)这条指令来为其设置缺省权限。所有需要打包到rpm包的文件和目录都在这个地方列出。
%files阶段有一个重要特性: %{buildroot}里的所有文件都需要明确指定是否要被打到rpm包里。如果不打也要用%exclude排除掉。当然,也不能声明%{buildroot}里不存在的文件或目录。
其他附加阶段
%pre #在此编写rpm包安装前执行的脚本。
%post #在此编写rpm包安装后执行的脚本。
%preun #在此编写rpm包卸载前执行的脚本。
%postun #在此编写rpm包卸载后执行的脚本。

例如:
%postun
if ["$1" = "0" ]; then
rm -rf $RPM_BUILD_ROOT%{jdk_home}/jdk
fi
这里的$1可能会有0,1,2或以上,这几个值。
0表示卸载这个包的最新版本
1表示第一次安装这个包
2或以上表示升级这个软件包

%changelog阶段
这是最后一个阶段,记录每次打包时的变更日志,日期一定不能写错,只能使用英文格式,如:
* WedApr 11 2014 ju.com <ju@puhuifianance.com> - 1.8.0-1
- modifythe spec file and rebuild

rpm包标准分组
制作rpm包的spec文件里定义的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         文档
SystemEnvironment/Base    系统环境/基础
SystemEnvironment/Daemons     系统环境/守护
SystemEnvironment/Kernel      系统环境/内核
SystemEnvironment/Libraries  系统环境/函数库
SystemEnvironment/Shells   系统环境/接口
UserInterface/Desktops    用户界面/桌面
UserInterface/X        用户界面/X窗口
UserInterface/X Hardware Support   用户界面/X硬件支持


常见宏定义
在系统的/usr/lib/rpm/macros文件中定义了各种宏变量,这里列出常见的宏定义:
%_prefix     /usr            #展开后是/usr
%_exec_prefix   %{_prefix}         #展开后是/usr
%_bindir     %{_exec_prefix}/bin       #展开后是/usr/bin
%_sbindir     %{_exec_prefix}/sbin     #展开后是/usr/sbin
%_libexecdir   %{_exec_prefix}/libexec   #展开后是/usr/libexec
%_datadir      %{_prefix}/share      #展开后是/usr/share
%_sysconfdir   %{_prefix}/etc       #展开后是/usr/etc
%_sharedstatedir %{_prefix}/com        #展开后是/usr/com
%_localstatedir  %{_prefix}/var      #展开后是/usr/var
%_libdir     %{_exec_prefix}/lib    #展开后是/usr/lib
%_includedir   %{_prefix}/include      #展开后是/usr/include
%_infodir    %{_prefix}/info         #展开后是/usr/info
%_mandir     %{_prefix}/man       #展开后是/usr/man


上面说了一堆制作rpm包涉及的一些概念和既定的东西,然而要真正制作一个rpm包,这些并没有什么大的卵用,哈哈,关键还要会写最最重要的SPEC文件,请见下回分解à《rpm包制作(二)》。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息