Red Hat Training

A Red Hat training course is available for RHEL 8

5.2. 有关宏的更多内容

本节介绍所选内置 RPM Macros。有关此类宏的详细列表,请参阅 RPM 文档

5.2.1. 定义您自己的宏

下面的部分论述了如何创建自定义宏。

流程

  • 在 RPM SPEC 文件中包括以下行:

    %global <name>[(opts)] <body>

删除 <body> 周围的空白。名称可以是字母数字字符,字符 _,长度必须至少为 3 个字符。包含 (opts) 字段是可选的:

  • Simple 宏不包含 (opts) 字段。在这种情况下,只执行递归宏扩展。
  • Parametrized 宏包含 (opts) 字段。在宏调用开始时传递括号之间的 opts 字符串可得到 argc/argv 处理的 getopt(3)
注意

旧的 RPM SPEC 文件使用 %define <name> <body> 宏模式。%define%global 宏之间的差异如下:

  • %define 是本地范围的。它适用于 SPEC 文件的特定部分。%define 宏的主体部分在使用时会被扩展。
  • %global 有全局范围。它适用于整个 SPEC 文件。在定义时扩展 %global 宏的正文。
重要

宏会被评估,即使被注释掉或者宏的名称被指定到 SPEC 文件的 %changelog 部分中。要注释掉宏,请使用 %%。例如 %%global.

其他资源

5.2.2. 使用 %setup 宏

这部分论述了如何使用 %setup 宏的不同变体构建带有源代码 tarball 的软件包。请注意,宏变体可以合并。rpmbuild 输出说明了 %setup 宏的标准行为。在每个阶段开始时,宏输出 Executing(%…​),如下例所示。

例 5.1. %setup 宏输出示例

Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.DhddsG

shell 输出启用了 set -x。要查看 /var/tmp/rpm-tmp.DhddsG 的内容,请使用 --debug 选项,因为 rpmbuild 在成功构建后删除临时文件。这将显示环境变量的设置,后跟:

cd '/builddir/build/BUILD'
rm -rf 'cello-1.0'
/usr/bin/gzip -dc '/builddir/build/SOURCES/cello-1.0.tar.gz' | /usr/bin/tar -xof -
STATUS=$?
if [ $STATUS -ne 0 ]; then
  exit $STATUS
fi
cd 'cello-1.0'
/usr/bin/chmod -Rf a+rX,u+w,g-w,o-w .

%setup 宏:

  • 确保我们在正确的目录中工作。
  • 删除之前构建的恢复。
  • 解包源 tarball。
  • 设置一些默认特权。

5.2.2.1. 使用 %setup -q 宏

-q 选项限制 %setup 宏的详细程度。仅执行 tar -xof 而不是 tar -xvvof。使用这个选项作为第一个选项。

5.2.2.2. 使用 %setup -n 宏

-n 选项指定已展开 tarball 中的目录名称。

当来自扩展 tarball 的目录与预期内容不同时,会使用这个情况(%{name}-%{version}),这可能会导致 %setup 宏的错误。

例如,如果软件包名称是 cello,但源代码以 hello-1.0.tgz 中存档,且包含 hello/ 目录,则 SPEC 文件内容需要如下:

Name: cello
Source0: https://example.com/%{name}/release/hello-%{version}.tar.gz
…
%prep
%setup -n hello

5.2.2.3. 使用 %setup -c 宏

如果源代码 tarball 不包含任何子目录,并在解压缩后的文件会填充当前目录,则使用 -c 选项。

然后,-c 选项会在归档扩展中创建目录和步骤,如下所示:

/usr/bin/mkdir -p cello-1.0
cd 'cello-1.0'

归档扩展后不会更改该目录。

5.2.2.4. 使用 %setup -D 和 %setup -T 宏

-D 选项会禁用删除源代码目录,在使用 %setup 宏时特别有用。使用 -D 选项时,不会使用以下行:

rm -rf 'cello-1.0'

-T 选项通过从脚本中删除以下行来禁用源代码 tarball 的扩展:

/usr/bin/gzip -dc '/builddir/build/SOURCES/cello-1.0.tar.gz' | /usr/bin/tar -xvvof -

5.2.2.5. 使用 %setup -a 和 %setup -b 宏

-a-b 选项可以扩展特定的源:

  • -b 选项代表 before。这个选项在进入工作目录前扩展特定的源。
  • -a 选项代表 after。这个选项在进入后扩展这些源。它们的参数是 SPEC 文件中的源号。

在以下示例中,cello-1.0.tar.gz 存档包含一个空 examples 目录。示例以单独的 example.tar.gz tarball 中提供,它们被扩展到同一名称的目录中。在这种情况下,如果您在进入工作目录后想扩展 Source1,请使用 -a 1

Source0: https://example.com/%{name}/release/%{name}-%{version}.tar.gz
Source1: examples.tar.gz
…
%prep
%setup -a 1

在以下示例中,在单独的 cello-1.0-examples.tar.gz tarball 中提供了示例,它扩展至 cello-1.0/examples。在这种情况下,在进入工作目录前,使用 -b 1 扩展 Source1

Source0: https://example.com/%{name}/release/%{name}-%{version}.tar.gz
Source1: %{name}-%{version}-examples.tar.gz
…
%prep
%setup -b 1

5.2.3. %files 部分中的常见 RPM 宏

下表列出了 SPEC 文件的 %files 部分中需要的高级 RPM Macros。

表 5.1. %files 部分中的高级 RPM Macros

Macro定义

%license

%license 宏识别列为 LICENSE 文件的文件,它将被安装,并被 RPM 标记成这样 。示例:%license LICENSE.

%doc

%doc 宏识别列为文档的文件,它将被安装,并被 RPM 标记成这样。%doc 宏用于有关打包的软件的文档,以及用于代码示例和各种附带项。如果包含代码示例,则必须小心地从文件中删除可执行模式。示例:%doc README

%dir

%dir 宏确保路径是由此 RPM 拥有的目录。这一点很重要,因此 RPM 文件清单准确知道在卸载时要清理哪些目录。示例: %dir %{_libdir}/%{name}

%config(noreplace)

%config (noreplace) 宏可确保以下文件是一个配置文件,因此如果已从原始安装校验和修改了该文件,则其不应在软件包安装或更新软件包时被覆盖(或替换)。如果有更改,则会在升级或安装时使用 .rpmnew 创建该文件,以便不修改目标系统上的预先存在的或修改的文件。示例:%config(noreplace) %{_sysconfdir}/%{name}/%{name}.conf

5.2.4. 显示内置宏

Red Hat Enterprise Linux 提供多个内置 RPM 宏。

流程

  1. 要显示所有内置 RPM 宏,请运行:

    rpm --showrc
    注意

    输出很长。要缩小结果范围,请在 grep 命令中使用上述命令。

  2. 要查找有关您系统 RPM 版本 RPM 宏的信息,请运行:

    rpm -ql rpm
    注意

    RPM 宏是在输出目录结构中标题为 macros 的文件。

5.2.5. RPM 发布宏

不同的发行版根据被打包的软件语言或发布的具体准则,提供不同的推荐 RPM 宏集合。

推荐的 RPM 宏集合通常以 RPM 软件包形式提供,可以使用 yum 软件包管理器安装。

安装后,宏文件可在 /usr/lib/rpm/macros.d/ 目录中找到。

流程

  • 要显示原始 RPM 宏定义,请运行:

    rpm --showrc

以上输出显示原始 RPM 宏定义。

  • 要确定宏的作用以及在打包 RPM 时如何有帮助,使用宏名称作为其参数运行 rpm --eval 命令:

    rpm --eval %{_MACRO}

其他资源

  • RPM man page

5.2.6. 创建自定义宏

您可以使用自定义宏覆盖 ~/.rpmmacros 文件中的发布宏。您所做的任何更改都会影响您计算机上的每个构建。

警告

不建议在 ~/.rpmmacros 文件中定义任何新宏。其他机器上不会包括此类宏,因为用户可能想要重新构建您的软件包。

流程

  • 要覆盖宏,请运行:

    %_topdir /opt/some/working/directory/rpmbuild

您可以从上面示例中创建 目录,包括通过 rpmdev-setuptree 实用程序的所有子目录。此宏的值默认为 ~/rpmbuild

%_smp_mflags -l3

以上宏通常用于传递 Makefile,如 make %{?_smp_mflags},并在构建阶段设置多个并发进程。默认情况下,它被设置为 -jX,其中 X 是内核数。如果您更改了内核数量,您可以加快或减慢软件包构建速度或减慢速度。