`
netcome
  • 浏览: 479845 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

使用 RPM 打包软件,第 1 部分: 构建和分发包

rpm 
阅读更多

顾名思义,开源软件的主要优势就是允许了解应用程序的内部工作原理。有了源代码,您可以研究应用程序的工作原理,更改、改进和扩展其操作,(在应用程序许可允许下)借鉴代码并将其用于其他用途,以及将应用程序移植到新平台上。

然而,这种自由访问并不总是我们所需要的。例如,用户可能不希望从源代码进行构建。相反,他或她可能只想像传统 “紧凑包装” 的应用程序一样安装该软件:插入媒体、运行安装程序、回答一系列提示,然后运行应用程序。确实,对于大部分计算机用户来说,这种预构建的软件是他们最希望得到的。预构建代码对系统特性不那么敏感,因此更统一且可预测。

通常,预构建的开源应用程序称为,捆绑了运行应用程序所需的所有二进制文件、数据和配置文件。包还包括将应用程序部署到系统上所需的所有步骤,这些步骤通常以脚本形式提供。脚本可以生成数据,启动和停止系统服务,或者操作文件和目录。脚本还可以执行操作来将现有软件升级到新版本。

由于每个操作系统都具有自己的独特特性,所以包通常仅适用于特定系统。而且,每个操作系统提供了自己的包管理器,一个用于在系统中添加和删除包的特殊实用程序。例如,基于 Debian Linux® 的系统使用 Advanced Package Tool (APT),而 Fedora Linux 系统使用 RPM Package Manager。包管理器通过添加和删除包中的各个文件来来预防不完整和错误的安装,以及 “卸载” 应用程序。包管理器还维护着系统上安装的所有包的清单,可以预先检查前提条件和辅助条件是否满足。

如果您是一名软件开发人员或系统管理员,以包的形式提供应用程序可以使安装、升级和维护更加轻松。在本文中,您将了解到如何使用流行的 RPM Package Manager 捆绑实用程序。作为演示,您将捆绑网络实用程序 wget,该程序用于从 Internet 下载文件。wget 实用程序很有用,但在标准的系统分发版中很难找到它。(而类似的 curl 通常包含在系统分发版中。)您将发现,您可以使用 RPM 分发几乎所有内容(脚本、文档和数据),以及执行几乎所有维护任务。

手动构建 wget

wget 实用程序,与其他许多开源应用程序一样,可以手动构建。要将 wget 捆绑在一个包中,首先需要了解构建过程。根据一般约定,构建 wget 需要 4 个步骤:

  1. 下载并解压源代码。
  2. 配置构建版本。
  3. 编译代码。
  4. 安装软件。

您可以从 ftp.gnu.org 下载 wget 源代码的最新版本(参见 参考资料 获取链接,截至 2009 年 9 月末,wget 的最新版本为 1.12)。其余步骤需要在命令行操作,如 清单 1 所示。


清单 1. 安装 wget
				
$ tar xzf wget-latest.tar.gz
$ cd wget-1.12
$ ./configure
configure: configuring for GNU Wget 1.12
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... build-aux/install-sh -c -d
checking for gawk... no
checking for mawk... no
checking for nawk... no
...
$ make
$ sudo make install

./configure 查询系统并设置适合于所选硬件和软件的编辑选项。make 编译代码,sudo make install 在系统目录中安装代码。默认情况下,安装的根目录为 /usr/local,但您可以对 ./configure 使用 --prefix=/some/full/path/name 选项来更改根目录。

要将此过程转换为 RPM,将源代码放在存储库中,编写一个配置文件来说明可在哪里找到要编译的源代码以及如何编译和安装代码。配置文件称为 spec 文件,是实用程序 rpmbuild 的输入。spec 文件和二进制文件被 rpmbuild 打包到一个 RPM 中。当其他用户下载您的 RPM 时,rpm 实用程序读取 spec 文件并根据预先编写的指令安装包。

构建您的第一个 RPM

在继续之前,需要注意一点。在过去,包只能由根用户和超级用户构建,因为只有根用户才能访问系统源代码库。但是,此方法具有一定的冒险性。因为根用户可以更改系统上的任何文件,它可以在临时构建 RPM 期间随意添加外部文件或删除重要文件,从而更改正在运行的系统。最近,RPM 系统经过了更改,允许任何用户在主目录中构建 RPM。不需要根用户特权就能构建 RPM,这可以阻止更改核心系统文件。下面介绍了这种更加现代的方法。

要构建 RPM,必须:

  • 依照 rpmbuild 规范设定一个目录结构。
  • 将源代码和附带文件放在目录中合适的位置。
  • 创建 spec 文件。
  • 编译 RPM。可以选择编译源 RPM,以与其他人共享您的源代码。

首先,构建目录。在主目录下的一个子目录中,假设为 $HOME/mywget,创建 5 个子目录:

  • BUILD。BUILD 用作实际编译软件的暂存空间。
  • RPMS。RPMS 包含 rpmbuild 所编译的二进制 RPM。
  • SOURCES。SOURCES 存储源代码。
  • SPECS。SPECS 包含您的 spec 文件,您想要构建的一个 RPM 对应一个 spec 文件。
  • SRPMS。SRPMS 包含在这个过程中构建的源 RPM。

您至少需要 SOURCES 中的源代码和 SPEC 中的一个 spec 文件。

将源代码(理想情况下应捆绑为一个 tarball 压缩文件)复制到 SOURCES 目录,如 清单 2 所示。如果有必要,重命名 tarball 压缩文件,以包含应用程序的版本号,便于与其他文件区分开。约定的命名格式为包-版本.tar.gz。对于 wget,您可以使用:


清单 2. 复制源代码
				
$ cd ~
$ mkdir mywget
$ cd mywget 
$ mkdir BUILD RPMS SOURCES SPECS SRPMS
$ cd SOURCES
$ cp wget-latest.tar.gz .
$ mv wget-latest.tar.gz wget-1.12.tar.gz
$ cd ..

接下来,创建 spec 文件。spec 文件只是一个具有特殊语法的文本文件。清单 3 给出了一个 spec 文件的例子。


清单 3. 示例 spec 文件
				
# This is a sample spec file for wget

%define _topdir	 	/home/strike/mywget
%define name			wget 
%define release		1
%define version 	1.12
%define buildroot %{_topdir}/%{name}-%{version}-root

BuildRoot:	%{buildroot}
Summary: 		GNU wget
License: 		GPL
Name: 			%{name}
Version: 		%{version}
Release: 		%{release}
Source: 		%{name}-%{version}.tar.gz
Prefix: 		/usr
Group: 			Development/Tools

%description
The GNU wget program downloads files from the Internet using the command-line.

%prep
%setup -q

%build
./configure
make

%install
make install prefix=$RPM_BUILD_ROOT/usr

%files
%defattr(-,root,root)
/usr/local/bin/wget

%doc %attr(0444,root,root) /usr/local/share/man/man1/wget.1

我们从头到尾分析一下这个 spec 文件。第 1-5 行定义在文件其余部分中使用的快捷变量。第 7-15 行使用 参数: 值 的形式设置若干个必需的参数。在第 7 行或其他地方可以看到,变量可以进行计算和组合,以生成某个设置的值。

大部分参数的名称都不言自明,但需要对 BuildRoot 稍作说明,以将其与已创建的 BUILD 目录路区分开。BuildRoot 代表最终的安装目录。换言之,如果 wget 最终安装在 /usr/local/bin/wget 和 /usr/local 中的其他子目录下,比如文档安装在 /usr/local/man 下,那么在 RPM 构建过程中 BuildRoot 代表 /usr/local。一旦设定了 BuildRoot,就可以使用 RPM_BUILD_ROOT 环境变量访问其值。应该始终在 spec 文件中设置 BuildRoot 并检查该目录的内容,确认包即将安装的内容。

下面有一些技巧:

  • 不要使用 ./configure --prefix=$RPM_BUILD_ROOT。此命令构建整个包,假定文件的最终位置为构建根目录。这可能导致需要在运行时定位其已安装文件的程序发生故障,因为当 RPM 最终安装在用户系统上时,安装的文件不再位于构建根目录下,该目录只是您的构建系统上的一个临时目录。
  • 不要在 Source 的定义中包含路径。
  • 主版本和次版本很重要。每次更改应用程序的代码或数据,以及构建好一个新 RPM 时,一定要增加主版本和次版本的值,以分别反映主要和次要的更改。您会发现每次构建一个 RPM 时就增加版本编号对于将每次修改尝试都分开很有用,即使是供您自己使用。

下一节代码首先是一个 %description。您应该在这里简单明了地描述软件。这一行将在用户运行 rpm -qi 来查询 RPM 数据库时显示。您可以说明包的用途,描述任何警告或额外的配置说明等。

接下来依次是 %prep%build 和 %install 节。每一节生成一个 shell 脚本,该脚本嵌入到 RPM 中,随后作为安装的一部分运行。%prep 准备源代码,比如解压 tarball 压缩文件。在这里,%setup -q 是一个 %prep 宏,用于自动解压 Source 中的特定 tarball 压缩文件。

您应该熟悉 %build 节中的指令。它们相当于用于手动配置和启动构建过程的步骤。%install 节也是如此。但是,尽管手动构建的目标目录是系统上的 /usr/local 目录,但 %install 指令的目标目录为 ~/mywget/BUILD。

%files 列出应该捆绑到 RPM 中的文件,还可以设置权限和其他信息。在 %files 内,您可以使用 %defattr 宏定义默认权限、所有者和 RPM 中的文件分组。在本例中,%defattr(-,root,root) 安装根用户拥有的所有文件,使用 RPM 从构建系统捆绑这些文件时找到的权限。

在 %files 中,可以在一行中包含多个文件。可以将 %doc 或 %config 添加到该行,以标记文件。%doc 告诉 RPM 该文件为一个文档文件,所以如果用户使用 --excludedocs 安装包,将不会安装该文件。%config 告诉 RPM 这是一个配置文件。在升级期间,RPM 将尝试避免使用 RPM 打包的默认配置文件覆盖用户小心修改的配置。

请注意,如果在 %files 下列出一个目录名称,RPM 将包含该目录下的每个文件。

构建 RPM

现在您的文件已经就绪,spec 文件也已经定义了,接下来就可以构建实际的 RPM 文件了。要构建它,使用适当命名的 rpmbuild 实用程序:

$ rpmbuild -v -bb --clean SPECS/wget.spec

此命令使用指定的 spec 文件构建一个二进制包(-bb 表示 “构建二进制包”),还会生成详细的输出(-v)。构建实用程序在生成包之后删除构建树(--clean)。如果还希望构建源 RPM,指定 -ba(“构建所有包”)来代替 -bb。(查看 rpmbuild 清单页面,了解完整的选项列表。)

rpmbuild 执行以下步骤:

  • 读取并解析 wget.spec 文件。
  • 运行 %prep 节,将源代码解压到临时目录。在这里,临时目录为 BUILD。
  • 运行 %build 节,编译代码。
  • 运行 %install 节,将代码安装到构建机器上的目录中。
  • 从 %files 节读取文件列表,将它们收集到一起,然后创建一个二进制 RPM(和源 RPM 文件,如果已选择)。

如果查看 $HOME/mywget 目录,应该找到一个名为 wget-1.12-root 的新目录,此目录表示目标目录。还应该找到一个名为 RPMS/i386 的新目录,而且它应该包含您的 RPM,名为 wget-1.12-1.i386.rpm。RPM 的名称表明这是针对 i386 处理器的 wgetversion 1.12。

要验证 RPM 是否包含合适的文件,可以使用 rpm 命令,如 清单 4 所示。


清单 4. 验证 RPM 内容
				
$ rpm -Vp RPMS/i386/wget-1.12-1.i386.rpm
missing     /usr/local/bin/wget
.M....G.    /usr/local/etc
missing   c /usr/local/etc/wgetrc
.M....G.    /usr/local/share
missing     /usr/local/share/info
missing   d /usr/local/share/info/wget.info
missing     /usr/local/share/locale
missing     /usr/local/share/locale/be
missing     /usr/local/share/locale/be/LC_MESSAGES
missing   d /usr/local/share/locale/be/LC_MESSAGES/wget.mo
.
.
.

命令 rpm -Vp RPMS/i386/wget-1.12-1.i386.rpm 验证包是否包含系统中的文件。尽管似乎存在很多错误,但每个错误都暗示了 RPM 文件的内容是正确的。如果您希望安装某个文件,而该文件未出现在输出中,则说明它未包含在包中。在这种情况下,请查看 spec 文件,确保该文件已在 %files 节中列出。

验证了 RPM 之后,可以将文件分发给同事。同事收到文件之后,应该可以运行 rpm 来在其自己的系统上安装 wget

$ sudo rpm -i wget-1.12-1.i386.rpm

RPM 的其他用途

这篇简短介绍文章只触及了 RPM 的用途的表面。尽管它最常用于安装软件和附带文件,但您几乎可以打包任何内容,从系统脚本到源代码到文档。在本系列第二期中您将会看到,还可以使用 RPM 修补源代码,以及重新构建和重新安装软件。RPM 分发格式可以在许多 Linux 系统上找到,是在 Red Hat 和 Fedora 等系统中安装二进制软件的首选方法。

如果您使用 RPM 构建和打包软件,那么也将能够体验到 RPM 的这些其他用途。

分享到:
评论
1 楼 okay456okay 2012-06-28  
不错的文章。其中IBM Developer上也有几篇RPM打包的文章,但是我觉得你写的更新。但是我还是建议系统的学习下RPM开发比较好,推荐Maximum RPM(http://www.jsxubar.info/maximum-rpm-introduction.html)这本书,由Redhat内部人员编写,相当不错。
因为真正要进行打包时,比如我的软件很简单,就一个执行文件和配置文件,没有任何安装操作,其实这个RPM包的功能就是将文件复制上去,就这么一个简单的操作,如果没有真正理解spec文件每个部分的作用,那在实际操作中还是不会。

相关推荐

    rpm打包及企业YUM仓库构建

    RPM 主要用于打包、分发和管理 Linux 下的软件,而 YUM 则是基于 RPM 的一个自动化工具,它可以解决 RPM 包之间的依赖关系问题。 #### 二、RPM 打包方法对比 在选择软件安装方式时,通常有以下几种选择: 1. **...

    SpringBoot之rpm打包文档.rar

    - 创建.spec文件:这是RPM打包的核心,包含了软件的元数据、依赖关系和构建指令。 - 编写%setup、%build、%install、%clean等脚本:分别对应源码解压、编译、安装到指定目录和清理工作。 - 设置文件权限和所有权...

    RPM打包全过程SPEC详解

    SPEC文件是RPM打包的核心,它包含关于软件包的所有信息,如版本、作者、依赖关系以及如何构建和安装软件的指令。 **2. 创建SPEC文件** 创建SPEC文件通常以`.spec`为扩展名,用文本编辑器打开并按照RPM的规范编写。...

    RPM打包和典型SPEC文件分析

    RPM打包过程主要分为两个部分:第一部分是编写SPEC文件,第二部分是通过rpmbuild命令根据SPEC文件构建出最终的RPM包。SPEC文件通常包含以下几个主要部分: 1. 宏定义区域:这通常在SPEC文件的开头部分,用于定义...

    rhl rpm打包原理详解

    RPM打包原理详解主要涉及如何创建自己的RPM软件包,以便在这些系统中方便地安装、升级和管理软件。本篇文章将深入探讨RPM打包的各个方面。 1. RPM基础知识: - **RPM结构**:RPM软件包由元数据和软件内容两部分...

    java 打包rpm打包文档.zip

    在Java世界中,通过RPM打包可以使SpringBoot应用更便于在Linux环境下分发和管理。 2. **SpringBoot与RPM集成** SpringBoot是一个轻量级的Java框架,简化了微服务的开发和部署。将SpringBoot应用打包成RPM,首先...

    集成jdk+mysql+tomcat+web项目打包成rpm

    3. 构建RPM包:使用`rpmbuild`命令,结合.spec文件生成RPM包。 4. 测试安装:生成的RPM包应在目标环境中进行测试安装,确保所有组件能正常工作。 集成说明文档:提供详细的安装指南,包括如何使用生成的RPM包,安装...

    Linux下RPM打包制作过程

    Linux下的RPM打包制作流程是将软件源代码转化为可供Linux系统安装的RPM包的过程,这一过程涉及到多个步骤和配置文件。RPM(Red Hat Package Manager)是一种广泛应用于Linux发行版的软件包管理器,它使得软件的安装...

    CMake:构建、打包和测试的跨平台工具系列软件

    CMake是一个开源、跨平台的构建系统,旨在管理软件构建过程。它通过使用简洁的脚本语言描述项目的构建规则,自动生成适用于...打包工具:CMake包含CPack,用于生成各种软件包格式,如RPM、DEB、NSIS等,方便软件分发。

    ARM架构和X86_64架构rpmbuild制作openssh和openssl的rpm包

    构建完成后,RPM包可以分发到对应架构的Linux系统中,通过`yum`或`dnf`等包管理器进行安装,确保了软件在不同环境下的统一管理和部署。 在实际应用中,理解并熟练掌握`rpmbuild`以及跨架构编译技术对于IT专业人员来...

    用rpmbuilder打rpm包

    在Linux系统中,RPM(Red Hat Package Manager)是一种广泛使用的软件包管理器,用于安装、升级、查询和卸载软件。RPM包是遵循RPM格式的软件包,它们通常用于Fedora、CentOS、RHEL等基于RPM的Linux发行版。`rpmbuild...

    hello程序的rpm包

    这两个标签强调了主题的核心——使用RPM包管理系统来管理和分发软件。RPM包的优势在于它的自动化能力,可以自动解决软件依赖,使得软件的安装和维护变得更加便捷。然而,RPM包也有其局限性,例如处理跨平台的兼容性...

    如何将Nginx源码包制作成RPM包.doc

    对于开发者而言,将源码编译为RPM包,可以使得软件分发更加便捷,同时也符合Linux社区的标准。本教程以Nginx 1.12.2版本为例,详细介绍如何将其源码包制作成RPM包。 首先,确保系统已经安装了`rpm-build`工具,它是...

    httpd2.4.37版本的rpm包

    5. **打包RPM**:使用`rpmbuild`命令,结合spec文件,将已安装的Apache软件及其配置信息打包成RPM格式。 6. **验证和分发**:测试RPM包的安装和卸载,确保一切正常后,可以分享给其他用户或者上传到软件仓库。 ...

    RPM Builder 将tar.gz 转成RPM

    3. **运行RPM Builder**:使用RPM Builder命令行工具,提供你的SPEC文件和源代码tar.gz文件。工具会读取SPEC文件,解压源代码,编译并打包成RPM格式。例如,如果你的SPEC文件名为`myproject.spec`,可以运行`...

    RPM包rpmbuild SPEC文件深度说明

    RPM包是Linux发行版中常见的软件分发格式,而`rpmbuild`是构建RPM包的工具。`SPEC`文件是rpmbuild的核心,它包含了构建RPM包的所有元数据和构建指令。这篇博客文章“RPM包rpmbuild SPEC文件深度说明”将深入探讨SPEC...

    hello world rpm包制作的例子

    在Linux世界中,RPM(Red Hat Package Manager)是一种广泛使用的软件包管理器,它用于安装、升级、查询和删除软件。"hello world rpm包制作的...熟练掌握RPM包制作,对于在Linux环境中管理和分发软件是十分重要的。

    利用rpmbuild制作rpm包的总结1

    在Linux系统中,RPM(Red Hat Package Manager)是一种广泛使用的软件包管理器,用于安装、升级、查询和卸载软件。`rpmbuild`工具是RPM的一部分,用于构建RPM软件包。本篇文章将总结如何利用`rpmbuild`来创建一个...

    精通rpm,rpm命令的使用

    2. **验证包完整性**:使用`rpm -V`命令验证RPM包是否完整。 3. **检查依赖关系**:使用`rpm -qp --requires <package.rpm>`命令检查软件包的依赖情况。 4. **解决依赖问题**:如果存在未满足的依赖,则需先安装缺失...

Global site tag (gtag.js) - Google Analytics