2019/08/24

CUDA10のコンパイラでrosのパッケージがコンパイルできない問題の対処法

背景


CUDA10のnvccを用いてrosのパッケージをコンパイルする際、エラーが発生してコンパイルできない問題が生じた。

記事の目的


CUDA10のnvccでrosパッケージをコンパイルできるようにする

nvccのバグ


ここでは、CUDA10のnvccでrosパッケージをコンパイルできない現象、原因及び対策について記載する。

現象

CUDA10のnvccでrosパッケージをコンパイルすると、下記のエラーが発生する場合がある。
  1. $ catkin_make
  2. ...
  3. /usr/include/pcl-1.7/pcl/point_cloud.h:586:100 error: template-id getMapping used as a declarator
  4. friend boost::shared_ptr& detail::getMapping(pcl::PointCloud &p);
  5. ^
  6. /usr/include/pcl-1.7/pcl/point_cloud.h:586:100 error: getMapping is neither function nor member function; cannot be declared friend
  7. cc1plus: error: expected ‘;’ at end of member declaration
  8. /usr/include/pcl-1.7/pcl/point_cloud.h:586:111: error: expected ‘)’ before ‘&’ token
  9. ...
  10. make: *** [all] Error 2

原因

nvccが利用しているgnuコンパイラのバグが原因である。このバグは、「friend関数によりnamespace内で定義された関数を使用する」記述があるコードで発生する。ところで、rosは独自に手を加えたPointCloudLibrary(PCL)を使用しているが、PCLのコード内に上記の記述が存在する('/usr/include/pcl-1.7/pcl/point_cloud.h'内 l.586)。nvccのコンパイラは、上記箇所をコンパイルする際に、関数のnamespace部分を削除してしまう(detail::getMapping→getMapping)。そのため、コンパイラ自身が関数を見つけられなくなり、エラーとなる。
  1. $less /usr/include/pcl-1.7/pcl/point_cloud.h
'point_cloud.h'内の該当箇所
  1.  
  2. namespace detail
  3. {
  4. template <typename PointT> boost::shared_ptr<pcl::MsgFieldMap>&
  5. getMapping (pcl::PointCloud<PointT>& p);
  6. } // namespace detail
  1.  
  2. protected:
  3. // This is motivated by ROS integration. Users should not need to access mapping_.
  4. boost::shared_ptr<MsgFieldMap> mapping_;
  5. friend boost::shared_ptr<MsgFieldMap>& detail::getMapping<PointT>(pcl::PointCloud<PointT> &p);
  6. public:
  7. EIGEN_MAKE_ALIGNED_OPERATOR_NEW
  8. };
  9. namespace detail
  10. {
  11. template <typename PointT> boost::shared_ptr<pcl::MsgFieldMap>&
  12. getMapping (pcl::PointCloud<PointT>& p)
  13. {
  14. return (p.mapping_);
  15. }
  16. } // namespace detail

対策

'/usr/include/pcl-1.7/pcl/point_cloud.h'を下記のように書き換えることで回避できる。
  1. // Add ---------------------------------------------------------------------- //
  2. template <typename PointT> boost::shared_ptr<pcl::MsgFieldMap>&
  3. getMapping (pcl::PointCloud<PointT>& p);
  4. // -------------------------------------------------------------------------- //
  5. namespace detail
  6. {
  7. template <typename PointT> boost::shared_ptr<pcl::MsgFieldMap>&
  8. getMapping (pcl::PointCloud<PointT>& p);
  9. } // namespace detail
  1.  
  2. protected:
  3. // This is motivated by ROS integration. Users should not need to access mapping_.
  4. boost::shared_ptr<MsgFieldMap> mapping_;
  5. // Change ------------------------------------------------------------------- //
  6. friend boost::shared_ptr<MsgFieldMap>& getMapping<PointT>(pcl::PointCloud<PointT> &p);
  7. // friend boost::shared_ptr<MsgFieldMap>& detail::getMapping<PointT>(pcl::PointCloud<PointT> &p);
  8. // -------------------------------------------------------------------------- //
  9. public:
  10. EIGEN_MAKE_ALIGNED_OPERATOR_NEW
  11. };
  12. // Add ---------------------------------------------------------------------- //
  13. template <typename PointT> boost::shared_ptr<pcl::MsgFieldMap>&
  14. getMapping (pcl::PointCloud<PointT>& p)
  15. {
  16. return (p.mapping_);
  17. }
  18. // -------------------------------------------------------------------------- //
  19. namespace detail
  20. {
  21. template <typename PointT> boost::shared_ptr<pcl::MsgFieldMap>&
  22. getMapping (pcl::PointCloud<PointT>& p)
  23. {
  24. return (p.mapping_);
  25. }
  26. } // namespace detail

備考

  • ros-kinetic、cuda 10.1で検証した
  • コンパイルが通ることと、実行可能であることを確認した

まとめ


  • rosをapt install時にインストールされるpclのヘッダーファイルを変更することにより、CUDA10のnvccでrosパッケージがコンパイルできなくなる問題を回避した

参考文献



変更履歴


  1. 2019/08/24: 新規作成

0 件のコメント:

コメントを投稿

MQTTの導入

背景 IoTデバイスの接続環境構築のため、MQTT(mosquitto)の導入を行った。 記事の目的 MQTT(mosquitto)をUbuntuに導入する mosquitto ここではmosquittoについて記載する。 MQTT MQTT(Message Qu...