Windows上でのMySQLビルド方法まとめ

2012/03/22追記:
 最新情報として、Visual Studio 2010 Express を用いて、MySQL 5.6 をビルドする方法について、新たなエントリを書きました。以下のリンク先の日記を参照ください。
http://d.hatena.ne.jp/sakaik/20120322/mysqlbuild_vc2010


 先日の GREE-OST で松信さんが「Windows上でのMySQLビルド」について語ってくれて、ブレークポイントを張ったりステップ実行したりと目の前で色々見せてくださったことに刺激を受けて、私も久々に Windows でのビルドにトライしてみました。以前「超極める!MySQL」という本にビルド方法が書いたものの、一応あれでも動くけどもうちょっと「ちゃんとした」やりかたのほうが良さそうなので、改めてここにまとめてみたいと思います。

目的

 自分で mysqld と mysql クライアントをビルドして、mysqldの動作をブレークポイント置いたりして確認できるようにする。
 →実環境で使うバイナリを作成することが目的ではなく、ステップ実行などで処理の流れを追えるような「学習のための」ビルド環境を作る

環境の準備

Visual Studio 起動前の作業

  • ソースの展開

 mysql-5.1.37.zip を展開して適当なところに配置(私は D:\work\mysql-5.1.37 にした)

  • configure

 コマンドプロンプトで上記ソース配置したフォルダ(D:\work\mysql-5.1.37)に移動し、win\configure.js を実行。私は以下のオプションで実施した(MYSQL_TCP_PORT については効きに疑問。。[あとで調べる])
実行すると、「done!」というダイアログが表示された。
 ここで js ファイルが他のプログラムに関連づけされてしまってうまく処理できない場合は後述する方法で設定対応が必要です。私はコレで数時間ハマりました。

win\configure.js WITH_INNOBASE_STORAGE_ENGINE WITH_ARCHIVE_STORAGE_ENGINE WITH_SKELETON_STORAGE_ENGINE WITH_PARTITION_STORAGE_ENGINE WITH_BLACKHOLE_STORAGE_ENGINE WITH_FEDERATED_STORAGE_ENGINE MYSQL_SERVER_SUFFIX=-sakaik MYSQL_TCP_PORT=3386 with_extra_charsets=complex

  • -
  • build準備

 win\build-vs8.bat を実行。他のバージョンのVisual Studio を使用している場合はそれにあったバッチを。(vs8 = Visual Studio 2005 です)

      • 「指定されたファイルが見つかりません。」と出るが気にしない(2度目の実行からは表示されない)

 sql\sql_locale.cc をテキストエディタで開き、「BOM付きの」UTF-8 にする。
秀丸エディタの場合、このファイルを開き「名前をつけて保存」する際に表示される「エンコードの種類」でUnicode(UTF-8)を指定して「BOMを付ける」にチェックを入れて保存すると良い。
 GREE-OSTでの松信さんの講演資料には「BOMなしのUTF-8」と説明されていますが、BOM付きにする必要がありますのでご注意ください。(たぶん今は正しい資料に差し替えられていると思います)

Visual Studio (VS) の起動とビルド

 MySql.sln をダブルクリックして VS を起動する。VC# か VC++ かを尋ねるダイアログが出たら迷わず VC++
 ここでは (1) mysqld のビルド (2)mysqlクライアントのビルド の順でやることにします。

  • mysqld のビルド
    • mysqldプロジェクトを右クリックして「スタートアッププロジェクト」にする
      • (べつにこのタイミングでやらなくてもいいのだけど、後でどうせやるので今のうちにしておきました)
    • mysqldプロジェクトを右クリックして「ビルド」
      • 私の環境(マシなほう)で約11分、(遅いほう)で約17分かかりました
  • mysqlクライアントのビルド
    • mysqlプロジェクトを右クリックして「ビルド」
      • 私の環境(マシなほう)では約2分かかりました


 以下のワーニングが出るが、とりあえず今回は気にしない(気にする人=ちゃんとバイナリを作成したい人=は後述する方法で対応可能っぽいです)。

warning C4819: ファイルは、現在のコード ページ (932) で表示できない文字を含んでいます。データの損失を防ぐために、ファイルを Unicode 形式で保存してください。

warning C4566: ユニバーサル文字名 '\u01B0' によって表示されている文字は、現在のコード ページ (932) で表示できません

 上のはところどころ、下のは sql_locale.cc でまとめて数百件(?)出ます。心配しないで!
 (日本語での月名や曜日名の表示に関わる処理を追いたい場合以外は関係ないので)

実行前の準備

 いよいよ mysqld を実行したいところですが、設定ファイルやデータファイルなどを用意する必要があります。私は必要な設定ファイル等は、D:\work\mysql-5.1.37\ 下に exe というフォルダを掘ってそこに集めることにしました。適宜お好みにあわせて読み替えてください。

  • 今回の作業用フォルダの作成
    • とりあえず上記の通り、ソースのフォルダ群と並んで、実行作業用の exe というフォルダを掘りました。
  • データファイルとメッセージファイルのコピー
    • win\data を作成した作業フォルダにコピー(exe\data\* になります)
    • sql\share を作成した作業フォルダにコピー(exe\share\* になります)
  • 設定ファイル(my.ini)の記述
    • 作業フォルダ下に my.ini を作成して以下ような内容を記述します(お好みに応じて)。(exe\my.ini)

[mysqld]
basedir=D:/work/mysql-5.1.37/exe
datadir=D:/work/mysql-5.1.37/exe/data
log_error=D:/work/mysql-5.1.37/exe/data/error.log
port=3386

  • 実行オプションの指定
    • mysqldプロジェクトを右クリックして、プロパティ-構成プロパティ-デバッグの画面の「コマンド引数」に以下の指定を(パスは自分の環境に合わせて)。

--defaults-file=D:/work/mysql-5.1.37/exe/my.ini

mysqld サーバ実行

 mysqld がデフォルトプロジェクト(太字)になっていることを確認して、緑の三角を押すかF5キーを押すなどしてデバッグ実行する。
 たぶんエラーになります(私はなりました)。これは unicodeの文字列を何故か内部ではcp932として処理されているために「文字数の最大長」の確認処理でエラーになってしまったもの。今回は気にしないことにするので、sql\mysqld.cc を編集して、以下の ASSERT(★印部分)をコメントアウトしてしまう。

static void test_lc_time_sz()
{
  DBUG_ENTER("test_lc_time_sz");
  for (MY_LOCALE **loc= my_locales; *loc; loc++)
  {
    uint max_month_len= 0;
    uint max_day_len = 0;
    for (const char **month= (*loc)->month_names->type_names; *month; month++)
    {
      set_if_bigger(max_month_len,
                    my_numchars_mb(&my_charset_utf8_general_ci,
                                   *month, *month + strlen(*month)));
    }
   : (略)
    if ((*loc)->max_month_name_length != max_month_len ||
        (*loc)->max_day_name_length != max_day_len)
    {
      DBUG_PRINT("Wrong max day name(or month name) length for locale:",
                 ("%s", (*loc)->name));
★      DBUG_ASSERT(0);
    }
  }
  DBUG_VOID_RETURN;
}


 再度実行すると・・・コマンドプロンプト画面が出て、消えます。my.ini で指定したデータフォルダの下に innodb 関連のファイルや error ログなどが作成されているので内容確認。

Version: '5.1.37-sakaik-debug' socket: '' port: 3386 Source distribution

 こんなのが出力されていて、立ち上がっているらしいのがわかります。

クライアントからの接続とブレイクポイントの確認

  • クライアントからの接続

 コマンドプロンプトから client\debug フォルダに移動(ここに mysqlクライアントのバイナリが作成されています)。

 mysql -uroot -P3386

 で接続すると自分がビルドしたMySQLサーバに接続されていることがわかります( 5.1.37-sakaik-debug というバージョン名になっている)。

D:\work\mysql-5.1.37\client\debug>mysql -uroot -P3386
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.1.37-sakaik-debug Source distribution

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

  • 試しに、一旦 mysqlクライアントからの接続を exit; で終了してみる
    • →VSの出力窓に「スレッド '_threadstart' (0xc24) はコード 0 (0x0) で終了しました。」と表示される。
  • ブレイクポイントの設定

 お好きなところにブレークポイントを設定する。
とりあえず mysqld.cc の static void create_new_thread(THD *thd) 関数の頭に設定してみるとか。(ソース行の左端の灰色のところをクリックすると赤い玉が付きます。これがブレークポイント
 先ほどと同様に mysql クライアントから接続すると、ここで停まります。(矢印が表示される)
 以下の3つのキーを覚えておくと便利でしょう。

F10:ステップオーバー(細かいところに入らずソース1行ずつを実行していく)
F11:ステップイン(関数呼び出しの時には呼び出し先の中にまで入って1行ずつ実行していく)
F5:実行再開(次のブレークポイントまでざざっと実行する)

その他トラブルシューティング

  • configure.js が実行できない

 他のアプリに 拡張子js が取られてしまっているとき、奪い返す必要があります。レジストリを変更することで取り返せます。

[HKEY_CLASSES_ROOT/.JS]
(既定)="JSFile"
"Content Type"="application/x-javascript"

  • ちゃんとビルドしたい

 Visual Studio 2005 の問題なのか、日本語Windows環境で動作させていると、コードページが cp932 として決めつけられている挙動をしているように見えます。色々検索したのですが設定やパラメタなどで変更する方法はなさそうで。。
 ということで、どうしても locale.cc やその他の部分を含めてきちんとビルドしたいという方は Windows の指定を変更することで、VSが期待通りにビルドしてくれるようになるようです(私自身は未確認)。
 コントロールパネル-地域と言語のオプション で開く画面の「詳細設定」タブで「Unicode対応でないプログラムの言語」を英語(米国)にします。再起動を促されるので再起動。これで英語モードで、おそらく cp932 の問題が発生せずにビルドできるようです。 ただし他の日本語アプリの多く(Becky! とかも)化けて使い物にならないので、このままの状態で普段の運用を続けるのは困難でしょう。 

謝辞

 久々に週末まるごとコレだけに費やすという楽しい経験(皮肉じゃなくて本当に!)のきっかけをくれた松信さん、グリーOSTのボスキャラのいちいさんにまず感謝です! 土日悩んでいる間いろいろ相手をしてくれたり教えてくれたりした松信さん、キムラデービーの木村さん、twitterでチャチャ入れくださった SH2 さん、うのさん、どうもありがとうございました! 一人だと飽きちゃうんですがおかげで(いい意味で)ハマりまくりました!(^^)



2009/08/14追記:キムラさんから追加情報をいただきました。http://blog.kimuradb.com/?eid=791633

そのため、当該部分をごまかすか、OSのロケールを英語にするしか、コンパイルを成功させる方法がありません。

   この言葉が欲しかった!(笑)
   warningがいっぱい出るのは仕方ないとして、それが鬱陶しい場合(これによって他の大切なエラーを見落としてしまう可能性とか)は、該当warning(C4566)を表示しないようにすることができるようです。