CentOS-7環境で32bit版のWINEをビルドしてみる

枠が空いていたので、[Linux Advent Calendar 2022](https://qiita.com/advent-calendar/2022/linux) 6日目の記事を書いてみます。今日はCentOS-7環境で32bit版のWINEをビルドするという小ネタを紹介してみます。

## 32bit版のWINE

64bitプロセッサが一般的になり、今では通常のPCで32bitプロセッサを使っているマシンを探すのが難しいほどになっています。そのため、CentOSなどのLinuxディストリビューションでも32bit向けにビルドされたパッケージで提供されないものがちらほら出てきています。

たしかに、現代ではわざわざ32bitなパッケージを使用する必要はありません。が、Windowsアプリ(PEバイナリ)をLinux上で動かすことができる、[WINE](https://ja.wikipedia.org/wiki/Wine)を使う場合はちょっと事情がことなります。

```sh
$ file sample.exe
sample.exe: PE32 executable (console) Intel 80386 (stripped to external PDB), for MS Windows
$
$ yum info wine.x86_64
...
Name        : wine
Arch        : x86_64
Version     : 4.0.4
Release     : 1.el7
Size        : 0.0
Repo        : installed
From repo   : epel
Summary     : A compatibility layer for windows applications
URL         : https://www.winehq.org/
License     : LGPLv2+
Description : Wine as a compatibility layer for UNIX to run Windows applications. This
            : package includes a program loader, which allows unmodified Windows
            : 3.x/9x/NT binaries to run on x86 and x86_64 Unixes. Wine can use native system
            : .dll files if they are available.
            :
            : In Fedora wine is a meta-package which will install everything needed for wine
            : to work smoothly. Smaller setups can be achieved by installing some of the
            : wine-* sub packages.
```

CentOS-7環境でもパッケージでWINEが提供されていますが、こちらは64bit版で提供されており、32bit向けのPEバイナリを実行しようとすると"Bas EXE format"というエラーになってしまいます。

```sh
$ # 64bit版のWINEでは32bit向けのPEバイナリを実行できない…。
$ file sample.exe
sample.exe: PE32 executable (console) Intel 80386 (stripped to external PDB), for MS Windows
$
$ /usr/bin/wine sample.exe
...
wine: Bad EXE format for Z:\home\centos\sample.exe.
```

## 32bit版のWINEパッケージ

32bit版のWINEパッケージをインストールすれば解決…なのですが、肝心のパッケージが提供されていません。 `epel-release` にも存在していないようです。前述したように現在では積極的に32bit向けのビルドを利用する必要はありませんが、今回のような「32bit版がないとダメ」なケースに時々遭遇します。

特にWindows PEバイナリであれば、これまでのソフトウェア資産という点で32bit版のバイナリしかない、というケースもままあることでしょう。

```sh
$ yum search wine | grep ^wine\\.
wine.x86_64 : A compatibility layer for windows applications
```

## WINEを32bit向けにビルドしよう

というわけで、CentOS-7上で32bit向けのWINEをビルドしてみます。単にビルドに必要なパッケージをインストールしてビルドする、というだけですが、この記事にメモとして残しておくと誰かの助けになるかもと考えています。

手順としては、32bit向けのビルドツール・ライブラリをインストールしたのち、WINEをビルドするという流れになります。

### ビルドに必要なパッケージ

まずはビルドに必要なパッケージをインストールします。数は多いですが以下のコマンドを実行するだけです。

```sh
$ sudo yum groupinstall -y 'Development Tools'
$ sudo yum install -y \
    samba-winbind-clients \
    libjpeg-turbo-devel \
    libtiff-devel \
    freetype-devel \
    glibc-devel.{i686,x86_64} \
    libgcc.{i686,x86_64} \
    libX11-devel.{i686,x86_64} \
    freetype-devel.{i686,x86_64} \
    gnutls-devel.{i686,x86_64} \
    libxml2-devel.{i686,x86_64} \
    libjpeg-turbo-devel.{i686,x86_64} \
    libpng-devel.{i686,x86_64} \
    libXrender-devel.{i686,x86_64} \
    alsa-lib-devel.{i686,x86_64} \
    flex \
    bison
$
$ # 32bit版WINEをビルドするには以下のパッケージも必要。
$ sudo yum install -y \
    glibc-devel \
    libstdc++-devel \
    icoutils \
    openal-soft-devel \
    prelink \
    gstreamer-plugins-base-devel \
    gstreamer-devel \
    ImageMagick-devel \
    fontpackages-devel \
    libv4l-devel \
    gsm-devel \
    giflib-devel \
    libXxf86dga-devel \
    mesa-libOSMesa-devel \
    isdn4k-utils-devel \
    libgphoto2-devel \
    fontforge \
    libusb-devel \
    lcms2-devel \
    audiofile-devel \
    glibc-devel.i686 \
    dbus-devel.i686 \
    freetype-devel.i686 \
    pulseaudio-libs-devel.i686 \
    libX11-devel.i686 \
    mesa-libGLU-devel.i686 \
    libICE-devel.i686 \
    libXext-devel.i686 \
    libXcursor-devel.i686 \
    libXi-devel.i686 \
    libXxf86vm-devel.i686 \
    libXrender-devel.i686 \
    libXinerama-devel.i686 \
    libXcomposite-devel.i686 \
    libXrandr-devel.i686 \
    mesa-libGL-devel.i686 \
    mesa-libOSMesa-devel.i686 \
    libxml2-devel.i686 \
    libxslt-devel.i686 \
    zlib-devel.i686 \
    gnutls-devel.i686 \
    ncurses-devel.i686 \
    sane-backends-devel.i686 \
    libv4l-devel.i686 \
    libgphoto2-devel.i686 \
    libexif-devel.i686 \
    lcms2-devel.i686 \
    gettext-devel.i686 \
    isdn4k-utils-devel.i686 \
    cups-devel.i686 \
    fontconfig-devel.i686 \
    gsm-devel.i686 \
    libjpeg-turbo-devel.i686 \
    pkgconfig.i686 \
    libtiff-devel.i686 \
    unixODBC.i686 \
    openldap-devel.i686 \
    alsa-lib-devel.i686 \
    audiofile-devel.i686 \
    freeglut-devel.i686 \
    giflib-devel.i686 \
    gstreamer-devel.i686 \
    gstreamer-plugins-base-devel.i686 \
    libXmu-devel.i686 \
    libXxf86dga-devel.i686 \
    libieee1284-devel.i686 \
    libpng-devel.i686 \
    librsvg2-devel.i686 \
    libstdc++-devel.i686 \
    libusb-devel.i686 \
    unixODBC-devel.i686 \
    qt-devel.i686
```

### WINEのビルド

あとはWINEをビルドするだけです。AWS EC2の `t2.xlarge` 環境であれば、20分ほどでビルドが完了します。

```sh
$ curl -s -O http://dl.winehq.org/wine/source/3.x/wine-3.13.tar.xz
$ tar Jxvf wine-3.13.tar.xz
$ cd wine-3.13
$ mkdir -p wine32
$ cd wine32
$ PKG_CONFIG_PATH=/usr/lib/pkgconfig ../configure --prefix=/opt/wine-3.13/win32
$ make -j `cat /proc/cpuinfo | grep processor | wc -l`
```

### 32bit PEバイナリを動かしてみる

ビルドが完了したので、さっそく32bitのPEバイナリを実行してみます。

```sh
$ # WINEのバイナリは32bit向けになっている。
$ file /opt/wine-3.13/win32/bin/wine
/opt/wine-3.13/win32/bin/wine: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=913bfb791bc902d4a634101aae1b543b23ddd910, not stripped
$
$ cat hello.c
#include <stdio.h>

int main(int argc, char *argv[])
{
        puts("hello,world.");
        return 0;
}
```

問題なくEXEが実行できました。

```sh
$ # WINEで32bit PEバイナリを実行する。
$ /opt/wine-3.13/win32/bin/wine hello.exe
hello,world.
```

### その他

32bit PEバイナリが実行できたのですが、WINEが作成する `~/.wine` ディレクトリは32/64bit版のWINEで共存できないようです。

```sh
$ /opt/wine-3.13/win32/bin/wine sample.exe
wine: '/root/.wine' is a 64-bit installation, it cannot be used with a 32-bit wineserver.
```

この場合は、単に `~/.wine` ディレクトリを削除してWINEを実行し直すことで問題を解消できます。

```sh
$ rm -r ~/.wine
$ /opt/wine-3.13/win32/bin/wine hello.exe
...
hello,world.
```

## まとめ

CentOS-7環境で32bit版のWINEをビルドする手順を紹介しました。32bit版WINEはパッケージでの提供は行われていないものの、(ひと手間かかりますが)自前でビルドすることで対応できます。古いWindows PEバイナリを動かしたいような場合にこの記事がお役に立てばと思います。