分类:
2006-04-05 17:02:27
rpmbuild -bb *.spec
时都做些什么:%prep
部分来将源代码解包到一个临时目录,并应用所有的补丁程序。
%build
部分来编译代码。
%install
部分将代码安装到构建机器的目录中。
%files
部分的文件列表,收集文件并创建二进制和源 RPM 文件。
%clean
部分来除去临时构建目录。
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)。但是您还可以使用那些组名以外的名称。
Source0
、
Source1
等等给这些源文件命名(通常为
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 脚本:
尤其要注意
%install
与这些节之间的差异。构建 RPM 时,
%install
用户的机器上运行什么。
在开发机器上运行;
它应该将产品安装在开发机器上或安装到一个构建根目录中。 另一方面,这些节指定当用户正在安装或卸载您的 RPM
包时将在
现在,让我们着手升级。如果用户只安装和删除您自己的包,那么前面节中的指令将正常工作;但在升级期间,它们会完全失效。
以下是 RPM 如何执行升级:
如果我们使用前面的示例来升级,那么 RPM 最后将运行 %postun 脚本, 它将除去我们在安装脚本中所做的所有工作!使用 RPM 的一般开发人员可能不会想到这一点。 我不会尝试解释其原因,只是解释您必须为此做点什么。
相当幸运的是,在一定程度上,脚本有一种方法可以告之是否正在安装、删除或升级包。每个脚本都被传递单一命令行参数 ― 一个数字。 这应该告诉脚本 在当前包完成安装或卸载之后将安装多少个包的副本。
只查看在各种情况下传递的值或许更容易,而不是尝试计算它。
这里是在安装期间传递的实际值:
这里是在升级期间传递的值:
这里是在删除期间传递的值:
可以通过将类似下例的一些东西添加到您的包中来自己测试它。
然后创建一个带稍高发行版号的新包,安装第一个,然后升级到第二个,最后卸载它,以查看所有可能性。
当然,在信任的公共社区上发布任何 RPM 之前,您总是要对它进行几次这样的尝试。
其他问题