Chinaunix首页 | 论坛 | 博客
  • 博客访问: 83795
  • 博文数量: 13
  • 博客积分: 384
  • 博客等级: 一等列兵
  • 技术积分: 90
  • 用 户 组: 普通用户
  • 注册时间: 2011-05-20 09:16
文章分类

全部博文(13)

文章存档

2011年(13)

最近访客

分类: LINUX

2011-07-16 15:03:37

出处
RPM 做什么

我们先来看看在您运行 rpmbuild -ba filename.spec 时,RPM 都 做些什么:

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

$BuildRoot$RPM_BUILD_ROOT 一 般是相同值,在%install时,一般将东西安装到这个临时根下,所以一般在installrm -rf $RPM_BUILD_ROOT%clean rm -rf $RPM_BUILD_ROOT%files中 声明了真正的路径,rpm会到构建根下寻找其对 应的文件。%clean 是一切都正常的情况下在 RPM 构建结束时运行的脚本,这样临时文件就不会一直 保留。

构建rpm包 时不会在%file所列路径中添加任何东西,此时所有东西都是安装在%RPM_BUILD_ROOT所在路径底下,只有在安装rpm包 时会在对应路径下添加。用来查一些内 置变量的值,如

rpm –showrc

_sourcedir
RPM
在哪里查找源文件(tar 文件,等)

_srcrpmdir
RPM 在哪里放入新的源 RPM 文件

_rpmdir
RPM 将 把新的二进制 RPM 文件放在哪里(在特定于体系结构的子目录中)

_topdir
BUILDSOURCE SPECSRPMRPM5个目录所在的目录。

/usr/lib/rpm/macros中 差一些宏的缺省值,如 %_sourcedir %_specdir %_srcrpmdir %_builddir %_rpmdir

注意: prep 后的操作都是在 tmp 的目录中进行的。

一、RPM 打包前的准备工作

1. 要打包套件,必须先安装 rpm-build 套件

$sudo yum install rpm-build

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

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

$sudo yum install fedora-rpmdevtools

执行完后,在 Home 目录底下就产生 rpmbuild 的目录
在 rpmbuild 目录底下又有 BUILD RPMS SOURCES SPECS SRPMS 五个子目录,如果是 RedHat 是没有这个包的,可以自己来建这些目录.

$fedora-buildrpmtree

$mkdir -p ~/rpmbuild/{BUILD,RPMS,S{OURCE,PEC,RPM}S}

这些目录的作用如下

BUILD        编译时所用的暂存目录
RPMS        放置打包好的套件
SOURCES   放置套件的原始码及修补档等等
SPECS    放置 .spec 档
SRPMS 放置 Source RPMS (.src.rpm)

-bp 只作准备 (解压与打补丁)
-bc 准备并编译
-bi 编译并安装
-bl 检验文件是否齐全
-ba 编译后做成*.rpm和src.rpm
-bb 编译后做成*.rpm

-bs 只做成*.src.rpm
-tc -ti -ta -tb -ts 的功能类似,只是所需参数由spec文件变成tar包。


3.建立 ~/.rpmmacros 档案
编辑 ~/.rpmmacros,主要是设定 %packager 及 %vendor 等等:

%_topdir 这个选项是配置 RPM 在构建时使用新的目录结构,而不是默认的目录结构.也可以自己使用如下命令来指定.

%_topdir %(echo $HOME)/rpmbuild %_smp_mflags -j3 %__arch_install_post /usr/lib/rpm/check-rpaths /usr/lib/rpm/check-buildroot %packager Fu Kai

echo "%_topdir $HOME/rpmbuild" > ~/.rpmmacros
如果有 GPG Key 可以加上类似底下几行,到时候要 GPG Sign 时会用到:

%_signature gpg %_gpg_path ~/.gnupg %_gpg_name Fu Kai

二、建立 RPM 的 spec 档案


我以打包 pcmanfm-0.3.0-beta3.tar.gz 为例
假设这个套件没有人打包过,因此必须自行建立 pcmanfm.spec 档案
先进到 ~/rpmbuild/SPECS 目录底下:

$cd ~/rpmbuild/SPECS

1. 利用 fedora-newrpmspec 工具程式来产生一个 spec 档的样本,然后再慢慢来修改

fedora-newrpmspec pcmanfm

执行完后,就会产生 pcmanfm.spec,spec 档的命名规则为 %{name}.spec,这个的 Encoding 必须为 UTF-8。

2. 编辑 pcmanfm.spec
2.1.Version、Release 及 Summary

Version Tag 及 Release Tag 的命名规则,请参考:

Version: 0.3.0 Release: 0.1.beta3%{?dist} Summary: PCMan File Manager

Version Tag 要是数字才行
pcmanfm-0.3.0-beta3 算是 Pre-release packages
(Version 中包含 “alpha”, “beta”, “rc”, “cvs”)
我们不能直接用在 Version 中,beta3 的部份要改放到 Release 中

格式: 0.%{X}.%{alphatag}
0 不变
%{X} 从 1 开始递增
%{alphatag} 来自於 Version Tag 中的字串

Release Tag for Pre-Release Packages:

所以 pcmanfm-0.3.0-beta3 的 Release Tag 就是 0.1.beta3
至於后面的 Dist Tag (%{?dist}) 则是给 mock build 时用的
Dist Tag 请参考:

2.2.Group、License、URL、 Source、Patch 及 BuildRoot

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 … 依此类推

必要时需要自己制作 patch 档案,例:

cd ~/rpmbuild/BUILD/pcmanfm-0.3.0-beta3 cp Makefile Makefile.orig

然后修改 Makefile

cd ~/rpmbuild/BUILD gendiff pcmanfm-0.3.0-beta3 .Makefile < ../SOURCES/pcmanfm-0.3.0-beta3-Makefile.patch

2.3.BuildRequires 及 Requires

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

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

2.4.%description

%description PCMan File Manager An extremly fast and lightweight file manager which features tabbed browsing and user-friendly interface Features: Extremly fast and lightweight Can be started in one second on normal machine Tabbed browsing (Similar to Firefox) Drag & Drop support Files can be dragged among tabs Load large directories in reasonable time File association support (Default application) Basic thumbnail support Bookmarks support Handles non-UTF-8 encoded filenames correctly Provide icon view and detailed list view Standard compliant (Follows FreeDesktop.org) Clean and user-friendly interface (GTK+ 2)

%description 要注意的是,每一行最长不要超过 79 个字元

2.5.%changelog

%changelog 部份,就是日期、打包者的姓名及 E-mail 等等
最后面则是要包含这次的 %{version}-%{release}
若有使用 Epoch Tag 则是 %{Epoch}:%{version}-%{release}

%changelog * Fri Aug 18 2006 Fu Kai

2.6.%prep

%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

2.7.%build

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

%build %configure make %{?_smp_mflags}

2.8.%install

%install rm -rf $RPM_BUILD_ROOT make install DESTDIR=$RPM_BUILD_ROOT %find_lang %{name} desktop-file-install \ –delete-original \ –vendor fedora \ –dir ${RPM_BUILD_ROOT}/%{_datadir}/applications \ –add-category X-Fedora \ ${RPM_BUILD_ROOT}/%{_datadir}/applications/pcmanfm.desktop

若还有其他相关的安装指令都可以加在这里
至於 locale mo 档的部份,则是要改用 %find_lang macro 来处理
另外,关於 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 请参考:

2.9.%clean

%clean
rm -rf $RPM_BUILD_ROOT

2.10.%files

%files -f %{name}.lang
%defattr(-,root,root,-)
%doc AUTHORS COPYING ChangeLog INSTALL NEWS README TODO
%{_datadir}/applications/fedora-pcmanfm.desktop

%files 后面的 -f %{name}.lang 则是跟 %find_lang macro 搭配
用来处理 locale mo 档
%doc 部份,则是放 AUTHORS COPYING ChangeLog INSTALL NEWS README TODO 等文件
至少要放版权的部份 (如 License: GPL 则 COPYING 的内容就是放 GPL 版权的内容)
若不知道还会安装哪些档案也没关系,之后可以利用 rpmbuild -bi 的 log 来查询

2.11.%post

%post
update-desktop-database %{_datadir}/applications >/dev/null 2>&1 || :

用来处理套件安装完成后要执行的指令
例如 update-desktop-database 那行就是在处理 Desktop files 部份

2.12.%postun

%postun
update-desktop-database %{_datadir}/applications >/dev/null 2>&1 || :

用来处理套件移除后要执行的指令
例如 update-desktop-database 那行就是在处理 Desktop files 部份

2.13.%pre
用来处理套件安装前要执行的指令
在本例中没有用到

2.14.%preun
用来处理套件移除前要执行的指令
在本例中没有用到

三、测试打包
除了 %files 的部份还没完全处理完外,其他部份大致上都没问题了

1.rpmbuild -bc
rpmbuild -bc 会从一开始一直做到 %build 为止
用来检查到 %build 为止是否还有问题
若有发现任何错误,如 command not found 等等
就要去 check required package 然后加到 Requires/BuildRequires 中

rpmbuild -bc pcmanfm.spec

像我一执行时就出现错误:

checking for PACKAGE… configure: error: Package requirements (gtk+-2.0 >= 2.6. 0 gthread-2.0 libstartup-notification-1.0) were not me t: No package ‘libstartup-notification-1.0′ found

查了一下,所需要的套件是 startup-notification-devel

$ locate libstartup-notification-1.0 /usr/lib/pkgconfig/libstartup-notification-1.0.pc $ rpm -qf /usr/lib/pkgconfig/libstartup-notification-1.0.pc startup-notification-devel-0.8-3.2.1

因此,修改 BuildRequires 如下:

BuildRequires: automake >= 1.9, gtk2-devel >= 2.6, gamin-devel, desktop-file-utils, gettext, startup-notification-devel

加进了 startup-notification-devel
而多加了 gettext 则是给 mock build 用的
因为在 mock build 时会去 check 是否有 gettext,有才会去执行 %find_lang macro

2.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/hu/LC_MESSAGES/pcmanfm.mo /usr/share/locale/it/LC_MESSAGES/pcmanfm.mo /usr/share/locale/pl/LC_MESSAGES/pcmanfm.mo /usr/share/locale/pt_BR/LC_MESSAGES/pcmanfm.mo /usr/share/locale/ru/LC_MESSAGES/pcmanfm.mo /usr/share/locale/sv_SE/LC_MESSAGES/pcmanfm.mo /usr/share/locale/zh_CN/LC_MESSAGES/pcmanfm.mo /usr/share/locale/zh_TW/LC_MESSAGES/pcmanfm.mo

因此,可以得知,%files 中还少了 /usr/bin/pcmanfm
至於 locale 的 mo 档部份,可以不用管,改交给 %find_lang macro 去处理了
而 /usr/share/applications/pcmanfm.desktop 则改由 desktop-file-install 处理
因此,修改后的 %files 部份如下:

%files -f %{name}.lang %defattr(-,root,root,-) %doc AUTHORS COPYING ChangeLog INSTALL NEWS README TODO %{_bindir}/pcmanfm %{_datadir}/applications/fedora-pcmanfm.desktop

相关的 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 的写法

3.rpmbuild -bs、rpmbuild -bb and rpmbuild -ba
若 rpmbuild -bi 都没错误,接下来就可以开始打包套件了

3.1.用 rpmbuild -bs 来产生 SRPMS

rpmbuild -bs pcmanfm.spec

3.2.用 rpmbuild -bb 来产生 RPMS

rpmbuild -bb pcmanfm.spec

3.3.用 rpmbuild -ba 来同时产生 SRPMS 及 RPMS

rpmbuild -ba pcmanfm.spec

四、使用 rpmlint 来检查 SRPMS RPMS

rpmlint -i ~/rpmbuild/SRPMS/pcmanfm-0.3.0-0.1.beta3.src.rpm rpmlint -i ~/rpmbuild/RPMS/i386/pcmanfm-*.rpm

rpmlint 的错误讯息请参考:

五、使用 mock 来 chroot build
mock 是一个 Chroot Build Tools
关於 mock 的安装、设定及使用请参考:
http://blog.candyz.org/20060818/1307

mock -r fedora-5-i386-core.cfg ~/rpmbuild/SRPMS/pcmanfm-0.3.0-0.1.beta3.src.rpm

六、RPM 建包其他进阶部份


1.devel subpackage
所有的可执行档及 *.so.* 要放在 main package
而所有的 headers, static libraries, libtool archives, *.so files, autotools,
and pkgconfig files 则要放在 -devel subpackage.

若套件有包含一些不重要的 examples 时,可以在 %install 最后的地方删除掉
把 examples 改放到 -devel 的 %doc 中

请参考:

的范例

2.不需要加到 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

详细清单请参考:

3.Documentation
若有相关的说明文件,可以独立成 -doc subpackage
并以 Documentation 当作 Group Tag

4.Configuration files
设定档请使用 %config(noreplace) 来代替 %config
只有当设定档有变时,才改用 %config 来覆盖掉旧的

5.Macros
详细的 Macros 请参考:

6.不要使用 %makeinstall macro
直接用:

make DESTDIR=$RPM_BUILD_ROOT install

7.Fedora RPM Development Tools
fedora-rpmdevtools,请参考:
http://fedoraproject.org/wiki/fedora-rpmdevtools

8.RPM scriptlet recipes
关於 %pre %post %preun %postun 的用法及注意事项,请参考:

七、RPM 建包时的 GPG Sign

rpmbuild –sign

在执行 rpmbuild 时加上 –sign 的参数

rpm –addsign

若在 rpmbuild 时没有使用 –sign 参数,也可以事后再用 rpm –addsign 来 Sign 套件

八、RPM 建包参考文件


阅读(2287) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~