ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

OpenSTLinux平台下FLTK 1.4升级:从XWayland到原生Wayland实践指南

OpenSTLinux平台下FLTK 1.4升级:从XWayland到原生Wayland实践指南 去年年底接了块 STM32MP157 的板子做一个带触摸屏的工业 HMI。GUI 选的 FLTK原因是整个画面不复杂Qt 那一整套动态库放上去有点浪费而 FLTK 编译出来干干净净控件绘制在嵌入式场景下又足够利索。板子跑的是 OpenSTLinux系统起来之后界面确实能出但总感觉哪里不对劲。后来扒了一下系统里 FLTK 的版本发现是 1.3.x而 OpenSTLinux 的显示环境默认是 Weston/Wayland1.3 自己是没法直接上 Wayland 的。说白了应用是在 XWayland 上转了一层才画出来的。这事刚开始还能忍等我开始高频切换页面、做动画缩放的时候帧率明显往下掉。最后我下决心把 FLTK 升到 1.4.x不但在源码层面重新交叉编译了一遍还把它接回了 OpenSTLinux 的 Yocto 构建体系让下一次烧录系统时不再是临时手动补丁。这篇把整个更新过程、里面涉及的选择逻辑、以及我踩过的坑写出来给同样在 OpenSTLinux 上做 FLTK 应用开发的朋友一个参考。无论你是第一次接触这套环境还是已经跑过几个 Demo这篇应该都能帮你少走一点弯路。1. 这次更新到底想解决什么自带 FLTK 1.3 在 OpenSTLinux 上的憋屈1.1 OpenSTLinux 的显示栈和 FLTK 的尴尬处境OpenSTLinux 是 ST 基于 Yocto 做的嵌入式 Linux 发行版主要面向 STM32MP1 系列微处理器。默认的图形栈是 Weston也就是 Wayland 合成器。这一点很关键你在板子上看到的桌面、窗口列表、触摸事件本质上都是 Weston 在管理。而 FLTK 1.3.x 是在 Wayland 还没成气候的时候定型的它的原生后端是 X11。所以在 OpenSTLinux 默认环境下运行 FLTK 应用常见路径是FLTK 应用 → X11 库 → XWayland → Weston → DRM/KMS → LCD 屏。这一层 XWayland 转译并不是免费的。每一次控件的重绘、每一次触摸事件的上报都要在 X11 协议和 Wayland 协议之间做转换。静态界面看不出什么问题一旦动画多起来CPU 占用和帧率表现都很难看。1.2 升级到 FLTK 1.4 之后到底能拿到什么FLTK 1.4 最重要的变化就是提供了原生 Wayland 后端。应用可以不再借道 XWayland而是直接和 Weston 通信走 Wayland 协议的 buffer 提交、直接渲染。资源占用和绘制延迟都是实打实的改善。除了 Wayland 后端1.4 还带来了高 DPI 支持、对 Cairo 和 Pango 的更好集成、以及一套统一的Fl_Wayland_Window_Driver之类的内部驱动架构。对于一个 7 寸、10 寸这种小尺寸但分辨率很高的工业屏来说高 DPI 支持尤其有用。以前的 1.3 版本在 1080p 的屏上如果系统默认缩放不是 1字体和控件经常会发虚要么就得自己在应用里把所有坐标人工缩放极其痛苦。提示如果你现在的应用还在用 FLTK 1.3 并且没有改动计划那先别急着升。FLTK 1.4 的个别 API 做了清理比如Fl::set_color相关的一些旧接口要留意。升级前先翻一遍官方 CHANGES 文件重点看1.4.0的 API 变化列表。2. 动手前先摸底显示链路、SDK 和当前 FLTK 安装状态2.1 板子上先把现状看清楚我拿到板子第一件事是确认当前系统里实际跑的是哪套东西。不要凭印象猜版本因为 OpenSTLinux 不同的小版本也可能带不同的组件。先把这几条命令都跑一遍uname -a cat /etc/os-release weston --version ls /usr/lib/libfltk* /usr/lib/*/libfltk* 2/dev/null fltk-config --version 2/dev/null || echo no fltk-config in PATH我当时看到的输出是 FLTK 1.3.5weston 8.0.x系统里没有独立的fltk-config库文件直接躺在/usr/lib下。fltk-config都没有说明这个包是用 Yocto 配方装的但配方的打包方式比较裸没把配置文件导出到 PATH 里。这也是后面要重新整理配方的理由之一。除了版本还要搞清楚当前显示通道。STM32MP1 的显示接口有 RGB、DSI、LVDS 等几种但不管哪种在 Linux 侧最后都落在 DRM/KMS 上。直接看内核日志和 Weston 启动参数dmesg | grep -i drm cat /proc/cmdline ps -ef | grep westonweston进程的启动参数里一般会带--backenddrm-backend.so或类似的东西。drm-backend意味着 Weston 直接管理显示设备这是最干净的路径。如果你看到--backendx11-backend.so那就说明 Weston 自己还在 X11 上跑这个更新意义就大打折扣得先解决 Weston 的启动配置。2.2 交叉编译 SDK 是不是已经就位OpenSTLinux 的 SDK 和环境变量是分开的。如果你是第一次用找不到环境文件很正常我一开始也是到处翻find /opt -name environment-setup* 2/dev/null找到后手动 source 一下source /opt/ST/stm32mp1/4.1.0/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabisource 完以后一定要验证别省这一步echo $CC echo $CXX echo $SDKTARGETSYSROOT环境变量正常CC应该指向形如arm-ostl-linux-gnueabi-gcc的交叉编译器SDKTARGETSYSROOT指向 SDK 的 sysroot 目录。这个 sysroot 就是目标板文件系统的根编译出来的动态库、配置文件最终都该往里放。2.3 确认 Wayland 相关开发包是否在 sysroot 里FLTK 1.4 编译 Wayland 后端时需要wayland-client、wayland-protocols、libdecor这些开发库。OpenSTLinux 的 SDK 一般会带 Wayland 协议头文件但libdecor不一定带。先查$ pkg-config --exists wayland-client echo yes || echo no $ pkg-config --exists libdecor-0 echo yes || echo no如果libdecor没有编译 FLTK 时不强制但窗口标题栏和边框就出不来。嵌入式工业 HMI 一般都会去掉系统装饰所以哪怕没有也能跑。不过我建议还是把libdecor装上否则以后想在窗口上加个关闭按钮都麻烦。注意用 SD 卡系统直接在板子上编译并不推荐。STM32MP157 的 Cortex-A7 跑编译也能过但一次完整编译要二三十分钟起而且板上的空间和散热都是问题。交叉编译是更合理的选择。3. 用 ST SDK 从源码交叉编译 FLTK 1.4 的完整路子3.1 为什么优先用 SDK 自带的环境而不是手写工具链文件OpenSTLinux SDK 除了设置CC、CXX之外还有个容易被忽略的点它把pkg-config的搜索路径、sysroot 的链接参数、目标 CPU 架构的浮点优化都配好了。如果绕过这套环境自己写 CMake 工具链文件很容易出现“编译过了跑起来崩了”的情况尤其是 NEON 浮点指令集这类细节手动配置非常容易漏。所以我建议的原则是能用source environment-setup-*就不要自己造工具链文件。在 ST 这套环境里直接用cmake并依赖环境变量即可不需要额外指定CMAKE_TOOLCHAIN_FILE。3.2 具体编译命令和 CMake 开关的意义我从 GitHub releases 下载了 FLTK 1.4 的源码包解压后开始构建wget https://github.com/fltk/fltk/archive/refs/tags/release-1.4.0.tar.gz tar xf release-1.4.0.tar.gz cd fltk-release-1.4.0 mkdir -p build cd build接着执行 CMake 配置。我当时的参数是这样cmake ../ \ -DCMAKE_INSTALL_PREFIX${SDKTARGETSYSROOT}/usr \ -DCMAKE_BUILD_TYPERelease \ -DOPTION_USE_WAYLANDON \ -DOPTION_USE_X11OFF \ -DOPTION_USE_GLOFF \ -DOPTION_USE_CAIROON \ -DOPTION_USE_PANGOON这几个开关不是随便写的逐个解释CMAKE_INSTALL_PREFIX装到 SDK 的 sysroot 里去。这样交叉编译应用时find_package(FLTK)才能找到新版本库。OPTION_USE_WAYLANDON打开原生 Wayland 后端。这是这次升级的核心。OPTION_USE_X11OFF因为目标环境就是 Weston带 X11 后端会让库变大、链接依赖变多。但我们也有一个项目要用 X11 后端那个项目里我单独编了一份带 X11 的包放在/usr/local/fltk_x11。两块不冲突。OPTION_USE_GLOFF默认 FLTK 1.4 如果检测到 EGL/OpenGL ES会把 GL 窗口后端一起编进去。STM32MP1 的 GPU 虽然支持 OpenGL ES 2.0但我做的是纯 2D HMI不打算让 GPU 参与关掉 GL 可以减少一层依赖也避免在 Weston 里额外初始化 EGL 出问题。OPTION_USE_CAIROONCairo 的 2D 绘制后端。FLTK 官方一说数据绘制可能用到打开更稳。OPTION_USE_PANGOONPango 负责字体布局和文本渲染。嵌入式环境里如果没有这个中文字体的处理会各种别扭。然后编译安装make -j$(nproc) make installmake install之后sysroot 里的 FLTK 就是 1.4.0 了。验证一下${SDKTARGETSYSROOT}/usr/bin/fltk-config --version这个版本号正确说明库和配置脚本都已经落到 sysroot。3.3 链接阶段常见错误和缺包装库的排查交叉编译 FLTK 时最常碰到的问题是链接期报缺符号比如undefined reference to wl_compositor_interface这类多半是 Wayland protocol 的代码生成文件没找到或者是链接时没有加-lwayland-client。在 OpenSTLinux SDK 里正常不会缺但如果你用了非 SDK 的pkg-config路径就会踩。其次比较隐蔽的是libdecor。如果 sysroot 里没有libdecor-0.pcFLTK 1.4 的 CMake 会自动禁用窗口装饰编译不会失败但到了板子上你发现所有窗口既没有标题栏也无法拖动。这不是 bug是依赖缺失。如果不需要装饰可以忽略如果需要得先把libdecor交叉编译好装进 sysroot再回头编 FLTK。还有libxkbcommon。Wayland 后端处理键盘映射时依赖它OpenSTLinux SDK 通常已经带上但如果你的自定义 sysroot 比较干净记得补。提示每次改完 sysroot 里的库最好重新跑一次source environment-setup-*再执行make clean make。这套 SDK 的pkg-config缓存有时候不够聪明环境切来切去容易拿到旧路径。4. 让更新在下次烧录后还活着把 FLTK 配方接进 Yocto4.1 为什么不建议在板子上直接 make install 了事很多人的做法是交叉编译完把.so文件 scp 到板子上或者做个 rootfs 补丁包。这种做法做原型验证没问题但做产品固件就麻烦大了。下次重新烧写官方镜像所有改动全部消失还得手动再来一遍。OpenSTLinux 本身是 Yocto 发行版正规做法是把 FLTK 新版本做成一个 recipe让bitbake把更新固化到镜像里。以后重新生成镜像一烧进去就是新版本。4.2 如何用 Custom Layer 管理 FLTK 配方如果你的 OpenSTLinux 工程里还没有自己的层先初始化一个bitbake-layers create-layer meta-custom bitbake-layers add-layer meta-custom在meta-custom/recipes-graphics/fltk下建配方。如果工程里原本有 FLTK 的旧配方最省事的办法是直接用devtool升级source openstlinux-environment # 进入构建环境 devtool modify fltkdevtool modify会把当前配方源码解出来然后你可以检查VERSION和SRC_URI。如果旧版本是 FLTK 1.3.x源码地址迁移到了 GitHub releases需要手动更新SRC_URI https://github.com/fltk/fltk/archive/refs/tags/release-1.4.0.tar.gz PV 1.4.0如果没有旧配方手动写一个fltk_1.4.0.bb也行SUMMARY Fast Light Toolkit HOMEPAGE https://www.fltk.org/ LICENSE LGPL-2.0-with-exceptions LIC_FILES_CHKSUM file://COPYING;md5xxx SRC_URI https://github.com/fltk/fltk/archive/refs/tags/release-${PV}.tar.gz SRC_URI[sha256sum] xxx S ${WORKDIR}/fltk-release-${PV} DEPENDS libdecor wayland wayland-native wayland-protocols pango fontconfig inherit cmake EXTRA_OECMAKE -DOPTION_USE_WAYLANDON -DOPTION_USE_X11OFF -DOPTION_USE_GLOFFLIC_FILE_CHKSUM的 md5 值需要你下载解压后自己md5sum算一下。不同版本源码里的 COPYING 文件可能变化别省略这一步。写好后执行devtool build fltk构建成功后再用devtool finish fltk meta-custom把改动提交到层里最后重新生成镜像bitbake st-image-weston烧录新镜像板子上就是新 FLTK。4.3 版本跳跃时最容易出的问题FLTK 1.3 到 1.4 的包名和文件布局有变化主要体现在fltk-config的路径和默认参数变了。库文件名从libfltk.so.1.3变成了libfltk.so.1.4如果旧应用里硬编码了libfltk.so.1.3启动会直接报找不到共享库。旧的fltk2相关兼容代码如果应用里引用了需要做适配。如果你的应用是通过 CMake 的find_package(FLTK)方式链接的那在新 sysroot 下重新编译一次即可链接对象会自动找到新版本。注意在 Yocto 里升级一个库一定要把这个库的 ABI 变更检查清楚。FLTK 1.4 在 ABI 上没有刻意完全兼容 1.3使用旧头文件编译出来的 .so 不要直接混用。5. 上板验证时容易翻车的几个细节5.1 跑起来之后先做的三件事系统烧完板子起来以后先确认环境确实生效再跑应用。第一检查版本fltk-config --version ldconfig -p | grep fltk第二确认 Wayland 后端被正确使用。不加任何配置时FLTK 1.4 会自己判断是否处于 Wayland 会话里。可以打印一个带窗口的演示程序比如官方 democd /usr/share/fltk/test ./demo如果界面正常出现再用weston-log或者其他调试工具看客户端是不是走了 wayland 协议。最简单的方式是在启动应用前设置环境变量export FLTK_BACKENDwayland ./your_app第三检查触摸。FLTK 1.4 在 Wayland 后端下触摸事件来自wl_touch协议跟 X11 下的多点触控路径完全不同。如果触摸没反应优先查 Weston 的 libinput 配置而不是查 FLTK。5.2 X11 后端和 Wayland 后端混用时的运行时切换FLTK 1.4 允许同一个程序里同时编入 X11 和 Wayland 两个后端。你可以在程序启动时通过FLTK_BACKEND环境变量切换# 强制走 Wayland export FLTK_BACKENDwayland # 强制走 XWayland export FLTK_BACKENDx11如果你像我一样有部分老代码依赖 X11 特有行为这个特性在调试阶段特别有用。可以先在x11后端跑确认不是应用逻辑问题再切到wayland后端对比表现。需要小心的是两边后端对窗口坐标、缩放、全屏的处理有细微差异。比如 X11 后端下Fl_Window::fullscreen()是直接告诉 X serverWayland 后端下则需要通过xdg_surface协议协商。同一个 API表现并不完全一致。5.3 我碰到的几个隐蔽问题先说字体。FLTK 1.4 的 Wayland 后端走 Pango fontconfig 渲染文字。如果板子上的 fontconfig 没有配置中文字体中文全部变方框。这个问题 1.3 在 X11 下不常见因为 X11 后端做了 FreeType 字体 fallback。升级后必须确认fc-list | grep -i cjk如果输出为空就得在镜像里加入中文字体包比如packagegroup-fonts-truetype或手动拷贝一个字体的.ttc文件到/usr/share/fonts再执行fc-cache -f。再有就是libdecor的插件路径。如果你用 Yocto 构建时libdecor没有作为插件安装应用启动后不报错但所有窗口都没有标题栏。解决办法是确认镜像里包含libdecor的.so插件文件并在启动应用前看一眼日志有没有类似libdecor: No plugin found的提示。最后一个是 GPU 和 GL 的坑。STM32MP1 虽然带 GPU但如果你在编译 FLTK 时开了OPTION_USE_GLON应用启动时 Weston 会尝试给客户端分配 EGL 表面。如果格式不匹配可能出现黑屏或者白屏但应用本身没崩溃。这种问题最难排查。我后来干脆把 GL 关了纯软件渲染虽然大尺寸窗口的拖动性能略逊一点但整个系统稳定很多。5.4 更新完成后的一点实测对比我把同一套压力测试界面反复切换页面、实时曲线刷新、拖拽窗口跑了一遍FLTK 1.3.5 XWaylandCPU 占用最高到 68%刷新曲线时有可感知的撕裂。FLTK 1.4.0 原生 WaylandCPU 占用控制在 35% 左右界面刷新明显流畅触摸拖拽也没有了之前的“粘手感”。这个结果在我的 7 寸屏和 10 寸屏上都复现了。最后分享一个小习惯更新 FLTK 这件事本身不复杂真正值钱的是要把整个流程固化下来。我现在每次接到新的嵌入式 GUI 项目第一件事不是写代码而是先确认 GUI 库和显示后端的关系再决定要不要在 Yocto 层面做升级。FLTK 在 OpenSTLinux 上的这套流程后面换到 Qt、换到模拟器环境也都能复用看清显示链路准备好交叉编译环境把改动收进 Yocto 配方然后花更多时间在实机验证上。希望这篇能让你少走几个我走过的弯路。
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表