Chinaunix首页 | 论坛 | 博客
  • 博客访问: 774696
  • 博文数量: 239
  • 博客积分: 60
  • 博客等级: 民兵
  • 技术积分: 1045
  • 用 户 组: 普通用户
  • 注册时间: 2009-03-22 18:25
文章分类

全部博文(239)

文章存档

2019年(9)

2018年(64)

2017年(2)

2016年(26)

2015年(30)

2014年(41)

2013年(65)

2012年(2)

分类: LINUX

2013-07-29 11:28:32

原文地址:rpm打包整理 作者:luckyqiao

最近在学习之余,学习了rpm打包,整理了一些资料(基于Qomo平台)

首先介绍下RPM

RPM 是 Red Hat Package Manager 的缩写,原意是Red Hat 软件包管理。 

这里先介绍一下RPM的一些用法。

查询功能: 

 1、对系统中已经安装的软件查询:rpm -q softwarename

 2、查询系统中已安装的包:rpm -qa [softwarename] 

 3、查询已安装软件包都安装到何处:rpm -ql softwarename 

安装,删除 rpm -ivh softwarename.rpm rpm -e softwarename


 其余更多的用法参照man rpm


打包前的工作:

1、安装打包套件:$sudo yum install rpm-build 

2、建立打包的环境: 不建议用 root 来打包套件,所以请改用一般的使用者身分来打包套件,首      先要安装 fedora-rpmdevtools 这个套件. 

 接著执行 fedora-buildrpmtree 来建立打包的环境:

 $sudo yum install fedora-rpmdevtools 执行完后,就会在HOME目录下生成rpmbuild目录 

 在 rpmbuild 目录底下又有 BUILD RPMS SOURCES SPECS SRPMS 五个子目录 

 也可以自己手动创建这五个目录:mkdir -p ~/{BUILD,RPMS,S{OURCE,PEC,RPM}S} 

 这些目录的作用如下 

 BUILD 编译时所用的暂存目录 

 RPMS 放置打包好的套件

 SOURCES 放置套件的原始码及修补档等等 

 SPECS 放置 .spec 档 SRPMS 放置 Source RPMS (.src.rpm) 

3、这里为了提高书写spec文件的效率,介绍几个vim的插件 

 spec文件里面有Group和%Changelog书写比较麻烦, 

 Group的插件下载: ren.org/qomo-toolkit/tree/vim/rpmgroups.vim,

 将rpmgroups文件放在/usr/share/vim/vim72/plugin/下, 

 然后执行source /usr/share/vim/vim72/plugin/rpmgroups.vim 

 在/etc/vimrc文件最后加上:let packager = "",

 “ ”中的是你的邮箱名。 

 然后在写Group时在插入状态下按\g,就会出来group选项,选择就好,不用担心书写错误; 

 在书写%Changelog时,在命令状态下按\c就会把刚才在/etc/vimrc文件最后加的那句会自动补  上去,很方便使用的。


运行 rpmbuild -ba filename.spec 时,RPM 都 做些什么:

读取并解析 filename.spec 文件
运行 %prep 部分来将源代码解包到一个临时目录,并应用所有的补丁程序。
%setup –q
%patch,%patch0,%patch1
运行 %build 部分来编译代码。
运行 %install 部分将代码安装到构建机器的目录中。
读取 %files 部 分的文件列表,收集文件并创建二进制和源 RPM 文件。
运行 %clean 部 分来除去临时构建目录。


打包最主要的就是书写spec文件,下面是一个spec文件的模板,后面就主要对这个文件和遇到的问题进行说明

Name:         #包名
Version:         #版本号 注: 版本号中不能含减号(-)字符。
Release:    1%{?dist} #释出号 注: 释出号中亦不能含减号(-)字符。
Summary:         #简单的说明

Group:             #软件所属类别 这个就用到了上面所说的那个vim插件
License:         #软件适用的许可证或版权规则 也可用Copyright(版权)来定义,二者同意
URL:             #打包软件有关信息的网页地址。
Source0:         #RPM打包时要包含的程序源码文件。
BuildRoot:    %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)

BuildRequires:    
Requires:    

%description

%prep
%setup -q

%build
%configure
make %{?_smp_mflags}

%install
rm -rf $RPM_BUILD_ROOT
make install DESTDIR=$RPM_BUILD_ROOT

%clean
rm -rf $RPM_BUILD_ROOT

%files
%defattr(-,root,root,-)
%doc

%changelog


spec文件说明:(这里我们用pcmanfm这个包作说明)
文件头(必选段):Name Version Release Summary Gruop License
可选的有:Vendor  Packager
功能段:%description  %files

Group 部份请参考:
/usr/share/doc/rpm-*/GROUPS 或是
举个例子:
Group: Applications/System
License: GPL
URL:
Source0:
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
Source 部份,最好是包含整个网址,而不要只有档名而已
若有好几个 Source 则用 Source0 Source1 Source2 … 依此类推
若有 Patch 档就需要用到 (例: Patch0: pcmanfm-0.3.0-beta3-Makefile.patch)
若有好几个 Pacth 则用 Patch0 Patch1 Patch2 … 依此类推

BuildRequires 及 Requires 的部份就要看原作者是否有提到需要哪些套件
不然,就得从 mock build 时的 build.log 中
慢慢去找出所需要的 BuildRequires 及 Requires

BuildRequires: automake >= 1.9, gtk2-devel >= 2.6, gamin-devel
Requires: gtk2 >= 2.6, gamin

%prep
一般我们用setup -p
单数如果像这样的软将源码包:pcmanfm-0.3.0-beta3.tar.gz
%setup macro 会把 source code tarball 解开并自动进到 %{name}-%{version} 的目录中
因为我们把 Version Tag 0.3.0-beta3 的 beta3 拆到 Release Tag 去
Version Tag 变成 0.3.0,所以 %setup 在 rpmbuild 时会出问题
rpmbuild 会解开 pcmanfm-0.3.0-beta3.tar.gz 并试著进到 pcmanfm-0.3.0 (%{name}-%{version}) 的目录中
但实际上应该是要进到 pcmanfm-0.3.0-beta3 的目录才对
因此,我们必须加上 -n pcmanfm-0.3.0-beta3 来解决这个问题
若有 Source2 Source5 等等的 tarball 同时也要解开时,可以使用 -a 参数来指定 (例: %setup -q -a 2 -a 5)
若有 Patch 档则同样在这里做处理 (例: %patch1 -p1 -b .bak)
其他一些在正式 build (make) 前要做的特殊处理,都可以在这里做
(例: find . -name \*.h -o -name \*.c | xargs chmod ugo-x)
%prep
%setup -q -n pcmanfm-0.3.0-beta3
其实还有一个办法,就是把这个包解压,然后重新打包为:pcmanfm-0.3.0.tar.gz,这样在Release时写beta3也可以。
(这个是个投机取巧的方法,但是确实解决了不少麻烦)

%build
若有需要加 configure 的参数,可以加在 %configure 后面
(例: %configure –prefix=%{_prefix})
若还有其他的编译指令需要执行时,都可以加在这里
%build
%configure
make %{?_smp_mflags}

%install
rm -rf $RPM_BUILD_ROOT
make install DESTDIR=$RPM_BUILD_ROOT
一般我们是安装在$RPM_BUILD_ROOT下的

另外,关於 desktop 档的部份,要在 %install 中使用 desktop-file-install 来处理
然后在 %files 中加入一行:
%{_datadir}/applications/fedora-pcmanfm.desktop
BuildRequires 的部份也要加入 desktop-file-utils:
BuildRequires: automake >= 1.9, gtk2-devel >= 2.6, gamin-devel, desktop-file-utils
另外还要加入:
Requires(post): desktop-file-utils
Requires(postun): desktop-file-utils
%post 及 %postun 的部份也要做处理
Desktop files 请参考:

%clean
rm -rf $RPM_BUILD_ROOT
这个是最后清理阶段

下面这四项很少用到,(这个要到一定的阶段,例如自己打补丁时)
%post
update-desktop-database %{_datadir}/applications >/dev/null 2>&1 || :
用来处理套件安装完成后要执行的指令
%postun
update-desktop-database %{_datadir}/applications >/dev/null 2>&1 || :
用来处理套件移除后要执行的指令
%pre
用来处理套件安装前要执行的指令
%preun
用来处理套件移除前要执行的指令

下来测试打包:
当然上面的书写并没有完全写好spec文件,需要在下面的测试后才能完整的写好spec文件。
1.rpmbuild -bc
rpmbuild -bc 会从一开始一直做到 %build 为止
用来检查到 %build 为止是否还有问题
若有发现任何错误,如 command not found 等等
就要去 check required package 然后加到 Requires/BuildRequires 中
$rpmbuild -bc pcmanfm.spec

这里如果有错误,一般的都是说Not found ****,一般都是缺少某个开发包
在这里有个办法,就是先用yum search **** | grep dev 来查寻,看源里是否有这个开发包,
如果有的话,就直接用yum install ****-devel 安装(这里的****-devel根据search的结果决定)

rpmbuild -bi
rpmbuild -bi 会从一开始一直做到 %install 为止
rpmbuild -bi pcmanfm.spec
这里经常会出现的错误为:
warning: Installed (but unpackaged) file(s) found:
/usr/bin/pcmanfm
/usr/share/applications/pcmanfm.desktop
/usr/share/locale/ca/LC_MESSAGES/pcmanfm.mo
/usr/share/locale/de/LC_MESSAGES/pcmanfm.mo
/usr/share/locale/es/LC_MESSAGES/pcmanfm.mo
/usr/share/locale/fr/LC_MESSAGES/pcmanfm.mo
/usr/share/locale/zh_TW/LC_MESSAGES/pcmanfm.mo
。。。。。。。。。

这里我们就要补充我们的%files段
针对上面这个问题,我们在%files段加入
%{_bindir}/pcmanfm
%{_datadir}/*  #这里是一个简写

相关的 macros 可以在 查询到
/usr/lib/rpm/macros需要的可以在这个文件理全有。
常见的如:
%{_sysconfdir} /etc
%{_initrddir} %{_sysconfdir}/rc.d/init.d
%{_prefix} /usr
%{_exec_prefix} %{_prefix}
%{_bindir} %{_exec_prefix}/bin
%{_lib} lib
%{_libdir} %{_exec_prefix}/%{_lib}
%{_libexecdir} %{_exec_prefix}/libexec
%{_sbindir} %{_exec_prefix}/sbin
%{_sharedstatedir} %{_prefix}/com
%{_datadir} %{_prefix}/share
%{_includedir} %{_prefix}/include
%{_oldincludedir} /usr/include
%{_var} /var
%{_tmppath} %{_var}/tmp
请尽量改用 macros 来取代 /etc /usr/bin /usr/lib 的写法

用 rpmbuild -bs 来产生 SRPMS
用 rpmbuild -bb 来产生 RPMS
用 rpmbuild -ba 来同时产生 SRPMS 及 RPMS(一般只需直接执行这句)

最后需要注意的一些问题:
不需要加到 BuildRequires 中的 Exceptions
bash
bzip2
coreutils
cpio
diffutils
fedora-release (and/or redhat-release)
gcc
gcc-c++
gzip
make
patch
perl
redhat-rpm-config
rpm-build
sed
tar
unzip
which
详细清单请参考:

Documentation
若有相关的说明文件,可以独立成 -doc subpackage
并以 Documentation 当作 Group Tag
Configuration files
设定档请使用 %config(noreplace) 来代替 %config
只有当设定档有变时,才改用 %config 来覆盖掉旧的
Macros
详细的 Macros 请参考:
不要使用 %makeinstall macro
直接用: make DESTDIR=$RPM_BUILD_ROOT install

RPM 建包参考文件






本人也是刚开始打包,这些资料是根据网上的一些资料加上自己的理解和遇到的问题写的,如有什么错误,希望斧正。
我的邮箱:qiaozqjhsy@gmail.com
阅读(1106) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~