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
- 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包制作(二)》。