C++ を用いて grpc を実装したい人生だった。【CMakeを使ったクライアント・サーバのビルド】

**@kenmaro**です。
普段は主に**秘密計算、準同型暗号などの記事について投稿しています**。
秘密計算に関連するまとめの記事に関しては以下をご覧ください。

> - [最先端の秘密計算技術、格子暗号スタディロードマップを公開！！（エンジニア、リサーチャー必読）](https://qiita.com/kenmaro/items/f2d4fb84833c308a4d29)
-  [秘密計算エンジニアを始めて３年が経った。（ついに機械学習モデルの暗号状態での学習について言及します。）](https://qiita.com/kenmaro/items/a1d90a074d552b7bf886)

## 概要
今回は、準同型暗号の話ではなく、
**grpc について自分の知っていることを全て書いていきたいと思います。**

grpc は、ご存じの通りGoogle が Clound Native Computing Foundation

https://www.cncf.io/

を通じてgraduate programe （OSSとして開発され、特に有用性が認められたもの）として認定されたOSSのうちの一つです。
この卒業生としてこれ以外に有名なものといえば、皆んな大好き kubernetes もあります。


grpc は、protobuf という通信用に定義されたクラスを proto ファイルと呼ばれる
定義ファイルで書くことで、通信に必要なprotobuf クラスを様々なコンピュータ言語で呼び出すことを可能にします。

したがって、同じproto ファイルを共有することで、

クライアントはPythonで実装し
サーバサイドはGo言語で実装する

などという合わせ技を比較的簡単に実装することが可能になります。


## 今回の内容

長らく私はPythonを主に使いgrpcを実装してきましたが、
ここ半年くらいはC++に大部分をシフトして実装を行うことが多いです。


### 公式チュートリアルの次に実行したいチュートリアルが存在しないように見える

今回は、このgrpcについて、C++を用いて実装する時に必要となるいくつかのことについてまとめていければと思います。
環境構築や、簡単な Hello, World 的なものは公式のドキュメントを使うことで実行できるかと思います。

しかしながら、実際にサービスをgrpcで組もうとした時、どうしても公式ドキュメントでは説明不足というか、なかなか欲しい情報を見つけるのに苦労しました。（単に私の力不足だった説もありますが。。）

というわけで、私が主にC++でgrpcを実装するときに使う流れを一度まとめていきます。
C++を用いてgrpcを実装しようと考えている方は、これらを読むことで、一通りC++を用いて
クライアントサイド、サーバサイドの実装のヒントを得ることができると考えています。


### 今回のチュートリアルの構成

以下の流れで記事を分けて書いていきたいと思います。

- **CMakeを使ったクライアント・サーバのビルド　（　<---- この記事の内容です。）**
- [C++でgrpcサーバを実装する](https://qiita.com/kenmaro/items/094803fd8bd50addd055)
- [C++でgrpcクライアントを実装する](https://qiita.com/kenmaro/items/e9326663cd94f67685d0)
- [protobufへのオブジェクトの出し入れについて、tips をまとめる](https://qiita.com/kenmaro/items/da3216d62f9891952a66)


この記事で言及しないことは以下です。（将来的にもし使えば追加するかもしれません。）

- C++を用いたgrpcのストリーミング通信

まとめるのは、あくまでも非ストリーミングrpc通信であり、ストリーミング通信は今の所あまり使っていないので言及しません。


## 何をしたいのか

兎にも角にも、まずは公式のチュートリアルを使い、grpcレポジトリのクローン、ビルド、環境構築を行いましょう。

チュートリアルはこちらです。

https://grpc.io/docs/languages/cpp/quickstart/

Build and install gRPC and Protocol Buffers
まで行った後に、example として、Hello, world の実行を行ったとします。

このあと、おそらくこう思うでしょう。

どうやれば自分のC++プロジェクトにgrpcを組み込めるのか、と。

この記事の目的は、自分のC++プロジェクトにgrpcを組み込むときのCMakeの記述、
その際のフォルダ構成の作り方です。（テンプレとして知っておくと便利だからです。）



## CMakeを用いたビルド環境の構築

前述したように、チュートリアルの
Build and install gRPC and Protocol Buffers
までは行ったということを前提にします。

CMakeを用いたビルド環境を整理しておくことで、既存のC++コードにgrpcを組み込むことが比較的簡単になります。
CMakeの書き方のチュートリアルは行いませんので、CMakeの基本的な使い方については、他の記事をご覧ください。


まず、私のチュートリアル用のレポジトリをクローンして下さい。

https://github.com/kenmaro3/grpc_cpp

このレポジトリを見ると、

- **controller**
- **protos**
- **client.cpp**
- **CMakeList.txt**
- **common.cmake**

が見えると思います。

それぞれテンプレートとなるフォルダ構成ですので、簡単に説明します。

### controller
この中に、server.cpp 
というような、サーバサイドの受け口となるコードを置きます。

今回は、controller/server.cpp とし、server.cpp の中にサーバサイドのコードを書いていきます。
次回以降実装するので、
hello, world とプリントするだけのメイン文にしています。

### protos
protoファイル（protobufの定義ファイル）をここに格納します。
protos/model の中に基本的にprotobuf として定義したい `message` を、
protos/ にサービス（つまりサーバサイドに定義したいサービスと関数）を格納します。

このように model フォルダを必ず用意する必要はないですが、用意しておくと比較的フォルダの見通しが良くなります。

また、protos/protos.sh
として、proto ファイルから　C++のコードを生成するときのコマンドを用意しておきます。

今回は、protos/server.proto を用意しています。
このserver.proto は、上のcontroller/server.cpp
と対応します。

サーバサイドにserver という名前のサービスを用意し、そのヘッダーのみをprotoに記述し、
実際の中身（ロジック）は contorller/server.cpp に記述することになります。

また、protos/model/ に、三つの message を定義しています。
今回は言及しませんが、眺めておくといいかと思います。


### client.cpp
クライアントサイドのコードです。
次回以降実装するので、
hello, world とプリントするだけのメイン文にしています。


### CMakeLists.txt

CMakeに必要なCMakeList.txtです。

```bash
pushd protos
sh protos.sh
popd
mkdir build
cd build
cmake ..
make -j4
```

とすることで、build の中に

```
client
server
```

という二つの実行バイナリがビルドされるはずです。

### common.cmake
これは、CMakeを用いてビルドするときに必要なファイルであり、
公式チュートリアルのレポジトリから引っ張ってきたものです。

CMakeLists.txt の6 行目

```CMakeLists.txt
include(common.cmake)
```

にてインクルードしています。中身を見る必要は（基本的に）ないと思います。



## ビルドしてみる

前述の通り、

```bash
pushd protos
sh protos.sh
popd
mkdir build
cd build
cmake ..
make -j4
```


とすることで、build の中に

```
client
server
```

という二つの実行バイナリがビルドされます。

それぞれ、

```
./client
./server
```

とすると

```
hello, world
```

と出力されるだけですが、基本的なフォルダ構成はこれで完成しています。

次回以降、この　client, server
に実際にクライアントサイド、サーバーサイドの実装を持たせていこうと思います。



## まとめ

C++ で実装するgrpc についての記事があまり充実していなかった（気がした）ため、
今回は私が知っているgrpcについての知識を全て書いていくべく、
数回にわけてチュートリアル（公式のチュートリアルの次に行いたいこと）をまとめていく第一回を書いてみました。


誰かの役に立てれば幸いです。

次回も是非ご覧ください。



今回はこの辺で。


@kenmaro