Windowsでmruby-http2を動かした
こんにちは、kindle fireでYouTubeで車モノ(knight riderやワイルドスピード)の映像を中毒患者の様に見まくる長男からタブレットを修理に出したといって、隔離してしばらくたち、今のところ、長男は隙を見て奥さんがおもに使っているChromebookでYouTubeを見ています。@kjunichiです。
mruby-http2 for win32
Xeonで昨年末久々にPC組んだ流れで、Windowsでの開発環境をあれこれ試している。 そんな中、今回はmrubyでhttp2をしゃべることが可能になるmrbgemのmruby-http2をWindowsで動かしてみた。
事前に必要なモノ
- openssl
- libevent
- nghttp2
- zlib
zlib以外は、
- Windows 10でMSVCでnghttp2のサンプルを動かす
の記事に少し書いてます。
ヘッダ無い問題
以下に挙げるヘッダがWindowsでは用意されていない模様。
- pwd.h
- unistd.h
- sys/socket.h
- sys/wait.h
- sys/resource.h
- sys/queue.h
- netdb.h
- netinet/in.h
- netinet/tcp.h
- poll.h
- signal.h
- pthread.h
- err.h
定数無い問題
mruby-http2をWindowsでビルドする際、以下の定数が未定義でエラーとなった。
- F_GETFL
- O_NONBLOCK
- SHUT_WR
型や構造体無い問題
mruby-http2をWindowsでビルドする際、以下の型が未定義でエラーとなった。
- ssize_t
- uid_t
- nfds_t
- struct pollfd
関数無い問題
mruby-http2をWindowsでビルドする際、以下の関数が未定義でエラーとなった。
- pipe
- fcntl
- alloca
- gmtime_r
- fork
- TAILQ_FOREACH
- kill
- daemon
pipe
_pipeなる関数が用意されており、これを用いることで対応出来た。 ただし、引数がUNIXのpipeと異なり3つ必要。
#ifndef _WIN32 rv = pipe(pipefd); #else rv = _pipe(pipefd, 65535, _O_BINARY); #endif
作成するパイプのバッファサイズの指定は決め打ちで暫定的に対処した。
fcntl
mruby-http2ではfcntlでソケットをノンブロッキング指定にする為に用いられていた。 Windowsではこのような用途にはioctlsocketを用いることで対応出来た。
#ifndef _WIN32 while ((flags = fcntl(fd, F_GETFL, 0)) == -1 && errno == EINTR) ; if (flags == -1) { mrb_raisef(mrb, E_RUNTIME_ERROR, "fcntl: %S", mrb_str_new_cstr(mrb, strerror(errno))); } while ((rv = fcntl(fd, F_SETFL, flags | O_NONBLOCK)) == -1 && errno == EINTR) ; if (rv == -1) { mrb_raisef(mrb, E_RUNTIME_ERROR, "fcntl: %S", mrb_str_new_cstr(mrb, strerror(errno))); } #else flags = 1; rv = ioctlsocket(fd, FIONBIO, &flags); if (rv != NO_ERROR) { mrb_raisef(mrb, E_RUNTIME_ERROR, "ioctlsocket: %S", mrb_str_new_cstr(mrb, "error")); // TODO } #endif
シグナルがWindowsでないと勘違いしてた問題
シグナル周りは一旦全部コメントアウトして無視することにして対応した。
- struct sigaction
- sigaction
関数自体を無効にしたものたち
単純にWindowsで動かすにには不要な機能はスパッと諦めて作業した。 その結果、以下の関数は、戻るだけだったり、固定値を返すだけにしたり、関数そのものをコメントアウトした。
- mrb_http2_get_uid
- mrb_http2_config_get_worker
- tune_rlimit
成果物
mrubyのbuild_config.rbに以下を記述することでwindowsでビルド可能なmruby-http2が利用できるハズ。
conf.gem :github => 'kjunichi/mruby-http2', :branch => 'support-for-win32'
まとめ
クライアントは、これらの問題を解決することで、動かせた。 サーバー側は、さらに対応が必要だった。これはまた、別の記事にするつもり。
ちなみに、mruby-cliでバイナリを作る場合は、今回のMSVCの対応とは別にmingw-w64での対応が必要となる。 もし、dockerを使わず直接Windows上でmruby-cliでワンバイナリをMSVCで作製すれば、今回のmrbgemが使えるかもしれません。
関連記事
- http2 ハッカソン #5に行ってきた
- libtrusterdでHTTP/2でphpを動かして分かったことのその後 #知見
- Windows 10でMSVCでnghttp2のサンプルを動かす
- Windows(MSVC)でmrubyからGPU対応のTensorflowを動かせた
- WindowsでDLLを作ろうとしてmrb_context_runの歴史を調べた