thrift did not exit cleanly:IoTDB编译故障排查 1. 这个报错到底在说什么——先读懂thrift编译机制1.1 iotdb-thrift-commons在IoTDB里扮演什么角色先说结论这个报错不是你代码写错了而是构建链路里最底层的一环出了问题——RPC通信代码的自动生成过程失败了。IoTDB是Apache基金会下的分布式时序数据库主打物联网场景的海量数据写入和查询。它天生就是一个分布式系统客户端要和服务端通信多个数据节点之间也要通信这套通信不能靠HTTP硬扛因为时序场景下写入吞吐极高、单条数据极轻RPC框架比HTTP更适用。IoTDB选择的是Apache Thrift这个框架的核心工作方式很特别你用一套IDL语法写一个.thrift接口描述文件然后由thrift编译器自动生成对应语言的通信代码。也就是说你在源码里看到的iotdb-thrift-commons模块它本身没什么“业务逻辑”它的唯一使命就是借助thrift编译器把iotdb.thrift这个接口描述文件转换成Java类。那些TServiceClient、IoTDBIService之类的类全是编译期间自动蹦出来的不是人手写的。问题就出在这个自动生成环节。你看到的thrift did not exit cleanly翻译成人话就是Maven在编译阶段调用了thrift编译器但这个编译器进程没干完活就退出了而且退出码不是0。Maven一看退出码不对劲直接判定编译失败停下来甩给你这行提示。1.2 thrift did not exit cleanly的本质含义这个错误信息看起来像是一个笼统的总括但其实它背后藏着可以继续深挖的细节。关键是下面这句话的潜台词thrift did not exit cleanly. Review output for more information.它告诉你去看更完整的输出而不是让你盯着这一行干瞪眼。在实际编译场景里thrift编译器失败的原因千差万别但Maven这个插件thrift-maven-plugin比较“克制的”它默认只把最简短的一句话打出来真正的失败原因往往在更早的日志里被淹没了。举个生活化的类比这就好比你去一家餐厅点了一份套餐后厨说“菜做不出来看看监控回放”。你不会真的去盯着监控回放但你必须知道——真正的问题可能出在食材采购、厨师状态、灶台故障任何一个环节。thrift编译同理它涉及本机是否装了thrift编译器、版本对不对、环境变量配没配、.thrift文件语法有没有问题、生成的代码和现有代码冲不冲突任何一个环节出问题最终都是这一句话报错。所以这篇文章的核心思路就是先搞清楚thrift编译的完整链条再沿着链条逐层排查。我接下来会把这几个环节逐拆开给出每一步的验证方法和解决方案最后分享一套我实际用过的排查完整序列照着抄就行。2. 排查前的准备确认环境和快速复现2.1 先看清楚你的编译环境在动手修改任何东西之前花两分钟把你的编译环境看清楚能省掉后面一半的折腾时间。我在实际排查中发现很多人报这个错的第一反应就是去改代码、改配置结果折腾半天发现问题根本不在那一层。你需要先确认这几件事第一你的操作系统是什么。这个问题在Windows上最邪门其次是Apple SiliconM1/M2/M3的MacLinux反而最少见。为什么因为thrift编译器官方对这三类平台的预编译支持程度不一样后面我会详细说。第二你用的IoTDB版本是多少。不同版本的IoTDB对thrift编译器的版本要求不一样。早期的0.12、0.13版本用的thrift可能是0.13.0后来版本可能要求0.14.1再后来的版本甚至调整过IDL文件结构。你可以打开IoTDB根目录下的pom.xml搜一下thrift.version或者thrift-maven-plugin配置确认它要求的具体版本号。这一步非常关键因为版本不匹配是这个问题里最高发的原因没有之一。第三你本机到底装没装thrift。有些人以为Maven会自动把thrift编译器下载下来不是的。thrift-maven-plugin这个插件只是一个壳它负责调度thrift编译器但它不会帮你安装编译器本体。这就好比你买了一台咖啡机插件但咖啡豆编译器得你自己去超市买。你得执行一下thrift -version看看本机有没有这个命令。如果提示command not found恭喜你问题已经找到一半了。2.2 快速复现错误并收集完整日志很多人遇到报错后只截取了最后几行日志就去搜解决方案这恰恰是最低效的做法。thrift编译失败的精确定位信息通常藏在日志的中间位置而不是最后几行。我建议按下面的方法复现一次顺手拿到完整日志后面排查就有据可依了# 进入IoTDB源码根目录 cd iotdb # 只编译报错的模块缩短编译时间避免被其他模块干扰 mvn compile -pl iotdb-thrift-commons -am -DskipTests -X build.log 21解释一下关键参数的含义-pl iotdb-thrift-commons只编译指定的模块不要全量编译这样报错范围更小日志更干净。-am加上依赖模块also make因为iotdb-thrift-commons可能依赖其他基础模块不带上会报找不到依赖。-X开启Maven的debug日志这会输出非常详细的信息包括thrift编译器具体执行了什么命令、输出是什么、退出码是多少。 build.log 21把标准输出和错误输出都写到build.log文件里方便后面搜索定位。日志文件生成之后不要直接去翻文件的末尾而是搜索几个关键词# 搜索thrift编译器的实际执行路径 grep -i thrift build.log | head -50 # 搜索具体的错误信息 grep -i error build.log | head -50 # 搜索exit相关的日志 grep -i exit build.log | head -30看到这里你手头应该握着三个关键信息了报错日志全文、IoTDB要求的thrift版本、本机thrift版本。有了这三样东西就可以进入真正的排查环节了。3. 六个常见原因与对应解决方案3.1 原因一本机根本没装thrift编译器这个原因最无脑但也最普遍尤其是刚接触IoTDB编译的新手或者换了一台新机器准备从头搭编译环境的人。判断方法很简单thrift -version如果输出类似Thrift version 0.14.1说明系统能直接找到thrift编译器这个原因排除。如果提示command not found那基本可以锁定问题所在了。解决方案安装thrift编译器不同系统安装方式不同我分别列一下Ubuntu/Debian系sudo apt install thrift-compiler # 注意Ubuntu官方源的版本可能比较旧安装后node -v查看版本如果和IoTDB要求不一致见3.2节macOSHomebrewbrew install thriftWindows这是最坑的平台。官方没有提供稳定的Windows预编译二进制包或者版本比较旧。我强烈建议Windows用户优先用WSLWindows Subsystem for Linux来完成IoTDB的编译在WSL里的Ubuntu环境上按Linux的方式安装thrift比在原生Windows下折腾要省心太多。如果你一定要在原生Windows下编译那可能需要下载thrift源码自己编译这就涉及安装依赖、编译工具链复杂度直接上一个量级。提示很多人以为装完thrift就能编译通过实际上这只是第一步。装完之后还得确认版本匹配否则下一步就翻车。安装完成后再用thrift -version确认一下命令能识别。到这里第一种原因解决。3.2 原因二thrift版本不匹配这是我在实际群里看到的最常见的坑也最隐蔽因为它的报错不一定明确告诉你“版本不对”而是表现为各种奇怪的编译错误。为什么版本不匹配会导致失败因为thrift编译器的不同版本对IDL语法、代码生成模板、默认参数的处理有差异。比如thrift 0.13.0生成的Java代码和thrift 0.14.1生成的Java代码就有细节上的差异如果thrift-maven-plugin调用的编译器版本和项目预期版本不一致生成的代码可能直接语法错误或者生成的文件路径与项目预期不匹配最终表现就是thrift did not exit cleanly。第一步确定IoTDB期望的thrift版本。打开IoTDB源码根目录下的pom.xml搜索关键词thriftproperties thrift.version0.14.1/thrift.version /properties或者可能在thrift-maven-plugin的配置里特意指定了版本。记住这个版本号。第二步对比你本机的thrift版本thrift -version第三步版本不一致时切换到你需要的版本。这里有两种可操作的方式方式一推荐直接用系统包管理器安装指定版本。比如macOS上你用brew install thrift0.14或者brew install thrift0.13。Ubuntu上如果官方源版本太老可以手动下载官方发布的对应版本二进制包或者从源码编译安装。方式二更省事修改IoTDB的pom.xml让thrift-maven-plugin使用你本机的thrift版本。这个方法要谨慎因为修改项目构建配置可能影响其他开发者但如果你只是本地编译验证一下完全可以这样干。具体做法是找到thrift-maven-plugin的配置段确认它没有强制指定executable参数。如果没指定插件会从PATH环境变量里找thrift命令此时你只要保证PATH里那个thrift版本满足项目要求即可。# 确认当前PATH中的thrift版本 which thrift # 如果发现这个路径不对可以临时指定 export PATH/usr/local/opt/thrift0.14/bin:$PATH # 再验证一次 thrift -version3.3 原因三环境变量指向错误这个原因常常和原因二混在一起出现但实质不同。原因二是版本不对原因三是系统里装了多个thrift但Maven调用的那个路径是错的或者是旧版本的。这种场景常见于你之前装过thrift A后来又装了thrift B两个版本共存但PATH环境变量里排在前面的刚好是那个不符合要求的旧版本。排查方法# 查看thrift命令实际指向的位置 which thrift # 或者在macOS上 type -a thrift # 查看PATH环境变量 echo $PATH解决方案也很直白把正确版本的thrift所在路径放到PATH的最前面让Maven优先找到它。或者在Maven编译时直接指定thrift.executable参数绕过PATH查找mvn compile -pl iotdb-thrift-commons -am -Dthrift.executable/path/to/your/correct/thrift这个thrift.executable参数是thrift-maven-plugin对外开放的配置项可以让插件精确使用你指定的thrift命令不受PATH干扰。实际使用中这一招非常管用尤其在系统存在多个thrift版本时能快速验证是不是路径错误导致的问题。3.4 原因四.thrift文件语法或生成代码冲突如果前面三个原因都排除了那就需要深入检查.thrift文件本身了。这个原因更“硬核”但也不是没有可能尤其是你修改过iotdb.thrift文件或者从老版本IoTDB升级到新版本IDL文件没有同步更新。可能发生的情况.thrift文件里有语法错误。虽然理论上官方发布的源码不应该有这种低级问题但架不住你改了它。thrift语法挺严格少一个分号、多一个空格在某些版本里都可能触发编译失败。同一个.thrift文件里include了其他.thrift文件但include路径不对导致找不到文件。生成代码和项目中已有的类产生冲突。比如你在.thrift文件里定义了一个service但项目里已经存在同名Java类这会导致生成代码覆盖或者编译冲突。排查方法先手动执行一次thrift编译器看看单独编译那个.thrift文件能否通过。这个操作可以绕过Maven直接暴露thrift本身的真实错误。# 找到iotdb-thrift-commons模块下的.thrift文件 find iotdb-thrift-commons -name *.thrift # 手动执行thrift编译注意gen目录要提前建好 thrift --gen java -out /tmp/thrift_test -I ./iotdb-thrift-commons/src/main/thrift iotdb-thrift-commons/src/main/thrift/iotdb.thrift如果手动编译直接报语法错误那就能定位到具体是哪个文件、哪一行出了问题。如果手动编译能通过说明问题在Maven插件的配置上比如gen目录不存在、classpath不对等。解决方案如果是.thrift文件语法错误修复语法。如果是include路径问题调整-I参数让编译器能找到被include的文件。如果是生成代码冲突检查项目中是否有和生成类同名的类删除或重命名冲突类。3.5 原因五Maven缓存与依赖冲突这个原因特别容易令人抓狂因为无论你怎么改代码都改不动它。Maven在构建过程中会下载大量依赖到本地仓库默认是~/.m2/repository如果本地缓存的某个依赖包损坏、不完整或者出现了版本冲突就可能导致thrift编译过程中的Classpath不一致最终编译器启动就失败。典型症状换了网络环境后编译突然失败。别的同事能编译就你编译不过。清理代码重新拉取后问题依旧存在。解决方案第一步清理Maven对本项目相关模块的缓存mvn clean第二步如果问题依旧把本地仓库中和thrift、IoTDB相关的目录删掉强制Maven重新下载# 备份你的.m2目录如果你有重要配置的话 cp -r ~/.m2 ~/.m2_backup # 删除thrift相关的缓存目录 rm -rf ~/.m2/repository/org/apache/thrift # 重新编译 mvn compile -pl iotdb-thrift-commons -am -DskipTests第三步如果还不行可以加上-U强制刷新所有快照版本依赖mvn compile -pl iotdb-thrift-commons -am -U -DskipTests注意rm -rf ~/.m2是一个优先级较低的操作因为它会导致所有项目所有依赖全部重新下载耗时很长。建议先只删除thrift相关的目录而不是整个本地仓库。3.6 原因六操作系统与架构兼容性问题这个原因在Apple Silicon Mac上特别典型在Windows原生环境中也时有发生。thrift编译器是一个原生可执行程序它依赖具体操作系统和CPU架构。如果thrift二进制包和你的系统不匹配它可能连启动都启动不了或者启动后异常退出最终表现就是thrift did not exit cleanly。判断方法检查你系统架构uname -mLinux/macOS或echo $PROCESSOR_ARCHITECTUREWindows。检查你的thrift二进制是什么架构file $(which thrift)如果显示x86_64但你的机器是arm64那就会出问题。典型场景Apple Silicon MacM1/M2/M3如果通过Homebrew安装thriftHomebrew会自动装arm64版本一般没问题。但如果你是从某个老教程里下载了x86_64二进制或者Rosetta转译安装的thrift就可能出现异常退出。Windows原生环境thrift官方一直没提供正式的Windows预编译包网上那些第三方编译包质量参差不齐。所以Windows用户我再次强烈建议使用WSL。解决方案使用包管理器重装匹配当前架构的thrift。如果包管理器里的版本太老手动从官方GitHub Releases下载对应架构的二进制包。Apple Silicon用户注意如果Homebrew的thrift有问题可以试试从源码编译安装thrift虽然编译本身要花几分钟但能确保架构完全匹配。# macOS上查看Homebrew安装的thrift架构 file /usr/local/bin/thrift # Intel mac通常在这 file /opt/homebrew/bin/thrift # Apple Silicon mac在这4. 实操过程从报错到编译通过的全记录4.1 分步排查的完整命令序列前面讲了六种原因和各自的解决方案这节我把它串成一个完整的实操流程。你直接照着一步步执行不用来回跳转绝大多数情况下都能解决。第1步收集基础信息# 1. 查看IoTDB要求的thrift版本 grep -n thrift pom.xml | grep -i version | head -5 # 2. 查看本机thrift版本 thrift -version which thrift # 3. 查看系统架构 uname -m # macOS/Linux # 或者 echo $PROCESSOR_ARCHITECTURE # Windows第2步如果thrift没装安装它根据你的系统选择安装方式这里不再重复。装完以后继续下一步。第3步版本不对切换版本如果第1步发现版本不一致优先尝试修改PATH环境变量指向正确版本export PATH/path/to/correct/thrift/bin:$PATH thrift -version # 确认版本正确或者使用Maven参数直接指定mvn compile -pl iotdb-thrift-commons -am -Dthrift.executable$(which thrift) -DskipTests第4步清理并重新编译# 清理旧编译产物 mvn clean # 重新编译指定模块 mvn compile -pl iotdb-thrift-commons -am -DskipTests如果第4步仍然失败进入第5步。第5步开启debug日志定位真实错误mvn compile -pl iotdb-thrift-commons -am -X -DskipTests build_full.log 21 grep -n thrift build_full.log | grep -i error\|exception\|fail | head -20这里重点是看日志里thrift编译器具体输出的错误内容而不是只看Maven最外层的总结。第6步排除Maven缓存问题rm -rf ~/.m2/repository/org/apache/thrift mvn compile -pl iotdb-thrift-commons -am -U -DskipTests第7步手动执行thrift编译器验证IDL文件本身# 定位thrift文件 find iotdb-thrift-commons -name *.thrift # 手动编译 mkdir -p /tmp/thrift_out thrift --gen java -out /tmp/thrift_out -I ./iotdb-thrift-commons/src/main/thrift ./iotdb-thrift-commons/src/main/thrift/iotdb.thrift如果这一步报语法错误或者文件找不到那问题就不是环境了而是IDL文件本身的问题。第8步还是不行考虑系统兼容性问题如果是Windows果断换WSL。如果是Apple Silicon Mac确认thrift架构是arm64。这八步走完还没有解决的话说实话我在实际中的经验是概率极低了。那剩下的大概率是整个项目依赖问题或者你拉取的源码本身有已知bug这种情况去GitHub Issues搜索thrift did not exit cleanly会更高效。4.2 我踩过的坑和关键注意事项坑一一开始就去改iotdb-thrift-commons模块的pom.xml我第一次遇到这个报错时直接打开了iotdb-thrift-commons/pom.xml看到thrift-maven-plugin的配置下意识觉得是插件版本有问题于是改插件版本、改各种参数折腾了半个多小时都没搞定。后来才发现我的thrift版本是0.13而项目要求的是0.14仅此而已。这个坑的教训是先确认最基础的环境因素再动构建配置。插件配置出问题的概率远小于环境变量和版本不匹配的概率。坑二漏了-am参数有次我嫌全量编译太慢只执行了mvn compile -pl iotdb-thrift-commons结果报了一大堆“找不到符号”的错误当时差点误判成代码问题。后来才想起-am参数砸上以后一切正常。这个坑的教训是iotdb-thrift-commons看起来是独立模块但它依赖了一些公共工具模块不带-am时Maven不会自动去编译这些依赖模块直接从本地仓库找找不到就报错。坑三Windows上装了thrift客户端工具就以为万事大吉有的Windows用户用Chocolatey装了thrift以为环境就绪了。结果Maven调用thrift时依然失败。排查了很久才发现Chocolatey仓库里的thrift版本老得离谱而且它的包不包含完整的编译器功能。最后还是用了WSL一次性解决。这个坑的教训是Windows上装thrift这件事本身就不靠谱与其花时间折腾兼容性不如直接用WSL省下的时间够你写好几个小时的代码了。坑四忽略.thrift文件编码问题这个比较少见但很隐蔽。有次我拉取源码后在Windows上解压.thrift文件被转成了UTF-8 with BOM格式thrift编译器解析这种文件时会在开头多看到一个不可见字符直接报语法错误。后来用sed把BOM头去掉才通过。注意如果你在Windows上解压Linux下创建的源码包注意检查.thrift文件有没有BOM头。用VSCode打开文件看右下角编码格式如果是UTF-8 with BOM就另存为UTF-8。坑五只盯着错误提示的末尾看Maven的报错信息有时很长真正的错误原因往往不在最后几行。比如有次报错信息里有thrift did not exit cleanly紧接着是Review output for more information但在这两个提示的前面其实已经有一行java.io.IOException: Cannot run program thrift: error2, No such file or directory。这就是典型的thrift未安装或PATH不对。但很多人不看前面死活发现不了。所以排查时一定要看完整日志而不是只盯最后的提示。这也是我为什么一开始就推荐你用-X参数输出完整日志的原因。5. 常见问题排查技巧实录5.1 典型报错速查表我把实际过程中高频遇到的报错表现和对应原因整理成一张速查表方便你以后遇到类似问题快速对照日志/报错特征最大可能原因优先处理方式Cannot run program thrift: error2, No such file or directory本机未安装thrift或PATH没有指向thrift可执行文件安装thrift确认thrift -version可用报错前有thrift exited with code: 1且本地thrift版本与项目pom中不一致thrift版本不匹配切换thrift版本或修改PATH报错前有The thrift compiler is not definedMaven插件没找到thrift指定-Dthrift.executable参数报错前有Error parsing或Syntax error.thrift文件语法错误手动执行thrift编译定位具体语法问题报错前有Undefined include或File not found.thrift文件include路径错误检查.thrift文件中的include路径编译到一半突然失败但之前能编译Maven缓存损坏或依赖下载不完整清缓存用-U参数强制更新Windows环境下编译失败排查无明确头绪Windows原生环境thrift支持问题换WSL编译Apple Silicon Mac上thrift命令能执行但编译崩溃thrift二进制架构不匹配用Homebrew重装arm64版thrift代码报错里出现大量TSocket、TProtocol相关异常生成的thrift代码与项目代码不兼容检查版本一致性重新生成代码这张表不是万能灵药但能帮你在看到报错日志后快速定位排查方向。5.2 独家避坑技巧除了上面这些标准排查手段我再分享几个平时不会写进文档、但实战中极其好用的小技巧。技巧一先跑mvn -v确认Maven和Java版本thrift编译器虽然不依赖具体的JDK版本但maven编译过程中如果Java版本过高或过低可能引发Class版本冲突间接导致thrift插件行为异常。具体来说IoTDB项目的JDK版本要求通常写在pom.xml的maven.compiler.source/maven.compiler.target里一般是Java 8或者Java 11。如果你本机默认JDK是17甚至21某些老版本IoTDB的构建脚本可能有兼容问题。# 查看当前JDK版本 java -version # 查看Maven版本 mvn -v如果版本不匹配可以用JAVA_HOME切换JDKexport JAVA_HOME/path/to/jdk11技巧二利用-DskipTests快速验证thrift编译本身thrift编译是在generate-sources阶段执行的和测试、打包无关。如果你只想验证thrift编译能不能通过用mvn generate-sources命令就行它会提前停止在代码生成阶段不会浪费时间在后续的单元测试和打包上mvn generate-sources -pl iotdb-thrift-commons -am -DskipTests一旦这条命令成功说明thrift编译已经没有问题了。技巧三把Maven的settings.xml里的镜像源换成一个稳定的源如果你的网络环境访问Maven中央仓库不稳定依赖下载不完整也可能导致一些奇怪的编译错误。在~/.m2/settings.xml里配置阿里云镜像或者其他稳定镜像能显著减少这类问题。mirrors mirror idaliyun/id urlhttps://maven.aliyun.com/repository/public/url mirrorOfcentral/mirrorOf /mirror /mirrors技巧四thrift编译器可能被别的软件污染有次我发现一个特别诡异的现象thrift -version能正常输出版本号但Maven调用它时总是失败。后来排查发现我为了调试别的项目在shell里设置了一个THRIFT_HOME环境变量指向了一个旧版本的目录而那个目录里的thrift文件已经被删了一半只剩一个残缺的符号链接。所以如果你设置了THRIFT_HOME或者THRIFT_EXECUTABLE这类环境变量不妨先取消掉再试一次unset THRIFT_HOME unset THRIFT_EXECUTABLE技巧五善用strace或者dtruss定位崩溃源头如果以上所有方法都无效thrift编译器一执行就崩溃那么你就要考虑是编译器执行时遇到了系统层面的错误。这已经属于比较极端的调试场景了。Linux上可以用strace跟踪系统调用看thrift在哪个环节崩了。macOS上可以用dtruss因为系统保护机制需要先开启权限sudo执行使用起来比strace麻烦一些。但说实话这种级别的调试通常用不到。如果你真的走到这一步更大的概率是你的thrift二进制包本身损坏直接重装一次反而更快。5.3 关于切换thrift版本时的一个高频疑问很多人会问“我修改了PATH让系统找到正确的thrift版本但为什么mvn有时候还是用旧的版本”这背后涉及到thrift-maven-plugin的一个常见特性插件查找thrift优先顺序是pom.xml中显式指定的executable参数 环境变量THRIFT_EXECUTABLEPATH中的thrift命令。所以你改了PATH不代表一定生效如果项目里显式配置了executable参数插件就会绕过PATH。遇到这种情况你需要查看iotdb-thrift-commons/pom.xml里是否配置了executable。如果配置了直接修改这个参数指向正确的thrift路径或者在编译命令里用-Dthrift.executable/your/path覆盖。如果没配置那就确认THRIFT_EXECUTABLE环境变量没有设置。这是我遇到过的、很多人可能都踩过的一个坑单独拎出来讲一下。6. 从报错到打通全链路编译的个人体会其实把这个报错解决完之后你再回头看整个过程会发现它本质上不是IoTDB特有的问题而是所有使用thrift-git的Java项目包括HBase、Cassandra、Hive等在编译时都会面临的通用问题。只不过IoTDB把这套流程放进了Maven架构里让你不用手动生成代码但也正是这种“自动化”让环境问题被隐藏在了一个又一个抽象层后面。我个人在实际操作中最大的体会是遇到“did not exit cleanly”这类报错第一反应不应该是去网上搜完整报错而是先把你手头的环境信息整理清楚——操作系统、thrift版本、项目需求版本、完整日志。有了这四样东西这个问题的排查路径就变得非常清晰了大概率能在十分钟内定位根因。最后再分享一个小技巧如果你实在不想被这个编译问题反复折腾直接把thrift编译这层用Docker隔离掉。写一个简单的Dockerfile里面装好指定版本的JDK、Maven、thrift编译器再把IoTDB源码挂载进去编译。这样任何一台新机器只要装了Docker拉取镜像就能直接复现编译环境不用再被系统差异折磨。我在团队内部就这么干的效果非常好尤其是队友换了新电脑的时候再不用花半天帮他们配环境了。把这个坑填上之后IoTDB的编译链路就畅通了后面无论是调试本地代码、做二次开发还是提交PR跑测试都省心很多。希望这篇记录能帮到正在被这个报错卡住的人。