C++でgRPC for Windows
必要な前提知識
- gRPC
- Protoファイルとそのコンパイル
ライブラリのビルド
gRPCはビルドパスが複雑な上、公式のWindows対応が少し弱いため試すだけで一苦労になりがちです。
単にやってみたいだけなら安定して色々できるGoを使うことをお勧めします。Windowsでも簡単です。
これもBazelがWindowsで安定に動作するようになれば、そっちに移行すべきだと思います。
現状ではgRPCの単純なビルドでも失敗するので採用し辛いです。
ここで利用するのはvcpkgです。
vcpkgの最大の利点はMicrosoftが管理していることです。これでWindowsのツールチェインの取得を失敗するようなことは限りなく少なくなるでしょう。
私はいつもGit for WindowsというBash付きの環境を導入するのですが、vcpkgはportable gitを利用しているようなので、それに合わせた方が環境を汚さないかもしれません。
git clone https://github.com/Microsoft/vcpkg cd vcpkg
Windows環境の場合、コマンドプロンプトかpowershellで実行しないと失敗する時があるので注意。 後、Visual Studioの英語の言語パックがないと失敗する。
bootstrap-vcpkg.bat
これでvcpkg.exeがビルドされる。
vcpkg.exe install grpc
これでx86版のライブラリがビルドされます。
ビルドは内部的にはCMakeが使われているので、ライブラリの全ての機能を使うためにはCMakeを使う必要があります。
手動
結局はパス問題なので、パスを好きな手段で繋げることでCMakeを使わずにビルドすることもできます。 vcpkgは親切にprotobufferのコンパイルと同時にProtoファイルのコンパイラであるprotoc.exeもビルドしてくれています。
その配置先である以下のバイナリを利用してProtoファイルから.pb.ccと.pb.hを生成します。 vcpkg/installed/x86-windows/tools/protobuf/protoc.exe
protocの引数については今回のテーマではないので以下のリンク等を参考にしてください。
protocプラグインの書き方 - Qiita
grpc/CMakeLists.txt at master · grpc/grpc · GitHub
gRPCのファイル生成にはプラグインが必要です。プラグインのパスは以下です。
vcpkg/installed/x86-windows/tools/grpc/grpc_cpp_plugin.exe
上記パスを引数に含めたprotocの実行によりProtoファイルから.grpc.pb.ccと.grpc.pb.hが生成されます。 これでファイル生成作業は終了です。
ビルドするには以下のパスを通してください。
vcpkg/installed/x86-windows/debug/lib
vcpkg/installed/x86-windows/include
実行環境には以下のパスを通してください。
vcpkg/installed/x86-windows/debug/bin
後は普通にビルドできます。
CMake
vcpkgは各ビルドしたライブラリをパッケージ化してくれます。 ただ、そのままではパッケージを見つけることができないのでCMake実行時にパッケージを見つけてくれるスクリプトを読み込ませます。
詳細を知りたい方は以下を読んでください。
vcpkg/integration.md at master · Microsoft/vcpkg · GitHub
方法としてはcmakeの実行時にvcpkg.cmakeのパスを渡すだけです。
cmake .-DCMAKE_TOOLCHAIN_FILE=C:\vcpkg\scripts\buildsystems\vcpkg.cmake
上記によりfind_packageによりinstallしたライブラリが見つかるようになります。
ただ、見つかるパッケージについては
vcpkg/installed/x86-windows/share/gRPCTargets.cmake
等を読む必要があり不便に感じます。
install終了時に
The package grpc:x86-windows provides CMake targets:
find_package(gRPC CONFIG REQUIRED) # Note: 8 target(s) were omitted. target_link_libraries(main PRIVATE gRPC::gpr gRPC::grpc gRPC::grpc++ gRPC::grpc_cronet)
等とは言ってくれているのですが。
protoファイルからCMakeで.pb.ccと.pb.hの生成を行うには以下のようにします。
find_package(protobuf REQUIRED) protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS foo.proto)
grpcの方のファイル生成サポートはgRPC::grpc_cpp_pluginだけなので下記のようにadd_custom_commandでコマンドを走らせる必要があります。
https://github.com/grpc/grpc/blob/master/examples/cpp/helloworld/CMakeLists.txt
後は各出力を自身のプロジェクトに組み込みビルドするだけです。 Protoファイルを書き換えてビルドするとそのまま反映されるので便利です。