MSYS2 MinGW32/64でRuby 2.2.4のビルド


## はじめに

MSYS2の`pacman`で入るRubyのバージョンは2.2.3なので、2.2系最新の2.2.4をビルドすることにした。
2.2.3の`PKGBUILD`を参考にしたら思いの外ハマったのでメモを残す。

## `makepkg-mingw`用のファイル群

### `PKGBUILD`

`make`のままだと`ld`がエラー吐いてコケることとなったので、`mingw32-make`または`mingw64-make`を利用するようにした。
`mingw32`だとか`mingw64`といった値が変数に定義されていないか`/etc/makepkg_mingw32.conf`の中身を探してみたがなかったので、やむを得ず`prepare()`内で判定を行わせているところがダサい。
パッチは`mingw-w64-ruby`のパッチをそのまま利用するのと、[ruby-listへの投稿](http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/50224)と同じ問題が発生したのでメールに添付されたパッチを拝借して`0004-fake-srcdir.patch`として利用するようにした。
さらに私の環境ではなぜか`wget`してきた各パッチのmd5sum値が変わっていた（中身を確認したが特に問題はないように感じた）ため値を変更している。
[Alexpux/MINGW-packages](https://github.com/Alexpux/MINGW-packages)をcloneすればmd5sumの値もきっと元のものと同じになるのだろうが、パッチファイルだけ欲しいのに全てのファイルを手元にcloneするのは躊躇われたので素直に`md5sums`の値を書き換えて対応している。
（と書いていて`SKIP`にしてもよかったのではないかと感じてきたが）

```bash:PKGBUILD
# Maintainer: Koutarou Tanaka <from.kyushu.island@gmail.com>

_make="make"
_realname=ruby
pkgbase=mingw-w64-${_realname}
pkgname="${MINGW_PACKAGE_PREFIX}-${_realname}"
pkgver=2.2.4
pkgrel=1
pkgdesc="An object-oriented language for quick and easy programming (mingw-w64)"
arch=('any')
url="http://www.ruby-lang.org/en"
license=("BSD, custom")
makedepends=("${MINGW_PACKAGE_PREFIX}-gcc" "${MINGW_PACKAGE_PREFIX}-pkg-config")
depends=("${MINGW_PACKAGE_PREFIX}-gcc-libs"
         "${MINGW_PACKAGE_PREFIX}-gdbm"
         "${MINGW_PACKAGE_PREFIX}-libyaml"
         "${MINGW_PACKAGE_PREFIX}-libffi"
         "${MINGW_PACKAGE_PREFIX}-ncurses"
         "${MINGW_PACKAGE_PREFIX}-openssl"
         "${MINGW_PACKAGE_PREFIX}-tk")
options=('staticlibs' 'strip')
source=("http://cache.ruby-lang.org/pub/ruby/${pkgver%.*}/${_realname}-${pkgver}.tar.bz2"
        0001-mingw-w64-time-functions.patch
        0002-use-gnu-printf.patch
        0003-fix-check-types.patch
        0004-fake-srcdir.patch)
md5sums=('c3d65f6d2ebe90dda81a37885ea244f5'
         '4256c35613e6dc15c164015ae8977d4a'
         '6d54f98b9e3a0d0077e9348dc7f69482'
         'f9170e918fa7b7118d241d238d7a0e3b'
         '17f203452e2340bb2be4f802db240c59')

prepare() {
  case "${MINGW_CHOST}" in
    i686-w64-mingw32 ) _make="mingw32-make";;
    x86_64-w64-mingw32 ) _make="mingw64-make";;
  esac

  cd ${srcdir}/${_realname}-${pkgver}
  patch -p1 -i ${srcdir}/0001-mingw-w64-time-functions.patch
  patch -p1 -i ${srcdir}/0002-use-gnu-printf.patch
  patch -p1 -i ${srcdir}/0003-fix-check-types.patch
  patch -p1 -i ${srcdir}/0004-fake-srcdir.patch

  autoreconf -fi
}

build() {

  local FFI_INC=$(pkg-config --cflags libffi)
  CPPFLAGS+=" -DFD_SETSIZE=2048 ${FFI_INC} -I${MINGW_PREFIX}/include/ncurses"
  CFLAGS+=" -I${MINGW_PREFIX}/include/ncurses ${FFI_INC}"
  CXXFLAGS+=" -I${MINGW_PREFIX}/include/ncurses ${FFI_INC}"

  [[ -d "${srcdir}/build-${MINGW_CHOST}" ]] && rm -rf "${srcdir}/build-${MINGW_CHOST}"
  mkdir -p "${srcdir}/build-${MINGW_CHOST}" && cd "${srcdir}/build-${MINGW_CHOST}"
  ../${_realname}-${pkgver}/configure \
    --prefix=${MINGW_PREFIX} \
    --build=${MINGW_CHOST} \
    --host=${MINGW_CHOST} \
    --target=${MINGW_CHOST}

  ${_make}
}

package() {
  cd "${srcdir}/build-${MINGW_CHOST}"
  ${_make} -f GNUMakefile DESTDIR="${pkgdir}" install-nodoc
  for script in {erb,gem,irb,rake,rdoc,ri}; do
    install ${srcdir}/ruby-${pkgver}/bin/${script} \
      ${pkgdir}${MINGW_PREFIX}/bin/
  done
}
```

### `template/fake.rb.in`へのパッチ

前述の通り[ruby-listへの投稿](http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/50224)と同じ問題が発生したのでメールに添付されたパッチを拝借している。
あくまで暫定対応版のようであるが、試しにパッチを当てて試したところ正常にビルド出来たのでひとまずこのまま利用することとした。

```diff:0004-fake-srcdir.patch
diff --git a/template/fake.rb.in b/template/fake.rb.in
index 6f5de50..69d97cc 100644
--- a/template/fake.rb.in
+++ b/template/fake.rb.in
@@ -17,12 +17,13 @@ class Object
   RUBY_RELEASE_DATE = "@RUBY_RELEASE_DATE@"
   RUBY_DESCRIPTION = "ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}]"
 end
-builddir = File.dirname(__FILE__)
-top_srcdir = "@abs_top_srcdir@"
+builddir = File.dirname(File.expand_path(__FILE__))
+srcdir = "@srcdir@"
 if /mingw/ =~ RUBY_PLATFORM
   # convert MSYS path to Windows path
-  top_srcdir.sub!(/\A\/([a-z])\//, '\\1:/')
+  srcdir.sub!(/\A\/([a-z])\//, '\\1:/')
 end
-$:.unshift(File.expand_path(builddir))
+top_srcdir = File.realpath(srcdir, builddir)
+$:.unshift(builddir)
 fake = File.join(top_srcdir, "tool/fake.rb")
 eval(File.read(fake), nil, fake)
```