RPM封装:创建一个RPM包的简化指南
   5 分钟阅读    邵晨峰

RPM封装:创建一个RPM包的简化指南

第一次接触RPM包的概念,初学者可能会不知所措,因为它给人留下了学习曲线陡峭的的印象。在本文中,我将演示用最少的知识和经验来构建RPM。请注意,本文只是作为入门,而不是RPM的完整指南。

基于ASCII的俄罗斯方块游戏

在我的演示中,我选择了一个简单的基于ASCII的终端游戏,用C编写。过程中做了一些细微的调整以确保可以相对简单的进行RPM构建。我将以一个名为Vitetris的游戏为例。您可以下载该游戏。

为确保创建RPM软件包时没有错误,我删除了Makefile中将文件权限更改为root的参数,以允许非root用户构建RPM。修改如下:

$ cat Makefile |grep 'INSTALL '
INSTALL = install
#INSTALL = install -oroot -groot # non-root users building the rpm won't be able to set this and the RPM build will fail.

进行此更改后,请创建一个新的压缩tarball,重命名为:vitetris-0.57.tar.gz

准备环境

安装开发环境在红帽企业Linux(RHEL)7系统上,你需要以下存储库构建RPM:rhel-7-server-rpmsrhel-7-server-extras-rpmsrhel-7-server-optional-rpms

您需要安装以下软件包:

# yum install -y rpm* gcc gpg* rng-tools

我使用rpm*,gpg*因为它使安装时要记住的事情变得更少更加易于管理。

手动编译软件

RPM打包成功的很大一步是了解您正在使用的软件。首先,最好以非root用户身份进行手动编译软件。我使用rpmbuilder用户。

首先提取压缩的tarball(vitetris-0.57.tar.gz),然后检查README文件。在这种情况下,自述文件不包含有关从源代码编译游戏的信息。一般的,用C语言编写的开源软件编译可分为三个步骤:configuremake,和make install。这次我们单独运行make以查看软件是否可以构建。

作为非root用户,请测试运行make是否成功:

[rpmbuilder@rpm vitetris-0.57]$ make
generating src/src-conf.mk
./src-conf.sh 'cc' '' ''
...
Done.
Now run ./tetris (or make install)

要测试游戏,只需运行./tetris以查看游戏是否可以正常游玩:

创建GPG密钥

对您的RPM软件包进行签名会让您的软件包更可信。因此,要以rpmbuilder用户身份创建GPG密钥。您需要一个具有root权限的会话来运行rngd(以加快生成过程),并需要一个具有X11转发功能的会话作为rpmbuilder用户。

以root身份运行:

# rngd -r /dev/urandom

如果出现以下错误:

Failed to init entropy source 2: Intel RDRAND Instruction RNG

尝试:

# rngd -r /dev/urandom -o /dev/random -f

您必须以具有X11转发功能的rpmbuilder用户会话登录到主机(否则,密钥生成将失败):

$ gpg --gen-key
...
Please select what kind of key you want:
(1) RSA and RSA (default)
(2) DSA and Elgamal
(3) DSA (sign only)
(4) RSA (sign only)
Your selection? 1
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 
Requested keysize is 2048 bits
Please specify how long the key should be valid.
0 = key does not expire
<n> = key expires in n days
<n>w = key expires in n weeks
<n>m = key expires in n months
<n>y = key expires in n years
Key is valid for? (0) 
Key does not expire at all
Is this correct? (y/N) y

GnuPG needs to construct a user ID to identify your key.

Real name: RPM Build User
Email address: rpmbuilder@rpm
Comment: RPM Builder GPG Signing Key
You selected this USER-ID:
"RPM Build User (RPM Builder GPG Signing Key) <rpmbuilder@rpm>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
You need a Passphrase to protect your secret key.

仅当您打开X11转发时,才会出现此提示。

...
gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u
pub 2048R/EEF6D9AD 2019-03-02
Key fingerprint = 6ED1 2456 B7ED EEC6 D0DF B870 444A 40A7 EEF6 D9AD
uid RPM Build User (RPM Builder GPG Signing Key) <rpmbuilder@rpm>
sub 2048R/D498F883 2019-03-02

如果您需要在自定义软件或在yum仓库配置中使用的此密钥时,可以使用以下命令导出密钥:

$ gpg --armor --export
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v2.0.22 (GNU/Linux)

为Vitetris游戏创建RPM包

要构建RPM,首先创建构建目录树和spec文件,然后将源代码放在正确的位置:

$ rpmdev-setuptree
$ rpmdev-newspec rpmbuild/SPECS/vitetris.spec
rpmbuild/SPECS/vitetris.spec created; type minimal, rpm version >= 4.11.
$ cp vitetris-0.57.tar.gz rpmbuild/SOURCES/

将初始详细信息添加到spec文件中

提供初始详细信息:

Name:           vitetris
Version:        0.57
Release:        1%{?dist}
Summary:        ASCII based tetris game

License:        BSD
URL:            https://www.victornils.net/tetris/
Source0:        vitetris-0.57.tar.gz

BuildRequires:  gcc

删除不必要的部分

  • 删除该Requires部分,因为此软件没有任何依赖性。
  • 删除此%configure部分,因为无需构建此软件configure(如果需要configure,请保留此部分,然后再运行make)。

添加描述信息

您可以在这里添加任何您喜欢的东西,这是一个例子:

%description
vitetris is a multiplayer ASCII-based Tetris game

测试初始版本

使用刚刚提供的信息测试构建,查看出现了哪些错误:

$ rpmbuild -ba rpmbuild/SPECS/vitetris.spec
...
RPM build errors:
Installed (but unpackaged) file(s) found:
/usr/local/bin/tetris
/usr/local/share/applications/vitetris.desktop
/usr/local/share/doc/vitetris/README
/usr/local/share/doc/vitetris/licence.txt
/usr/local/share/pixmaps/vitetris.xpm

将上一步中的文件列表添加到规范文件

您需要将上一步中的文件列表添加到spec文件的%files节中,如下所示:

%files
/usr/local/bin/tetris
/usr/local/share/applications/vitetris.desktop
%doc /usr/local/share/doc/vitetris/README
/usr/local/share/doc/vitetris/licence.txt
/usr/local/share/pixmaps/vitetris.xpm

请注意,在自述文件的前面需要放上%doc,以将其标识为参考文件。没有这个,RPM仍然会成功构建。

重新运行构建

$ rpmbuild -ba rpmbuild/SPECS/vitetris.spec
Wrote: /home/rpmbuilder/rpmbuild/SRPMS/vitetris-0.57-1.el7.src.rpm
Wrote: /home/rpmbuilder/rpmbuild/RPMS/x86_64/vitetris-0.57-1.el7.x86_64.rpm
Wrote: /home/rpmbuilder/rpmbuild/RPMS/x86_64/vitetris-debuginfo-0.57-1.el7.x86_64.rpm
Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.AqR4Aq
+ umask 022
+ cd /home/rpmbuilder/rpmbuild/BUILD
+ cd vitetris-0.57
+ /usr/bin/rm -rf /home/rpmbuilder/rpmbuild/BUILDROOT/vitetris-0.57-1.el7.x86_64
+ exit 0

给RPM包签名

给RPM包签名很简单:

$ rpmsign --addsign /home/rpmbuilder/rpmbuild/RPMS/x86_64/vitetris-0.57-1.el7.x86_64.rpm 
Enter pass phrase: Pass phrase is good. 
/home/rpmbuilder/rpmbuild/RPMS/x86_64/vitetris-0.57-1.el7.x86_64.rpm:

如果出现此错误:

You must set "%_gpg_name" in your macro file

则需要在你的公钥值中设置%_gpg_name

$ gpg --list-keys 
/home/rpmbuilder/.gnupg/pubring.gpg
-----------------------------------
pub 2048R/EEF6D9AD 2019-03-02
uid RPM Build User (RPM Builder GPG Signing Key) <rpmbuilder@rpm>
sub 2048R/D498F883 2019-03-02

$ echo "%_gpg_name EEF6D9AD" >> .rpmmacros

再试一次:

$ rpmsign --addsign /home/rpmbuilder/rpmbuild/RPMS/x86_64/vitetris-0.57-1.el7.x86_64.rpm
Enter pass phrase: 
Pass phrase is good.
/home/rpmbuilder/rpmbuild/RPMS/x86_64/vitetris-0.57-1.el7.x86_64.rpm:

以root用户身份测试RPM包的安装/卸载

# rpm -i /home/rpmbuilder/rpmbuild/RPMS/x86_64/vitetris-0.57-1.el7.x86_64.rpm
warning: /home/rpmbuilder/rpmbuild/RPMS/x86_64/vitetris-0.57-1.el7.x86_64.rpm: Header V4 RSA/SHA1 Signature, key ID eef6d9ad: NOKEY

# /usr/local/bin/tetris

卸载RPM:

# rpm -qa |grep tetris
vitetris-0.57-1.el7.x86_64
=# rpm -e vitetris-0.57-1.el7.x86_64
# /usr/local/bin/tetris
-bash: /usr/local/bin/tetris: No such file or directory

结论

根据需求打包自定义RPM包通常可能会很困难。在本文中,我旨在说明,很少的配置也足以构建RPM。

要了解更多信息,请参阅Red Hat的RPM包装指南

原文链接:https://developers.redhat.com/blog/2019/03/18/rpm-packaging-guide-creating-rpm/

作者:Mohammad Ahmad

译者:邵晨峰