在 CentOS / RedHat 上从源代码构建 RPM 包的 7 个步骤

有时您可能可以访问开源应用程序源代码,但可能没有 RPM 文件来将其安装到您的系统上。
在这种情况下,您可以编译源代码并从源代码安装应用程序,或者自己从源代码构建 RPM 文件,然后使用 RPM 文件安装应用程序。也可能存在您想要为您开发的应用程序构建自定义 RPM 包的情况。本篇解释了如何从源代码构建 RPM 包。

为了构建 RPM,您就需要源代码,这通常意味着一个包含 SPEC 文件的压缩 tar 文件。SPEC 文件通常包含有关如何构建 RPM、哪些文件是包的一部分以及应该安装在哪里的说明。RPM 在构建过程中执行以下任务。
  1. 执行规范文件的准备部分中提到的命令和宏。
  2. 检查文件列表的内容
  3. 执行规范文件的构建部分中的命令和宏,文件列表中的宏也在这一步执行。
  4. 创建二进制包文件
  5. 创建源包文件

RPM 执行上述步骤后,会创建二进制包文件和源包文件。

二进制包文件包含所有源文件以及用于安装或卸载包的任何附加信息,它通常通过安装特定于平台的软件包的所有选项启用。
二进制包文件包含为特定架构编译的完整应用程序或函数库,源包通常由原始压缩的 tar 文件、spec 文件和创建二进制包文件所需的补丁组成。

让我们看看如何使用 tar 文件创建一个简单的源代码和 BIN RPM 包。

1.安装rpm-build包

要根据我们刚刚创建的 spec 文件构建 rpm 文件,我们需要使用 rpmbuild 命令。

rpmbuild 命令是 rpm-build 包的一部分。如下图所示安装。

# yum install rpm-build

rpm-build 依赖于以下包。如果您还没有安装这些,yum 会自动为您安装这些依赖项。

elfutils-libelf
rpm
rpm-libs
rpm-python

2. RPM 构建目录

rpm-build 将自动创建以下目录结构,这些结构将在 RPM 构建期间使用。

# ls -lF /root/rpmbuild/
drwxr-xr-x. 2 root root 4096 Feb  4 12:21 BUILD/
drwxr-xr-x. 2 root root 4096 Feb  4 12:21 BUILDROOT/
drwxr-xr-x. 2 root root 4096 Feb  4 12:21 RPMS/
drwxr-xr-x. 2 root root 4096 Feb  4 12:21 SOURCES/
drwxr-xr-x. 2 root root 4096 Feb  4 12:21 SPECS/
drwxr-xr-x. 2 root root 4096 Feb  4 12:21 SRPMS/

注意:以上目录结构适用于 CentOS 和 RedHat 使用 rpmbuild 包时。您也可以使用 /usr/src/redhat 目录,但您需要在 rpm 构建期间相应地更改 topdir 参数。如果您在 SuSE Enterprise Linux 上执行此操作,请使用 /usr/src/packages 目录。

如果要使用自己的目录结构而不是 /root/rpmbuild,可以使用以下选项之一:

  • 使用 –buildroot 选项并在 rpmbuild 期间指定自定义目录
  • 在 rpmrc 文件或 rpmmacros 文件中指定 topdir 参数。

3.下载源Tar文件

接下来,下载要构建的包的源 tar 文件并将其保存在 SOURCES 目录下。

在这个例子中,我使用了icecase开源应用程序的源代码,它是一个用于流式传输多媒体的服务器软件。但是,为任何其他应用程序构建 RPM 的步骤完全相同。您只需要为您尝试构建的 RPM 下载相应的源代码。

# cd /root/rpmbuild/SOURCES/

# wget http://downloads.xiph.org/releases/icecast/icecast-2.3.3.tar.gz

# ls -l
-rw-r--r--. 1 root root 1161774 Jun 11  2020 icecast-2.3.3.tar.gz

4. 创建 SPEC 文件

在这一步中,我们通过创建规范文件在构建过程中指导 RPM。spec 文件通常由以下八个不同的部分组成:

  1. 前言 – 前言部分包含有关正在构建的包的信息并定义包的任何依赖项。通常,前导码由条目组成,每行一个,以标签开头,后跟冒号,然后是一些信息。
  2. %prep – 在本节中,我们为构建过程准备软件。在此过程中删除任何先前的构建,并扩展源文件 (.tar) 文件等。
  3. 更关键的一点是了解有预定义的宏可用于执行各种快捷选项来构建 rpm。当您尝试构建任何复杂的包时,您可能会使用这些宏。在下面的示例中,我使用了一个名为 %setup 的宏,它删除了任何以前的构建,解压缩源文件并更改文件的所有权。您还可以使用 %prep 部分下的 sh 脚本来执行此操作,但 %setup 宏通过使用预定义的 sh 脚本简化了该过程。
  4. %description – 描述部分通常包含关于包的描述。
  5. %build – 这是负责执行构建的部分。通常 %build 部分是一个 sh 脚本。
  6. %install – % install 部分也像 %prep 和 %build 一样作为 sh 脚本执行。这是用于安装的步骤。
  7. %files – 此部分包含属于包的文件列表。如果这些文件不是 %files 部分的一部分,那么它在包中将不可用。完整路径是必需的,您可以在此部分中设置文件的属性和所有权。
  8. %clean – 此部分指示 RPM 清除不属于应用程序正常构建区域的任何文件。举个例子,如果应用程序在 /tmp/ 中创建一个临时目录结构作为其构建的一部分,它将不会被删除。通过在 %clean 部分添加 sh 脚本,可以在构建过程完成后删除该目录。

这是我为 icecast 应用程序创建的用于构建 RPM 文件的 SPEC 文件。

# cat /root/rpmbuild/SPECS/icecast.spec
Name:           icecast
Version:        2.3.3
Release:        0
Summary:        Xiph Streaming media server that supports multiple formats.
Group:          Applications/Multimedia
License:        GPL
URL:            http://www.icecast.org/
Vendor:         Xiph.org Foundation team@icecast.org
Source:         http://downloads.us.xiph.org/releases/icecast/%{name}-%{version}.tar.gz
Prefix:         %{_prefix}
Packager: 	Karthik
BuildRoot:      %{_tmppath}/%{name}-root

%description
Icecast is a streaming media server which currently supports Ogg Vorbis
and MP3 audio streams. It can be used to create an Internet radio
station or a privately running jukebox and many things in between.
It is very versatile in that new formats can be added relatively
easily and supports open standards for commuincation and interaction.

%prep
%setup -q -n %{name}-%{version}

%build
CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%{_prefix} --mandir=%{_mandir} --sysconfdir=/etc

make

%install
[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT

make DESTDIR=$RPM_BUILD_ROOT install
rm -rf $RPM_BUILD_ROOT%{_datadir}/doc/%{name}

%clean
[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT

%files
%defattr(-,root,root)
%doc README AUTHORS COPYING NEWS TODO ChangeLog
%doc doc/*.html
%doc doc/*.jpg
%doc doc/*.css
%config(noreplace) /etc/%{name}.xml
%{_bindir}/icecast
%{_prefix}/share/icecast/*

%changelog

In this file, under % prep section you may noticed the macro “%setup -q -n %{name}-%{version}”. This macro executes the following command in the background.

cd /usr/src/redhat/BUILD
rm -rf icecast
gzip -dc /usr/src/redhat/SOURCES/icecast-2.3.3.tar.gz | tar -xvvf -
if [ $? -ne 0 ]; then
  exit $?
fi
cd icecast
cd /usr/src/redhat/BUILD/icecast
chown -R root.root .
chmod -R a+rX,g-w,o-w .

在 %build 部分,您将看到带有配置选项的 CFLAGS,这些选项定义了在 RPM 安装过程中可以使用的选项和前缀选项,安装和 sysconfig 目录必须存在的目录,系统文件需要复制到该目录下.

在该行下方,您将看到 make 实用程序,它确定需要编译的文件列表并正确编译它们。

在 % install 部分,%install 下方的“make install”行用于获取从上一步编译的二进制文件,并将它们安装或复制到适当的位置,以便可以访问它们。

5. 使用 rpmbuild 创建 RPM 文件

一旦 SPEC 文件准备好,您就可以开始使用 rpm –b 命令构建您的 rpm。-b 选项用于执行构建过程的所有阶段。如果您在此阶段看到任何错误,则需要在重新尝试之前解决它。错误通常是库依赖项,您可以根据需要下载并安装它。

# cd /root/rpmbuild/SPECS

# rpmbuild -ba icecast.spec
Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.Kohe4t
+ umask 022
+ cd /root/rpmbuild/BUILD
+ cd /root/rpmbuild/BUILD
+ rm -rf icecast-2.3.3
+ /usr/bin/gzip -dc /root/rpmbuild/SOURCES/icecast-2.3.3.tar.gz
+ /bin/tar -xf -
+ STATUS=0
+ '[' 0 -ne 0 ']'
+ cd icecast-2.3.3
+ /bin/chmod -Rf a+rX,u+w,g-w,o-w .
+ exit 0
Executing(%build): /bin/sh -e /var/tmp/rpm-tmp.ynm7H7
+ umask 022
+ cd /root/rpmbuild/BUILD
+ cd icecast-2.3.3
+ CFLAGS='-O2 -g'
+ ./configure --prefix=/usr --mandir=/usr/share/man --sysconfdir=/etc
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking whether to enable maintainer-specific portions of Makefiles... no
checking for gcc... gcc
..
..
..
Wrote: /root/rpmbuild/SRPMS/icecast-2.3.3-0.src.rpm
Wrote: /root/rpmbuild/RPMS/x86_64/icecast-2.3.3-0.x86_64.rpm
Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.dzahrv
+ umask 022
+ cd /root/rpmbuild/BUILD
+ cd icecast-2.3.3
+ '[' /root/rpmbuild/BUILDROOT/icecast-2.3.3-0.x86_64 '!=' / ']'
+ rm -rf /root/rpmbuild/BUILDROOT/icecast-2.3.3-0.x86_64
+ exit 0

注意:如果您使用的是 SuSE Linux,如果 rpmbuild 不可用,请尝试使用“rpm -ba”来构建 rpm 包。

在上述 rpmbuild 安装过程中,您可能会注意到以下错误消息:

错误 1:找不到 XSLT 配置

checking for xslt-config... no
configure: error: XSLT configuration could not be found
error: Bad exit status from /var/tmp/rpm-tmp.8J0ynG (%build)
RPM build errors:
    Bad exit status from /var/tmp/rpm-tmp.8J0ynG (%build)

方案一:安装libxstl-devel

对于 xslt-config,您需要安装 libxstl-devel 包,如下所示。

yum install libxstl-devel

这还将安装以下依赖项:

  • libgcrypt
  • libgcrypt-devel
  • libgpg-错误-开发

错误 2:libvorbis 错误

checking for libvorbis... configure: error: must have Ogg Vorbis v1.0 or above installed
error: Bad exit status from /var/tmp/rpm-tmp.m4Gk3f (%build)

解决方案 2:安装 libvorbis-devel

对于 Ogg Vorbis v1.0,安装 libvorbis-devel 包,如下所示:

yum install libvorbis-devel

这还将安装以下依赖项:

  • 利博格
  • libogg-devel
  • 库沃尔比斯

6. 验证源文件和二进制 RPM 文件

rpmbuild 完成后,您可以验证源 rpm 和二进制 rpm 是否在以下目录中创建。

# ls -l /root/rpmbuild/SRPMS/
-rw-r--r-- 1 root root 1162483 Aug 25 15:46 icecast-2.3.3-0.src.rpm

# ls -l /root/rpmbuild/RPMS/x86_64/
-rw-r--r--. 1 root root 349181 Feb  4 12:54 icecast-2.3.3-0.x86_64.rpm

7.安装RPM文件进行验证

作为最后一步,您可以安装二进制 rpm 以验证它是否安装成功并且所有依赖项都已解决。

# rpm -ivvh /root/rpmbuild/RPMS/x86_64/icecast-2.3.3-0.x86_64.rpm
D: ============== /root/rpmbuild/RPMS/x86_64/icecast-2.3.3-0.x86_64.rpm
D: loading keyring from pubkeys in /var/lib/rpm/pubkeys/*.key
D: couldn't find any keys in /var/lib/rpm/pubkeys/*.key
D: loading keyring from rpmdb
D: opening  db environment /var/lib/rpm cdb:mpool:joinenv
D: opening  db index       /var/lib/rpm/Packages rdonly mode=0x0
D:  read h#     210 Header sanity check: OK
D: added key gpg-pubkey-c105b9de-4e0fd3a3 to keyring
D: Using legacy gpg-pubkey(s) from rpmdb
D: Expected size:       349181 = lead(96)+sigs(180)+pad(4)+data(348901)
D:   Actual size:       349181
D: ========== relocations
D:      added binary package [0]
D: found 0 source and 1 binary packages
D: ========== +++ icecast-2.3.3-0 x86_64/linux 0x2
..
..

以上安装完成后,您可以验证您的自定义创建的 rpm 文件是否安装成功,如下所示。

# rpm -qa icecast
icecast-2.3.3-0.x86_64
(完)