Chapter 7. Packaging Ruby gems


Ruby is a dynamic, interpreted, reflective, object-oriented, general-purpose programming language.

Programs written in Ruby are typically packaged by using the RubyGems software, which provides a specific Ruby packaging format.

Packages created by RubyGems are called gems and they can be re-packaged into RPM packages.

Note

This documentation refers to terms related to the RubyGems concept with the gem prefix, for example, .gemspec is used for the gem specification, and terms related to RPM are unqualified.

7.1. How RubyGems relate to RPM

RubyGems represent Ruby’s own packaging format. However, RubyGems contain metadata similar to metadata required by RPM. This metadata streamlines packaging gems as RPMs. RPMs re-packaged from gems fit with the rest of the distribution. End users are also able to satisfy dependencies of a gem by installing the appropriate RPM-packaged gem and other system libraries.

RubyGems use terminology similar to RPM packages, such as spec files, package names, dependencies, and other items.

To conform with the rest of RHEL RPM distribution, packages created by RubyGems must comply with the following rules:

  • Follow the rubygem-%{gem_name} pattern when naming your packages.
  • Use the #!/usr/bin/ruby string as the interpreter directive.

7.2. RubyGems spec file conventions

A RubyGems spec file must meet the following conventions:

  • The file contains a definition of %{gem_name}, which is the name from the gem’s specification.
  • The source of the package must be the full URL to the released gem archive.
  • The version of the package must be the gem’s version.
  • The file contains the following BuildRequires: directive:

    BuildRequires: rubygems-devel

    The rubygems-devel package contains macros needed for a build.

  • The file does not contain any additional rubygem(foo) Requires or Provides directives because these directives are autogenerated from the gem metadata.

7.2.1. RubyGems spec file example

The following is the RubyGems-specific part of an example spec file for building gems. The remaining part of the spec file follows the generic guidelines.

A RubyGems-specific part of an example spec file

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

# Modify the gemspec if necessary
# Also apply patches to code if necessary
%patch 0 -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}/

7.2.2. RubyGems spec file directives

The following are the specifics of particular items in the RubyGems-specific part of the spec file.

Table 7.1. RubyGems' spec directives specifics
DirectiveRubyGems specifics

%prep

RPM can directly unpack gem archives. The %setup -n %{gem_name}-%{version} macro provides the directory into which the gem is unpacked. At the same directory level, the %{gem_name}-%{version}.gemspec file is automatically created. You can use this file to perform the following actions:

  • Modify the .gemspec file
  • Apply patches to the code.

%build

This section includes commands for building the software into machine code. The %gem_install macro operates only on gem archives. Therefore, you must first re-create the archive by using the gem build ../%{gem_name}-%{version}.gemspec command. The recreated gem file is then used by %gem_install to build and install the gem code into the default ./%{gem_dir} temporary directory. Before being installed, the built sources are placed into a temporary directory that is created automatically.

%install

The installation is performed into the %{buildroot} hierarchy. You can create the necessary directories and then copy the installed code from the temporary directories into the %{buildroot} hierarchy. If the gem creates shared objects, they are moved into the architecture-specific %{gem_extdir_mri} path.

7.2.3. Additional resources

7.3. RubyGems macros

The following are macros useful for packages created by RubyGems. These macros are provided by the rubygems-devel package.

Table 7.2. RubyGems' macros
Macro nameExtended pathUsage

%{gem_dir}

/usr/share/gems

Top directory for the gem structure.

%{gem_instdir}

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

Directory with the actual content of the gem.

%{gem_libdir}

%{gem_instdir}/lib

The library directory of the gem.

%{gem_cache}

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

The cached gem.

%{gem_spec}

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

The gem specification file.

%{gem_docdir}

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

The RDoc documentation of the gem.

%{gem_extdir_mri}

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

The directory for gem extension.

7.4. Using gem2rpm to generate a spec file

You can use the gem2rpm utility to create an RPM spec file.

7.4.1. Creating an RPM spec file for a Ruby gem

You can generate an RPM spec file for a RubyGems package by using the gem2rpm utility.

Prerequisites

  • You have the gem2rpm utility installed on your system:

    $ gem install gem2rpm

Procedure

  1. Download a gem in its latest version and generate the RPM spec file for this gem:

    $ gem2rpm --fetch <gem_name> > <gem_name>.spec
  2. Edit the generated spec file to add the missing information, for example, a license and a changelog.

Additional resources

7.4.2. Using custom gem2rpm templates to generate a spec file

gem2rpm templates are standard Embedded Ruby (ERB) files that RPM spec files can be generated from. You can edit the template from which the RPM spec file is generated instead of editing the generated spec file.

Prerequisites

  • You have the gem2rpm utility installed on your system:

    $ gem install gem2rpm

Procedure

  1. Display all gem2rpm built-in templates:

    $ gem2rpm --templates
  2. Select one of the built-in templates and save it as a custom template:

    $ gem2rpm -t <template> -T > rubygem-<gem_name>.spec.template

    Note that for RHEL 10 Beta, the fedora-27-rawhide template is recommended.

  3. Edit the template as needed. For more information, see gem2rpm template variables.
  4. Generate the spec file by using the edited template:

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

Additional resources

7.4.3. gem2rpm template variables

The following are the variables included in the gem2rpm template for RPM spec file generation.

Table 7.3. Variables in the gem2rpm template
VariableExplanation

package

The Gem::Package variable for the gem.

spec

The Gem::Specification variable for the gem (the same as format.spec).

config

The Gem2Rpm::Configuration variable that can redefine default macros or rules used in spec template helpers.

runtime_dependencies

The Gem2Rpm::RpmDependencyList variable that provides a list of package runtime dependencies.

development_dependencies

The Gem2Rpm::RpmDependencyList variable that provides a list of package development dependencies.

tests

The Gem2Rpm::TestSuite variable that provides a list of test frameworks allowing their execution.

files

The Gem2Rpm::RpmFileList variable that provides an unfiltered list of files in a package.

main_files

The Gem2Rpm::RpmFileList variable that provides a list of files suitable for the main package.

doc_files

The Gem2Rpm::RpmFileList variable that provides a list of files suitable for the -doc subpackage.

Red Hat logoGithubRedditYoutubeTwitter

Learn

Try, buy, & sell

Communities

About Red Hat Documentation

We help Red Hat users innovate and achieve their goals with our products and services with content they can trust.

Making open source more inclusive

Red Hat is committed to replacing problematic language in our code, documentation, and web properties. For more details, see the Red Hat Blog.

About Red Hat

We deliver hardened solutions that make it easier for enterprises to work across platforms and environments, from the core datacenter to the network edge.

© 2024 Red Hat, Inc.