BEIKE blog

備忘録です

protocol buffersと仲良くしたい

概要

protocol buffersと少しでも仲良くするための手助けとなるようにメモを残しておく。(結構めちゃくちゃな事書いてるかも)

解決した方法を時系列を追って紹介していきたいと思う。

先にまとめ

以下を読んで行くと分かるがこけると結構苦労するので、protocol buffers関連でこけることを 予期できるならばDockerを使おう。

解決したこと

protocol競合によるビルド失敗回避

roslaunch後に「apt-get」「source」間でprotocol競合によるprocess died回避

解決までの流れ

あの頃は、cartgrapherを導入したときだったgoogleなんとかというファイルがインストールされていくのを見ていた。 cartgrapherはgoogleが提供しているらしいと知っていたため、すんなりそれらを受け入れた。

しかしcartgrapher導入後、新たに別のパッケージを導入しようとcloneしてコンパイルしたら大量のエラーが出た。 その時はこのパッケージに不備があるのかと思った、またrosのバージョンが違ったのかと考えたがエラーを見たところ googleと書いてあったりgazebo9などが書いてあった。

この時点でgoogleとgazebo9が原因そうなことはエラーから考えられた。gazebo9については、gazeboのバージョンが違うと考えられた。しかしソースコードを見てもgazeboのバージョンについてプログラムするところが見つからなかった。そこでgoogleのエラーをコピペして検索したところprotocolのバージョンが競合しているということを知った。

そこからprotocolとの戦いが始まった。まず競合と言っても何と何が競合しているのかサッパリわからなかった。 googleでエラー探しをしていたところ下記のようなissueを発見した。

This file was generated by an older version of protoc which is incompatible with your Protocol Buffer headers. Please regenerate this file with a newer version of protoc. · Issue #6527 · BVLC/caffe · GitHub

この記事によると競合しているのは「apt-get」と「source」間であることがわかった。それらを示しているのが記事によると以下です。

for apt-get:

$ export PATH=/usr/bin:$PATH
$ protoc --version

for source:

$ export PATH=/usr/local/bin:$PATH
$ protoc --version

以上のコマンドによりそれぞれのバージョンを確認することが可能です。

場所がわかったことは、解決するのにとても助かった。まず行ったのはsource側のプロトコルのアップデートだ。これは単にファイルの書き換えをすれば変更できることがわかったので、以下のような作業を行いsource側のprotocolのバージョンを3.9にあげた。

$ curl -OL https://github.com/google/protobuf/releases/download/v3.9.0/protoc-3.9.0-linux-x86_64.zip
$ unzip protoc-3.9.0-linux-x86_64.zip -d protoc3
$ sudo mv protoc3/bin/* /usr/local/bin/
$ sudo mv protoc3/include/* /usr/local/include/

そのおかげでprotocol競合によるビルド失敗回避を達成した。しかし結局は実行後にprotocolのバージョンがそれぞれ違うから低い方をアップデートしろみたいなことを言われた。

そこでapt-getの方のバージョンを上げてsource(3.9)と合わせようと考えた。そこでいろいろやっていたら、間違えてsourceの方を変更してしまった。しかもその時やっていたやり方がコンパイルを行ったりするやつで何かしらのエラーがあるとかで、またprotocol競合によるビルド失敗回避ができなくなってしまった。

以下のやり方でコンパイルを行いなんとか戻した。と同時に「apt-get」のバージョンアップは今の所自身が認知してる限りだとバージョン3.1ぐらいまでしか対応していない。実際私のバージョンは3.0だった。それを「source」と合わせろってなると、「apt-get」側に合わせないとバージョンの統一ができないことがわかる。なので「apt-get」の方のバージョンは3.0のままで「source」の方を3.0になるようにした。つまり両方3.0のバージョンにした。

$ wget https://github.com/protocolbuffers/protobuf/releases/download/v3.0.0-alpha-2/protobuf-cpp-3.0.0-alpha-2.tar.gz
$ tar -xvf protobuf-cpp-3.0.0-alpha-2.tar.gz
$ cd protobuf-3.0.0-alpha-2
$ ./configure --disable-shared CXXFLAGS="-fPIC"
$ make -j8 
$ sudo make install

以上です。 いつかまた喧嘩する日が来るかもしれない。。。

また喧嘩した

記事書いた次の日に喧嘩した、、、、。 見たときは、なんの冗談なんだと思った。

rosを全消ししたりと戦いまくった。

結果的に言うとなんとかなった。明日また喧嘩するかもしれない、、、。

また時系列と共に解決方法を記述していくぜ。

以前の状況を踏まえて説明すると

for apt-get:

$ export PATH=/usr/bin:$PATH
$ protoc --version

for source:

$ export PATH=/usr/local/bin:$PATH
$ protoc --version

こいつらを実行するときに3.0.0になるようにバージョンを揃えていた。

それでビルドは問題なかった。

しかし実行時にまた競合が起こってしまった。

エラー内容はこのソースは3.12だけど3.00ダウンロードされているんだけどみたいなやつだった。

(見たくないのでスクショ取るの忘れてしまった。)

実行とビルドは別の話らしい(これらを踏まえると)

結局色々ごちゃごちゃ手当たり次第バージョンを3.0.0やら3.6.0にしてるとある変化に気づいて解決できた。

ある操作を行ったら、実行時のエラーが3.12から3.6に変化したのだ。このことより変更方法に気づいた。

またrosの場合catkin_makeを使用してビルドを行うのだがprotbufのバージョンを変更後はbuildとdevelファイルを削除して 再ビルドを行ったほうがいいかもしれない。ビルドしたときにそのバージョンが実行ファイルと結びつくんじゃないのかと考えるからだ。

これらより行ったほうが良さそうな操作を以下にまとめる。


  • protbufのバージョン変更について 以下のコマンドによりバージョンがそれぞれ競合してないことを確認する。

for apt-get:

$ export PATH=/usr/bin:$PATH
$ protoc --version

for source:

$ export PATH=/usr/local/bin:$PATH
$ protoc --version
  • 競合していたら以下の作業を行う(なんのバージョンがいいかはそれぞれで。以下は私のバージョン)

source側

~$ curl -OL https://github.com/google/protobuf/releases/download/v3.0.0/protoc-3.0.0-linux-x86_64.zip
~$ unzip protoc-3.0.0-linux-x86_64.zip -d protoc3
~$ sudo mv protoc3/bin/* /usr/local/bin/     ←もしもファイルが存在しているなら削除してから
~$ sudo mv protoc3/include/* /usr/local/include/ ←もしもファイルが存在しているなら削除してから
~$ sudo ldconfig

apt側

~$ unzip protoc-3.0.0-linux-x86_64.zip -d protoc3 ←上と同じファイルをもっかいunzip
~$ sudo mv protoc3/bin/* /usr/bin/     ←もしもファイルが存在しているなら削除してから

以上の作業によりビルドまでは問題なく行えるまでには、できると思う。

  • 実行時に競合が起こってしまった場合は以下の作業を行う(以下は私のバージョン)

リポジトリのクローン

~$ git clone https://github.com/google/protobuf.git
~$ cd protobuf
~$ git checkout 3.0.x

サブモジュールの更新

~$ git submodule update --init --recursive
~$ ./autogen.sh

コンパイル&インストール

~$ ./configure
~$ make          # 10分〜20分くらいかかります
~$ make check       # 5分〜10分くらいかかります
~$ sudo make install
~$ sudo ldconfig

以上です。

後はワークスペースに戻り以前のビルド関係のファイルを削除し再ビルドを行い、実行すればうまく行くと思います。