PCL1.7.2で一部のライブラリがエラーLNK1189でビルドできない問題の対処
PCLのビルド中にpcl_featureについては下記のようなエラーメッセージが出て使えなくなってしまった。
fatal error LNK1189: オブジェクトまたはメンバーの数がライブラリの最大許容数 65535 を超えています。
調べたところ下記のページが見つかった。被害者の共通点は Visual Studio を使っていること。
- Link error 1189 library limit of 65535 objects exceeded · Issue #833 · PointCloudLibrary/pcl · GitHub
- Point Cloud Library (PCL) Users mailing list - PCL Features Library Limit Exceeded
Visual Studio のコンパイラはライブラリ内のメンバー数に制限を課しているそう。
この問題を回避するには『PCLビルド時の PCL_ONLY_CORE_POINT_TYPES をONにして、pcl_featureのメンバーを減らす』しか方法がないそう。
ただし、これを行うとpcl::PointNormal等の一部のポイントタイプが、今まで通りには使えなくなる。
というわけで、以下では
- LNK1189エラーの解消方法
- 今まで通りにポイントタイプを使うための方法
をメモ。
LNK1189エラーの解消方法
- cmake-gui で PCL_ONLY_CORE_POINT_TYPES を ON にする
- Configure を押す
- Generate を押す
- 生成された PCL.sln を開いて ALL_BUILD する
- クリーン・リビルドする必要はなく、単純にビルドでよい
今まで通りにポイントタイプを使うための方法
- 今まで作ったプロジェクトに PCL_NO_PRECOMPILE マクロを定義する
CMakeLists.txt内に書いておきたい場合:
add_definitions(-DPCL_NO_PRECOMPILE)
ソースファイル内に書いておきたい場合:
#define PCL_NO_PRECOMPILE
動作確認
下記のコードの PointT, NormalT の typedef を自分が使いたいポイントタイプに書き換えて、1,2行目のコメントを入れ替えて実行してみる。
//#define PCL_NO_PRECOMPILE // ここを入れ替えて試す #undef PCL_NO_PRECOMPILE // //#include <pcl/point_types.h> #include <pcl/point_cloud.h> #include <pcl/features/normal_3d_omp.h> #include <pcl/filters/extract_indices.h> typedef pcl::PointXYZINormal PointT; // 適当に設定 typedef pcl::PointCloud<PointT> PointCloudT; typedef PointCloudT::Ptr PointCloudPtrT; typedef PointCloudT::ConstPtr PointCloudConstPtrT; typedef pcl::PointNormal NormalT; // 適当に設定 typedef pcl::PointCloud<NormalT> NormalCloudT; typedef NormalCloudT::Ptr NormalCloudPtrT; typedef NormalCloudT::ConstPtr NormalCloudConstPtrT; void main() { // Create data pcl::IndicesPtr indices(new std::vector<int>); PointCloudPtrT cloud_in(new PointCloudT), cloud_out(new PointCloudT); NormalCloudPtrT normals(new NormalCloudT); // Test filter 1 pcl::ExtractIndices<PointT> ext; ext.setInputCloud(cloud_in); ext.setIndices(indices); ext.filter(*cloud_out); // Test filter 2 pcl::NormalEstimationOMP<PointT, NormalT> ne; ne.setInputCloud(cloud_in); ne.setKSearch(5); ne.compute(*normals); std:system("pause"); }
PCL_NO_PRECOMPILE が未定義だと次のエラーがでる。
2>test.obj : error LNK2001: 外部シンボル ""protected: virtual void __thiscall pcl::NormalEstimation<struct pcl::PointXYZINormal,struct pcl::PointNormal>::computeFeature(class pcl::PointCloud<struct pcl::PointNormal> &)" (?computeFeature@?$NormalEstimation@UPointXYZINormal@pcl@@UPointNormal@2@@pcl@@MAEXAAV?$PointCloud@UPointNormal@pcl@@@2@@Z)" は未解決です。 2>test.obj : error LNK2001: 外部シンボル ""private: virtual void __thiscall pcl::NormalEstimationOMP<struct pcl::PointXYZINormal,struct pcl::PointNormal>::computeFeature(class pcl::PointCloud<struct pcl::PointNormal> &)" (?computeFeature@?$NormalEstimationOMP@UPointXYZINormal@pcl@@UPointNormal@2@@pcl@@EAEXAAV?$PointCloud@UPointNormal@pcl@@@2@@Z)" は未解決です。 2>test.obj : error LNK2001: 外部シンボル ""protected: virtual void __thiscall pcl::ExtractIndices<struct pcl::PointXYZINormal>::applyFilter(class pcl::PointCloud<struct pcl::PointXYZINormal> &)" (?applyFilter@?$ExtractIndices@UPointXYZINormal@pcl@@@pcl@@MAEXAAV?$PointCloud@UPointXYZINormal@pcl@@@2@@Z)" は未解決です。 2>test.obj : error LNK2019: 未解決の外部シンボル "protected: void __thiscall pcl::ExtractIndices<struct pcl::PointXYZINormal>::applyFilterIndices(class std::vector<int,class std::allocator<int> > &)" (?applyFilterIndices@?$ExtractIndices@UPointXYZINormal@pcl@@@pcl@@IAEXAAV?$vector@HV?$allocator@H@std@@@std@@@Z) が関数 "protected: virtual void __thiscall pcl::ExtractIndices<struct pcl::PointXYZINormal>::applyFilter(class std::vector<int,class std::allocator<int> > &)" (?applyFilter@?$ExtractIndices@UPointXYZINormal@pcl@@@pcl@@MAEXAAV?$vector@HV?$allocator@H@std@@@std@@@Z) で参照されました。 2>C:\test\Release\test.exe : fatal error LNK1120: 外部参照 4 が未解決です。