原文 [how to build RPM](https://access.redhat.com/sites/default/files/attachments/rpm_building_howto.pdf)
Author: Chris Negus
Editor: Allison Pranger
Date: 09/16/2011
## 译文:
### 概览
您已经创建了一些要安装在Red Hat Enterprise Linux系统上的软件。现在的问题是,“软件完成后,如何打包该软件以使其他人易于安装和管理?”
答案是将其打包成RPM安装包。
尽管有其他方式,可以将软件打包成特定格式的压缩包(通过压缩包或其他类型的存档文件)通过解压缩的方式安装到Linux
系统,但是将Linux软件打包为RPM,可以为您带来一下好处:
#### 在包中包括描述其组件,版本号,大小,包的元数据
组,项目网址等待信息。
#### 将软件包添加到yum存储库,以便客户可以轻松找到您的软件。
#### 让客户端使用常见的Linux工具(yum,rpm和PackageKit)来安装,删除和管理
您的软件。
#### 使用相同的Linux安装工具轻松更新和部署软件的新版本。
您无需成为程序员即可创建RPM:只需了解如何创建SPEC
文件并使用命令来构建该SPEC文件并将内容打包到RPM中。如何打包RPM格式的安装包是本文要详述的内容。创建RPM安装包不仅对管理公司的软件有用,而且也被列为红帽认证工程师(RHCE)考试技能测试范畴。
### 初步理解RPMS的构建过程
#### 了解RPMS的构建过程
创建RPM包需要了解如何使用文本编辑器以及如何运行一些创建,签名,发布命令
需要打包的软件准备好以后,构建RPM所需的大部分工作是编辑
RPM SPEC文件。在SPEC文件中,您可以:
##### 确定软件包中的命令,配置文件,文档和其他项目。
##### 定义最终在目标Linux系统上安装组件的位置。
##### 设置每个文件的权限和所有权。
##### 定义依赖包。
##### 将文件标记为配置文件或文档文件。
##### 定义安装或卸载时需要额外执行的命令(例如创建用户帐户,创建目录或移动文件)。
##### 添加变更日志,以识别您的每个软件版本中进行了哪些更改。
一旦掌握了构建RPM的基本功能(如本文档所述),您便可以
会发现大量强大灵活的RPM打包工具帮助您创建RPM。例如,您可以将平台特定的标签添加到SPEC文件,以便可以使用相同的标签。使用同样的SPEC文件来为多种计算机体系结构构建RPM。
### 将现有的源代码包重建为RPM
学习如何创建RPM软件包的最好方法是从现有的源代码RPM软件包开始
并重建它。 通过该过程,您可以明白创建RPM包所涉及的过程和组件。 本节概述了从现有资源重建树RPM软件包的步骤。
注意:构建此RPM后,请勿在生产系统上使用它,因为该软件包将与一个已经存于Red Hat Enterprise Linux软件频道中的RPM包产生冲突。
#### 1. 登录:以普通用户(非root用户)身份登录Red Hat Enterprise Linux系统。
#### 2. 获取源代码包:下载有效的源代码包。 本示例使用的源代码包:
```bash
$ wget ftp://ftp.redhat.com/pub/redhat/linux/enterprise/6Workstation/en/os/SRPMS/tree-1.5.3-2.el6.src.rpm
```
#### 3. 安装源代码:将源代码安装到新的~/rpmbuild目录:
```bash
rpm -ihv tree-1.5.3-2.el6.src.rpm
```
这将在您的主目录中创建一个rpmbuild目录结构,类似于以下内容:
```
~/SPECS
~/SPECS/tree.spec
~/BUILDROOT
~/SOURCES
~/SOURCES/tree-1.5.3.tgz
~/SOURCES/tree-1.2-no-strip.patch
~/SOURCES/tree-no-color-by-default.patch
~/SOURCES/tree-1.2-carrot.patch
~/SOURCES/tree-preserve-timestamps.patch
```
注意:您的主目录中的新rpmbuild目录包括一个SPECS目录(该目录包括tree.spec文件)和SOURCES目录。 SOURCES目录包含代码的tree1.5.3.tgz压缩文件和四个补丁文件。
#### 4. 编辑规格文件:查看规格文件。 使用vim或emacs编辑器会在编辑文件时为文件添加颜色:
```bash
vim ~/rpmbuild/SPECS/tree.spec
```
示例文件的内容如下所示。 完成更改后,保存并退出文件。
```
Summary: File system tree viewer
Name: tree
Version: 1.5.3
Release: 2%{?dist}
Group: Applications/File
License: GPLv2+
Url: http://mama.indstate.edu/users/ice/tree/
Source: ftp://mama.indstate.edu/linux/tree/tree-%{version}.tgz
Patch1: tree-1.2-carrot.patch
Patch2: tree-1.2-no-strip.patch
Patch3: tree-preserve-timestamps.patch
Patch4: tree-no-color-by-default.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
%description
The tree utility recursively displays the contents of directories in a treelike format. Tree is basically a UNIX port of the DOS tree utility.%prep
%setup -q
# Fixed spelling mistake in man page.
%patch1 -p1 -b .carrot
# Don't strip binary in the Makefile -- let rpmbuild do it.
%patch2 -p1 -b .no-strip
# Preserve timestamp on man page.
%patch3 -p1 -b .preserve-timestamps
# Disable color output by default.
%patch4 -p1 -b .no-color-by-default
%build
make CFLAGS="$RPM_OPT_FLAGS" "CPPFLAGS=$(getconf LFS_CFLAGS)" %{?_smp_mlags}
%install
rm -rf $RPM_BUILD_ROOT
mkdir -p $RPM_BUILD_ROOT%{_bindir}
make BINDIR=$RPM_BUILD_ROOT%{_bindir} \
MANDIR=$RPM_BUILD_ROOT%{_mandir}/man1 \
install
chmod -x $RPM_BUILD_ROOT%{_mandir}/man1/tree.1
%clean
rm -rf $RPM_BUILD_ROOT
%files
%defattr(-,root,root)
%{_bindir}/tree
%{_mandir}/man1/tree.1*
%doc README LICENSE
%changelo
...
```
安装rpm-build软件包后,您可以在以下位置阅读有关SPEC文件功能的信息:
/ usr / share / doc / rpm-build * / spec文件。
name是程序包的base name,
summary是该程序包的单行说明,
Version是upstream版本号包,
而Release是您作为打包者添加的编号,以反映该版本的多个版本
相同的上游版本(例如错误修复),
URL指向生成源代码的项目站点,
Source指向用于制作程序包的原始源代码,
BuildRoot标识位置RPM的临时目录,
其他行准备构建环境,添加
修补,编译和构建软件,标识软件包中的文件和权限,以及
允许您记录随时间变化的日志。
在本文档的最后,您可以找到一些rpm -qp选项,可用于检查
您构建的软件包的内容。
#### 5. 构建RPM:
使用rpmbuild命令将您的spec file和内容转换为RPM包, 您还可以将源代码打包到单独的源RPM(src.rpm)中。
安装rpm-build软件包(以root用户身份)并运行rpmbuild(普通用户):
```bash
#Run as root
$ sudo yum install rpm-build
#Run as regular user account
$ rpmbuild -ba ~/rpmbuild/SPECS/tree.spec
```
这样会在RPMS和SRPMS子目录中分别生成二进制RPM包和源码RPM包。
#### 6. 签名RPM:
为了防止RPM在分发的各个阶段被恶意篡改,需要对RPM包签名。
签名RPM包要求您创建一对公钥和私钥,使用私钥对您的RPM签名,
然后将公钥分发给客户端,以便客户端验证安装包的可靠性,以防止安装包被恶意篡改。
```bash
#Generate public/private keys
$ gpg --gen-key
```
生成公用/专用密钥时,大多数参数可以使用默认值。
输出结类似于以下形式
```
pub 2048R/99A9CF07 2011-09-16
Key fingerprint = 90BF B5DC 628E C9E0 88D0 E5D1 E828 4641 99A9 CF07
uid Chris Negus (My own build of the tree package.) <cnegus@redhat.com>
sub 2048R/48E60E56 2011-09-16
```
使用生成的密钥ID(在本例中为99A9CF07)将私钥导出为公钥:
```bash
#Export public key
$ gpg -a -o RPM-GPG-KEY-ABC –-export 99A9CF07
```
为了确保使用密钥ID对软件包进行签名,可以在.rpmmacros 文件添加如下_gpg_name参数:
```bash
#Add _gpg_name keyID to your .rpmmacros file
vi ~/.rpmmacros
```
```
%_gpg_name 99A9CF07
```
现在您可以给RPM包签名了。
```bash
#Sign pkg
$ rpm –-resign ~/rpmbuild/RPMS/x86_64/tree-1.5.3-2.el6.x86_64.rpm
```
#### 7. 在yum存储库中发布RPM:
发布RPM的一种方式是,在已有 Web服务器的基础桑创建yum存储库,并将RPM发布到yum存储库,以便各种客户端工具可以访问到RPM包。
下面假设系统中已经安装正在运行了Web服务器,以下步骤将演示如何创建一个yum存储库并发布RPM到此存储库。
```bash
$ sudo mkdir /var/www/html/abc
#Make the public key available
$ sudo cp ~/RPM-GPG-KEY-ABC /var/www/html/abc/
$ sudo cp ~/rpmbuild/RPMS/x86_84/tree-1.5.3-2.el6.x86_64.rpm /var/www/html/abc/
#Create the yum repository
$ sudo createrepo /var/www/html/abc
```
#### 8. 创建存储库(.repo)文件:
创建一个.repo文件,该文件标识存储库的URL。
想要安装软件包的客户端将能够简单地将abc.repo文件复制到自己的文件中
RHEL系统的/etc/yum.repos.d目录将其启用。 替换what.example.com
使用您自己的Web服务器的FQDN:
```bash
$ vim abc.repo
```
```
[abc-repo]
name=My ABC yum repository
baseurl=http://whatever.example.com/abc
gpgkey= http://whatever.example.com/RPM-GPG-KEY-ABC
```
```bash
$ cp abc.repo /var/www/html/abc
```
#### 9. 准备客户端以安装RPM:
要安装RPM,客户端只需简单地将abc.repo文件复制到/etc/yum.repos.d目录,然后使用yum命令从您的存储库安装任何软件包即可。
```bash
$ sudo wget http://whatever.example.com/abc/abc.repo -O /etc/yum.repos.d/abc.repo
$ sudo yum install tree
```
要在将来如果要更新RPM,您只需重建RPM,将最新版本复制到yum
存储库目录(本例中为/var/www/html/abc),然后重新运行createrepo命令。
客户下次将安装最新的RPM包或更新软件包。
### 检查您的RPM包装
一旦完成RPM的构建,就可以使用rpm命令检查其内容并进行
确保签名是否正常工作。 您可以在任何Red Hat Enterprise Linux系统上执行此操作,只要您
可以获得包和公钥。
#### 1. 首先导入用于签名软件包的密钥并检查签名:
```bash
#Import key file
$ sudo rpm --import ~/RPM-GPG-KEY-ABC
#Check signature
$ rpm -K ~/rpmbuild/RPMS/x86_64/tree-1.5.3-2.el6.x86_64.rpm
```
```
~/rpmbuild/RPMS/x86_64/tree-1.5.3-2.el6.x86_64.rpm: sha1 md5 OK
```
#### 2. 接下来,检查文件的内容。
这可以通过多种方式来实现。
选项 -q 查询
-p 从软件包查询包信息(如果不指定该参数,命令默认将从rpm数据库查询,而数据库中未安装此rpm包,可能得不到信息,或其他版本的信息)
-i 显示信息
```bash
$ rpm -qpi ~/rpmbuild/RPMS/x86_64/tree-1.5.3-2.el6.x86_64.rpm
```
```
Name : tree Relocations: (not relocatable)
Version : 1.5.3 Vendor: (none)
Release : 2.el6 Build Date: Thu 15 Sep 2011 11:53:37 PM EDT
Install Date: (not installed) Build Host: cnegus.linuxtoys.net
Group : Applications/File Source RPM: tree-1.5.3-2.el6.src.rpm
Size : 73868 License: GPLv2+
Signature : (none)
URL : http://mama.indstate.edu/users/ice/tree/
Summary : File system tree viewer
Description :
The tree utility recursively displays the contents of directories in a
tree-like format. Tree is basically a UNIX port of the DOS tree
utility.
```
使用-l(小写L)选项,可以列出软件包的内容:
```bash
$ rpm -qpl ~/rpmbuild/RPMS/x86_64/tree-1.5.3-2.el6.x86_64.rpm
```
```
/usr/bin/tree
/usr/share/doc/tree-1.5.3
/usr/share/doc/tree-1.5.3/LICENSE
/usr/share/doc/tree-1.5.3/README
/usr/share/man/man1/tree.1.gz
```
rpm命令还有许多其他选项用于检查和使用RPM软件包。 参考rpm手册页以获取详细信息(键入man rpm)。
### 从零开始构建RPM
要创建自己的RPM,您需要创建自己的spec文件(并将其放在SPECS目录中),然后
将所需的可执行文件,脚本,用户文档文件和配置文件收集到压缩包中
包含在RPM中。 您可以通过简单地复制现有的规范文件并对其进行修改来创建规范文件。
或者您可以使用vim或emacs命令打开以.spec结尾的任何新文件。
编辑器将在新文件中自动创建一个模板以方便编写RPM spec文件。 那你可以
遵循本文档前面介绍的其余部分。
要查看RPM内容压缩包的示例,可以尝试使用tar解压缩tree安装包和源码包:
```bash
$ tar xvf ~/rpmbuild/SOURCES/tree-1.5.3.tgz
tree-1.5.3/CHANGES
tree-1.5.3/INSTALL
tree-1.5.3/LICENSE
tree-1.5.3/Makefile
tree-1.5.3/README
tree-1.5.3/tree.c
tree-1.5.3/strverscmp.c
tree-1.5.3/man/tree.1
tree-1.5.3/man/tree.1.fr
```
要创建自己的tarball,你可以简单的将内容放在 一个目录中(例如〜/ abc-1.0)并把包含在SOURCES的文件包装成一个tarball即可:
```bash
tar -cvzf ~/rpmbuild/SOURCES/abc-1.0-1.tar.gz ~/abc-1.0/
```
### 获得更多关于RPMS的帮助
构建RPM的能力远远超出本文档中的描述。 大多数复杂性来自构建
spec文件。 您可以定义依赖对其他应用或库文件的依赖关系,设置文件的类型和权限,并在安装或卸载软件包时运行脚本。
下面是一些可以寻找帮助的地方:
怎样创建RPM包 (Fedora Project)
已经为Fedora项目创建了数千个RPM软件包。 FedoraProject.org网站上有一个
与创建用于Red Hat Enterprise Linux的RPM相似的出色文档:
http://fedoraproject.org/wiki/How_to_create_an_RPM_package
使用 RPM 打包软件
还可以在以下站点找到更多信息,以帮助您开始构建第一个RPM:
http://www.ibm.com/developerworks/library/l-rpm1/.
有疑问加站长微信联系(非本文作者))