CentOS 7: Ruby 2.3をインストールする

CentOS 7のRubyは2.0です。この記事ではFedora 25のsrc.rpmを利用してCentOS 7にRuby 2.3をインストールします。

1 Fedora 25のsrc.rpmを使ってRuby 2.3をインストールする

  • この記事ではFedora 25のsrc.rpmを利用します。src.rpmを使わずに、自前でRubyのコードをビルドしてインストールしている場合はそちらの方が良いでしょう。
  • CentOS 7のrpmに比べてFedora 25のrpmではload, Suggests、Recommends等の新しい機能が追加されており、CentOS 7向けに変更が必要となります。
  • この記事ではSuggestsとRecommendsはRequiresに置き換えています。これらはコメントアウトしても良いかもしれません。
  • loadはSOURCESディレクトリに置かれたrpmマクロファイルを読み込みます。この記事ではloadで読み込まれるrpmマクロファイルを/usr/lib/rpm/macros.d/に一時的にコピーすることで対処します。
  • この記事ではrubygem-xxxパッケージはビルドしていません。依存関係を適切に対処すればビルドは可能ですが、ビルドの順番を割り出す必要がありいます。この記事ではsudo gem installで対処するようにします。
#!/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 動作確認

バージョンとHello, Worldは以下の通りです。

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

なお、Ruby 2.3のビルド時にRuby内部のテストが実行されています。すべてPASSしないとビルドは成功しません。