首页/新闻资讯/正文详情

Qt 5.14.2 aarch64静态交叉编译实战:从环境搭建到内网部署

发布时间:2026/9/24 23:58:43 来源:云帆数科 栏目:资讯中心
Qt 5.14.2 aarch64静态交叉编译实战:从环境搭建到内网部署
搞Qt的交叉编译尤其是目标平台还限定在aarch64又要静态链接这事儿说大不大说小也不小。如果只是用现成的SDK点点鼠标那确实没什么好写的但当你需要在一个纯内网环境里给国产ARM板子交付一套Qt程序不能指望板子上装一堆运行时依赖也不方便随便联网装包的时候静态交叉编译几乎是唯一走通的路。Qt 5.14.2是很多人选定的版本原因很现实它不算太老对aarch64的官方支持已经挺稳但又比5.15、6.x这类版本少了许多新引入的坑整个round下来成功率很高。这篇东西就是我从零开始把整套流程踩完一遍之后整理出来的手册适合那些需要在x86_64的Linux主机上给aarch64的板子编译出静态Qt程序然后一把拷过去就能跑的工程师。1. 开始之前先想清楚这几件事1.1 静态 vs 动态交叉 vs 本机别把需求搞混很多人一开口就说“我要Qt交叉编译”但实际需求可能只是“我想在板子上跑一个Qt程序”。这两者之间的路径差得很远。如果你只是调试阶段板子上已经准备好了Qt的运行库那动态交叉编译就够了编译出来的程序只有几MBscp上去配上LD_LIBRARY_PATH就能跑。但等到你真正要发布的时候会发现板子环境千奇百怪有的系统没有Qt库有的库版本不对有的系统连libstdc.so的符号都缺这时候动态方案就成了噩梦。静态编译的意义在于程序把Qt核心库、第三方依赖全部揉进同一个ELF文件里拷过去就能跑。代价也很明显编译时间更长产物体积可能上百MB而且插件机制需要额外处理。就算如此我个人依然推荐交付阶段坚持静态方案因为省掉的问题远比带来的麻烦多。另外要注意“交叉”和“本机”的区别。如果板子性能足够好直接在aarch64设备上编译最省心但现实是很多ARM板子内存和磁盘都紧张编译Qt这种耗时的工程太遭罪。交叉编译就是把编译动作搬到性能更好的x86_64主机上通过配置工具链让产出的二进制文件的目标架构是aarch64。本文所说的就以这个场景为准x86_64主机目标架构aarch64。1.2 主机环境与工具链选型考虑到多个国产系统比如银河麒麟、统信UOS都跑在aarch64上而它们的官方容器、开发环境又往往给了CentOS系的镜像我这次选用的主机环境是Ubuntu 20.04 x86_64。常用的交叉工具链名称是gcc-aarch64-linux-gnu和g-aarch64-linux-gnu用apt就能装版本一般是9.x或10.x编译Qt 5.14.2完全没有问题。如果你用的是板卡厂商提供的工具链那也没关系参数大同小异重点是保证OpenSSL、zlib这些依赖在sysroot中的架构是aarch64不能混用x86_64的库。武装好工具链之前先确认一下版本aarch64-linux-gnu-gcc --version aarch64-linux-gnu-g --version能正常输出版本再继续否则后面所有configure和make的错误都会指向一个模糊的“工具链有问题”排查起来非常浪费时间。1.3 依赖库的取舍策略越少越好Qt本身依赖的第三方库不少比如libjpeg、libpng、freetype、fontconfig、glib、xkbcommon等。如果你走动态编译这些库只需要在目标板上存在即可但静态编译时它们会被链接进最终的二进制里。如果这些库本身在交叉工具链的sysroot里缺位或者架构不对编译就会失败。所以老手的第一个原则是能省则省能用Qt源码内置就绝不依赖外部库。Qt的configure脚本提供了很多路径选项像-qt-zlib、-qt-libpng、-qt-libjpeg、-qt-pcre用来让它使用源码自带的三方库而不是去系统找。对于Qt 5.14.2来说如果只想做一个基础的Widgets界面程序关闭一些重型模块比如QtWebEngine、QtWebView之后依赖能压到很少。真到了必须链接外部库的场景比如需要OpenSSL的QSslSocket那就得确认sysroot里对应的库是aarch64的静态版本libssl.a、libcrypto.a稍后我会细说。2. 搭建交叉编译环境sysroot与依赖项2.1 准备aarch64交叉工具链Ubuntu下直接使用包管理器安装最省事。sudo apt update sudo apt install gcc-aarch64-linux-gnu g-aarch64-linux-gnu这一步会把编译器、链接器、汇编器等装到/usr/bin/下头文件和库的默认位置分别在/usr/aarch64-linux-gnu/include、/usr/aarch64-linux-gnu/lib。理论上只要在配置Qt时把-sysroot指向这里就能找到大部分基础库。如果需要指定特定版本的工具链比如板卡厂商提供了定制过的gcc那就把它的bin目录加进PATH并把交叉编译器名称传进去。Qt一般在-device选项里会拼出编译器但更通用的做法是用-xplatform linux-aarch64-gnu-g并配合-device-option CROSS_COMPILEaarch64-linux-gnu-后面会讲到。2.2 准备一个有效的sysroot所谓sysroot就是交叉编译时编译器把它当作目标机根目录来看待的一棵目录树。比如你的板子根目录是/但你不可能在板子上编译于是在主机上建一个目录$HOME/myrootfs/里面把usr/include、usr/lib、lib等目录按同样的结构放进去。配置时通过-sysroot $HOME/myrootfs告诉编译器头文件和库到这里去找而不是找主机上的。最省事的做法是直接把我们上面安装的/usr/aarch64-linux-gnu/作为sysrootexport SYSROOT/usr/aarch64-linux-gnu这个目录下已经有include、lib等子目录对大多数基础依赖来说够用了。如果你的依赖库需要手动安装比如libuuid、libfontconfig的静态库就需要把它们放到这个sysroot里对应的位置并且分清架构别把x86_64的库放进去。有些老手喜欢拷贝整个设备的rootfs过来做sysroot好处是依赖保证和板子完全一致坏处是体积大还要处理符号链接。对于Qt 5.14.2的常规交叉编译前面这种方式够用。2.3 静态编译的一大关键让第三方库进入静态链接如果最终目标bin需要用到libpng、libjpeg等库而configure时选了外部库那这些库必须以.a静态库形式出现在sysroot里同时确保编译期头文件还存在。否则链接的时候会出现“cannot find -lpng”一类的问题。以libpng为例如果你不想用Qt内部自带的版本而是想链接系统提供的静态库可以这样操作在目标板一样的aarch64环境或rootfs中用包管理器下载libpng-dev的.a版本或者直接在Ubuntu的aarch64包源码中交叉编译libpng再安装到$SYSROOT。但这属于折腾自己。对于大多数场景直接用Qt自带的-qt-libpng会舒服得多效果几乎一样。基于同样的逻辑我的建议是尽可能多用Qt自带的库别追求“完全只用外部系统库”否则每多一个依赖出问题的概率就翻一倍。3. 配置并编译Qt 5.14.2configure参数逐项拆解3.1 configure的基本思路把下载好的qt-everywhere-src-5.14.2.tar.xz解压后整个Qt源码的配置工作都集中在configure脚本上。这里需要确立一个基本认知configure用于生成一套为当前目标机定制的构建规则是个一次性动作决定了之后几百个模块怎么编一定要认真看输出别不管三七二十一回车到底。针对静态交叉编译我最常用的一个configure组合如下./configure \ -release \ -static \ -opensource \ -confirm-license \ -prefix /opt/Qt5.14.2-aarch64-static \ -xplatform linux-aarch64-gnu-g \ -device-option CROSS_COMPILEaarch64-linux-gnu- \ -sysroot /usr/aarch64-linux-gnu \ -nomake examples \ -nomake tests \ -skip qtwebengine \ -skip qtwebview \ -skip qt3d \ -skip qtcanvas3d \ -skip qtdoc \ -skip qtcharts \ -no-opengl \ -no-dbus \ -no-icu \ -no-iconv \ -qt-zlib \ -qt-libpng \ -qt-libjpeg \ -qt-pcre \ -qt-xkbcommon-x11 \ -no-feature-getentropy这一行里的每个参数背后都有讲究不是抄来就能用建议对照下面的说明做增减。3.2 关键参数的逻辑-release -static发布版、静态链接这是核心目标。-static会直接指示Qt构建出静态库所有模块都以.a方式存在。-xplatform linux-aarch64-gnu-g指定交叉编译的platform文件。Qt内置了linux-aarch64-gnu-g这个mkspec它的作用就是让qmake知道用aarch64-linux-gnu-g这套工具链来编译。配合-device-option CROSS_COMPILE...可以指定交叉编译器的前缀。这里出现的问题通常是如果主机环境里同时有多个交叉工具链需要确认aarch64-linux-gnu-gcc确实在PATH里。-sysroot指向aarch64的头文件和库所在目录。前面我们已经把它设成/usr/aarch64-linux-gnu。这个参数会让gcc自动加--sysroot从而让include和link的搜索路径切到目标架构。各种-skipQt官方源码包会包含所有模块其中qtwebengine这种Chromium系模块交叉编译起来极其痛苦需要处理一堆Python工具和target/host双编译问题。在架构为aarch64的静态版本里绝大多数情况用不到WebEngine。跳过这些不用的模块能省下大量编译时间。还有qtcharts之类除非你有图表需求否则没必要编进去。-no-opengl很多嵌入式板子虽然有GPU但OpenGL驱动不一定完整。静态编译时如果带了OpenGL链接阶段就需要libGL、libEGL等库动不动就报找不到。先禁用等基本流程通了再按需开启。如果板子的GPU支持ES2可以换-opengl es2这需要交叉工具链里有对应的EGL库。-no-dbusDBus在桌面上很有用但静态交叉编译时要连着DBus的库一起处理麻烦。嵌入式场景大多不需要它。-no-feature-getentropy这是一个很细节的坑。Qt 5.14.2内部某些模块会检测系统的getentropy函数如果目标系统的glibc较老没有这个函数编译时会出现undefined reference。为了兼容更多老版本内核/glibc这个feature会直接关掉相关的使用路径减少低层glibc版本差异带来的编译问题。-qt-zlib -qt-libpng -qt-libjpeg -qt-pcre -qt-xkbcommon-x11这些参数很值钱。它们告诉Qt不要乱找外部系统的zlib、libpng等库直接用Qt源码里自带的那份一起编译进来。这里面最容易被坑的是libpng如果外部sysroot里没有合适的aarch64静态库编译会中断而-qt-libpng直接绕开了这个问题。同理-qt-xkbcommon-x11也把xkbcommon的源码纳入Qt编译中避免连到主机上的错误库。-nomake examples -nomake tests不编译示例和测试。省时间省空间。3.3 执行configure与常见错误把上面那串命令放到Qt源码根目录执行后正常会刷出一堆输出最后提示“Qt is now configured for building”。看到类似这样的话恭喜配置阶段过了。如果中间报了ERROR要认真看。最常碰到的错误有以下几类找不到编译器通常是因为CROSS_COMPILE前缀不对或者aarch64-linux-gnu-g不在PATH里。确认方法which aarch64-linux-gnu-g找不到某个库的头文件比如缺少fontconfig.h或xkbcommon.h说明sysroot里没有对应的开发包。可以用apt-file search远程查或者去目标板对应的环境下安装然后拷贝到sysroot。glibc头文件版本不匹配这类错误往往提示bits/libc-header-start.h找不到或者某些宏未定义大概率是-sysroot没传对导致编译器用了主机系统的头文件。检查一下$SYSROOT/usr/include是否存在。配置完成后开始编译make -j$(nproc)因为模块多整个编译过程可能要等1-3小时取决于机器性能。建议输出信息重定向到日志文件方便后面查错make -j$(nproc) build.log 21编译完成后安装到指定目录make install装完后检查一下/opt/Qt5.14.2-aarch64-static里面应该能看到lib/和bin/目录。确认lib/libQt5Core.a存在说明静态库编译成功。如果只想编部分核心模块可以只执行make module-qtbase之类但初回建议完整构建保证后续写程序时想用什么模块都有。4. 用静态Qt写第一个程序并部署到目标机4.1 构建一个最简单的Qt Widgets程序环境齐了先从Hello World级别开始验证。假设有这样一个hello.pro和main.cpp#include QApplication #include QLabel int main(int argc, char *argv[]) { QApplication app(argc, argv); QLabel label(Hello aarch64 Qt static); label.show(); return app.exec(); }.pro文件里只需要指定QT widgets等基本项然后用我们交叉编译的qmake生成Makefile/opt/Qt5.14.2-aarch64-static/bin/qmake hello.pro make如果没有意外当前目录会生成一个名为hello的ELF文件。注意这里用到的qmake是刚刚构建出来的aarch64版qmake它生成的是交叉编译的Makefile所以make看到的编译器就是aarch64-linux-gnu-g。这步如果错用了主机上的qmake会编译出一个x86_64的程序。4.2 静态编译绕不开的插件问题你会不会觉得静态编译一切顺利程序就能动不动跑起来了还真不一定。静态Qt最经典的坑是程序编译成功拷到板子上双击运行结果报错This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem. Available platform plugins are: (empty)这个报错的核心原因是Qt的很多功能是通过插件机制动态加载的比如显示平台插件libqlinuxfb.so、图片格式插件libqjpeg.so。动态编译时这些插件是独立文件运行时能从目录里加载而静态编译时这些插件不在目录里也没被链接进主程序于是Qt觉得“我连一个可用的平台插件都没有”。解决办法是主动告诉程序要导入哪些插件。有两种常见做法。第一种在代码里显式导入插件#include QApplication #include QLabel #include QtPlugin Q_IMPORT_PLUGIN(QLinuxFbIntegrationPlugin) int main(int argc, char *argv[]) { QApplication app(argc, argv); QLabel label(Hello aarch64 Qt static); label.show(); return app.exec(); }相关头文件会由Qt提供如果不知道插件类名可以到/opt/Qt5.14.2-aarch64-static/plugins/platforms/目录下查看生成的.a文件比如libqlinuxfb.a对应的类名就是QLinuxFbIntegrationPlugin。第二种在.pro文件中用QTPLUGIN声明QTPLUGIN qlinuxfb qjpeg qpngqmake看到这些名字后会查找可用的插件并链接进去效果和手动Q_IMPORT_PLUGIN一样。这种方式更清晰我建议优先用。另外如果你在多个机器上跑也可以配合qt.conf指定插件路径不过静态编译下插件被链进来之后路径配置的意义就不大了。这里要特别提醒一下如果程序带GUI显示插件通常至少需要一个。在无桌面环境下最常见的是linuxfb直接操作framebuffer或eglfs基于OpenGL ES的显示。选择哪个取决于板子硬件和显卡支持。没有图形界面的纯后台Qt程序平台插件报错不会出现但只要有UI这个坑十有八九会踩到。4.3 部署与验证编译完成后在x86_64主机上用file命令看下产物file hello如果提示是ELF 64-bit LSB executable, ARM aarch64, statically linked说明架构和静态链接状态都对。如果看到x86-64那就是qmake路径选错了。再用ldd检查一下动态依赖ldd hello静态链接的程序ldd通常会提示not a dynamic executable这也是一个验证手段。但注意即使Qt库全静态了glibc的NSS模块可能还会产生少量动态关系这取决于系统的/etc/nsswitch.conf等配置基础场景不用太纠结。接下来把程序拷贝到目标板子上scp hello user板子IP:/home/user/然后执行chmod x hello ./hello只要不是一开始就把linuxfb插件漏了一般都能看到窗口。如果没有屏幕可以用QT_QPA_PLATFORMoffscreen ./hello测试程序是否正常启动这个环境变量能让Qt用offscreen平台插件日志里如果是QStandardPaths: XDG_RUNTIME_DIR not set这类信息说明程序核心已经跑起来了。5. 避坑锦囊与实战心得5.1 我遇到过的几个典型报错“undefined reference to getentropy”这个报错很经典。Qt 5.14.2在一些系统上会去调用getentropy但目标板用的老版本glibc比如2.28以下没有这个函数最终链接时报undefined reference。解决方式前面说过configure时加-no-feature-getentropy生效这个feature的宏定义。“undefined reference to dlopen”Qt某些模块比如QtDBus或者插件系统相关如果你把DBus留着可能链到后期时提示缺dlopen。直接办法是给Makefile或.pro里加LIBS -ldl。大多数情况下关闭DBus模块能一并解决。“libQt5Core.a: could not read symbols: File truncated”这个多半是因为编译过程中系统崩溃或者磁盘满了导致静态库生成不完整。把对应模块清理掉重新编译即可。用make clean选模块或直接删除模块目录下build文件夹再make。“GL/gl.h: No such file or directory”configure阶段如果没禁用OpenGL而sysroot里又缺OpenGL头文件就会出现。如果你不需要OpenGLconfigure加-no-opengl。如果确实需要GLES则要补齐GLES的头文件和库。程序启动后界面文字全是方块静态Qt默认可能不链接fontconfig导致没有合适的字体渲染路径。解决方法是把ttf字体文件放到板子上并设置QT_QPA_FONTDIR指向字体目录或者在Qt程序初始化时用QFontDatabase加载本地字体。常见做法是交叉编译libfontconfig并链进去但如果你用的是-qt-xkbcommon这种静态路径字体这块用本地字体文件更可靠。5.2 静态产物体积优化静态编译的Qt程序体积往往惊到你——动不动就50MB、100MB一个Hello World都可能到了30MB以上。体积大的主要原因是Qt库全进去了加上debug信息。优化有几个方向编译时用-release模式不要用-debug这能省不少链接完用aarch64-linux-gnu-strip处理ELF文件剥掉符号表和重定位信息aarch64-linux-gnu-strip hello这样能不改变程序功能把体积压缩一小半。模块裁剪。只编qtbase里需要的feature用configure的-skip减模块如果产品只用widgets和network那-skip qtdeclarative -skip qtquickcontrols2这类会明显减短编译体积。编译选项里加-optimize-size会优先体积优化。这些做完一个Hello World静态程序可能压到15MB-25MB左右对于现代存储来说小事一桩。如果还是嫌大那么建议用musl工具链做纯静态体积会更小但Qt与musl的适配会额外耗时间典型项目里不一定划算。5.3 纯内网交付时的实操建议很多项目现场是纯内网环境板子连不上外网连yum源都没有所以“把运行环境带过去”是刚需。静态编译正好契合这个场景。但有几个细节如果提前处理能省很多事儿把Qt交叉编译环境放到一台专用的编译服务器上不要把编译任务放在临时虚拟机里否则换机器后重启环境又要花半天时间。编出来的产物连同版本号一起归档。因为Qt静态库一旦编好再想换模块组合可能需要重新编译Qt库本身版本记录清晰能少走弯路。板子的内核和glibc版本最好提前确认。纯静态情况下大部分运行时不依赖板子的glibc但如果程序里调用了板子特定版本的库还是要提前确认兼容性。如果板子需要安装nginx之类的服务做数据转发记得确认aarch64的rpm或deb包是否可以直接静态拷贝而不要现场搞yum源。热词里提到的“aarch64 纯内网 安装nginx”其实正是这类场景的典型代表能静态带过去的工具就静态带过去能在编译期搞定的事就不拖到部署期。把编译好的Qt库和工具链整体tar一份存到内网文件服务器。后面每来一个需求直接在编译服务器上出包再拷进内网。5.4 这套流程能扩展到哪些地方这套方法和流程不局限于Qt 5.14.2往前套Qt 5.12、5.15也适用只是configure参数略有差异。往扩展了说除了Qt你还能用同样的sysroot思路编译GCC、GDB、openssl、nginx等大多数C/C项目只需要把工具链前缀和sysroot路径换掉就行。比如很多嵌入式板子上的nginx完全没有必要现场用发行版源去装直接在主机上交叉编译一个静态或半静态版本拷过去就运行省去依赖七零八落的问题。这个思路在纯内网系统交付中非常实用因为我们永远无法预测目标机器上的环境有多“干净”。从我个人的经验来看Qt静态交叉编译的难点并不在于某个参数多难记而在于需要建立一个完整的“环境思维”工具链、sysroot、第三方库、Qt模块、插件、部署每一步都是链条的一环任何一环通不过后面都没法走。只要把这一整套流程理顺一次后面再遇到新的板子、新的Qt版本基本就是参数替换的问题。这篇文章如果你能照着跑通一遍后面就可以少走很多弯路了。

相关推荐

设备租赁App开发实战:从租约状态机到库存预占设计
设备租赁App开发实战:从租约状态机到库存预占设计

1. 设备租赁行业的“资产账”,不是普通进销存能算清的1.1 设备租赁和销售的业务逻辑差异在哪销售业务里,商品卖出那一刻所有权就转移了,后续的维护、折旧、退换基本是独立的售后事件。而租赁业务完全不同:设备的所有权始终留在公司… · 2026/9/24 23:58:43

从冯诺依曼体系看Linux内核:CPU、内存与中断如何协同
从冯诺依曼体系看Linux内核:CPU、内存与中断如何协同

1. 从一条指令的执行轨迹说起:冯诺依曼体系到底长什么样很多人在学习计算机组成原理时,对冯诺依曼体系的理解停留在“五大部件:运算器、控制器、存储器、输入设备、输出设备”这个层面,然后考试一过就抛在脑后。等到接触操作系统、… · 2026/9/24 23:58:43

大麦抢票自动化工具 ticket-purchase 双端跑通三步走,附完整环境自检指南
大麦抢票自动化工具 ticket-purchase 双端跑通三步走,附完整环境自检指南

大麦抢票自动化工具 ticket-purchase 双端跑通三步走,附完整环境自检指南 【免费下载链接】ticket-purchase 大麦自动抢票,支持人员、城市、日期场次、价格选择 项目地址: https://gitcode.com/GitHub_Trending/ti/ticket-purchase ticket-purcha… · 2026/9/24 23:58:43

I2C总线从开漏输出到多主仲裁:嵌入式工程师避坑指南
I2C总线从开漏输出到多主仲裁:嵌入式工程师避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:11:54

Jetson Orin NX大文件上传WiFi掉线?从电源管理到驱动固件的完整排障与根治
Jetson Orin NX大文件上传WiFi掉线?从电源管理到驱动固件的完整排障与根治

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:11:54

GT911触摸调试全解析:从I2C通信到tslib校准的嵌入式实战
GT911触摸调试全解析:从I2C通信到tslib校准的嵌入式实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:11:54

微信小程序薪资分享工具开发实战:匿名提交与社交验证机制
微信小程序薪资分享工具开发实战:匿名提交与社交验证机制

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:11:54

SECS/GEM协议实战:从HSMS配到S6F11调试的完整链路
SECS/GEM协议实战:从HSMS配到S6F11调试的完整链路

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:11:54

Tiny10 英文版中文化实战:离线语言包安装与常见报错排查
Tiny10 英文版中文化实战:离线语言包安装与常见报错排查

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:11:42

数值优化(Numerical Optimization)学习系列-03-共轭梯度方法(Conjugate Gradient)
数值优化(Numerical Optimization)学习系列-03-共轭梯度方法(Conjugate Gradient)

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:31

创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战
创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:31

MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX
MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:37

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码