KMP / CMP 鸿蒙版本 Beta 发布,他有什么特别之处?
华为官方适配的 KMP/CMP 鸿蒙适配版本终于出来了,这个版本真的拖了好久了,虽然之前也有腾讯维护的 ovCompose 和 Kuikly 版本,但是现在华为官方的社区版本终于出来,也算是给了 KMP/CMP 鸿蒙官方适配的名分。
当然,他实际上和
ovCompose和Kuikly版本也是密不可分。
事实上 KMP/CMP 适配鸿蒙的门槛还是相当高的,它需要把鸿蒙当作 Kotlin/Native 的新 Target 实现,这次的实现路线需要大量的 KN 和 LLVM 适配,然后 Kotlin 会直接编译成鸿蒙 ELF 二进制,再用 NAPI / CAPI 和 ArkTS / ArkUI 协作完成渲染。
Kotlin/Native 用
KonanTarget描述"我要为谁出二进制",每个 Target 一般有三要素:family、architecture、triple。
当然,这套代码 Kotlin/Native 核心实现来自腾讯 KuiklyBase 体系,CMP UI 那边的统一渲染也是来自腾讯 ovCompose ,所以项目里你可以看到不少 // region Tencent Cod 这样的代码,grep "// region Tencent Code" -r 就能列出对应改动。
KMP 鸿蒙
KMP 适配鸿蒙,首先就是需要在 KonanTarget.kt 新增和 OHOS 平台,同时扩张出 Family.OHOS :
-
OHOS_ARM64 : KonanTarget("ohos_arm64", Family.OHOS, Architecture.ARM64) -
OHOS_X64 : KonanTarget("ohos_x64", Family.OHOS, Architecture.X64)
这两个 Target 也意味着,从 Gradle DSL
kotlin { ohosArm64() }一直到中间 IR 的 lowering 阶段,Kotlin 编译器都知道了鸿蒙平台的存在。
然后就是让 LLVM 后端真能产出能跑的二进制,这一步简单说就两件事:
-
clang 参数:用毕昇 LLVM 19,然后 host-defines 上沿用 Linux 一路,因为鸿蒙底层 libc 是 musl,工具链以 Linux ELF 派生
-
链接器:Linker.kt 用
class OhosLinker(targetProperties: OhosConfigurables) : LinkerFlags(...),配套OhosConfigurables做 dispatch
那 KMP 到这里 Kotlin 到 ELF 的工具链就这么简单接通了, 然后就是产物:
-
编译器用鸿蒙官方毕昇 LLVM 19 和 Kotlin/Native 自带 LLVM 解耦
-
产物大概有:
-
libkn.so(业务通用动态库) -
libkn.a(静态库,供 hap 二次链接) -
libkn_api.h(C 头,供宿主 C/C++ 访问 Kotlin 导出 API,和libkn_api.h配套) -
.kexe(可执行)
-
-
模块化编译:通过
emitRuntime/emitStdlib/moduleIncludes分别产出 runtime、stdlib、业务模块多个 so,可以按需装载、热替换和排查符号问题

-
缓存:支持 per-file / per-klib 静态缓存,可以加速 Debug 增量构建
-
DFX:内置 hilog 接入、crash 栈解析,Sanitizer 方面支持 ASAN

所以整个流程大概就是: Kotlin 源代码 → Kotlin/Native 编译器(带 OHOS Target) → 毕昇 LLVM 19(OHOS 工具链) → ELF 静态/动态库 (.a/.so/.kexe),最终被鸿蒙应用以 dlopen 方式装载:
CMP 鸿蒙
完成 KMP 的基础之后,就是 CMP 在鸿蒙上的 Skia 绘制,目前也有两条路线:
-
自渲染(skia 路径)
-
统一渲染(fusionRenderer 路径)
自渲染
自渲染路径和 iOS 的 KN一致,CMP 自己持有一块 GL Surface,自己 swap,鸿蒙这一侧的载体是提供一个 ArkUI 的 XComponent,暴露一个原生 EGL Surface,外加触摸事件投递:
-
ComposeArkUIViewController作为入口类,接到ArkUIViewController的生命周期回调后,会把 EGL 上下文与 Skia Surface 接起来 -
帧驱动用
ChoreographerManager接收鸿蒙 vsync 信号,然后送给ComposeSceneRender做组合与重绘
基本都是和 ovCompose 没什么太大区别,一个妈生的。
统一渲染
这个就有意思了,通过 ArkUI RenderNode 作为挂载锚点 ,由 ArkUI 渲染线程驱动反向 draw 回调,Compose 直接在 ArkUI 提供的 Canvas 上完成绘制,fusion 模式下 Compose 不再持有独立 EGL/GPU 上下文 ,所以省去双份 GPU 上下文与离屏 buffer 开销 :
-
JsRenderNode(通过 NAPI / RenderNode JS API 同步)
-
CRenderNode(通过 Native C++ 直接挂载)

不过目前统一渲染 的 ArkUINativeViewFusionRenderNode.kt 文件头是:

但是实现上又是:

所以这个是属于华为的设计,还是和腾讯有关系?我也分不清了,但是看起来还是更多像是华为的实现,或者只是模板污染了?
所以看下来,目前鸿蒙社区版本基本就是继承了 KuiklyBase 和 ovCompose 的实现,算是这两个的分支?而且目前已经合入了 JetBrains 上游 Kotlin 2.2.21 / Compose 1.9.2 ,还在能加了 LTPO/DVSync 自适应帧率、 CommonGC 全新算法替代原 CMS 算法等调整,所以也不全是腾讯的直接迁移。
不过问题来了,未来 KMP 和 CMP 在鸿蒙等于是多分叉?比如:
-
JetBrains 的 KMP/CMP
-
基于 JetBrains 的腾讯 Kuikly 和 ovCompose
-
基于 Kuikly 和 ovCompose 的 CPF-KMP-CMP
或者就是后续完全分叉?开发者自己选用哪个?反正我暂时是没搞懂。那么你选的话呀,你会选个?
链接
更多推荐



所有评论(0)