欢迎加入开源鸿蒙PC社区: https://harmonypc.csdn.net/

欢迎在PC社区平台申请新建项目:https://atomgit.com/OpenHarmonyPCDeveloper/

欢迎加入开源鸿蒙PC社区:Harmony PC 开发者社区

欢迎在PC社区平台申请新建项目:OpenHarmony PC Developer - 开源代码托管,代码协作 - AtomGit

本文记录 Mesa 24.3.4.1.1 在 HarmonyOS PC AArch64 上的适配、Conan 制品交付和消费者验证。上游源码版本是 Mesa 24.3.4,24.3.4.1.1 是本项目的 Conan 交付版本。测试数字只采用实际回报和日志中已经验证的口径,不把未完成的跨平台测试写成全量通过。

一、先看结论

Mesa 是图形栈的核心项目,涉及 EGL、GLES、GBM、OSMesa、Gallium 和多个软件渲染后端。HarmonyOS PC 适配的难点不只是把代码编译出来,还要让共享库导出表、动态加载、无显示器软件渲染和 ELF 运行时约束同时成立。

本轮交付的关键结果:

项目结果
上游项目Mesa
上游源码版本24.3.4
Conan 交付版本24.3.4.1.1
官方源码地址https://archive.mesa3d.org/mesa-24.3.4.tar.xz
源码 SHA-256e641ae27...(以配方和证据日志中的完整值为准)
目标平台HarmonyOS PC / AArch64
分支fix/mesa-24.3.4.1.1
PRMR #11116
最新交付提交da7d9cfe95f7ac42746f271631593e35f3c17731
交付状态PR 已更新并触发 /rebuild,以页面最终状态为准

本轮最终修复集中在两个问题:

  1. libdrm 静态库通过 link_whole 被并入共享 libEGL,导致 137 个 drm* 符号泄漏到 EGL 导出表。
  2. llvm-nm 将三个 libc weak-UND 符号按 4 字段输出,触发 egl-symbols-check 的误报。

最终使用正式交付补丁 0011 和 0012,conan create 返回 0,test_mesa、EGL 动态加载、GBM/EGL/GLES 消费者和 OHOS 专项测试均通过。

图 1:MR #11116 显示 Mesa 高难度交付已合入,页面展示版本、分支、测试统计和审核状态。

二、Mesa 在图形栈中的位置

可以把本次适配理解为下面这条链路:

Mesa 源码
  -> Meson 构建 EGL/GLES/GBM/OSMesa/Gallium
  -> Conan 配方打包 include/ lib/ bin/
  -> ohpcd 制品仓发布 mesa/24.3.4.1.1
  -> 下游通过 EGL/GLES/GBM 或 OSMesa 消费
  -> HarmonyOS PC 上动态加载、渲染并运行

这里有三个容易混淆的版本号:

名称含义
mesa-24.3.4官方上游 tarball/tag 的源码版本
mesa/24.3.4.1.1本项目 Conan 配方使用的交付版本
fix/mesa-24.3.4.1.1AtomGit 交付分支

Conan 版本增加修订号,不代表伪造了一个上游 Mesa 版本;它用于承载 HarmonyOS PC 的配方、补丁和制品修订。

三、为什么这是高难度适配

3.1 共享 EGL 的导出表不是“能链接”就结束

Mesa 的 libEGL 会链接多个静态和共享组件。在本项目中,libdrm 通过 link_whole 进入链接闭包。普通链接成功只能说明符号能被解析,却不能说明共享库的公开导出表符合 EGL 的接口边界。

第一次检查时,egl-symbols-check 发现 137 个 drm* 符号从 libEGL 泄漏出去。这个问题会带来两个风险:

  • 下游可能误以为这些 DRM 符号是 EGL 的稳定公开 API;
  • 同名符号与系统 libdrm 或其他图形组件发生意外绑定。

3.2 weak-UND 符号会造成测试误报

egl-symbols-check 使用 llvm-nm 检查导出符号。HarmonyOS libc 中的 pthread_mutexattr_destroy、pthread_mutexattr_init、pthread_mutexattr_settype 以 weak-UND 形式出现,llvm-nm 的输出字段形态与检查脚本默认假设不同。

这三个符号不是 Mesa 把错误 API 导出到 EGL,而是平台 libc 的弱未定义引用。如果不区分 weak-UND 和真实导出,检查会把平台 ABI 特征误报成 Mesa 导出错误。

3.3 图形库必须面对无显示器环境

HarmonyOS PC 适配不能假定存在 X11、Wayland 或真实 DRM 设备。Mesa 的软件渲染路径、EGL surfaceless、GLES 最小调用和 OSMesa 离屏上下文,是更适合在设备上验证的路径。

本轮消费者验证覆盖 eglInitialize、eglQueryString、GLES2 调用、OSMesa 固定管线,以及 GBM/EGL/GLES 公开头文件的编译链接。它们验证的是可消费性,不等价于真实 GPU 驱动或窗口系统已经支持。

四、难度拆解:Mesa 为什么不是普通 C/C++ 库适配

很多库的 HarmonyOS PC 适配,只需要解决“编译器不认识某个宏”“缺一个头文件”或“测试 ELF 需要签名”。Mesa 不一样:它是一个把图形 API、动态链接 ABI、软件渲染器、硬件驱动接口、编译器工具链和窗口系统适配层组合在一起的图形栈。一个库的构建成功,并不代表另一个层面的接口边界正确。

4.1 难点一:一个源码树同时生成多类用户可见库

本次包不只生成一个 libmesa.so。交付物中至少涉及:

组件下游用途验证重点
libEGL.so.1上下文、显示连接、surfaceless 初始化SONAME、动态加载、导出符号表
libGLESv2.soGLES2 渲染 API公开头文件、链接和运行时依赖
libGLESv1_CM.so兼容固定管线接口包内布局和消费链路
libgbm.so.1图形缓冲区管理接口gbm.h、pkg-config、链接边界
libOSMesa.so.8无窗口系统离屏软件渲染上下文创建、像素缓冲区和 GL 版本

这意味着“一个二进制跑起来”不够。任何一个组件遗漏安装、SONAME 错误、导出表污染或运行时加载到系统同名库,都会让下游得到错误的结论。因此文章必须同时给出制品内容图、SONAME 图和真实 dlopen 图。

4.2 难点二:Meson 交叉编译和图形依赖不是普通静态链接

Mesa 使用 Meson 构建,且依赖链中包含 LLVM、libdrm、expat 以及生成阶段的 bison/flex/m4。这里同时存在 build-machine 工具和 host-machine 图形库:

构建机工具:bison / flex / m4
目标机库:libdrm / LLVM / expat / Mesa EGL-GLES-GBM
运行时组件:Gallium driver / libEGL / libGLAPI / 系统 libc

如果把这些角色混在一起,常见结果是“配置阶段找到的是宿主工具,运行时加载的是目标库的错误版本”,或者 Conan 根据 ABI 计算出另一个 package ID。本次真机安装时必须固定 OHOS / armv8 / clang 15 / C++17 / libc++,正是为了让消费者获得与已发布 Mesa 包相同的二进制身份。

4.3 难点三:共享库 ABI 比链接成功更严格

静态库通过 link_whole 进入共享库时,链接器并不会自动判断哪些符号应该成为对外 ABI。libEGL 在修复前泄漏 137 个 drm* 符号就是典型例子:生成 libEGL.so 没有失败,dlopen 也未必立即失败,但共享库已经暴露了不应公开的实现细节。

这类问题难在它通常只会被符号质量门禁或复杂下游发现。为此,本项目把检查从“库是否存在”提升为:

共享库文件存在
  -> SONAME 正确
  -> EGL 声明 API 存在
  -> 静态 libdrm 内部符号不泄漏
  -> dlopen 和 eglInitialize 可运行

--exclude-libs,ALL 的意义也在这里:它处理 ABI 边界,而不是一次普通的编译兼容补丁。

4.4 难点四:平台工具行为会改变测试结论

本轮不仅要面对 Mesa 自身代码,还要面对 llvm-nm、Meson、LLVM 工具链和 HMDFS 文件系统的行为差异。

  • llvm-nm 对 weak-UND 的输出字段形态,使 EGL 符号检查把 libc 弱引用误判为非法导出;
  • HMDFS 对某些权限、缓存和临时文件操作的语义与常规 Linux 文件系统不同;
  • HarmonyOS PC 没有可假定存在的 X11、Wayland、/dev/dri 或桌面 GPU 驱动路径;
  • SDK clang 在链接阶段会调用自身的 lld,运行时还需要正确的 LLVM/libxml2 搜索路径。

这些问题都不能靠把测试直接跳过解决。项目采用的是“明确平台边界 + 最小独立复验”的方式:对 weak-UND 只忽略三项已经解释的符号;对无 GPU 场景使用 surfaceless EGL 和 llvmpipe;对 SDK linker 运行时缺库问题显式设置 SDK LLVM 库路径。

4.5 难点五:软件渲染成功与硬件驱动成功必须分开

Mesa 的软件渲染路径可以在没有 GPU 驱动、没有显示服务器的条件下产生有效结果。图 5 的 EGL 1.5 初始化和 llvmpipe/OSMesa 测试证明的是:

Mesa 包可加载
  + EGL API 可初始化
  + 软件渲染路径可用
  + Conan 消费者能在真机运行

它不证明以下结论:

真实 GPU 驱动已加载
X11/Wayland 已支持
DRM 设备节点可用
所有 Gallium 硬件后端均可用

高难度适配的价值不是把结论写大,而是精确划分“已经验证的软件栈能力”和“仍依赖设备图形基础设施的能力”。

4.6 难点六:上游测试规模大,不能用一个通过率掩盖差异

MR 页面记录的上游审查口径达到 3264 项。Mesa 测试不仅有普通单元断言,还包括驱动专属、IR、缓存、反汇编、图像比较和平台工具依赖。OHOS 上某个 GTest 未完成,可能是 HMDFS、GLSL IR、字节序、外部工具、后端模块或网络来源阻塞,并不必然说明 EGL/GLES 基础链路损坏。

因此,本项目把测试结果拆成三层:

层次本轮回答的问题结论表达
上游测试台账哪些原始测试和平台边界存在保留未完成项、首错和恢复条件
包级门禁配方、补丁、共享 ABI、test_package 是否闭环conan create、符号检查和审计通过
真机消费者发布制品能否被真实下游加载和调用dlopen、EGL 1.5、退出码 0

只有三层都呈现,读者才能区分“完成了软件图形栈可消费交付”和“尚未具备全部硬件驱动矩阵”。这也是 Mesa 适配相较普通库最容易被误报、也最需要严谨说明的地方。

五、适配前的环境和源码固定

5.1 固定官方源码

配方使用官方 Mesa 归档地址:

https://archive.mesa3d.org/mesa-24.3.4.tar.xz

适配前至少保存以下信息:

curl -fL -o mesa-24.3.4.tar.xz \
  https://archive.mesa3d.org/mesa-24.3.4.tar.xz
sha256sum mesa-24.3.4.tar.xz

实际配方证据确认官方 URL 和 e641ae27... 源码摘要一致。发布文章时应把完整 SHA-256 从最终日志复制过来,不要只保留省略值。

5.2 目标配置

本次构建以 OHOS AArch64 为目标,核心设置为:

os=OHOS
os.version=6.0
arch=armv8
build_type=Release
compiler=clang
compiler.version=15
compiler.cppstd=17
compiler.libcxx=libc++

图 2:真机终端显示 HarmonyOS、AArch64、Conan 2.29.1,以及 clang 和 binary-sign-tool 的实际路径。

Mesa 是 Meson 项目,Conan 配方负责把目标编译器、工具链、依赖路径和安装布局传入构建过程。不要把服务器上的 Linux Mesa 包路径直接复制到真机;最终验证必须从 Conan 包的 include/、lib/ 和实际运行环境取得文件。

5.3 依赖边界

Mesa 可以包含很多可选驱动和窗口系统后端。HarmonyOS PC 本轮的验证重点是:

  • EGL 共享库及其 SONAME;
  • GLESv1/GLESv2 公开接口;
  • GBM 接口和链接闭包;
  • OSMesa 软件渲染;
  • Gallium softpipe/llvmpipe 离屏路径;
  • OHOS 专项进程名和离屏渲染测试。

X11、Wayland、真实 GPU 内核驱动、系统 DRM 设备等能力如果没有在设备上成立,必须作为边界说明,而不是从测试分母中悄悄删除。

六、两项正式修复

6.1 补丁 0011:收敛 libEGL 的静态符号泄漏

问题表现:

egl-symbols-check: drm* leaked symbols = 137

根因是 libdrm 静态库通过 link_whole 被整体带入共享 libEGL。整体链接能保证内部符号可用,但也可能把不属于 EGL 公开接口的符号带入动态导出表。

解决方式是在 libEGL 的链接参数中增加:

-Wl,--exclude-libs,ALL

这个选项不删除 EGL 自己的公开 API,而是限制静态库成员符号向共享库外部导出。修复后,检查结果从 137 个 drm* 泄漏降为 0。

需要注意:--exclude-libs,ALL 是链接边界控制,不是“把 libdrm 从 Mesa 删除”。EGL 内部仍可以使用所需实现,只是不把静态依赖的内部符号伪装成 EGL 公共 API。

6.2 补丁 0012:处理平台 libc 的 weak-UND 检查误报

问题表现是 egl-symbols-check 将三个 weak-UND 符号当作异常:

pthread_mutexattr_destroy
pthread_mutexattr_init
pthread_mutexattr_settype

解决方式是在测试注册时增加三个明确的 --ignore-symbol:

--ignore-symbol pthread_mutexattr_destroy
--ignore-symbol pthread_mutexattr_init
--ignore-symbol pthread_mutexattr_settype

这不是把真实 EGL 符号检查关闭,而是把已经确认属于平台 libc weak-UND 的三项从误报集合中排除。其他未列出的异常符号仍会让检查失败。

两个补丁均已注册到 conandata.yml,并同步更新 manifest.yaml 和 notes.md。它们不是只存在于执行端临时目录的测试副本,Conan 干净创建时会实际应用。

七、构建、打包和门禁

在真机消费前,先使用 conan download "mesa/24.3.4.1.1:*" -r=ohpcd 从 ohpcd 获取对应 OHOS AArch64 二进制包。下载输出中的 package ID、revision、shared=True 和 ABI settings 是制品来源的可复核身份,不应以本地源码构建目录替代。

图 3:真机从 ohpcd 获取 Mesa 二进制包,输出包含 package revision、OHOS / armv8 / clang 15 / C++17 / libc++ 设置与共享库选项。

典型的 Conan 构建入口如下:

conan create archives/m/mesa/24.3.4.1.1 \
  -pr:h=ci/conan/profiles/ohos-aarch64 \
  -pr:b=ci/conan/profiles/ohos-aarch64 \
  -r=ohpcd \
  --build=missing \
  -c tools.build:jobs=8

本轮 conan create 返回 0,并在包内执行 test_mesa。消费者输出包含:

GL_VERSION 4.5 Compatibility Profile Mesa 24.3.4 (llvmpipe)
test_mesa ALL PASS

构建门禁关注的不是单一退出码,而是下面几项是否同时成立:

门禁关注内容本轮结果
配方门禁源码、补丁、构建和打包逻辑完整通过
conan create干净构建、安装和 test_package通过
EGL 符号检查drm* 泄漏、weak-UND 误报通过,泄漏 137→0
消费者测试EGL/GLES/GBM/OSMesa 真实调用通过
OHOS 专项softpipe 离屏渲染与进程名检查通过
原子性审计仅 Mesa 白名单文件变化通过

八、消费者验证:证明包真的能用

8.1 OSMesa test_package

test_package/test.c 通过 Conan 创建流程编译并运行,实际调用 OSMesaCreateContextExt、OSMesaMakeCurrent 等公开 API,并检查 OpenGL 版本。它验证的是 Mesa 包的头文件、库文件、链接关系和运行时加载,而不是仅检查包目录是否存在。

8.2 libEGL.so.1 动态加载

另一个消费者使用 dlopen 和 dlsym:

dlopen libEGL.so.1
  -> dlsym eglGetDisplay
  -> dlsym eglInitialize
  -> dlsym eglQueryString
  -> surfaceless EGL/GLES2

实际结果为 dlopen OK,并初始化出 EGL 1.5。这一步尤其重要,因为共享库的 SONAME 和动态加载路径是很多下游项目真正关心的接口。

图 4:从完整 package reference 定位缓存目录,确认包内含 libEGL、libGLESv1_CM、libGLESv2、libOSMesa 和 libgbm,且 libEGL 的 SONAME 为 libEGL.so.1。

8.3 GBM/EGL/GLES 最小公开头消费

本轮还分别使用 GBM、EGL、GLESv2 和 GLESv1_CM 的公开头文件编译最小程序,并链接对应库。四项消费者均返回 0。它们证明了包的 include/lib 布局和公开链接关系,但不声称设备存在真实 DRM 节点或 GPU 加速。

8.4 OHOS 专项离屏测试

OHOS 专项 ohos_adapt_test 覆盖进程名获取和 softpipe 离屏渲染,运行结果为 ALL PASS。该测试的价值是验证 Mesa 在没有窗口系统的 HarmonyOS 环境下仍可走软件渲染路径。

图 5:消费者程序编译成功后,通过包内库路径 dlopen libEGL.so.1,在 surfaceless 软件渲染环境初始化 EGL 1.5,并以退出码 0 结束。

九、测试结果如何如实表达

本轮没有宣称 Mesa 的全量 GTest 全部通过。证据中明确保留以下未完成项:

未完成集合数量原因边界
util_tests Cache7HMDFS 平台阻塞
general_ir_test7上游 GLSL IR 差异
valhall_disasm_test244反汇编器字节序/工具差异
未实例化驱动 GTest未统一计数libclc、AMDGPU LLVM 模块或网络条件阻塞

因此正确表述是:

当前 OHOS 配置下,Mesa 核心包构建、EGL 符号质量门禁、Conan 消费者、EGL/GLES/GBM/OSMesa 最小验证和 OHOS 专项测试通过;部分依赖特定 GPU 后端、反汇编工具、GLSL 行为或 HMDFS 语义的上游 GTest 保留未完成项及恢复条件。

不应写成“Mesa 上游全部测试通过”或“所有 GPU 驱动均已适配”。

十、常见失败与排查方法

10.1 drm* 符号仍然泄漏

先检查实际使用的 libEGL.so.1.0.0 是否来自当前 Conan 包,再确认 --exclude-libs,ALL 已进入正式配方补丁并在干净 conan create 中应用。只在临时构建目录手工加链接参数,不能作为交付修复。

10.2 egl-symbols-check 报 pthread 符号

先用 llvm-nm 查看符号类型和字段数,确认是 libc weak-UND,而不是 EGL 真正导出的强符号。只有确认属于这三个已知平台弱引用时,才能使用对应的 --ignore-symbol;不能扩大忽略名单来掩盖新的符号污染。

10.3 dlopen libEGL.so.1 失败

检查三个方面:

  1. libEGL.so.1 的 SONAME 是否正确;
  2. LD_LIBRARY_PATH 或 rpath 是否指向 Conan 包的 lib/;
  3. 依赖的 GLES、GLAPI、LLVM 或系统库是否来自同一套 ABI。

本项目的质量警告明确要求下游使用显式包路径区分系统 /lib64/libEGL.so,不能让系统同名库抢先加载。

10.4 为什么没有真实 GPU 画面

本轮验证的重点是 HarmonyOS PC 上的可消费软件渲染和动态库接口。没有 /dev/dri、真实 GPU 驱动或窗口系统时,EGL surfaceless、OSMesa、softpipe/llvmpipe 仍然可以验证编译、链接、加载和离屏渲染;这不等价于硬件加速已经启用。

十一、截图证据说明

本文已经按下面顺序嵌入图片。发布到 CSDN 时,依次上传本目录对应 JPG,并将本地相对图片链接替换为 CSDN 自动生成的在线链接:

  1. PR 交付图:显示 MR #11116、分支 fix/mesa-24.3.4.1.1、最新提交和评审状态。
  2. 真机环境图:完整 HarmonyOS PC 桌面和终端,显示 uname -a、uname -m、conan --version。
  3. 制品下载图:显示 conan download "mesa/24.3.4.1.1:*" -r=ohpcd 成功,以及 os=OHOS、arch=armv8 的包设置。
  4. 包内消费者图:显示 Conan 安装成功、conan cache path、libEGL.so.1 或 libOSMesa.so 的实际路径。
  5. 运行验证图:显示 eglInitialize EGL 1.5、OSMesa GL_VERSION ... llvmpipe、ALL PASS 和退出码 0。

截图中没有 token、密码、私钥或不必要的内网地址。发布时保留图注,避免审核人员需要从终端内容自行推断每张图证明的结论。

十二、可复用流程

后续适配其他图形库时,可以复用以下顺序:

  1. 固定官方源码 URL、版本和 SHA-256。
  2. 列出需要交付的组件、共享库、SONAME 和公开头文件。
  3. 先验证平台工具链和依赖制品是否可消费,再开始大规模测试。
  4. 将每个修复写入正式补丁、conandata.yml 和 manifest,禁止只改临时 build 目录。
  5. 对共享库同时做链接、导出符号、SONAME、dlopen 和真实 API 消费验证。
  6. 区分软件渲染、窗口系统和真实 GPU 驱动能力,不扩大测试结论。
  7. 以 conan create、test_package、OHOS 专项和 W3/W4 门禁作为交付闭环。
  8. 文章中同时呈现 PR 事实、制品来源、真机路径和运行输出。

十三、结语

Mesa 24.3.4.1.1 的 HarmonyOS PC 适配重点不是“把 Mesa 编译出来”,而是把图形栈的边界说清楚并验证清楚:

官方 Mesa 24.3.4 源码
  -> OHOS AArch64 Meson/Conan 构建
  -> libEGL 导出表收敛(drm* 137 -> 0)
  -> weak-UND 平台误报修正
  -> Conan 制品安装
  -> EGL/GLES/GBM/OSMesa 消费
  -> surfaceless/llvmpipe 真机验证

这条证据链证明的是:Mesa 的核心共享库和软件渲染消费者可以在 HarmonyOS PC AArch64 上构建、打包、加载和运行;平台专属 GTest、真实 GPU 驱动和窗口系统能力仍按日志中记录的边界保留。

十四、FAQ

Q1:为什么源码是 24.3.4,Conan 却是 24.3.4.1.1?

24.3.4 是上游源码版本,24.3.4.1.1 是 HarmonyOS PC 适配后的 Conan 交付版本。后缀用于表达配方和补丁修订,不改变上游源码身份。

Q2:为什么必须关注 libEGL 的导出符号?

共享库的导出表就是下游可见接口。静态依赖通过 link_whole 泄漏 137 个 drm* 符号,会污染 ABI 边界,甚至引发同名符号冲突。--exclude-libs,ALL 用于收敛静态库内部符号。

Q3:--ignore-symbol 会不会掩盖真实问题?

只有三个已经确认属于 HarmonyOS libc weak-UND 的符号被忽略,其他符号仍由检查脚本校验。忽略项必须记录原因、来源和恢复条件,不能用通配符关闭检查。

Q4:为什么 dlopen 要设置包的库路径?

系统可能已有同名 /lib64/libEGL.so。显式设置 Conan 包的 LD_LIBRARY_PATH 或 rpath,才能确认加载的是本次交付的 Mesa,而不是系统库。

Q5:llvmpipe 通过是否代表 GPU 驱动通过?

不是。llvmpipe 是软件渲染器。本轮只证明软件渲染和图形 API 消费链路可用,不宣称 Intel、AMD、NVIDIA 或其他硬件驱动已经完成适配。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐