MSYS対応のmake v3.82を作ってみた

暫くupdateがなかったのは、ちょっと忙しかっただけではなく、make v3.82をwindows(MinGW/MSYS)上で動かそうとすると、バグだらけで泣いていたからです。自分のソースなら如何様にも弄れますが、他人様のソースなので、どのようにあるべきか?を考えてると、中々先に進まない…
ともあれ、取りあえず動く物が出来たので、ご紹介しておきます。ただし、こいつも、gccに対してパラレルmakeを実施するとハングするので、使うのは趣味の世界です。テストは問題なく通るんですけどね〜何故か。しかし、ここまで出来が微妙だと、MSYSライブラリだけではなく、make自体にも何か不具合が潜んでそうで、ちょっと怖いですよ、正直言って。

※2013/7/15追記/修正: バッチを使用したとき、firestorageからパッチを正しくダウンロードできないことが判明しましたので、バッチを修正しました(直リンクを使っていたのですが、そのURLは永続的ではないことが分かりました)。

開発環境

  • MinGWインストーラーでC, C++, MSYS Basic System, MinGW Developer ToolKitをインストール。カタログファイルは2013/7/9時点の最新を使用。
  • MSYS Shell上でコンパイルを実施(MinGW Shellのショートカットのプロパティを開き、リンク先を「C:\MinGW\msys\1.0\msys.bat」から「C:\MinGW\msys\1.0\msys.bat MSYS」に変えればOK。MinGW Shellとは別のショートカットを用意した方が良いかも)
  • /usr/local/binに独自でコンパイルしたgcc、autoconf、automakeなどを格納している場合、それが実行されない様にしてください。MSYS用のバイナリーは/usr/bin(/bin)配下のコンパイラ等を使用しないと、正しく作成されませんので、注意してください。

必要要件

下記のパッケージが必要です。いずれもmingw-getで入手可能です。
下の方で紹介しているバッチシェルを利用する場合、バッチ内で取得するため、特に個別に用意する必要はありません。

  • msysCORE-bin
  • msys-libintl-dll
  • msys-libiconv-dll
  • msys-binutils-bin
  • msys-gcc-bin
  • msys-w32api-dev
  • msysCORE-dev
  • msys-autoconf-bin
  • msys-automake-bin
  • msys-libiconv-bin
  • msys-libiconv-dev
  • msys-gettext-bin
  • msys-gettext-dev
  • msys-libgettextpo-dll
  • msys-texinfo-bin

make v3.82の入手

GNU Makeのページからmake-3.82.tar.bz2をダウンロードしてください。
下の方で紹介しているバッチシェルを利用する場合、バッチ内で取得するため、特に個別に用意する必要はありません。

make v3.82用パッチの準備

次の2つのパッチをダウンロードしてください。
下の方で紹介しているバッチシェルを利用する場合、バッチ内で取得するため、特に個別に用意する必要はありません。

diff-make-3.82-1-msys.patchは、本来は修正すべきではないバイナリーテストに対するパッチです。MinGW/MSYSは「/」に対して「/usr」をmountしているため、バイナリーテスト(functions/realpath)で意図しない結果が得られてしまい、エラーとなります。このエラーを防ぐためのパッチです。
diff-make-3.82-1.patchが、make v3.82全体の問題を修正するパッチです。ただし、ソースをすべて見直しした訳ではないので、バグを取り切れていない可能性大です。暫定パッチと思ってください。

ソースの展開とパッチ適用

$ tar -xf make-3.82.tar.bz2 -C 任意のディレクトリ
$ cd 上記のディレクトリ
$ autoreconf -fvi
$ patch -p1 < パッチの格納ディレクトリ/diff-make-3.82-1-msys.patch
$ patch -p1 < パッチの格納ディレクトリ/diff-make-3.82-1.patch

上記のautoreconfは、ソース内のコンフィグ情報をMSYS用に書き換えるコマンドです。これを実行することにより、「i686-pc-msys」と言う開発環境を認識するようになります。

Makefileの生成

次のコマンドを実行してください。問題がなければMakefile(とmakeに必要なファイル)が生成されます。

$ mkdir -p 任意のディレクトリその2
$ cd 上記のディレクトリ
$ ソースを展開したディレクトリ/configure --prefix=/usr \
 --with-libiconv-prefix=/usr --with-libintl-prefix=/usr \
 CPPFLAGS="-D__CYGWIN__" \
 CFLAGS="-O3 -fno-unit-at-a-time -s -march=i386 -mtune=i686" \
 CXXFLAGS="-O3 -fno-unit-at-a-time -s -march=i386 -mtune=i686" \
 LDFLAGS="-Wl,--enable-auto-import"

コンパイルとテスト

次のコマンドを実行してください。make checkでuptimeが見つからないとか、check-loadavgでエラーが出たりしますが、無視してください。

$ make
$ make check

makeのインストール

ここまでで、特に問題がなければ、次のコマンドを実行し、makeをインストールしてください。make -vで「GNU Make 3.82」と「Built for i686-pc-msys」が表示されていれば完成です。

$ make install-strip
$ make -v
GNU Make 3.82
Built for i686-pc-msys
Copyright (C) 2010  Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

パッケージ準備からmakeのインストールまで行うバッチシェル

gccコンパイルよりはマシですが、細々した物が面倒な方のためにバッチを用意しました。build-make-3.82-1-msys.shをダウンロードして任意のディレクトリに格納してください。
次のように実行するだけで、上記のことをすべて自動で実行します。

$ ./build-make-3.82-1-msys.sh
バッチシェルの補足説明
カレントディレクトリ/build.log
バッチシェル実行時のメッセージ(エラーも含む)を記録しています。問題が発生したとき、このファイルを参照してください。
カレントディレクトリ/diff-make-3.82-1-msys.patch
カレントディレクトリ/diff-make-3.82-1.patch
カレントディレクトリ/make-3.82.tar.bz2
ダウンロードしたソースおよびパッチが格納されます。
カレントディレクトリ/make-3.82-1-msys.bin.tar.xz
コンパイル済みのバイナリがtar.xz形式で格納されます。このファイルが残っていれば、開発環境がなくなっても「tar -xf make-3.82-1-msys.bin.tar.xz -C /」を実行すれば、make v3.82が使用可能になります。
/usr/local/src/make-3.82/
ソース展開時に一時的に使用します。なお、バッチ実行時に存在していた場合、削除されますので注意してください。
/usr/local/src/make-3.82-1/
パッチ等を適用したソース環境です。なお、バッチ実行時に存在していた場合、削除されますので注意してください。
/usr/local/src/make_alt/
コンパイル済みのバイナリのバックアップを格納しています。特に問題なければ、バッチ実行後に削除しても構いません。なお、バッチ実行時に存在していた場合、削除されますので注意してください。
/usr/local/src/make_build/
コンパイル環境です。特に問題なければ、バッチ実行後に削除しても構いません。なお、バッチ実行時に存在していた場合、削除されますので注意してください。
バッチシェルの補足説明 その2(自虐ネタ)
  • サクッと作った物なのでバグがあったらゴメンナサイ。ダウンロード(wget)で失敗している場合は、いったん、そのファイルを消してから再実行した方が良いかも。
  • wgetでリトライしていない・エラーを無視しているのは何故?…借りているオンラインストレージ(firestorage)の応答が変だからです。965バイトしかないのに、「返信したデータは966バイトだよ」とかおかしな事を応答するせいでwgetが正常に動きません(T-T)
  • 英語が変。すみません、使えない子なんです…
  • バッチが読みにくい。orz