はじめに
ecl_exceptionsは、ROSパッケージのひとつでテンプレートベースの例外管理をするライブラリです。今回、これを使用するときにDataExceptionは使用できるが、StandardExceptionが使用できなかったので原因を調査しました。
前提条件
| 環境 | バージョン |
|---|---|
| 開発機 | Ubuntu 16.04.6 LTS |
| ROS | Kinetic Kame |
| コンパイル | c++11 |
エラー詳細
DataExceptionとStandardExceptionを使用した場合、下記のようなエラーが発生します。
ecl::StandardException::StandardException(char const*, ecl::ErrorFlag, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)' に対する定義されていない参照です
ネットで検索すると、Std::__cxx11::basic_string vs std::basic_stringがあり、コンパイルしているC++のバージョンとリンク対象がコンパイルされたC++のバージョンが異なるときに出るエラーのようです。
ソースを確認する
ヘッダを確認するとstandard_exception.hppとdata_exception.hppでdata_exception.hppはテンプレートのためヘッダに実装されているが、standard_exception.hppは、standard_exception.cppに実体が実装されています。
ここでコンパイルオプション(CMakeLists.txt)を調べると、indigo-kineticには何もついていません。ROS2のBouncy(CMakeLists.txt#L22)からは、ecl_enable_cxx14_compilerマクロがあり、これがecl_cxx.cmake#L6で定義されているため、Bouncy以降でC++14を使っている場合は、問題なく使えるようです。
まとめ
- C++のバージョンは、依存するROSパッケージの対応があるか確認する必要がある
- 対応がない場合、自分の手元でビルドし直す必要がある