Chinaunix首页 | 论坛 | 博客
  • 博客访问: 91031
  • 博文数量: 42
  • 博客积分: 880
  • 博客等级: 准尉
  • 技术积分: 375
  • 用 户 组: 普通用户
  • 注册时间: 2006-03-03 12:47
个人简介

学习笔记

文章分类

全部博文(42)

文章存档

2017年(2)

2011年(6)

2009年(1)

2007年(7)

2006年(26)

我的朋友

分类:

2006-04-05 17:02:27

rpm包是一种常见的Linux软件发布包。制作rpm包的关键是spec文件。
将需要打包的文件复制到/usr/src/packages/SOURCES/ (SUSE)
SPEC文件复制到/usr/src/packages/SPECS
在此目录下运行rpmbuild -bb *.spec即可生成相应的二进制rpm包(在RPMS/系统arch/目录下).

下面总结了在运行 rpmbuild -bb *.spec 时都做些什么:
  • 读取并解析 filename.spec 文件
  • 运行 %prep 部分来将源代码解包到一个临时目录,并应用所有的补丁程序。
  • 运行 %build 部分来编译代码。
  • 运行 %install 部分将代码安装到构建机器的目录中。
  • 读取 %files 部分的文件列表,收集文件并创建二进制和源 RPM 文件。
  • 运行 %clean 部分来除去临时构建目录。

spec 文件内容

spec 文件有几个部分。第一部分是未标记的;其它部分以 %prep%build 这样的行开始。


第一部分(未标记)定义了多种信息,其格式类似电子邮件消息头。

Summary 是一行关于该软件包的描述。

Name 是该软件包的基名, Version 是该软件的版本号。 Release 是 RPM 本身的版本号 ― 如果修复了 spec 文件中的一个错误并发布了该软件同一版本的新 RPM,就应该增加发行版号。

License 应该给出一些许可术语(如:“GPL”、“Commercial”、“Shareware”)。

Group 标识软件类型;那些试图帮助人们管理 RPM 的程序通常按照组列出 RPM。您可以在 /usr/share/doc/rpm-4.0.2/GROUPS 文件看到一个 Red Hat 使用的组列表(假设您安装的 RPM 版本是 4.0.2)。但是您还可以使用那些组名以外的名称。

Source0Source1 等等给这些源文件命名(通常为 tar.gz 文件)。 %{name}%{version} 是 RPM 宏,它们扩展成为头中定义的 rpm 名称和版本。因此,在这个实例中, Source0 被设置为 indent-2.2.6.tar.gz

不要在 Source 语句中包含任何路径。缺省情况下,RPM 会在 /usr/src/redhat/SOURCES 中寻找文件。请将您的源文件复制或链接到那里。(要使 spec 文件尽量可移植的话,应当尽量避免嵌入自己开发机器上的假想路径。其他开发人员就可以指示 RPM 在别的目录下查找源文件,而不用修改您的 spec 文件。)

描述
接下来的部分从 %description 行开始。您应该在这里提供该软件更多的描述,这样任何人使用 rpm -qi 查询您的软件包时都可以看到它。您可以解释这个软件包做什么,描述任何警告或附加的配置指令,等等。

Shell 脚本
下面几部分是嵌入 spec 文件中的 shell 脚本。

%prep 负责对软件包解包。在最常见情况下,您只要用 %setup 宏即可,它会做适当的事情,在构建目录下解包源 tar 文件。加上 -q 项只是为了减少输出。

%build 应该编译软件包。该 shell 脚本从软件包的子目录下运行,在我们这个例子里是 indent-2.2.6 目录,因而这常常与运行 make 一样简单。

%install 在构建系统上安装软件包。这似乎和 make install 一样简单,但通常要复杂些。我将在下面解释这点。

文件列表
%files 列出应该捆绑到 RPM 中的文件,并能够可选地设置许可权和其它信息。

%files 中,您可以使用 一次 %defattr 来定义缺省的许可权、所有者和组;在这个示例中, %defattr(-,root,root) 会安装 root 用户拥有的所有文件,使用当 RPM 从构建系统捆绑它们时它们所具有的任何许可权。

可以用 %attr(permissions,user,group) 覆盖个别文件的所有者和许可权。

可以在 %files 中用一行包括多个文件。

可以通过在行中添加 %doc%config 来标记文件。 %doc 告诉 RPM 这是一个文档文件,因此如果用户安装软件包时使用 --excludedocs ,将不安装该文件。您也可以在 %doc 下不带路径列出文件名,RPM 会在构建目录下查找这些文件并在 RPM 文件中包括它们,并把它们安装到 /usr/share/doc/%{name}-%{version} 。以 %doc 的形式包括 README 和 ChangeLog 这样的文件是个好主意。

%config 告诉 RPM 这是一个配置文件。在升级时,RPM 将会试图避免用 RPM 打包的缺省配置文件覆盖用户仔细修改过的配置。

警告:如果在 %files 下列出一个目录名,RPM 会包括该目录下的所有文件。通常这不是您想要的,特别对于 /bin 这样的目录。

安装和卸载脚本看起来很简单,但它们工作原理中的一些意外可能会引起大问题。

这里是一些基本信息。可以将下列四节中的任意一个添加到 .spec 文件, 它列出了在您的包安装期间各个点上运行的 shell 脚本:

%pre
在安装包之前运行
%post
在安装包之后运行
%preun
在卸载包之前运行
%postun
在卸载包之后运行

尤其要注意 %install 与这些节之间的差异。构建 RPM 时, %install用户的机器上运行什么。
在开发机器上运行; 它应该将产品安装在开发机器上或安装到一个构建根目录中。 另一方面,这些节指定当用户正在安装或卸载您的 RPM 包时将在

现在,让我们着手升级。如果用户只安装和删除您自己的包,那么前面节中的指令将正常工作;但在升级期间,它们会完全失效。

以下是 RPM 如何执行升级:

  • 运行新包的 %pre
  • 安装新文件
  • 运行新包的 %post
  • 运行旧包的 %preun
  • 删除新文件未覆盖的所有旧文件
  • 运行旧包的 %postun

如果我们使用前面的示例来升级,那么 RPM 最后将运行 %postun 脚本, 它将除去我们在安装脚本中所做的所有工作!使用 RPM 的一般开发人员可能不会想到这一点。 我不会尝试解释其原因,只是解释您必须为此做点什么。

相当幸运的是,在一定程度上,脚本有一种方法可以告之是否正在安装、删除或升级包。每个脚本都被传递单一命令行参数 ― 一个数字。 这应该告诉脚本 在当前包完成安装或卸载之后将安装多少个包的副本

只查看在各种情况下传递的值或许更容易,而不是尝试计算它。

这里是在安装期间传递的实际值:

  • 运行新包的 %pre (1)
  • 安装新文件
  • 运行新包的 %post (1)

这里是在升级期间传递的值:

  • 运行新包的 %pre (2)
  • 安装新文件
  • 运行新包的 %post (2)
  • 运行旧包的 %preun (1)
  • 删除新文件未覆盖的任何旧文件
  • 运行旧包的 %postun (1)

这里是在删除期间传递的值:

  • 运行旧包的 %preun (0)
  • 删除文件
  • 运行旧包的 %postun (0)

可以通过将类似下例的一些东西添加到您的包中来自己测试它。 然后创建一个带稍高发行版号的新包,安装第一个,然后升级到第二个,最后卸载它,以查看所有可能性。 当然,在信任的公共社区上发布任何 RPM 之前,您总是要对它进行几次这样的尝试。


其他问题

  • 多个rpm包用到相同的文件时,安装不同的rpm包时,如果文件版本不同时,会产生冲突。在这种情况下,最好在作包的时候才产生这个文件(夹),而不要让多个rpm包用相同的目录打包。可以放在%post部分。
  • %post部分能完成许多配置及安装后的启动工作。



阅读(1725) | 评论(2) | 转发(0) |
0

上一篇:随系统启动程序

下一篇:网页设计工具

给主人留下些什么吧!~~

chinaunix网友2011-01-05 14:20:35

好贴