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

资讯详情

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

Windows下Qt MinGW编译VTK 8.1.0完整指南:从配置到集成

Windows下Qt MinGW编译VTK 8.1.0完整指南:从配置到集成 Windows10 Qt下用MINGW 编译VTK-8.1.0这事儿我前后折腾过好几次把弯路都走完了。VTK 8.1.0本身不算新但它在Windows上配合Qt做医学图像可视化、点云显示、三维渲染仍然很能打尤其很多科研团队的老项目就锁定在这个版本上。麻烦在于官方预编译的VTK基本都是MSVC工具链你手里Qt如果装的是MINGW版本直接链过去全是“undefined reference”根本不给你商量的余地。所以我这篇文章就把从零开始用MINGW编译VTK 8.1.0的完整流程写清楚适合那些需要在Qt Creator里用MinGW Kit开发可视化应用、又不想被MSVC绑定死的朋友。文章会涉及版本匹配、CMake参数、编译命令、Qt集成和常见报错看到最后你大概率能自己复现一遍。1. 编译前的关键认知为什么这件事不能绕过去1.1 工具链匹配问题是第一道坎很多朋友拿到VTK源码后第一反应是“官方不是有编译好的包吗下载下来直接用不就行了”问题就出在这里。VTK官网和GitHub Release里提供的Windows预编译二进制绝大多数是用MSVCVisual Studio编译出来的二进制接口跟MinGW完全不同。C没有稳定的ABIMSVC编译出来的静态库、动态库的符号修饰规则、异常处理方式、标准库实现和MinGW的GCC完全对不上。而你在Qt官方安装包里选的“MinGW 7.3.0 64-bit”工具链本质上就是GCC的Windows发行版。编译出来的程序想要链接VTKVTK也必须是由同源GCC工具链编译出来的。用MSVC版VTK去对接MinGW版Qt链接器会给你刷屏式地报错像undefined reference to vtkRenderWindowInteractor::New()这种它们不是同一个世界的东西。所以方案基本只有一个拿到VTK源码用MinGW自己编译一份。编译出来的VTK库内部所有符号都基于GCC的ABI规范再跟MinGW版Qt链接就顺畅了。这也是为什么社区里一直有人说“Windows下VTK必须本地编译”本质不是在谈追求性能而是在谈ABI一致性。1.2 版本组合怎么选才稳VTK 8.1.0发布于2018年它对应的Qt版本和编译器版本其实很宽泛但放到现在我们手边的Qt安装包通常是5.12.x或5.15.x搭配的MinGW版本一般是7.3.0或8.1.0。我在实际编译中验证过下面这些组合Qt 版本自带编译器VTK 版本编译结果Qt 5.9.9MinGW 5.3 32位VTK 8.1.0可用但只能是32位Qt 5.12.12MinGW 7.3 64位VTK 8.1.0推荐稳定Qt 5.15.xMinGW 8.1 64位VTK 8.1.0可用偶有模板兼容警告最省心的组合是Qt 5.12.x配MinGW 7.3 64位这套组合我在三台不同机器上编过VTK 8.1.0没有额外打补丁一次通过的概率很高。Qt 5.15配MinGW 8.1也能编但VTK 8.1.0的某些老旧模板代码在GCC 8.1下会放出一堆deprecated警告虽然不影响结果看着心烦。另外要注意位数问题。如果Qt安装包是mingw73_64那么整个工具链、VTK库、最终生成的exe都是64位的。如果用的是Qt 5.9自带的mingw53_32那就只能编32位VTK不能混。判断方法很简单看Qt安装目录下的编译器路径里带的是_64还是_32。2. 环境搭建把三件套准备到位2.1 下载清单与版本核对开始之前先检查以下三样东西Qt安装包需要在Qt官方安装管理器里勾选对应版本的MinGW编译器比如Qt 5.12.12下的MinGW 7.3.0 64-bit。注意不要只装了MSVC版Qt那样MinGW Kit是空的。CMake建议3.10以上我用的是CMake 3.20没遇到问题。CMake版本太老的话对Qt5模块的查找规则可能不支持。VTK 8.1.0源码包去VTK官网或GitHub的tags页拿VTK-8.1.0.tar.gz或者clone v8.1.0分支。名字一定要确认是8.1.0别下成8.2或者9.x分支之间CMake选项变化很大。还有一点很多新手会忽略不要用“qt-everywhere”源码包那是给Qt自身开发用的我们只需要Qt安装目录里现成的库和编译器即可也就是D:\Qt\Qt5.12.12\5.12.12\mingw73_64这个目录。2.2 环境变量与目录规划MinGW编译器需要能在命令行里被直接调用所以要先把它的bin目录加进PATH。在Windows搜索框输入“编辑系统环境变量”打开后找到“Path”变量新增一行D:\Qt\Qt5.12.12\Tools\mingw730_64\bin注意这个工具链路径在Qt目录的Tools文件夹下不是5.12.12\mingw73_64那个文件夹。后者是Qt的库文件目录前者才是gcc、g、mingw32-make所在的目录。很多同学配错PATH结果CMake一检测编译器就报g.exe not found其实就是PATH指错位置了。同时建议规划好源码和构建目录整个过程中不要出现中文、空格、特殊符号。我习惯放在D:\src\VTK-8.1.0 # 源码目录 D:\build\VTK-8.1.0-build # 构建目录构建目录单独拎出来和源码目录分开这是CMake的一个好习惯。VTK编译会生成大量中间文件混在源码目录里会污染源码后续想重新配置或者删掉构建产物都不方便。2.3 Qt Creator Kit 配置检查如果你打算编译完VTK后在Qt Creator里直接开发还需要确认Kit是否正确。打开Qt Creator进入“工具 → 选项 → Kits构建套件”查看默认Kit的“编译器”一栏C和C编译器都应该指向MinGW的gcc和g调试器应该指向gdbCMake应该指向你安装的cmake.exe。这里要特别注意很多人的电脑上还装了Visual StudioQt Creator会自动检测出MSVC Kit。如果创建项目时误选了MSVC Kit后面用CMake编译VTK项目时又会回到ABI不匹配的老问题上。所以编译VTK期间统一走MinGW Kit不要混用。3. CMake配置核心参数逐个说清楚3.1 生成器怎么选打开CMake GUI源码目录选D:/src/VTK-8.1.0构建目录选D:/build/VTK-8.1.0-build然后点击“Configure”。弹窗里会让你选择生成器这时候选MinGW Makefiles不要选NMake Makefiles也不要选MSYS Makefiles。为什么是MinGW Makefiles这个方法因为它会生成基于mingw32-make的Makefile跟Windows命令行环境契合不需要额外安装MSYS或Cygwin那套Unix模拟层。选MSYS Makefiles的话CMake会去找sh.exe注意如果电脑装了Git Bashsh.exe就会被意外检测到然后编译时冒出各种路径转换问题。MinGW Makefiles走的是cmd.exe mingw32-make完全避开这些坑。点击Configure后CMake会先检测C和C编译器。如果你没有指定native compilers它会自动在PATH里找gcc.exe和g.exe。只要前面PATH配对了这里就能顺利通过。万一检测不到也可以直接勾选“Specify native compilers”手动指定编译器路径C: D:\Qt\Qt5.12.12\Tools\mingw730_64\bin\gcc.exe C: D:\Qt\Qt5.12.12\Tools\mingw730_64\bin\g.exe3.2 关键CMake变量解读首次Configure完成后CMake会展开一堆配置项红色高亮显示。这时候需要逐个确认以下关键变量CMAKE_BUILD_TYPE设置为Release。不要用DebugDebug版VTK库体积巨大、编译时间翻倍而且MinGW版Qt项目默认也是Release模式居多。后续如果确实需要单步调试VTK源码再单独编一个Debug目录也不迟。CMAKE_PREFIX_PATH这个变量是让我第一次掉坑的地方。它的作用是告诉CMake去哪找Qt的库和CMake配置文件。必须指向你的Qt库目录注意是包含lib/cmake/Qt5的那个目录D:/Qt/Qt5.12.12/5.12.12/mingw73_64不配置这个变量CMake会报Could not find a package configuration file provided by Qt5或者在生成时找不到Qt5Widgets、Qt5OpenGL这些模块。VTK_QT_VERSION设置为5。VTK 8.1.0还保留着对Qt4的兼容支持默认值有时候不太明确显式选5更稳妥。VTK_GROUP_ENABLE_Qt设置为YES。VTK 8.1.0采用了模块组的管理方式Qt相关的渲染交互模块都在这个组里比如vtkGUISupportQt、vtkRenderingQt。如果这里不打开最终编译出来的VTK库完全没有Qt相关的模块后面你的Qt项目里找不到需要的VTK库。BUILD_SHARED_LIBS默认是ON保持打开。共享库模式下VTK的dll方便单独分发而且MinGW下编译动态库比静态库省事。如果你想要静态链接后面会同时面对一堆Qt库和VTK库的静态依赖问题这里不建议新手碰。VTK_BUILD_EXAMPLES、VTK_BUILD_TESTING、BUILD_TESTING全部设为OFF。官方示例和测试代码对编译速度影响很大我们只是要用VTK库不是要跑测试套件。我第一次编译时忘了关多了将近二十分钟的编译时间。VTK_GROUP_ENABLE_Python 等无关模块组如果你不用Python封装、不用Web渲染可以把VTK_GROUP_ENABLE_Python、VTK_GROUP_ENABLE_Web、VTK_GROUP_ENABLE_Imaging这些设为NO或WANT。这样CMake会裁掉大量用不到的模块编译时间直接砍掉一半以上。配置完成后再次点击Configure红色选项消失最后点击Generate生成Makefile。3.3 配置过程中的两个经典坑我在配置时遇到过两个比较有代表性的问题。第一个是Qt5_DIR-NOTFOUND。原因是CMAKE_PREFIX_PATH没设对或者指向了D:/Qt/Qt5.12.12/Tools/mingw730_64那是编译器不是Qt库。记住要指向带5.12.12/mingw73_64的那一层目录。第二个是CMake报Cannot find source file .../vtkRenderingOpenGL2/autoinit之类的问题。这个多半是源码包解压不完整或者用了Git clone但子模块没拉全。用Git拉VTK仓库时一定要加--recurse-submodules或者直接下载官方发行版的tar.gz包它已经把子模块都打包进去了。4. 编译与集成从命令行到Qt Creator4.1 mingw32-make 编译实操配置完成后进入构建目录打开命令行不必非得用VS的Developer Command Prompt普通cmd就行因为MinGW不依赖VS环境。先确认编译器和make工具可用gcc --version mingw32-make --version然后执行编译cd D:\build\VTK-8.1.0-build mingw32-make -j8-j后面的数字表示并行编译任务数一般取CPU物理核心数或线程数。8线程编译VTK全套库机器配置不太差的话大约需要40分钟到一个小时。4线程会久一些可能要一个半小时。如果内存少于8GB建议用-j4否则g并行编译时内存经常飙到70%容易卡死。编译过程中屏幕会滚动大量编译日志看到[ 98%]、[100%]这样的进度百分比就说明正常。期间也可能出现个别警告只要不是Error基本不用管。编译结束后检查一下构建目录会生成bin和lib文件夹。bin里是VTK的dll文件比如vtkCommonCore-8.1.dll、vtkGUISupportQt-8.1.dlllib里是对应的导入库MinGW下是.dll.a后缀的文件。只要这些文件存在编译就算成功了。4.2 在Qt项目里接入VTK这是整个流程里最有成就感的一步。打开Qt Creator新建一个普通Qt Widgets Application打开.pro文件的话需要手动配置我推荐直接用CMake方式建项目更好继承VTK的CMake体系。一个最小化的CMakeLists.txt应该是这样的cmake_minimum_required(VERSION 3.10) project(VtkDemo) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_PREFIX_PATH D:/Qt/Qt5.12.12/5.12.12/mingw73_64 D:/build/VTK-8.1.0-build ) find_package(VTK REQUIRED) find_package(Qt5 REQUIRED COMPONENTS Widgets) include(${VTK_USE_FILE}) add_executable(VtkDemo main.cpp) target_link_libraries(VtkDemo PRIVATE Qt5::Widgets ${VTK_LIBRARIES} ) target_link_libraries(VtkDemo PRIVATE opengl32)include(${VTK_USE_FILE})会把VTK的头文件路径和宏定义比如需要定义VTK_USE_QT等配置项直接带进来。${VTK_LIBRARIES}则链接所有用到的VTK模块。最后补一个opengl32是因为VTK的OpenGL渲染在Windows下依赖系统库不链的话部分情况会报链接错误。main.cpp里有个容易忘的关键点VTK 8.1在Windows下使用OpenGL2渲染后端时需要手动初始化渲染模块。我的建议是在任何Qt程序入口也就是main函数之前加上#include vtkAutoInit.h VTK_MODULE_INIT(vtkRenderingOpenGL2); VTK_MODULE_INIT(vtkRenderingVolumeOpenGL2); VTK_MODULE_INIT(vtkInteractionStyle);不加上这几个宏运行时经常报Error: no override found for vtkRenderWindow因为这个错误坑过不少人。运行时还有个小细节把D:/build/VTK-8.1.0-build/bin加到系统PATH或者在Qt Creator的“运行环境”里把PATH补上。否则exe启动时会弹窗说找不到vtkCommonCore-8.1.dll。5. 常见报错与排查速查表5.1 高频错误对照表我把编译和集成阶段最常出现的错误整理成一个表方便你按图索骥报错特征根本原因解决办法Could not find a package configuration file provided by Qt5CMAKE_PREFIX_PATH没指向Qt库目录设置CMAKE_PREFIX_PATH为Qt的mingw73_64目录error: cannot find -lopengl32缺少Windows OpenGL系统库链接在CMakeLists中加target_link_libraries(... opengl32)undefined reference to vtkXxx::New()VTK模块未初始化或未链接检查VTK_MODULE_INIT宏确认link了${VTK_LIBRARIES}no override found for vtkRenderWindowOpenGL2模块未初始化添加VTK_MODULE_INIT(vtkRenderingOpenGL2)fatal error: QtWidgets/QWidget: No such fileQt头文件路径没进include检查find_package(Qt5)是否执行CMAKE_PREFIX_PATH是否配对sh.exe was found in your PATH生成器选择不当或Git Bash干扰改用MinGW Makefiles生成器构建环境不加载Git Bash无法打开包括文件: vtkAutoInit.hVTK库的include目录缺失重新检查编译是否成功确认构建目录存在include/vtk-8.1mingw32-make: command not foundMinGW bin目录没进PATH检查PATH中是否有Qt/Tools/mingw730_64/bin5.2 两个典型问题详解第一个典型问题是undefined reference成片出现。这种情况多数不是VTK没编出来而是模块没有初始化。VTK 8.1引入了模块自动初始化机制以前你需要在代码里手动include一堆工厂头文件现在通过VTK_MODULE_INIT宏一键搞定。但很多从VTK 6/7时代看老教程的人会漏掉这一步于是链接时凡是跟渲染、交互相关的类全部找不到实现。我建议在项目的公共头文件或者main.cpp最上方固定保留这四个宏#include vtkAutoInit.h VTK_MODULE_INIT(vtkRenderingOpenGL2); VTK_MODULE_INIT(vtkRenderingVolumeOpenGL2); VTK_MODULE_INIT(vtkInteractionStyle); VTK_MODULE_INIT(vtkRenderingFreeType);其中vtkRenderingFreeType和文字标注有关做医学图像标注、测量文字时会用到干脆一起初始化了。第二个典型问题是Qt Creator里一个项目同时有两个Kit不小心选错后编译报一堆奇奇怪怪的错。比如你项目选到了MSVC Kit编译器变成cl.exe而Qt库是MinGW版的链接器直接不认。解决方法是新建项目或打开项目时在“Projects”页面左侧的构建套件选择里只保留MinGW Kit把MSVC Kit从构建列表里移除。也可以给MinGW Kit起个一眼能认出的名字比如“Qt 5.12 MinGW 64”省得下次再选错。5.3 编译速度太慢的优化思路如果你只需要VTK的某几个模块比如只做医学图像体绘制、只做点云显示其实不用编全量VTK。CMake配置时可以针对性关闭大量用不到的模块组减少编译单元数量。我自己的经验是保留这几个组就够了VTK_GROUP_ENABLE_Rendering渲染核心必须有VTK_GROUP_ENABLE_QtQt支持VTK_GROUP_ENABLE_Imaging图像处理按需VTK_GROUP_ENABLE_Views如果不需要视图框架可以关其余像VTK_GROUP_ENABLE_Web、VTK_GROUP_ENABLE_Python、VTK_GROUP_ENABLE_Geovis在CMake搜索框里搜到后全部设为NO。我用这种方式把编译时间从50分钟压到了20分钟以内。另外还可以在CMake变量VTK_BUILD_ALL_MODULES设为OFF这样CMake不会强行编译所有模块只编译你打开的那些依赖链。还有一个小技巧编译的时候关掉杀毒软件实时防护。Windows Defender在编译VTK这种大量生成小文件的场景下会频繁扫描磁盘占用很高。我实测过在Defender开启的状态下编译时间至少慢30%。构建目录加入白名单也可以效果类似。最后说点个人经验这套流程我前前后后跑了不下十遍最深的体会是Windows下编译VTK大多数坑不是VTK自身的问题而是编译环境没理顺。路径里一个空格、PATH里多一个Git Bash、Kit选错都会让你折腾一下午。所以动手之前花10分钟把工具链、版本、目录、环境变量都核对一遍远比盲目点Configure和Generate划算。我个人现在养成的习惯是每一次配置都开一个文本文件记录版本号、路径和关键CMake变量编译出问题的时候回查非常省事。如果你也是第一次在Windows下用MinGW编译VTK 8.1.0按这篇文章的顺序走下来大概率能一次通过。万一还是卡住了回头看看自己的PATH和CMAKE_PREFIX_PATH是不是又指歪了这俩地方是所有阴间报错的重灾区。
返回列表