Ubuntu18.04にProtobufとgRPC C++の環境構築

Ubuntu18.04にProtobuf(3.6.1)とgRPC(v1.18.0)の環境を構築します。

ProtobufとgRPCのバージョン依存関係があります。

開発環境では、最新のProtobuf(3.13.0)を使えないので、サポートしているProtobuf(3.6.1)を使用します。
また、最新のgRPC(1.32.0)が古いProtobuf(3.6.1)でコンパイルできないので、Protobuf(3.6.1)を使用したgRPC(v1.18.0)を使用します。

# 環境
- AsRock DeskMini GTX1060(Z370)
- Core i9-9900 (3.10GHz 8core 16thread)
- メモリー32GB
- NVIDIA GeForce GTX 1060 Mobile(6GB GDDR5)
- Ubuntu 18.04.5
- ROS Melodic
- Qt Creator 4.9.2
- cmake-3.17.0
- protobuf 3.6.1
- gRPC v1.18.0

参考：
[サービス間通信のための新技術「gRPC」入門](https://knowledge.sakura.ad.jp/24059/)

# protobufのインストール

protobufは、protobufのリポジトリとgRPCのthird_party/protobufフォルダからもインストールできます。

- aptのprotobuf 3.0.0のアンインストール

apt-getで既にインストールした場合、アンインストールします。
（apt-getのprotobufが3.0.0です）

```
sudo apt-get remove protobuf-compiler
sudo apt-get remove libprotobuf-dev
sudo apt-get remove libprotobuf-lite10
```

- protobuf 3.6.1のインストール

```
sudo apt-get install autoconf automake libtool curl make g++ unzip
git clone -b 3.6.x https://github.com/protocolbuffers/protobuf.git
cd protobuf
git submodule update --init --recursive
./autogen.sh

./configure
make
make check
sudo make install
sudo ldconfig # refresh shared library cache.
```

- protobufのバージョン確認

```
$ protoc --version
libprotoc 3.6.1

$ which protoc 
/usr/local/bin/protoc
```

# gRPCのインストール

$HOME/.localにインストールします。

- MY_INSTALL_DIRの設定

```
$ export MY_INSTALL_DIR=$HOME/.local
$ mkdir -p $MY_INSTALL_DIR
$ export PATH="$PATH:$MY_INSTALL_DIR/bin"
```

PATHを~/.bashrcにも追加

```
export PATH=$PATH:$HOME/.local/bin
```

- cmakeのインストール

```
$ sudo apt-get install cmake
$ cmake --version
cmake version 3.10.2
```

Version 3.13以降のcmakeが必要なので、新しいcmakeをインストールします。

```
$ wget -q -O cmake-linux.sh https://github.com/Kitware/CMake/releases/download/v3.17.0/cmake-3.17.0-Linux-x86_64.sh
$ sh cmake-linux.sh -- --skip-license --prefix=$MY_INSTALL_DIR
$ rm cmake-linux.sh
```

- Pre-requisitesのインストール

```
$ sudo apt-get install build-essential autoconf libtool pkg-config libssl-dev
```

- repositoryの取得

```
$ git clone --recurse-submodules -b v1.18.0 https://github.com/grpc/grpc
$ cd grpc
```

- Install c-ares

```
cd third_party/cares/cares
git fetch origin
git checkout cares-1_13_0
mkdir -p cmake/build
cd cmake/build
cmake -DCMAKE_BUILD_TYPE=Release ../..
sudo make -j4 install
rm -rf third_party/cares/cares  # wipe out to prevent influencing the grpc build
```

- Install zlib

```
cd third_party/zlib
mkdir -p cmake/build
cd cmake/build
cmake -DCMAKE_BUILD_TYPE=Release ../..
sudo make -j4 install
rm -rf third_party/zlib  # wipe out to prevent influencing the grpc build
```

- Install protobuf

protobufのリポジトリから既にインストールした場合、不要です。
third_party/protobufから再度インストールしても問題ないです。

```
cd third_party/protobuf
mkdir -p cmake/build
cd cmake/build
cmake -Dprotobuf_BUILD_TESTS=OFF -DCMAKE_BUILD_TYPE=Release ..
sudo make -j4 install
rm -rf third_party/protobuf  # wipe out to prevent influencing the grpc build
```


- Install gRPC (package mode)

```
cd grpc
mkdir -p cmake/build
cd cmake/build
cmake \
  -DCMAKE_BUILD_TYPE=Release \
  -DgRPC_INSTALL=ON \
  -DgRPC_BUILD_TESTS=OFF \
  -DgRPC_CARES_PROVIDER=package \
  -DgRPC_PROTOBUF_PROVIDER=package \
  -DgRPC_SSL_PROVIDER=package \
  -DgRPC_ZLIB_PROVIDER=package \
  -DCMAKE_INSTALL_PREFIX=$MY_INSTALL_DIR \
  ../..

make -j4 install
```

```
$ protoc --version
libprotoc 3.6.1

$ which protoc 
/usr/local/bin/protoc

```

# gRPC example の実行

- Build the example

```
$ cd examples/cpp/helloworld
$ mkdir -p cmake/build
$ cd cmake/build
$ cmake ../..
$ make -j
```

- Run the example

```
$ ./greeter_server

# From a different terminal
$ ./greeter_client
Greeter received: Hello world
```

# protoファイルからgrpcとprotobufのC++コードの生成

```
$ protoc \
    --grpc_out=./codegen \
    --cpp_out=./codegen \
    --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` \
    ./telemetry.proto

$ cd codegen
$ ls
telemetry.grpc.pb.cc  telemetry.grpc.pb.h  telemetry.pb.cc  telemetry.pb.h
```