5.7. RubyGems 软件包

本节介绍 RubyGems 软件包是什么,以及如何将它们打包到 RPM 中。

5.7.1. RubyGems 是什么

Ruby 是一个动态、解释、反射、面向对象的通用编程语言。

使用 Ruby 编写的程序通常使用 RubyGems 项目打包,该项目提供了特定的 Ruby 打包格式。

RubyGems 创建的软件包名为 gems,也可以将其重新打包到 RPM 中。

注意

本文档指的是与 gem 前缀相关的 RubyGems 概念,如 .gemspec 用于 gem 规范,且与 RPM 相关的术语无效。

5.7.2. RubyGems 与 RPM 的关系

RubyGems 代表 Ruby 自己的打包格式。但是,RubyGems 包含 RPM 所需的元数据,它启用了从 RubyGems 转换到 RPM。

根据 Ruby 打包指南,可以以这种方式将 RubyGems 软件包重新打包到 RPM 中:

  • 这些 RPM 适合其余发行版。
  • 最终用户可以通过安装适当的 RPM 软件包 gem 来满足 gem 的依赖项。

RubyGems 使用类似 RPM 的术语,如 SPEC 文件、软件包名称、依赖项和其他项目。

要适应 RHEL RPM 的其他发行版本,由 RubyGems 创建的软件包必须遵循以下列出的约定:

  • gems 的名称必须遵循此模式:

    rubygem-%{gem_name}
  • 要实现 shebang 行,必须使用以下字符串:

    #!/usr/bin/ruby

5.7.3. 从 RubyGems 软件包创建 RPM 软件包

要为 RubyGems 软件包创建源 RPM,需要以下文件:

  • gem 文件
  • RPM SPEC 文件

下面的部分描述了如何从 RubyGems 创建软件包中创建 RPM 软件包。

5.7.3.1. RubyGems SPEC 文件惯例

RubyGems SPEC 文件必须满足以下条件:

  • 包含 %{gem_name} 的定义,这是 gem 规范中的名称。
  • 软件包的来源必须是发布的 gem 归档的完整 URL;软件包的版本必须是 gem 的版本。
  • 包含 BuildRequires: 一个定义的指令,可以拉取(pull)构建所需的宏。

    BuildRequires:rubygems-devel
  • 不包含任何 RubyGems RequiresProvides,因为它们是自动生成的。
  • 除非要明确指定 Ruby 版本兼容性,否则请不要包含如下定义的 BuildRequires: 指令:

    Requires: ruby(release)

    自动生成的对 RubyGems 的依赖关系(Requires: ruby(rubygems))就足够了。

5.7.3.2. RubyGems macros

下表列出了对于 RubyGems 创建的软件包有用的宏。这些宏由 rubygems-devel 软件包提供。

表 5.4. RubyGems 的宏

宏名称扩展路径使用

%{gem_dir}

/usr/share/gems

gem 结构的顶级目录。

%{gem_instdir}

%{gem_dir}/gems/%{gem_name}-%{version}

包含 gem 的实际内容的目录。

%{gem_libdir}

%{gem_instdir}/lib

gem 的库目录。

%{gem_cache}

%{gem_dir}/cache/%{gem_name}-%{version}.gem

缓存的 gem。

%{gem_spec}

%{gem_dir}/specifications/%{gem_name}-%{version}.gemspec

gem 规范文件。

%{gem_docdir}

%{gem_dir}/doc/%{gem_name}-%{version}

gem 的 RDoc 文档。

%{gem_extdir_mri}

%{_libdir}/gems/ruby/%{gem_name}-%{version}

gem 扩展的目录。

5.7.3.3. RubyGems SPEC 文件示例

用于构建 gems 的 SPEC 文件示例以及其特定部分的说明如下。

RubyGems SPEC 文件示例

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

# Modify the gemspec if necessary
# Also apply patches to code if necessary
%patch0 -p1

%build
# Create the gem as gem install only works on a gem file
gem build ../%{gem_name}-%{version}.gemspec

# %%gem_install compiles any C extensions and installs the gem into ./%%gem_dir
# by default, so that we can move it into the buildroot in %%install
%gem_install

%install
mkdir -p %{buildroot}%{gem_dir}
cp -a ./%{gem_dir}/* %{buildroot}%{gem_dir}/

# If there were programs installed:
mkdir -p %{buildroot}%{_bindir}
cp -a ./%{_bindir}/* %{buildroot}%{_bindir}

# If there are C extensions, copy them to the extdir.
mkdir -p %{buildroot}%{gem_extdir_mri}
cp -a .%{gem_extdir_mri}/{gem.build_complete,*.so} %{buildroot}%{gem_extdir_mri}/

下表解释 RubyGems SPEC 文件中特定项的具体内容:

表 5.5. 特定于 RubyGems 的 SPEC 指令

SPEC 指令RubyGems 特定

%prep

RPM 可以直接解包 gem 归档,以便您可以运行 gem unpack 命令来从 gem 中提取源。%setup -n %{gem_name}-%{version} 宏提供 gem 已解压缩的目录。在同一目录级别,会自动创建 %{gem_name}-%{version}.gemspec 文件,该文件可用于重新构建 gem,以修改 .gemspec 或将补丁应用到代码。

%build

此指令包括将软件构建到机器代码的命令或一系列命令。%gem_install 宏只在 gem 归档上运行,而 gem 可使用下一个 gem 构建重新创建。然后,%gem_install 创建的 gem 文件会被用于构建代码并安装到临时目录中,默认为 ./%{gem_dir}%gem_install 宏构建并安装代码。在安装之前,构建的源会被放入自动创建的临时目录中。

%gem_install 宏接受两个附加选项: -n <gem_file>,它可以覆盖用于安装的 gem,-d <install_dir>,它可能会覆盖 gem 安装目的地;不建议使用这个选项。

%gem_install 宏不能用于安装到 %{buildroot} 中。

%install

安装将在 %{buildroot} 层次结构中执行。您可以创建需要的目录,然后将临时目录中安装的内容复制到 %{buildroot} 层次结构中。如果这个 gem 创建共享对象,则会移到特定于构架的 %{gem_extdir_mri} 路径中。

其他资源

5.7.3.4. 使用 gem2rpm 将 RubyGems 软件包转换为 RPM SPEC 文件

gem2rpm 实用程序将 RubyGems 软件包转换为 RPM SPEC 文件。

以下小节描述了如何进行:

  • 安装 gem2rpm 工具
  • 显示所有 gem2rpm 选项
  • 使用 gem2rpm 将 RubyGems 软件包覆盖到 RPM SPEC 文件
  • 编辑 gem2rpm 模板
5.7.3.4.1. 安装 gem2rpm

以下流程描述了如何安装 gem2rpm 工具。

流程

$ gem install gem2rpm
5.7.3.4.2. 显示 gem2rpm 的所有选项

下面的步骤描述了如何显示 gem2rpm 工具的所有选项。

流程

  • 要查看 gem2rpm 的所有选项,请运行:

    gem2rpm --help
5.7.3.4.3. 使用 gem2rpm 将 RubyGems 软件包覆盖到 RPM SPEC 文件

以下流程描述了如何使用 gem2rpm 实用程序将 RubyGems 软件包到 RPM SPEC 文件。

流程

  • 在其最新版本中下载 gem,并为这个 gem 生成 RPM SPEC 文件:

    $ gem2rpm --fetch <gem_name> > <gem_name>.spec

描述的步骤根据 gem 元数据中提供的信息创建 RPM SPEC 文件。但是 gem 丢失了通常在 RPM 中提供的一些重要信息,如许可证和更改日志。因此,生成的 SPEC 文件需要编辑。

5.7.3.4.4. gem2rpm 模板

gem2rpm 模板是一个标准嵌入式 Ruby(ERB)文件,其中包含下表中列出的变量。

表 5.6. gem2rpm 模板中的变量

变量解释

package

gem 的 Gem::Package 变量。

spec

gem 的 Gem::Specification 变量(与 format.spec 相同)。

config

Gem2Rpm::Configuration 变量,可以重新定义 spec 模板帮助程序中使用的默认宏或规则。

runtime_dependencies

Gem2Rpm::RpmDependencyList 变量提供软件包运行时依赖项列表。

development_dependencies

Gem2Rpm::RpmDependencyList 变量提供软件包开发依赖项列表。

测试

Gem2Rpm::TestSuite 变量提供允许执行测试框架的列表。

files

Gem2Rpm::RpmFileList 变量提供软件包中未过滤的文件列表。

main_files

Gem2Rpm::RpmFileList 变量提供适合主软件包的文件列表。

doc_files

Gem2Rpm::RpmFileList 变量提供适合 -doc 子软件包的文件列表。

格式

gem 的 Gem::Format 变量。请注意,此变量现已弃用。

5.7.3.4.5. 列出可用的 gem2rpm 模板

使用以下步骤列出所有可用的 gem2rpm 模板。

流程

  • 要查看所有可用的模板,请运行:

    $ gem2rpm --templates
5.7.3.4.6. 编辑 gem2rpm 模板

您可以编辑生成 RPM SPEC 文件而不是编辑生成的 SPEC 文件的模板。

使用以下步骤编辑 gem2rpm 模板。

流程

  1. 保存默认模板:

    $ gem2rpm -T > rubygem-<gem_name>.spec.template
  2. 根据需要编辑模板。
  3. 使用编辑的模板生成 SPEC 文件:

    $ gem2rpm -t rubygem-<gem_name>.spec.template <gem_name>-<latest_version.gem > <gem_name>-GEM.spec

现在,您可以使用编辑的模板构建一个 RPM 软件包,如 构建 RPM 中所述。