ARTICLE DETAIL

资讯详情

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

MinGW编译PCL全家桶:Qt点云开发环境搭建指南

MinGW编译PCL全家桶:Qt点云开发环境搭建指南 简介面向需要在Windows下使用Qt MinGW工具链进行三维点云处理的开发者这是一份基于Qt MinGW编译的PCL点云库及其依赖库整合包涵盖Boost、Eigen、FLANN、Qhull、VTK等关键组件可解决逐项手动编译依赖耗时长、易出错的问题。压缩包共2000个文件大小151.31MB其中以1997个hpp头文件为主覆盖PCL核心功能及全部依赖库接口附带txt、pdf与doc文档提供编译说明、库作用介绍及配置指引。目前已有36人学习下载适合刚接触PCL或需要在Qt环境下快速搭建点云开发环境的中级工程师。借助这份整合包可直接获取头文件层面的完整依赖集合并理清各库分工Eigen负责矩阵运算FLANN用于近似近邻搜索Qhull处理凸包与三角剖分VTK支撑三维可视化。目录结构保留各库原有层级便于按模块引用可大幅降低环境搭建门槛快速进入点云预处理、特征匹配与表面重建等开发工作。1. 用 MinGW 编译 PCL 全家桶Windows 点云开发里最难走但最值得走的一条路Windows 上做点云处理绕不开 PCLPoint Cloud Library而把 PCL 接进 Qt 界面最常见也最折磨人的一条路就是“基于 Qt 自带 MinGW 工具链把 PCL 及其所有依赖库 boost、eigen、flann、qhull、VTK 全部源码编译一遍”。这件事难在不是装一个安装包就能完事而是要同时满足 Qt 的 32/64 位、MinGW 的编译器版本、C 运行时库、以及一堆依赖库的 ABI 兼容。很多人卡在“链接时一堆未定义符号”或“cannot mix incompatible Qt library”这种玄学错误上其实根子都是编译器血统不对。这篇笔记的读者是已经在用 Qt Creator、知道 CMake 怎么写、但被 PCL 官方预编译包只支持 MSVC 这件事卡住的人。我会把从 boost 到 VTK再到 PCL 本体的完整编译命令、CMake 参数、以及我踩过的五个典型坑都拆开讲保证你照着走能跑通一个 QtMinGWPCL 的窗口程序。这条路时间成本不低但一旦编译成功你的 Qt 工程就能彻底摆脱 MSVC 与 MinGW 混用的黑匣子后续升级依赖库也只要重跑一遍脚本。2. PCL 依赖链的本质编译器血统决定一切2.1 依赖树先理清boost/eigen/flann/qhull/VTK 各管哪一块PCL 在 Windows 上编译官方文档会告诉你先装一堆第三方库但不会告诉你哪一个是“头文件库”、哪一个是“二进制库”更不会告诉你它们之间还有隐藏的版本耦合。我先按职责拆一下boostPCL 里大量用到智能指针shared_ptr、线程、文件系统、随机数和一些几何算法。boost 里真正被链接的库主要是boost_system、boost_filesystem、boost_thread、boost_chrono、boost_date_time等。编译 boost 是所有步骤里最耗时的也是版本敏感度最高的。eigen纯头文件库提供矩阵运算。PCL 的核心数据结构比如Eigen::Matrix4f直接暴露给用户所以 eigen 的版本要和 PCL 要求的版本匹配否则模板报错会异常难查。flann最近邻搜索库PCL 的 KdTree 用它做底层。flann 是自己写 C 的多半还需要配合lz4等压缩库而且它的 CMake 配置在 MinGW 下容易出“找不到编译器特性”的问题。qhull凸包计算库PCL 的ConvexHull、Delaunay 三角化依赖它。qhull 很老但源码里 Windows 相关的宏写得不太好MinGW 下容易遇到__declspec(dllexport)未定义之类的怪错。VTKPCL 的可视化模块核心负责 3D 渲染、交互、窗口显示。VTK 的编译是第二耗时大户而且它默认会用 OpenGL2在 Windows 上需要额外注意 Qt 版本对接。这五个库eigen 最简单头文件复制即可qhull 和 flann 居中boost 和 VTK 最复杂。它们的编译顺序必须固定先 boost/eigen再 flann/qhull然后 VTK最后 PCL。因为 PCL 的 CMake 会同时检查这些库的版本和编译类型顺序反了会导致 CMake 缓存混乱。2.2 MSVC 与 MinGW 的 ABI 差异混用二进制库为什么必然翻车“MSVC 和 MinGW 区别”是很多人一开始就搞不清楚的点。MSVC 的 C 运行时是MSVCP140.dll那一套MinGW 用的是libstdc-6.dll两者不仅动态库不同符号修饰规则name mangling、异常处理模型、结构体内存布局都可能不一样。这就意味着你用 MinGW 编译 Qt 工程去链接一个 MSVC 编译好的 PCL 静态库链接器会报“未定义引用”或者更离谱的“重复定义”这不是你代码写错了而是 ABI 不兼容。更隐蔽的问题在 Qt 本身Qt 官方在 Windows 上提供的预编译二进制分两套一套是 MSVC 2019/2022 对应的一套是 MinGW 对应的。如果你装了 Qt 6.2 MinGW 版又手贱从 PCL 官网下载了基于 MSVC 的 PCL 1.12 预编译包那即使你能编译过运行时一加载 Qt 插件就会弹 “q.qpa.plugin could not find the Qt platform plugin windows”或者干脆报 “cannot mix incompatible Qt library (version 0x50601) with this library”。这个错误就是典型的二进制混用。所以结论是要么全部用 MSVC要么全部用 MinGW中间没有后悔药。我选择 MinGW因为我用的是 Qt Creator 自带的 MinGW 工具链不想再装一套 Visual Studio而且最终发布程序时可以只带几个 MinGW 运行时 DLL体积和部署都更可控。2.3 选型建议什么时候值得自己编译什么时候直接下现成包先把丑话说在前面如果你只是写论文要用 PCL或者只是验证算法不要自己编译。官方有一个 pre-built 的 PCL 安装包基于 MSVC配合 VS2017/2019 三步就能配好。但如果你想做 Qt 界面而且你的 Qt 是 MinGW 版那基本没有现成 PCL 包可用。社区里偶尔有人分享 MinGW 版 PCL 编译产物但版本往往和你手头的 Qt 对不上且缺少调试符号出问题没法查。我自己判断的标准有三条第一Qt 是否已经用 MinGW 写了大量业务代码第二是否需要 PCL 的 Debug 库来调试崩溃第三后续是否要改 PCL 源码或加模块。满足任意两条就值得自己编译。这篇文章就是你决定自己编译后的完整路线图。这里还要提醒一个版本对齐问题根目录下我编译用的组合是Qt 5.12.12 MinGW 7.3 32位因为 PCL 1.12 对 GCC 7 支持最好、boost 1.72、eigen 3.3.7、flann 1.9.1、qhull 2015.2、VTK 8.2.0、PCL 1.12.0。这套组合是经过社区大量验证的“稳定搭配”。你需要根据自己的 Qt 版本调整基本原则是Qt 的编译器版本要 ≥ 依赖库编译时用的 GCC 版本否则链接时会有 C11 ABI 变化导致的兼容问题。3. 准备编译环境工具链、源码和路径规划3.1 从 Qt 安装目录里挑 MinGW 工具链不自找麻烦的方式很多人第一反应是上网下载“MinGW 官网下载”然后再装一个独立的 MinGW-w64。但如果你已经装了 Qt 5.12其实 Qt 自带了一套编译好的 MinGW 工具链和配套的 Qt 库就在Qt\Qt5.12.12\Tools\mingw730_32下。直接用这一套能保证编译器、运行库和 Qt 库的版本完全匹配省去大量排查时间。我一般不会额外装其他版本 MinGW原因很简单Qt 库是拿这一套 MinGW 编译的你换一个更新版本的 GCC 去编译 PCL再链接 Qt 库大概率会出现 C ABI 不兼容或运行时崩溃这属于自己给自己挖坑。正确做法是打开 Qt Creator在“工具—选项—构建套件Kits”里确认编译器指向mingw730_32\bin\g.exeqmake 指向Qt\5.12.12\mingw73_32\bin\qmake.exe。准备阶段的另一个重要操作是环境变量。我会建一个统一的第三方库根目录比如D:\PCL\thirdparty然后把编译好的各库都安装到这个目录下不同的子目录里。然后用管理员权限设置系统环境变量set PATHD:\Qt\Qt5.12.12\Tools\mingw730_32\bin;%PATH% set PATHD:\PCL\thirdparty\bin;%PATH%这里的D:\PCL\thirdparty\bin是后续所有库的 DLL 输出目录之后编译 PCL 和运行程序都要依赖它。我建议把 PATH 写进系统环境变量而不是只在命令行里 export因为 CMake 在查找库和运行时加载 DLL 时都会读系统 PATH命令行临时设的很容易漏。3.2 下载依赖库源码与版本匹配清单这一步没什么捷径把源码包准备好就行。我列一下我当时用的版本和下载方式依赖库版本安装方式备注boost1.72.0源码编译只编译所需静态库不要全编eigen3.3.7头文件复制用 CMake 生成并安装到前缀目录flann1.9.1CMake 编译需要关闭BUILD_CUDA等选项qhull2015.2CMake 编译老版本兼容性更好VTK8.2.0CMake 编译必须开启VTK_QT_VERSION5PCL1.12.0CMake 编译需要开启WITH_VTK和 Qt 支持下载源码时注意boost 的包是boost_1_72_0.zipeigen 的包是eigen-3.3.7.tar.bz2flann 和 qhull 都是 release 压缩包。VTK 和 PCL 的源码包之间有一个隐藏兼容问题PCL 1.12 要求 VTK 不低于 8.2但 VTK 9.0 的模块结构变了所以选 VTK 8.2.0 是相对安全的。VTK 源码包里有个VTKData之类的测试数据包可以在 CMake 配置阶段关掉相关测试不必下载。3.3 建立统一的前缀目录与 CMake 查找路径为了避免每个库编译时链接到不同路径下“碰巧存在”的旧版本我强制所有依赖库安装到同一前缀目录D:\PCL\thirdparty但每个库要用自己的子目录。比如 boost 安装到D:\PCL\thirdparty\boosteigen 安装到D:\PCL\thirdparty\eigenflann 安装到D:\PCL\thirdparty\flannqhull 安装到D:\PCL\thirdparty\qhullVTK 安装到D:\PCL\thirdparty\VTK。然后我在系统里新建一个 CMake 工具链文件专门给 PCL 用# MinGW-PCL.cmake set(CMAKE_SYSTEM_NAME Windows) set(CMAKE_C_COMPILER D:/Qt/Qt5.12.12/Tools/mingw730_32/bin/gcc.exe) set(CMAKE_CXX_COMPILER D:/Qt/Qt5.12.12/Tools/mingw730_32/bin/g.exe) set(CMAKE_PREFIX_PATH D:/Qt/Qt5.12.12/5.12.12/mingw73_32 D:/PCL/thirdparty/boost D:/PCL/thirdparty/eigen D:/PCL/thirdparty/flann D:/PCL/thirdparty/qhull D:/PCL/thirdparty/VTK D:/PCL/thirdparty/PCL )这个文件会在后面所有库的 CMake 配置里被反复用到。CMAKE_PREFIX_PATH 的作用是让 CMake 自动去这些目录找lib/cmake下的配置文件省得每个库都要手填-DXXX_DIR。这里有个细节CMake 查找包时按前缀路径顺序搜索所以 Qt 的路径要放在最前面否则万一某个库也带了个qt文件夹就会找错。4. 逐个编译依赖库从 boost 到 VTK 的完整命令与参数4.1 编译 boostbootstrap 与 b2 的必设参数boost 的编译在 MinGW 下比 MSVC 简单因为只需要跑bootstrap.bat mingw然后b2就能干完。但你不能傻乎乎地全库编译一编就是两小时最后发现有一半的库根本没用上。我一般只编 PCL 真正需要的几个system、filesystem、thread、chrono、date_time、regex。另外为了让发布简单我选择静态库避免带一堆 boost DLL。进入 boost 源码目录后先打开 MinGW 命令行或者直接在 Qt Creator 的工具链配置里打开执行cd D:/PCL/boost_1_72_0 bootstrap.bat mingw b2 toolsetgcc address-model32 architecturex86 ^ --with-system --with-filesystem --with-thread ^ --with-chrono --with-date_time --with-regex ^ linkstatic runtime-linkshared ^ variantrelease threadingmulti ^ --prefixD:/PCL/thirdparty/boost install参数说明address-model32对应 32 位 MinGW如果你的 Qt 是 64 位就改成 64linkstatic表示编静态库runtime-linkshared表示动态链接 MinGW 运行时即 libstdc这个是常见搭配能减少静态编译时的一些兼容问题threadingmulti是必须的因为 C 多线程库需要。注意这里的--with-*只编指定库能省掉大量编译时间。boost 编译完成后会在D:\PCL\thirdparty\boost\lib下生成一堆libboost_system-gcc7-mt-x32-1_72.a之类的静态库。命名里有gcc7表示编译器版本mt表示多线程x32表示 32 位。PCL 的 CMake 会自动检测这些命名不需要你手工指定。4.2 编译 eigen头文件库也要走 CMake 安装可能有人觉得 eigen 是纯头文件库直接复制 include 目录就行。但我不建议直接复制因为 PCL 的 CMake 配置是通过Eigen3_DIR来找 eigen 的而只有用 CMake 安装过的 eigen 才会生成Eigen3Config.cmake等文件。直接复制头文件会导致 PCL 的 CMake “找到了头文件但找不到包配置文件”报错很莫名其妙。eigen 的编译几乎可以无脑跑mkdir D:/PCL/build-eigen cd D:/PCL/build-eigen cmake .. -G MinGW Makefiles ^ -DCMAKE_TOOLCHAIN_FILED:/PCL/MinGW-PCL.cmake ^ -DCMAKE_INSTALL_PREFIXD:/PCL/thirdparty/eigen mingw32-make install这里用MinGW Makefiles生成器而不是默认的Unix Makefiles是因为我们要配合 MinGW 工具链使用。安装完成后D:\PCL\thirdparty\eigen\share\eigen3\cmake下就有Eigen3Config.cmake了。注意 eigen 只提供头文件所以没有 DLL 问题但安装目录里会有include\eigen3和include\unsupported两个目录PCL 的find_package(Eigen 3.3 REQUIRED)会自动处理。4.3 编译 flann 与 qhull两个小库但坑不少flann 和 qhull 编译命令类似但有几个关键开关直接影响 PCL 的兼容性。flann 的 CMake 配置命令mkdir D:/PCL/build-flann cd D:/PCL/build-flann cmake .. -G MinGW Makefiles ^ -DCMAKE_TOOLCHAIN_FILED:/PCL/MinGW-PCL.cmake ^ -DCMAKE_INSTALL_PREFIXD:/PCL/thirdparty/flann ^ -DBUILD_CUDA_LIBOFF -DBUILD_PYTHON_BINDINGSOFF ^ -DBUILD_MATLAB_BINDINGSOFF -DBUILD_EXAMPLESOFF ^ -DBUILD_TESTSOFF -DUSE_OPENMPOFF mingw32-make install这里有个血泪点USE_OPENMP在 MinGW 下默认是 ON但 MinGW 自带的 OpenMP 运行时libgomp和 flann 的静态库链接时容易出问题表现为运行时 flann 的并行分支永远不执行或者直接崩溃。我后来直接关闭 OpenMPPCL 的 KdTree 性能会略降但单线程模式更稳定点云规模不大时完全能接受。qhull 编译命令mkdir D:/PCL/build-qhull cd D:/PCL/build-qhull cmake .. -G MinGW Makefiles ^ -DCMAKE_TOOLCHAIN_FILED:/PCL/MinGW-PCL.cmake ^ -DCMAKE_INSTALL_PREFIXD:/PCL/thirdparty/qhull ^ -DBUILD_SHARED_LIBSOFF -DTARGET_CPUGENERIC mingw32-make installTARGET_CPUGENERIC很重要如果默认值是 x86qhull 的某些内联汇编或 CPU 特性检测会在 MinGW 下编译不过。另外BUILD_SHARED_LIBSOFF是为了生成静态库这样后面 PCL 链接时不会有一堆 qhull 动态库的调用约定问题。如果你有多个项目要用 qhull 动态库也可以改成 ON但必须保证所有 PCL 依赖库的链接方式一致全静态或全动态否则混合链接会出重复符号。4.4 编译 VTKQt 模块要一起打开VTK 是这五个依赖库中最大的一块编译时长可能超过半小时。它的 CMake 选项很多但核心就几个mkdir D:/PCL/build-vtk cd D:/PCL/build-vtk cmake .. -G MinGW Makefiles ^ -DCMAKE_TOOLCHAIN_FILED:/PCL/MinGW-PCL.cmake ^ -DCMAKE_INSTALL_PREFIXD:/PCL/thirdparty/VTK ^ -DVTK_QT_VERSION5 ^ -DVTK_Group_QtON ^ -DVTK_Group_RenderingON ^ -DVTK_USE_QVTK_QOpenGLWidgetON ^ -DBUILD_TESTINGOFF -DBUILD_EXAMPLESOFF ^ -DCMAKE_BUILD_TYPERelease mingw32-make -j4 install关键参数是VTK_QT_VERSION5这里不是指 Qt 大版本而是指 VTK 的 Qt 接口版本VTK 里分 Qt4/Qt5 接口。如果你的 Qt 是 5.12VTK 8.2 就必须选VTK_QT_VERSION5否则QVTKWidget类的头文件会引用 Qt4 的模块编译时直接报一堆找不到QtGui的头文件。VTK_USE_QVTK_QOpenGLWidgetON是让 VTK 支持 Qt5 的QOpenGLWidget渲染窗口这个选项在 VTK 8.2.0 里默认是打开的但手动写出来能避免和默认值混淆。这里必须强调mingw32-make -j4的-j4是并行编译线程数要根据你内存调整我 8G 内存用-j4刚好内存不足时容易在链接阶段 OOM。4.5 编译 PCL 本体关键 CMake 开关与链接顺序所有依赖库都安装好后终于到了 PCL 本体。PCL 的 CMake 配置选项比较多但核心就这些mkdir D:/PCL/build-pcl cd D:/PCL/build-pcl cmake .. -G MinGW Makefiles ^ -DCMAKE_TOOLCHAIN_FILED:/PCL/MinGW-PCL.cmake ^ -DCMAKE_INSTALL_PREFIXD:/PCL/thirdparty/PCL ^ -DPCL_QT_VERSION5 ^ -DWITH_VTKON ^ -DWITH_OPENGLON ^ -DWITH_QhullON ^ -DWITH_FLANNON ^ -DWITH_BOOSTON ^ -DWITH_EIGENON ^ -DCMAKE_BUILD_TYPERelease mingw32-make -j4 installPCL_QT_VERSION这个变量是 PCL 自己定义的用来告诉它要用的 Qt 接口版本必须等于 5。WITH_VTKON才会把pcl_visualization模块编进来否则你的 Qt 界面里没法用PCLVisualizer控件。WITH_OPENGLON是配套的因为 VTK 渲染底层要 OpenGL。PCL 编译时还有个隐藏顺序问题如果你在配置步骤之前没有把 VTK 的QVTKWidgetPlugin编译出来WITH_VTKON可能找不到 Qt 接口CMake 会自动把WITH_VTK降级为 OFF 并打印警告。我建议在编译 VTK 时确认是否生成了libvtkGUISupportQt-8.2.a和QVTKWidgetPlugin.dll在 VTK 的lib/plugins/sqldrivers目录下如果没有说明VTK_Group_QtON没生效需要回看 VTK 的 CMakeLog.txt。PCL 编译完成后会在D:\PCL\thirdparty\PCL\bin下生成pcl_visualizer_d.dll等若干 DLL记得把D:\PCL\thirdparty\PCL\bin和D:\PCL\thirdparty\VTK\bin加进系统 PATH否则运行 Qt 程序时加载不到这些动态库。5. 编译与链接避坑我遇到的五个典型问题5.1 错误“cannot mix incompatible Qt library”的根源现象编译通过但一运行 Qt 程序程序启动时就弹窗报fatal: cannot mix incompatible Qt library (version ex50601) with this library或者控制台输出qt.qpa.plugin: could not find the Qt platform plugin windows。原因这个错误几乎都是因为 Qt 的 DLL 路径错乱导致的。最典型的情况是你系统 PATH 里同时存在 MSVC 编译的 Qt 库和 MinGW 编译的 Qt 库比如你之前装过 PCL 官方预编译包它自带了一套 MSVC 版 Qt DLLQt5Core.dll等然后你的 Qt Creator 工程又用 MinGW 工具链运行时系统先在 PATH 里找到了 MSVC 版 Qt 的 DLL于是 Qt 内部的版本校验发现不一致直接拒绝加载。解决删除或卸载多余的 PCL 预编译包并在运行时保证 PATH 里只有一套 Qt。我的做法是在 Qt Creator 的“构建运行环境”里把 MinGW 的 Qt 目录D:\Qt\Qt5.12.12\5.12.12\mingw73_32\bin放到系统 PATH 最前面同时把 VS 相关的 Qt 路径从 PATH 里删掉。如果还报错就用Process Explorer或Dependencies查看进程实际加载的 Qt5Core.dll 路径这是最直接的确认方式。5.2 boost 版本不对导致模板无法解析现象PCL 编译时出现一堆模板错误比如error: swap is not a member of std::__1或者no member named shared_ptr in namespace boost。明明 boost 已经编译好了但 CMake 的find_package(Boost)找到了代码却用不了。原因常见原因是系统 PATH 里残留了其他版本的 boost 头文件或者你下载的是 boost 1.66 而 PCL 1.12 内部用了boost::filesystem::path的新接口二者不匹配。还有一种情况是 boost 编译时用的编译器版本和 PCL 编译时用的不一致导致BOOST_LIB_DIAGNOSTIC宏诊断出的版本名和 CMake 查找的不一致。解决先卸载掉所有旧 boost包括 conda、vcpkg 装到系统里的然后确认 PCL 的 CMake 缓存里Boost_INCLUDE_DIR指向的是D:/PCL/thirdparty/boost/include/boost-1_72。如果仍然报模板错误把 PCL 的-DBoost_USE_STATIC_LIBSON加上去掉旧版本动态库的影响。另外在 PCL 编译前手动执行一下echo %BOOST_ROOT%如果环境变量里有旧路径直接把变量删掉CMake 就不会优先找它了。5.3 flann 的命名空间冲突与“已定义”报错现象PCL 编译到pcl/kdtree模块时报一堆链接错误“multiple definition offlann::IndexParams::~IndexParams()” 或 “undefined reference toflann::KDTreeCuda3DIndex...”。原因flann 默认会用内部命名空间flann但如果 PCL 里同时引用了 flann 的旧头文件和新头文件或者 flann 编译时FLANN_STATIC宏没定义就会出现符号冲突。MinGW 下还特别容易因为 flann 使用了lz4库而 PCL 没有显式链接 lz4导致LZ4_compress_default未定义引用。解决在编译 flann 时增加一个 CMake 定义-DCMAKE_CXX_FLAGS-DFLANN_STATIC并用-DBUILD_STATIC_LIBSON。然后在编译 PCL 时手工给CMAKE_EXE_LINKER_FLAGS加上-llz4。lz4 的 MinGW 版可以从 Qt 自带的mingw730_i686的lib目录中找到liblz4.a把它复制到 flann 的lib目录下CMake 就能找到了。5.4 qhull 和 Qhull 命名冲突现象PCL 编译pcl/surface模块时报错error: Qhull is not a class or namespace。原因qhull 库的 C 头文件里有一个类叫QhullPCL 自己也有一个Qhull类在pcl/surface/qhull头文件里两者在同一个编译单元时会发生命名冲突。MinGW 下由于头文件包含顺序和宏定义不同这种冲突更容易暴露。解决这是 PCL 1.12 的老问题。最稳妥的办法是不要升级 qhull 到 2015.2 之后的版本因为新版本改了头文件布局但改进不彻底。如果你必须用新 qhull可以在编译 PCL 时加上-DPCL_NO_PRECOMPILEON来跳过预编译头这样能缓解冲突。另外在 PCL 的pcl/surface/qhull目录下找到qhull.cpp把它的#include qhull/src/qhull_a.h改成#include qhull/src/qhull_b.h并用#undef清理掉 Qhull 相关符号这个方法我在自己的工程里验证过可以绕开冲突不改 PCL 源码。5.5 链接时找不到 -lpublic 这类 MinGW 特有报错现象PCL 链接阶段报错error: cannot find -lpublic或者cannot find -lQt5::Core。原因MinGW 的 GCC 链接器在处理 CMake 生成的导入库时会把库名解析为libpublic.a但如果某个库没有生成对应的导入库或者 CMake 配置里把 Qt 的库名写成了Qt5::Core这种 CMake 目标名GCC 直接用它去-l找文件自然找不到。这种情况多发生在你手工把find_package(Qt5)的库变量传给 PCL 的 CMake 时类型不对。解决不要手工传Qt5::Core给旧版 CMake 配置的模块。我一般把 PCL 的 CMake 配置里的Qt5_DIR变量明确指定到 Qt 的lib/cmake/Qt5目录这样find_package(Qt5)会生成正确的导入库文件。另外检查一下有没有把CMAKE_SHARED_LINKER_FLAGS误设成包含-Wl,--whole-archive这个会导致链接器去找所有符号从而挑出public这种无效名字。6. 把 PCL 接到 Qt 工程CMake 配置与运行期验证6.1 一个最简的 QtPCL 点云显示 CMakeLists所有依赖库编译完最后一步就是在你的 Qt 工程里接通 PCL。这里我直接给一个最小可用的 CMakeLists.txt它会在 QMainWindow 里显示一个点云cmake_minimum_required(VERSION 3.10) project(CloudViewer) set(CMAKE_CXX_STANDARD 14) set(CMAKE_INCLUDE_CURRENT_DIR ON) find_package(Qt5 COMPONENTS Widgets OpenGL REQUIRED) find_package(PCL 1.12 REQUIRED COMPONENTS common io visualization) find_package(VTK 8.2 REQUIRED) find_package(Eigen3 3.3 REQUIRED) add_executable(CloudViewer main.cpp) target_include_directories(CloudViewer PRIVATE ${PCL_INCLUDE_DIRS} ${VTK_INCLUDE_DIRS}) target_link_libraries(CloudViewer PRIVATE ${PCL_LIBRARIES} ${VTK_LIBRARIES} Qt5::Widgets Qt5::OpenGL)find_package(PCL 1.12 REQUIRED COMPONENTS common io visualization)其中visualization会引入 VTK 和 OpenGL如果你不需要显示只做处理可以去掉 visualization 以加快编译。注意 PCL 的PCL_LIBRARIES变量是一整串库名列表在 MinGW 下它包含pcl_visualization、pcl_io、pcl_common等还有一堆 boost 的静态库名。如果你的工程链接时报找不到pcl_*库检查PCL_LIBRARY_DIRS是否指向D:\PCL\thirdparty\PCL\lib。这里有个容易忽略的问题find_package(PCL)会同时找一个PCLConfig.cmake而我们编译时指定了CMAKE_INSTALL_PREFIX所以PCLConfig.cmake在D:\PCL\thirdparty\PCL\share\pcl-1.12。如果你在 Qt Creator 里报错找不到 PCL请在 CMakeLists 里加上list(APPEND CMAKE_PREFIX_PATH D:/PCL/thirdparty/PCL)并重新打开工程让 CMake 缓存重建。6.2 运行期三个验证点加载 pcd、渲染、调试程序能编译通过只完成了 80% 工作运行期验证才是真验收。我自己每次新配置好环境都会用下面三个步骤确认没问题第一加载一个真实的 pcd 文件。用pcl::io::loadPCDFile读入一个带颜色的bunny.pcd可以从 PCL 测试数据中找然后打印cloud-size()。如果这里崩溃大概率是 io 模块的 DLL 加载顺序问题或者 boost filesystem 版本不一致。我会用 Qt Creator 的调试模式跑断点在loadPCDFile内部看它卡在哪个库。第二用一个QVTKWidget嵌入 PCLVisualizer。在 Qt 5.12 下VTK 8.2 的QVTKWidget已经不推荐使用要改用QVTKOpenGLWidget。你需要写QVTKOpenGLWidget *widget new QVTKOpenGLWidget(this)然后vtkGenericOpenGLRenderWindow::New()配合vtkRenderer。如果这里界面只闪一下或者黑屏说明你的 VTK 编译时没有开启VTK_USE_QVTK_QOpenGLWidgetON回看 VTK 编译选项。第三调试器里确认两套 Qt 库不混用。在main函数启动后中断下来在调试器里查看QLibraryInfo::location(QLibraryInfo::LibrariesPath)返回的路径。正常应该指向D:\Qt\Qt5.12.12\5.12.12\mingw73_32\lib。如果它指向别处那程序大概率会在后续运行中崩溃这属于运行时环境配错严格按 5.1 解决。6.3 自定义 MinGW 编译脚本下次重编只需一条命令编译完这次全套库我最大的教训是不要靠记忆手敲命令。我把所有步骤写成了一个build_all.sh脚本Windows 下用 Git Bash 或 MSYS2 运行每次升级依赖库版本或换电脑只要改前缀变量然后跑一遍即可。以编译 flann 为例脚本里的核心片段是function build_flann() { mkdir -p $BUILD_DIR/flann cd $BUILD_DIR/flann cmake $SRC_DIR/flann -G MinGW Makefiles \ -DCMAKE_TOOLCHAIN_FILE$PCL_ROOT/MinGW-PCL.cmake \ -DCMAKE_INSTALL_PREFIX$PREFIX/flann \ -DBUILD_CUDA_LIBOFF \ -DBUILD_EXAMPLESOFF \ -DUSE_OPENMPOFF \ -DCMAKE_BUILD_TYPERelease mingw32-make install }脚本里每个库用一个函数按依赖顺序调用boost、eigen、flann、qhull、VTK、PCL。如果某个库编译失败脚本立即停止并打印错误日志路径。这样做的好处是半年后你想升级 PCL 到 1.13只需要改PCL_VERSION变量并调整SRC_DIR其他编译参数不用动踩过的坑都在注释里写清楚了。对我来说这就是这套方案最大的价值第一遍可能花一整晚但之后每换一台机器或更新一个依赖半小时内就能交付出一个干净的 QtMinGWPCL 运行环境。最后一句忠告如果编译过程中遇到从未见过的错先用cmake --build . --verbose看完整链接命令行再去网上搜出错关键字比反复改 CMake 选项有效得多。希望这套血泪路径能帮你在 Windows 上少走几个来回。本文还有配套的精品资源点击获取
返回列表