十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Windows下Qt与MinGW环境编译PCL完整实战指南

Windows下Qt与MinGW环境编译PCL完整实战指南 简介在Windows下借助Qt与MinGW工具链进行点云开发的C工程师常受困于PCL及其依赖库的编译配置与版本匹配问题。这份整合包直接提供PCL与boost、eigen、flann、qhull、VTK的MinGW编译成果省去逐一下载源码、手动编译和排查兼容性错误的繁琐过程。资源共2000个文件压缩包约151.31MB其中以1997个hpp头文件为主完整覆盖各库的声明与模板实现另附txt、pdf、doc格式的说明文档便于查阅配置要点与使用细节。目前已有34人学习下载适合中高级点云开发者作为环境搭建参考。包内各依赖库分工明确Eigen负责矩阵运算、FLANN提供近邻搜索、Qhull处理凸包与三角剖分、VTK完成三维可视化结合PCL本身可快速构建从数据读取到可视化的完整点云处理流程对理解库间协作与后续二次开发均有直接帮助。1. 在 Windows 上让 Qt、MinGW 和 PCL 共存的现实解法点云库里 PCL 的大多数 Windows 编译教程都默认你使用 Visual Studio 和 MSVC 编译器这导致很多 Qt 开发者陷入一个尴尬境地明明用 Qt 写界面却为了编译 PCL 不得不跨到 msvc 工具链最后在 QWidget 与 VTK 渲染窗口之间来回折腾。更麻烦的是Qt 从 5.15 开始不再提供离线安装包新用户只能通过在线安装器勾选 Qt 版本与编译器套件想要凑齐一套能用的 Qt MinGW 环境本身就是第一步门槛。本文要解决的是如何用 Qt 自带的 MinGW 编译器从 boost 开始一路手写编译 PCL 及其全链路依赖库。这条路线看起来绕远但当你真正面对某些国产 OS 的适配、内网离线部署或者需要定制编译器选项时手写编译会是你在 msvc 方案之外唯一的救命稻草。整个流程我会按依赖顺序讲标注每个库的编译参数、CMake 选项和最容易出错的环节能直接照着敲也能让你明白每个参数的含义下面是全文的编译路线图。2. 编译链选型MinGW 与 Qt 的版本匹配逻辑2.1 为什么放弃 MSVC 转而使用 MinGWMSVC 和 MinGW 的区别不止是编译器厂商不同它影响的是链接器、运行库和调试信息格式。PCL 官方仓库对 Windows 的支持部分面向 MSVC但 VTK 的 Qt 渲染模块对 MinGW 是友好的前提是你的 Qt 版本是 MinGW 套件编译的且 VTK 源码的 Qt 插件模块能识别到 qmake 的路径。另外许多工业现场的上位机程序仍然依赖 Qt 5.15.x MinGW 版本比如带触摸屏的工控机场景项目批量部署后没法要求客户安装 VC Redistributable此时 MinGW 自带的 libgcc、libstdc 共享库只需和 exe 放在同一目录即可运行。选择 MinGW 还有一层考虑是编译产物的跨机器稳定性。MSVC 编译的 PCL 动态库默认依赖 /MD 运行库如果部署机器缺少对应版本的 Universal CRT运行时会直接报缺失 msvcp140.dll。而 MinGW 的二进制只要带上 libstdc-6.dll 和 libgcc_s_seh-1.dll 即可。对于长时间在野外运行的点云采集设备这一特性非常实际。2.2 工具链版本组合建议MinGW 编译器版本、Qt 版本和 CMake 版本三者的搭配直接决定后续编译能否顺利通过。根据社区常见实践经验推荐下列组合组件推荐版本说明Qt5.15.2 MinGW 8.1.0 64-bit在线安装器可选自带编译器套件MinGWQt 自带 8.1.0 SEH注意 Qt 安装目录下的 mingw81_64 文件夹CMake3.20 及以上低于 3.16 不支持 PCL 的部分 target 语法PCL1.12.1对 VTK 9 支持较完善若用 VTK 8.2 则选 1.11VTK9.0.3 或 9.2.69.0.3 与 Qt 5.15 的兼容性最稳提示PCL 1.13 以上版本要求 CMake 3.17同时 Eigen 最小版本提到 3.3编译时留意日志中的版本检查输出。2.3 编译顺序与依赖关系梳理PCL 的依赖库之间不是完全独立的编译顺序错了会导致 CMake 找不到 find_package 的配置文件。推荐顺序为eigen → boost → flann → qhull → VTK → PCL。eigen 是 header-only只需把头文件拷贝到指定目录并设置环境变量boost 编译时间最长放到第一步编译可以让后续工作更轻松VTK 最复杂放在 PCL 之前最后一个编译能保证 CMake 的缓存文件指向正确的 vtk 版本。在实际操作中你可以使用-DCMAKE_PREFIX_PATH参数显式指定所有第三方库的安装前缀避免 CMake 因为系统 PATH 中存在旧版本而误选这是最常见的坑之一。3. 逐步编译从 boost 到 flann 的完整命令行方案3.1 编译 boostb2 参数详解boost 不需要 CMake它使用自己的 b2 构建系统。进入 boost 源码目录后先执行 bootstrap.bat 生成 b2.exe然后执行如下命令b2 toolsetgcc address-model64 architecturex86 --prefixD:/dev/boost_install --build-dirD:/dev/boost_build -j 8 --layoutsystem variantrelease linkstatic runtime-linkstatic threadingmulti install上面命令的每个参数都有明确作用toolsetgcc告诉 boost 使用 MinGW 的 gcc 编译器而不是系统默认的 MSVCaddress-model64与目标平台位数一致如果这里设错了后续链接 PCL 时会报architecture mismatch的错误。--layoutsystem代表生成不带版本号的库文件例如 libboost_system.a否则会生成 libboost_system-mgw81-mt-x64-1_75.a 这种长名字文件会对 CMake 的 find_package 查找逻辑造成困扰。runtime-linkstatic表示链接器运行时采用静态方式这在之后配合 PCL 编译时会简化 DLL 拷贝工作。等待编译完成后将D:/dev/boost_install加入系统环境变量或 CMake 的CMAKE_PREFIX_PATH。验证 boost 是否编译成功可以执行以下命令ls D:/dev/boost_install/lib/libboost_system.a如果没有生成该文件检查 boost 编译日志中的error: could not find a Boost installation字样多半是--prefix路径写错或权限不足。需要提醒的是 boost 编译耗时较长在 8 核机器上大约 20 分钟期间不要打开其他高负载程序避免编译中断导致部分目标文件损坏。3.2 eigenheader-only 库的极简处理方式eigen 是所有依赖里唯一不需要编译的库它不需要生成 .a 或 .dll。从官方仓库下载源码后整个unsupported和Eigen两个文件夹需要保留。推荐做法是将其解压后拷贝到D:/dev/eigen然后设置 CMake 变量set(EIGEN_INCLUDE_DIR D:/dev/eigen) set(EIGEN_INCLUDE_DIRS D:/dev/eigen)之所以要显式规定是因为 eigen 的版本检查依赖signature_of_eigen3_matrix_library文件如果 CMake 在不同路径下找到了其他版本的 eigen编译时会出现EIGEN_VERSION_MISMATCH的错误。另一个问题是PCL 的pcl_common模块对 eigen 的版本有硬性检查要求最低版本 3.2推荐直接用最新稳定版 3.4。处理完这一步可以写一个临时 CMakeLists.txt 调用find_package(Eigen3 REQUIRED)验证是否成功过程中注意输出中EIGEN3_VERSION是否为期望值。3.3 flann编译时最容易被忽略的依赖细节flann 的源码使用 CMake 构建系统但它在 Windows 下有个特殊之处无法直接将 MinGW 作为生成器使用需要在 CMake 图形界面中指定生成器为MinGW Makefiles同时把 C 和 C 编译器路径指向 Qt 的 MinGW bin 目录。如果不指定CMake 默认会去查找微软的 cl.exe导致生成失败。cmake -G MinGW Makefiles -DCMAKE_BUILD_TYPERelease -DCMAKE_PREFIX_PATHD:/dev/qt/5.15.2/mingw81_64 -DBUILD_MATLAB_BINDINGSOFF -DBUILD_PYTHON_BINDINGSOFF -DBUILD_CUDA_LIBOFF -DCMAKE_INSTALL_PREFIXD:/dev/flann_install .. mingw32-make -j 8 mingw32-make install参数-DBUILD_MATLAB_BINDINGSOFF是必须的因为 flann 的 MATLAB 绑定需要 VC 的 mex 编译器MinGW 环境下即使设为 ON 也不会成功只会拖慢速度。-DBUILD_CUDA_LIBOFF同理除非你的机器上有完整 CUDA 工具链。编译完成后检查D:/dev/flann_install/lib/libflann.dll和libflann_s.a是否存在。静态库.a文件在后续链接 PCL 时会被优先选择但如果你计划把 PCL 作为动态库使用需要保留.dll文件。3.4 qhull容易被版本迷惑的数学库qhull 是一个用于计算凸包的 C 库PCL 的凸包模块和部分滤波算法依赖它。编译命令如下cmake -G MinGW Makefiles -DCMAKE_BUILD_TYPERelease -DCMAKE_INSTALL_PREFIXD:/dev/qhull_install -DQHULL_USE_MANUAL_PRECOMPILED_HEADERSOFF .. mingw32-make -j 8 mingw32-make installqhull 的 CMake 配置中有个常见陷阱它默认会生成一个qhull_r的动态库同时也会生成静态库libqhullstatic_r.a这两个库的存在会让 CMake 的 find_package 同时发现多个目标。建议在编译后删除不需要的静态库或保留动态库即可因为 PCL 编译时会通过QHULL_LIBRARY变量查找。如果后面 PCL 配置出现Could NOT find Qhull的错误检查 qhull 安装目录下是否存在qhull/libqhull_r/pch目录如果存在但 CMake 仍找不到手动指定-DQHULL_INCLUDE_DIR和-DQHULL_LIBRARY两个变量。4. VTK 编译与 Qt 集成的核心矛盾点4.1 VTK 9 还是 VTK 8.2如何决策VTK 的选择直接影响 PCL 的渲染模块能不能正常用。VTK 8.2 对 Qt4 的支持较为完备但使用 Qt5 时会有部分宏冲突VTK 9 系列则全面转向 Qt5/Qt6 的适配模块化体系更清晰。结合 Qt 5.15 的现状推荐选择 VTK 9.0.3。它的 CMake 参数相对稳定且 PCL 1.12 版本能直接识别 VTK 9 的组件名称。如果选择更高版本如 9.2.6在编译 PCL 时可能遇到vtkAVIWriter等模块被移除而导致的 CMake 报错。VTK 编译的关键在于打开 Qt 相关的模块同时关闭测试和示例以节省时间。命令行参考如下cmake -G MinGW Makefiles -DCMAKE_BUILD_TYPERelease -DCMAKE_PREFIX_PATHD:/dev/qt/5.15.2/mingw81_64 -DVTK_GROUP_ENABLE_QtYES -DVTK_QT_VERSION5 -DQT_QMAKE_EXECUTABLED:/dev/qt/5.15.2/mingw81_64/bin/qmake.exe -DVTK_GROUP_ENABLE_RenderingYES -DVTK_GROUP_ENABLE_ImagingYES -DVTK_GROUP_ENABLE_ViewsYES -DBUILD_TESTINGOFF -DBUILD_EXAMPLESOFF -DCMAKE_INSTALL_PREFIXD:/dev/vtk_install ..-DQT_QMAKE_EXECUTABLE这行参数特别关键它告诉 VTK 的编译脚本直接使用 Qt 自带的 qmake避免从 PATH 中寻找其他版本这是很多教程都没写清楚的地方。-DVTK_GROUP_ENABLE_QtYES则显式激活 VTK 的两个 Qt 相关模块 QVTKWidgetPlugin 和 QVTKOpenGLNativeWidget这两个模块是后续在 QWidget 中嵌入 PCL 可视化窗体的底层依赖。编译涉及模块较多建议先直接编译全部目标再等待错误VTK 9.0.3 使用 MinGW 在 8 核处理器上编译时间约 30 分钟。mingw32-make -j 8 mingw32-make install4.2 Qt 版本与 VTK 的命名空间冲突编译 VTK 过程中最容易出现的问题是QVTKWidget与 Qt 自身的QWidget在继承关系上的冲突表现为报错含有error: undefined reference to vtkGUISupportQt::vtkEventQtSlotConnect::connect。此问题的出现通常是因为 VTK 在编译时没有找到 Qt 的 moc 工具或者 VTK_QT_VERSION 参数与 qmake 的实际版本不一致。解决该问题的正确手段是先确认 CMake 缓存中存在Qt5Core_DIR等变量并指向 Qt 安装目录的lib/cmake/Qt5Core路径。若不存在则再次调用 cmake 命令追加-DQt5_DIRD:/dev/qt/5.15.2/mingw81_64/lib/cmake/Qt5然后mingw32-make clean后重新编译。另一个常见现象是error: cannot find -lQt5::Core这主要是因为 Qt 的 CMake 导出文件里的库名格式与 MinGW 的生成器不匹配将CMAKE_PREFIX_PATH同时加入 Qt 和 VTK 安装目录可解决。4.3 编译 VTK 时的表格化资源清单模块组启用选项用途是否必须Qt 支持VTK_GROUP_ENABLE_QtYESQVTKOpenGLNativeWidget 嵌入必须渲染VTK_GROUP_ENABLE_RenderingYES点云三维渲染必须成像VTK_GROUP_ENABLE_ImagingYES深度图转换与滤波视需求视图VTK_GROUP_ENABLE_ViewsYES多视图交互推荐测试BUILD_TESTINGOFF跳过编译测试程序必须关闭示例BUILD_EXAMPLESOFF跳过编译示例必须关闭VTK 编译成功后并且你需要把D:/dev/vtk_install/lib下所有 dll 文件拷贝到 Qt 的mingw81_64/bin目录下或者添加到 PATH 环境变量的最前面。这一步若不执行后续运行任何依赖 VTK 的程序都会提示找不到vtkCommonCore-9.0.dll。我一般会额外建立一个D:/dev/all_dll目录把所有第三方库的 dll 统一放到其中配合 Qt 的windeployqt工具一起使用便于维护部署包。5. 编译 PCL 主工程CMake 参数全局编排5.1 一层 CMake 命令打通所有依赖PCL 的主源码体积大且 CMake 选项极多但 Windows 下真正需要手动指定的只有依赖库路径与少数模块开关。以下命令可以在 MinGW 环境下一次性配置完成cmake -G MinGW Makefiles -DCMAKE_BUILD_TYPERelease -DCMAKE_PREFIX_PATHD:/dev/boost_install;D:/dev/eigen;D:/dev/flann_install;D:/dev/qhull_install;D:/dev/vtk_install;D:/dev/qt/5.15.2/mingw81_64 -DWITH_VTKON -DWITH_QTON -DWITH_OPENMPON -DWITH_PCAPOFF -DWITH_PNGOFF -DWITH_LASOFF -DBUILD_appsOFF -DBUILD_examplesOFF -DCMAKE_INSTALL_PREFIXD:/dev/pcl_install ..WITH_QT的开关在部分新闻版本中会被忽略因为 PCL 对 Qt 的依赖是通过 VTK 间接引入的但你显式加上没有坏处。WITH_PCAP、WITH_PNG和WITH_LAS若非实际需要尽量设为 OFF否则 CMake 会尝试查找 libpcap、libpng、LASlib 等额外依赖增加不确定性。BUILD_appsOFF跳过 PCL 自带的工具集编译可以在首次编译时节省 10 分钟以上。5.2 处理 CMake 找不到库的问题PCL 的 CMake 脚本通过find_package(Boost)、find_package(FLANN)、find_package(Qhull)等宏来搜索依赖。这些宏不会去系统 PATH 找只会在CMAKE_PREFIX_PATH指定的目录中搜索。因此每次编译失败先检查你的CMAKE_PREFIX_PATH是否包含所有依赖的安装根目录且目录结构是否为root/include、root/lib的标准布局。如果某个库安装在非标准位置可以单独加一个-DXXX_DIR变量-DBOOST_ROOTD:/dev/boost_install -DFLANN_ROOTD:/dev/flann_install -DQHULL_ROOTD:/dev/qhull_install编译 PCL 时也可能遇到Could NOT find Qt5的报错这与你前面 VTK 编译时是否成功找到 Qt 无直接关系必须在 PCL 的 CMake 命令中再次显式指定如下环境变量set Qt5_DIRD:/dev/qt/5.15.2/mingw81_64/lib/cmake/Qt55.3 编译完成后验证全部依赖的 QT 集成情况生成后的安装物包括PCLConfig.cmake和PCLConfigVersion.cmake它们存放在D:/dev/pcl_install/share/pcl-1.12目录下。为了确保安装没有问题在编译自己的 Qt 工程前先执行以下命令行验证库可被正常链接cmake --find-package -DNAMEPCL -DCOMPILER_IDGNU -DLANGUAGECXX -DMODEEXIST如果输出-- Found PCL则说明 CMake 认知正常。接着创建一个测试目录里面写一个 5 行的 CMakeLists.txtcmake_minimum_required(VERSION 3.10) project(pcl_test) find_package(PCL REQUIRED COMPONENTS common io) include_directories(${PCL_INCLUDE_DIRS}) add_executable(${PROJECT_NAME} main.cpp) target_link_libraries(${PROJECT_NAME} ${PCL_LIBRARIES})在main.cpp中调用任意一个 PCL API 头文件并构建链接若链接过程没有缺少符号说明所有静态库和 DLL 依赖已经闭合。这一步会暴露 boost 的 layout 问题如果你发现libboost_system-mgw81-mt-x64-1_75.a这种文件名出现说明 boost 编译时 layout 参数未生效返回去用--layoutsystem重编 boost 就很明确了。5.4 使用 Qt 工程调用 PCL 的 CMake 最低模板将 PCL 集成到 Qt 的 QWidget 工程中需要让 CMake 同时找到 Qt 和 PCL。模板文件如下cmake_minimum_required(VERSION 3.20) project(pointcloud_viewer) set(CMAKE_CXX_STANDARD 14) set(CMAKE_AUTOMOC ON) find_package(Qt5 REQUIRED COMPONENTS Widgets) find_package(PCL REQUIRED COMPONENTS common io visualization) add_executable(${PROJECT_NAME} main.cpp viewer.cpp) target_link_libraries(${PROJECT_NAME} Qt5::Widgets ${PCL_LIBRARIES})其中CMAKE_AUTOMOC ON会让 CMake 自动处理 Qt 的 Q_OBJECT 宏无需手动运行 moc。如果可视化模块无法编译如找不到vtkAutoInit.h在find_package(PCL ...)前添加一行include_directories(D:/dev/vtk_install/include/vtk-9.0)同时检查你的 VTK 库文件名是否包含vtkGUISupportQt-9.0模块。PCL 的 visualization 组件编译时CMake 会自动通过 VTK 的 target 处理宏定义不需要再手动添加VTK_USE_QVTK之类的定义但前提是 VTK 编译时开启了 Qt 组模块否则这里会链接失败。6. 部署时一次拿全的 DLL 清单与运行时排错技巧6.1 用 windeployqt 配合第三方路径完成收集编译好的点云程序在部署机器上需要 Qt 运行库和 PCL/VTK 的第三方 DLLwindeployqt 只能收集 Qt 自身的依赖不会处理 PCL 的。常见做法是先执行 windeployqt 收集 Qt 相关文件D:/dev/qt/5.15.2/mingw81_64/bin/windeployqt.exe --release --no-translations --no-system-d3d-compiler --no-opengl-sw D:/build/pointcloud_viewer.exe执行完后在 exe 目录中会出现 Qt5Core.dll、Qt5Widgets.dll、platforms/qwindows.dll 等必要文件。之后再从D:/dev/vtk_install/bin和D:/dev/pcl_install/bin手动拷贝带lib前缀的 DLL 到同一目录。DLL 名称来源库是否必选libboost_system.dllboost必须libpcl_common.dllPCL必须libpcl_io.dllPCL必须libflann.dllflann必须libqhull_r.dllqhull推荐vtkCommonCore-9.0.dllVTK必须vtkRenderingQt-9.0.dllVTK必须libgcc_s_seh-1.dllMinGW必须拷贝时建议使用下述命令逐一确认依赖比肉眼扫描更可靠D:/dev/mingw/bin/objdump.exe -p D:/build/pointcloud_viewer.exe | grep DLL Name该命令会列出可执行文件所有依赖的 DLL 名称然后逐个核对是否存在于 exe 同级目录。其中容易被忽略的是libstdc-6.dll它是 MinGW 特有的 C 标准库实现若缺失程序启动时不会给出中文提示只会静默退出。6.2 运行时崩溃的快速定位手段程序启动后如果窗口无法显示多半是 Qt 平台插件路径错误报错信息形如This application failed to start because no Qt platform plugin could be initialized。这是因为 QWidget 程序找不到platforms目录请检查 windeployqt 是否生成了对应文件夹。若生成但仍报错将平台插件目录完整拷贝到部署目录后再测试一次。另一类高频问题是 PCL 的visualization模块打开一个空窗口后便闪退常见原因与 VTK 的 OpenGL 渲染有关。先运行 Windows 自带的dxdiag确认 GPU 驱动支持 OpenGL 3.2 以上如果使用虚拟机则修改 VTK 渲染设备为软件渲染在代码中增加vtkOpenGLRenderWindow::SetGlobalMaximumNumberOfMultiSamples(0);6.3 二次复用第三方目录的维护技巧整个编译流程完成后我把D:/dev下所有安装目录统一维护为一个目录树三级结构为include、lib与bin。下次新开 Qt 工程时只需要在系统环境变量中加入CMAKE_PREFIX_PATHCMake 的 find_package 就能一次性找到所有依赖不需要为每个工程手动指定-D参数。这一步看似简单但在多个工程、多分支开发时能省下大量时间每次升级依赖库版本时也可以直接从 dev 目录替换lib文件后再重编译不会影响已存在的工程配置。本文还有配套的精品资源点击获取
返回列表