去年从上一家公司离职后,我休息了一段时间。回想这5年,从x86到飞腾/龙芯,从Ubuntu到麒麟V10、可以说把国产化道路上的“地雷”都踩了个遍。
国产化适配到底难在哪?其实不在于Qt语法本身,而在于环境、依赖、底层图形栈和硬件的兼容性。今天我就把印象最深的5个典型问题记录下来,既是给自己做个复盘,也希望能帮到正在这条路上挣扎的同行。
坑一:打包发布后的“xcb”平台插件噩梦
问题现象:
在麒麟系统上开发完Qt程序,一切正常。但打包发给甲方测试,双击运行直接报错:
qt.qpa.plugin: Could not load the Qt platform plugin “xcb”
当时就懵了,明明在开发机上跑得好好的。
问题根源:
说白了,就是目标机器上缺少Qt程序依赖的底层图形库(X11/XCB相关)。我们的开发机装了完整Qt SDK,库是齐全的,但甲方客户的纯运行环境往往很“干净”。
解决方案:
-
暴力但有效的办法:把Qt安装目录下的 plugins/platforms/ 整个文件夹拷贝到你程序的发布目录里,确保 链接forms 子目录下。
-
根治的办法:编写启动脚本,在运行程序前 export LD_LIBRARY_PATH,把程序自带的库路径加上。再配合 ldd 命令检查依赖,把缺失的 .so 文件一个个补全。
-
偷懒的大招:用 linuxdeployqt 工具自动抽取依赖,省心省力。
坑二:从x86向ARM架构(飞腾/鲲鹏)迁移,编译都过不去
问题现象:
项目要求把一套成熟的Qt显控软件从x86平台移植到飞腾2000+麒麟V10的全国产化环境中。本来以为Qt是跨平台的,结果源码拷过去,编译各种报错,要么找不到头文件,要么链接时库版本对不上。
问题根源:
-
交叉编译工具链版本不匹配。ARM平台的gcc和x86平台的不是一回事。
-
第三方依赖库没有ARM版本。比如有些自编译的 .so 文件,在x86下能用,到了ARM下直接报错。
-
代码里有些假设是x86字节序或对齐方式的写法,在ARM上会崩溃。
解决方案:
-
确认工具链:飞腾平台用 gcc-arm-8.3-2019.03 这个版本比较稳。
-
源码重编:所有第三方依赖库,不要偷懒拷二进制,一定要在ARM机器上从源码重新 ./configure && make 一遍。
-
代码规范:涉及到内存操作(比如 memcpy、结构体指针强转)的地方,注意字节对齐问题,加上 #pragma pack 或者在QT中用 QDataStream 规范序列化。
坑三:Release版本下崩溃,连个屁都查不到
问题现象:
程序在研发部跑得好好的,发到客户现场跑了几天,偶尔崩溃一次。关键是客户机器上没有开发环境,给回来的只有一行“段错误”的提示,没有行号,没法定位。
问题根源:
Release模式默认不带调试符号,而且为了性能优化,代码执行顺序可能都被打乱了。用常规的 printf 大法根本抓不住这种偶发崩溃。
解决方案:
-
确保生成Core Dump文件:在国产麒麟系统上,默认的coredump路径可能在 /var/core 或 /tmp 下。用 ulimit -c unlimited 放开限制。
-
保留符号表:编译Release版本的时候,加 -g 选项生成调试信息,但用 strip 命令剥离出来单独保存。这样既不影响程序运行效率,等崩溃发生时,又能用 gdb 加载符号表去分析core文件。
-
调试命令:拿到core文件后,gdb ./YourApp core,然后输入 bt(backtrace),就能看到崩溃时的函数调用堆栈,哪怕看不到行号,也能锁定是哪个模块的哪类操作出了问题。
坑四:界面花屏,怀疑人生
问题现象:
在统信UOS上,Qt界面某些时候会花屏、闪烁,或者QML界面里的控件直接消失不见。重启程序有时能好,有时不行。
坑五:中文输入法无法调用
问题现象:
Qt程序里的 QLineEdit 和 QTextEdit 控件,死活调不出系统的中文输入法(搜狗、麒麟自带的都试过),只能打英文。
上面这些内容,只是我这5年工作里很小的一部分。从去年离职到现在,我也在思考接下来的方向。目前不想再去坐班了,希望以远程技术顾问或按次计费的救火队员身份,继续为有需要的团队服务。
如果你正在做国产化(麒麟、统信UOS、飞腾、龙芯)相关的Qt项目,遇到了编译通不过、跑起来崩溃、界面不显示等疑难杂症,欢迎私信我。我这边可以提供按小时远程排查或按问题打包解决的服务。
PS:另外2个问题,我整理成了一份《麒麟/UOS下Qt常见报错速查手册》PDF,里面包含详细的排查命令和脚本。需要的朋友评论区留邮箱,我发给你