ぷろみん

プログラミング的な内容を扱ってます

C++でgRPC for Windows

必要な前提知識

ライブラリのビルド

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ファイルを書き換えてビルドするとそのまま反映されるので便利です。