CentOS 7: Install Ruby 2.3

CentOS 7's ruby version is 2.0. This article will describe installing Ruby 2.3 with using Fedora 25's src.rpm.

1 Install Ruby 2.3 with using Fedora 25's src.rpm

  • This article uses Fedora 25's src.rpm. If you already have built and installed ruby 2.3 without using src.rpm, you do not have to use this article's way.
  • Fedora 25's rpm have some new features like load, Suggests and Recommends. You need to change these for CentOS 7's rpm.
  • This article changes Suggest and Recommends to Requires. Deleting these may be alright.
  • The load feature will load rpm macro file which are in SOURCES directory. This article will copy rpm macro file to /usr/lib/rpm/macros.d.
  • This article does not build rubygem-xxx packages. You can build rubygem-xxx with using Fedora 25's src.rpm but you have to check dependencies order. You can use "sudo gem install" instead of rubygem-xxx package.
#!/bin/sh

set -e

FEDORA25=https://dl.fedoraproject.org/pub/fedora/linux/releases/25
FEDORA25_PACKAGES_R=${FEDORA25}/Everything/source/tree/Packages/r

# Fedora 25's ruby version will be changed. ruby and rubypick package
# must be installed together.
RUBY_SRPM="
ruby-2.3.1-58.fc25.src.rpm
rubypick-1.1.1-5.fc24.src.rpm
"

RUBY_RPMS_DIR=$(mktemp -d -t centos-ruby.sh.XXXXXX)
trap 'rm -rf ${RUBY_RPMS_DIR}* 2>/dev/null' 0

rpmbuild_install_srpm()
{
  wget -q "${FEDORA25_PACKAGES_R}/${1}"
  sudo yum-builddep -y "${1}"
  rpm -i "${1}"
  rm -f "${1}"
}

rpmbuild_convert_unknown_tag()
{
  sed -e 's/^Suggests:\(.*\)/Requires:\1/g' \
      -e 's/^Recommends:\(.*\)/Requires:\1/g' \
      -i SPECS/*.spec
}

rpmbuild_load_macro()
{
  local macro macros source sources
  macros=""
  sources=$(grep '^%{?load:%{.*}}' SPECS/*.spec | \
               sed -e 's/^%{?load:%{\(.*\)}}/\1/g')
  for source in ${sources}; do
    macro=$(grep -i "^${source}" SPECS/*.spec | \
               awk -F':' '{ print $2 }' | sed -e 's/ //g')
    [ -f /usr/lib/rpm/macros.d/"${macro}" ] && continue
    macros="${macros} ${macro}"
  done

  for macro in ${macros}; do
    sudo cp SOURCES/"${macro}" /usr/lib/rpm/macros.d/
    printf "%s" "${macro} "
  done
}

rpmbuild_unload_macro()
{
  [ -z "${1}" ] && return
  local macro
  for macro in "$@"; do
    sudo rm -f /usr/lib/rpm/macros.d/"${macro}"
  done
}

rpmbuild_build()
{
  local macros curdir
  curdir=${PWD}
  cd ~/rpmbuild
  rpmbuild_convert_unknown_tag
  macros=$(rpmbuild_load_macro)
  rpmbuild -ba --define 'with_rubypick 1' SPECS/*.spec
  cp -a RPMS/* "${RUBY_RPMS_DIR}"/
  rpmbuild_unload_macro "${macros}"
  cd "${curdir}"
  rm -rf ~/rpmbuild
}

rpmbuild_install()
{
  local pkgs
  pkgs=$(find "${RUBY_RPMS_DIR}"/ -type f)
  # shellcheck disable=SC2086
  sudo yum localinstall -y ${pkgs} && rm -f ${pkgs}
}

ruby_install()
{
  local pkg
  for pkg in "$@"; do
    rpmbuild_install_srpm "${pkg}"
    rpmbuild_build
  done
  rpmbuild_install
}

ruby_main()
{
  # CentOS 7's ruby will cause build error of Fedora 25's ruby.
  sudo yum remove -y ruby
  sudo yum install -y rpmdevtools yum-utils
  # shellcheck disable=SC2086
  ruby_install ${RUBY_SRPM}
}

ruby_main

2 Execution result

Ruby version and "Hello, World" are the following.

$ ruby -v
ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-linux]
$ cat <<EOF | ruby
print "Hello, World\n"
EOF
Hello, World

And Ruby's test has been already done when building ruby src.rpm. if test is failed, building Ruby's package will be failed.