PointCloudLibrary / pcl

Point Cloud Library (PCL)
https://pointclouds.org/
Other
9.86k stars 4.61k forks source link

[compile error] link error #5487

Open munitioner opened 1 year ago

munitioner commented 1 year ago

Operating environment in windows11 qt5.15.2+pcl1.12.1+vtk9.1 vtk9.1 Compile with cmake+vs2022 Qt compiles using cmake PCL is installed using PCL-1.12.1-AllInOne-msvc2019-win64.exe

QT CMakeLists.txt set(PCL_DIR "D:/Program Files (x86)/PCL 1.12.1/cmake") find_package(PCL 1.12 REQUIRED) include_directories(${PCL_INCLUDE_DIRS}) link_directories(${PCL_LIBRARY_DIRS}) add_definitions(${PCL_DEFINITIONS})

set(FLANN_ROOT "D:/Program Files (x86)/PCL 1.12.1/3rdParty/FLANN") set(FLANN_INCLUDE_DIRS "D:/Program Files (x86)/PCL 1.12.1/3rdParty/FLANN/include") set(FLANN_LIBRARY_DIRS "D:/Program Files (x86)/PCL 1.12.1/3rdParty/FLANN/lib") include_directories(${FLANN_INCLUDE_DIRS}) link_directories(${FLANN_LIBRARY_DIRS}) target_link_libraries(zxtx_autocar PRIVATE ${PCL_LIBRARIES})

Compilation Error lidar2lidar.cpp.obj:-1: error: LNK2001: 无法解析的外部符号 "protected: virtual void cdecl pcl::NormalEstimation<struct pcl::PointXYZINormal,struct pcl::PointXYZINormal>::computeFeature(class pcl::PointCloud &)" (?computeFeature@?$NormalEstimation@UPointXYZINormal@pcl@@U12@@pcl@@MEAAXAEAV?$PointCloud@UPointXYZINormal@pcl@@@2@@Z) lidar2lidar.cpp.obj:-1: error: LNK2019: 无法解析的外部符号 "public: void cdecl pcl::NormalEstimationOMP<struct pcl::PointXYZINormal,struct pcl::PointXYZINormal>::setNumberOfThreads(unsigned int)" (?setNumberOfThreads@?$NormalEstimationOMP@UPointXYZINormal@pcl@@U12@@pcl@@QEAAXI@Z),函数 "void cdecl icp_match(class std::shared_ptr<class pcl::PointCloud > const &,class std::shared_ptr<class pcl::PointCloud > const &,class Eigen::Matrix<double,4,4,0,4,4> &)" (?icp_match@@YAXAEBV?$shared_ptr@V?$PointCloud@UPointXYZINormal@pcl@@@pcl@@@std@@0AEAV?$Matrix@N$03$03$0A@$03$03@Eigen@@@Z) 中引用了该符号 lidar2lidar.cpp.obj:-1: error: LNK2001: 无法解析的外部符号 "private: virtual void cdecl pcl::NormalEstimationOMP<struct pcl::PointXYZINormal,struct pcl::PointXYZINormal>::computeFeature(class pcl::PointCloud &)" (?computeFeature@?$NormalEstimationOMP@UPointXYZINormal@pcl@@U12@@pcl@@EEAAXAEAV?$PointCloud@UPointXYZINormal@pcl@@@2@@Z) lidar2lidar.cpp.obj:-1: error: LNK2019: 无法解析的外部符号 "public: cdecl pcl::visualization::PointCloudGeometryHandlerXYZ::PointCloudGeometryHandlerXYZ(class std::shared_ptr<class pcl::PointCloud const > const &)" (??0?$PointCloudGeometryHandlerXYZ@UPointXYZINormal@pcl@@@visualization@pcl@@QEAA@AEBV?$shared_ptr@$$CBV?$PointCloud@UPointXYZINormal@pcl@@@pcl@@@std@@@Z),函数 "public: bool __cdecl pcl::visualization::PCLVisualizer::addPointCloud(class std::shared_ptr<class pcl::PointCloud const > const &,class pcl::visualization::PointCloudColorHandler const &,class std::basic_string<char,struct std::char_traits,class std::allocator > const &,int)" (??$addPointCloud@UPointXYZINormal@pcl@@@PCLVisualizer@visualization@pcl@@QEAA_NAEBV?$shared_ptr@$$CBV?$PointCloud@UPointXYZINormal@pcl@@@pcl@@@std@@AEBV?$PointCloudColorHandler@UPointXYZINormal@pcl@@@12@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@4@H@Z) 中引用了该符号 lidar2lidar.cpp.obj:-1: error: LNK2001: 无法解析的外部符号 "public: virtual void cdecl pcl::visualization::PointCloudGeometryHandlerXYZ::getGeometry(class vtkSmartPointer &)const " (?getGeometry@?$PointCloudGeometryHandlerXYZ@UPointXYZINormal@pcl@@@visualization@pcl@@UEBAXAEAV?$vtkSmartPointer@VvtkPoints@@@@@Z)

mvieth commented 1 year ago

Try adding #define PCL_NO_PRECOMPILE at the top of your source code. The all-in-one installer contains template instantiations only for the most commonly used point types, but not for PointXYZINormal (see also here: https://pcl.readthedocs.io/projects/tutorials/en/master/adding_custom_ptype.html#how-to-add-a-new-pointt-type)

munitioner commented 1 year ago

Try adding #define PCL_NO_PRECOMPILE at the top of your source code. The all-in-one installer contains template instantiations only for the most commonly used point types, but not for PointXYZINormal (see also here: https://pcl.readthedocs.io/projects/tutorials/en/master/adding_custom_ptype.html#how-to-add-a-new-pointt-type)

This is my source code. I added # define PCL at the top of the code NO PRECOMPILE, but other errors occurred D:\Program Files (x86)\PCL 1.12.1\3rdParty\FLANN\include\flann\util\heap.h:108: error: C2143: 语法错误: 缺少“,”(在“<”的前面) D:\Program Files (x86)\PCL 1.12.1\3rdParty\FLANN\include\flann/util/heap.h(108): error C2143: 语法错误: 缺少“,”(在“<”的前面) D:\Program Files (x86)\PCL 1.12.1\3rdParty\FLANN\include\flann/util/heap.h(112): note: 查看对正在编译的 类 模板 实例化“flann::Heap::CompareT”的引用 D:\Program Files (x86)\PCL 1.12.1\3rdParty\FLANN\include\flann/util/heap.h(161): note: 查看对正在编译的 类 模板 实例化“flann::Heap”的引用 D:\Program Files (x86)\PCL 1.12.1\3rdParty\FLANN\include\flann\util\random.h:120: error: C2039: "random_shuffle": 不是 "std" 的成员 D:\Program Files (x86)\PCL 1.12.1\3rdParty\FLANN\include\flann/util/random.h(120): error C2039: "random_shuffle": 不是 "std" 的成员 D:\Program Files (x86)\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.32.31326\include\set(23): note: 参见“std”的声明 D:\Program Files (x86)\PCL 1.12.1\3rdParty\FLANN\include\flann\util\random.h:120: error: C3861: “random_shuffle”: 找不到标识符

`// lidar 2 lidar calibration

define PCL_NO_PRECOMPILE

include

include

include

include

include

include <Eigen/Core>

include <pcl/point_cloud.h>

include <pcl/point_types.h>

include <pcl/io/pcd_io.h>

include <pcl/kdtree/kdtree_flann.h>

include <pcl/registration/icp.h>

include <pcl/registration/icp_nl.h>

include <pcl/visualization/pcl_visualizer.h>

include <pcl/visualization/point_cloud_color_handlers.h>

include <pcl/features/normal_3d_omp.h>

include <pcl/filters/statistical_outlier_removal.h>

include <pcl/filters/voxel_grid.h>

include <pcl/features/fpfh_omp.h>

include <pcl/registration/transformation_estimation_svd.h>

typedef pcl::PointNormal PointXYZN; typedef pcl::PointCloud PointCloudXYZN; typedef PointCloudXYZN::Ptr PointCloudXYZNPtr;

typedef pcl::PointXYZINormal PointT; typedef pcl::PointCloud PointCloud; typedef PointCloud::Ptr PointCloudPtr;

void icp_match(const PointCloudPtr& src, const PointCloudPtr& base, Eigen::Matrix4d &trans) { pcl::NormalEstimationOMP<PointT, PointT> norm_est; pcl::search::KdTree::Ptr kdtree(new pcl::search::KdTree());

norm_est.setNumberOfThreads(8); norm_est.setSearchMethod(kdtree); norm_est.setKSearch(20);

norm_est.setInputCloud(src); norm_est.compute(src); norm_est.setInputCloud(base); norm_est.compute(base);

pcl::IterativeClosestPointWithNormals<PointT, PointT, float> icp; // pcl::IterativeClosestPoint<PointT, PointT, float> icp; icp.setInputSource(src); icp.setInputTarget(base);

std::cout<<"source points size "<size()<<std::endl; std::cout<<"target points size "<size()<<std::endl;

icp.setMaxCorrespondenceDistance(5.0); icp.setMaximumIterations(100); icp.setTransformationEpsilon(1e-4); icp.setEuclideanFitnessEpsilon(1e-3);

PointCloudPtr src_registered(new PointCloud); Eigen::Matrix4f init_pose = trans.cast();

icp.align(*src_registered, init_pose);

std::cout<<"align icp final"<<std::endl;

if (icp.hasConverged()) { trans = icp.getFinalTransformation().cast(); } else {

std::cout << "align failed" << std::endl;

} }

void lidar2lidarCalibration(const std::string& path1, const std::string& path2) { pcl::PointCloud::Ptr source_pts(new pcl::PointCloud); pcl::PointCloud::Ptr target_pts(new pcl::PointCloud); pcl::io::loadPCDFile(path1, source_pts); pcl::io::loadPCDFile(path2, target_pts);

std::vector indices; pcl::removeNaNFromPointCloud(source_pts, source_pts, indices); pcl::removeNaNFromPointCloud(target_pts, target_pts, indices);

pcl::VoxelGrid filter; filter.setLeafSize(0.1f, 0.1f, 0.1f); filter.setInputCloud(source_pts); filter.filter(source_pts); filter.setInputCloud(target_pts); filter.filter(target_pts);

pcl::StatisticalOutlierRemoval sor;

sor.setInputCloud(source_pts); sor.setMeanK(10); sor.setStddevMulThresh(1.0); sor.filter(*source_pts);

sor.setInputCloud(target_pts); sor.filter(*target_pts);

std::cout<<"load pcd"<<std::endl;

Eigen::Matrix4d tran_mat_icp; Eigen::Matrix4d tran_mat_teaser;

tran_mat_icp.setIdentity();

icp_match(source_pts, target_pts, tran_mat_icp);

std::cout<<"the calibration result is "<<std::endl<<tran_mat_icp<<std::endl;

PointCloudPtr transed_cloud(new PointCloud); pcl::transformPointCloud(source_pts, transed_cloud, tran_mat_icp);

pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("trans_viewer")); viewer->setBackgroundColor(0, 0, 0);

pcl::visualization::PointCloudColorHandlerCustom source_color_handle(target_pts, 255, 0, 0); pcl::visualization::PointCloudColorHandlerCustom target_color_handle(transed_cloud, 0, 255, 0);

viewer->addPointCloud(target_pts, source_color_handle, "source"); viewer->addPointCloud(transed_cloud, target_color_handle, "target");

viewer->spin(); //https://github.com/PointCloudLibrary/pcl/issues/172 //viewer windows can't close viewer->close(); } `

mvieth commented 1 year ago

These errors come from the FLANN library, a dependency of PCL. The all-in-one installer includes the latest version of FLANN. Are you compiling your project as C++17 or C++20? random_shuffle was removed in C++17. PCL currently uses/is compiled as C++14, and I would recommend to use the same for your project.

Also, it might be better to use PCL_NO_PRECOMPILE only for those headers where you actually need it. So you could e.g. try

#define PCL_NO_PRECOMPILE
#include <pcl/features/normal_3d_omp.h>
#undef PCL_NO_PRECOMPILE

(same for other headers where you get link errors). Alternatively, make sure that PCL_NO_PRECOMPILE is not defined when including kdtree_flann.h (that's where the flann errors come from:

#undef PCL_NO_PRECOMPILE
#include <pcl/kdtree/kdtree_flann.h>
#define PCL_NO_PRECOMPILE
munitioner commented 1 year ago

These errors come from the FLANN library, a dependency of PCL. The all-in-one installer includes the latest version of FLANN. Are you compiling your project as C++17 or C++20? random_shuffle was removed in C++17. PCL currently uses/is compiled as C++14, and I would recommend to use the same for your project.

Also, it might be better to use PCL_NO_PRECOMPILE only for those headers where you actually need it. So you could e.g. try

#define PCL_NO_PRECOMPILE
#include <pcl/features/normal_3d_omp.h>
#undef PCL_NO_PRECOMPILE

(same for other headers where you get link errors). Alternatively, make sure that PCL_NO_PRECOMPILE is not defined when including kdtree_flann.h (that's where the flann errors come from:

#undef PCL_NO_PRECOMPILE
#include <pcl/kdtree/kdtree_flann.h>
#define PCL_NO_PRECOMPILE

These settings have been generated in qt cmakelists.txt,set(CMAKE_CXX_STANDARD 17),It should be based on the C++17 standard,But my problem still exists

cmake_minimum_required(VERSION 3.5)

project(zxtx_autocar VERSION 0.1 LANGUAGES CXX)

set(CMAKE_INCLUDE_CURRENT_DIR ON)

set(CMAKE_AUTOUIC ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON)

set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON)

mvieth commented 1 year ago

Okay, so would it be an option to change it to set(CMAKE_CXX_STANDARD 14)? If not, have you tried my suggestion with the more selective use of PCL_NO_PRECOMPILE?

munitioner commented 1 year ago

Okay, so would it be an option to change it to set(CMAKE_CXX_STANDARD 14)? If not, have you tried my suggestion with the more selective use of PCL_NO_PRECOMPILE? Change the set (CMAKE_CXX_STANDARD 17) in CMakeLists.txt in QT to set (CMAKE_CXX_STANDARD 14), and then add it to the source file

undef PCL NO PRECOMPILE

include <pcl/kdtree/kdtree_ flann.h>

define PCL NO PRECOMPILE

There are no compilation errors, but there are cmake errors

D:\Program Files (x86)\PCL 1.12.1\cmake\PCLConfig.cmake:59: error: visualization is required but vtk was not found D:/Program Files (x86)/PCL 1.12.1/cmake/PCLConfig.cmake:353 (pcl_report_not_found) D:/Program Files (x86)/PCL 1.12.1/cmake/PCLConfig.cmake:540 (find_external_library) CMakeLists.txt:57 (find_package)

mvieth commented 1 year ago

Have you tried setting VTK_DIR or VTK_ROOT to the correct directory?

Haibara-z commented 5 months ago

how did you solve this problem?