鸿蒙PC真编译移植实战:交叉编译 CPython 3.12,把 Thonny IDE 真正搬到 OpenHarmony 桌面

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

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

适配开源地址:https://atomgit.com/OpenHarmonyPCDeveloper/ohos_thonny

写在前面:为什么是 Thonny?为什么要"真编译移植"?

鸿蒙 PC 走到今天,常见软件基本不缺了——浏览器、终端、编辑器、截图工具、开发工具——但如果你教学生写 Python,或者自己写点脚本调试 API,会尴尬地发现:鸿蒙 PC 上没有一个好用的教学 Python IDE
在这里插入图片描述

Thonny 是个几乎无可替代的选择:

  • 内置 Python 解释器,新装系统就能跑
  • 界面极简,专为初学者设计(不像 VS Code 那样要折腾一堆)
  • 变量、调用、内存一栏尽收眼底
  • 跨平台(Win/macOS/Linux/Raspberry Pi)

Thonny 4.1.7 的技术构成是 Electron + Angular + 原生 Tk,这套技术栈在鸿蒙上有一个"近水"和"远水"的差距:

方案描述难度
A. 壳方案(功能等价)ArkTS 重写菜单/编辑器/Shell + 内嵌 libpython3.12.so看起来像 Thonny,但 不是上游源码
B. 真编译移植交叉编译真实 CPython 3.12 + vendored 上游 Thonny 源码让 Thonny 运行时栈真的跑起来

这次走 B,文章就是这次踩坑的全程实录。

鸿蒙PC移植效果截图:
在这里插入图片描述

在这里插入图片描述

一、设备系统版本——最容易被忽略的硬门槛

1.1 设备到底要什么版本?

我前后对接的设备是 HUAWEI MateBook Pro,UDID 3QC0124C20000733这次实机验证用的是 HarmonyOS 7.0.0(26.0.0)——比之前 DevEco Studio 启动弹窗里默认识别的版本(6.0.x)更新一代。

DevEco 设备选择器

注意上面那个版本号:HUAWEI MateBook Pro 7.0.0(26.0.0)。我必须把"7.0.0(26.0.0)"放在第一位先讲,是因为后面所有坑的前置判断,都跟这个版本直接相关。

1.2 系统版本影响什么?

  • 应用能不能起来——这是最直接的。Thonny HAP 之前几轮调试 UI 起不来(EntryAbility 不实例化、filesDir 为空、无崩溃日志),根因就是设备系统还是旧版。系统升级到 7.0.0(26.0.0) 后,进程能正常进入 onCreate、加载 libthonny_native.so、解压 zip、调用 setPythonHome,链路就跑通了
  • DevEco SDK 是否匹配——compileSdkVersion: 6.0.1(21)targetSdkVersion: 6.0.2(22)compatibleSdkVersion: 6.0.1(21),低于系统版本是允许的(向上兼容)

怎么确认自己的设备版本? 设置 → 关于本机 → 系统版本。或者在 DevEco 设备选择器里直接看。


二、工程结构与 B 路线——免交叉编译的预编译产物

2.1 两个目录共同构成可移植性

ohos_Thonny_native/
├── src/thonny/                    # 上游 Thonny 4.1.7 Python 包(vendored)
│   └── res/thonny.png             # ← 应用图标源(官方 logo)
├── native/build/ohospython/       # 交叉编译全产物(644MB,.gitignore 忽略)
├── ohos_hap/                      # DevEco 工程
│   ├── AppScope/resources/base/media/app_icon.png  # ★ 桌面图标(app.json5 引用)
│   └── entry/src/main/cpp/prebuilt/libpython3.12.a # 33MB,构建必需(已入库)
└── ohos_hap/entry/src/main/resources/rawfile/ohos_python_stdlib.zip  # 11MB(已入库)

关键:B 路线需要的两件东西都已在仓库里

文件大小是否入库
prebuilt/libpython3.12.a33 MB
python_inc/1.7 MB
rawfile/ohos_python_stdlib.zip11 MB
native/build/(交叉编译全产物)644 MB🚫 忽略

也就是说,别人 clone 这个仓库后,不需要自己交叉编译 CPython——直接走路线 B,开 DevEco 编译签名就能装。

2.2 .gitignore 的关键解禁

这一步之前踩过坑:.gitignoreprebuilt/python_inc/ 也排除了,导致 clone 后编不了。已删除那两行规则,同时保留 native/build/ 的忽略(644MB 太大,没必要入库)。

2.3 架构原理:为什么是"静态链接 + 数据解压"这套设计?

理解这套架构,才能理解后面所有坑的来源。核心矛盾只有一个:鸿蒙应用沙箱的 filesDir 是 noexec 的

也就是说,你不能像在 Linux 上那样:

# 传统做法(鸿蒙上走不通)
./python3.12 script.py    # ← filesDir 里的二进制无法 exec

于是只能换思路:

传统思路鸿蒙思路
python3.12 可执行文件放进沙箱,exec把解释器编译成静态库 libpython3.12.a,链进 NAPI 的 .so
stdlib 放在可执行文件旁边stdlib 打成 zip 放 rawfile,运行时解压到 filesDir 当纯数据读
用户代码由子进程运行用户代码由 PyRun_SimpleString同进程内嵌执行

所以数据流是这样的:

HAP 安装
  → ArkTS aboutToAppear
  → 读取 rawfile/ohos_python_stdlib.zip(11MB,stdlib + Thonny 源码)
  → zlib 解压到 filesDir/ohos_python/
  → NAPI setPythonHome(该目录)
  → C++ 侧 setenv PYTHONHOME/PYTHONPATH
  → Py_InitializeEx(0)(只跑一次,g_pyInited 守卫)
  → PyRun_SimpleString(用户代码)

代价:静态链接导致 C 扩展(math.so 等)无法 dlopen——这就是第七节日志里那个 backend_soft skipped 的来源。

收益:绕开 noexec 限制,真实的 CPython 解释器跑起来了。

另一个关键约束是 nativeLib.debugSymbol.strip = false——剥符号会导致 musl 上 dlopen SIGSEGV。这是从旧 ohos_Thonny 项目继承的教训,写进了 build-profile.json5

这套架构不是 Thonny 专属的,任何"Python 解释器 + 应用"的组合(IDE、脚本工具、数据处理)都能照搬。


在这里插入图片描述

三、签名坑——9568320 no signature file

3.1 现象

DevEco Run 输出最后一行:

Install Failed: error: failed to install bundle.
code: 9568320
error: no signature file.

3.2 真相:产物名里就有线索

列出产物目录:

-rw-r--r--@ entry-default-unsigned.hap

只要文件名带 unsigned,就说明 SignHap 任务压根没执行

3.3 根因:signingConfig 是空字符串

打开 ohos_hap/build-profile.json5

"signingConfigs": [
  {
    "name": "default",
    "type": "HarmonyOS",
    "material": { /* 完整密钥材料都在 */ }
  }
],
"products": [
  {
    "name": "default",
    "signingConfig": "",          // ← 空!引用断了

signingConfigs 里有完整的密钥材料,但 products[].signingConfig 是空字符串——两边的引用断开了。打包时 hvigor 找不到该用哪套签名,就静默跳过了 SignHap 步骤。

3.4 修复:一字之差

- "signingConfig": "",
+ "signingConfig": "default",

别忘了构建时先停 hvigor 守护进程(README 记的 uv_cwd 坑):

hvigorw --stop-daemon && rm -rf .hvigor entry/build

清理后重建:

> hvigor Finished :entry:default@SignHap... after 1 s 132 ms
> hvigor BUILD SUCCESSFUL in 4 s 880 ms

产物变成 entry-default-signed.hap,多出来的 ~254 KB 就是签名数据。

3.5 真机运行日志

DevEco Run 输出:

DevEco 启动日志

14:59:46.478 Launching org.thonny.native.ohos
14:59:46.682 No changes were detected on the selected modules...
14:59:46.845 $ hdc shell aa start -a EntryAbility -b org.thonny.native.ohos -m entry in 163 ms
14:59:46.845 org.thonny.native.ohos successfully launched within 367 ms

successfully launched——签名成功、安装成功、启动成功。


四、图标坑——桌面图标没变?

4.1 第一次替换图标时栽的跟头

应用装上去后,桌面图标还是鸿蒙的红板子默认占位图。明明改了 entry 里的 app_icon.png,HAP 里却还是 30937 字节的旧图。

4.2 真相:图标有两个位置

位置被谁引用作用
AppScope/resources/base/media/app_icon.pngapp.json5"icon": "$media:app_icon"桌面应用图标(用户能看到的)
entry/src/main/resources/base/media/app_icon.pngmodule.json5 的 ability icon模块级 / 任务管理图标
entry/.../startIcon.png"startWindowIcon"启动闪屏图标

app.json5 是应用级配置,引用的是 AppScope 资源,不是 entry只改 entry 等于没改桌面图标

4.3 修复

cp src/thonny/res/thonny.png ohos_hap/AppScope/resources/base/media/app_icon.png
cp src/thonny/res/thonny.png ohos_hap/entry/src/main/resources/base/media/app_icon.png
cp src/thonny/res/thonny.png ohos_hap/entry/src/main/resources/base/media/startIcon.png

4.4 资源缓存的二次坑

清理时如果只删 entry/build/default/intermediates/res

hvigor ERROR: Error Code: 00308018 Unknown Error
TypeError: Error Code: 00308018 Unknown Error
BUILD FAILED in 997 ms

会报这个未知错误。原因是只删了缓存目录,构建工具状态不一致。必须先 --stop-daemon 再完整 rm -rf .hvigor entry/build(同 uv_cwd 坑的纪律)。


五、tabIndex 坑——ArkTS 保留字

5.1 编译错误

想加个页签切换,第一版用了 @State tabIndex: number = 0

ERROR: 10505001 ArkTS Compiler Error
Property 'tabIndex' in type 'Index' is not assignable to the same property in base type 'CustomComponent'.
Type 'number' is not assignable to type '(index: number) => CommonAttribute'.

tabIndexCustomComponent 基类内置的通用属性(焦点顺序),不能用作状态变量名。

5.2 修复

- @State tabIndex: number = 0;
+ @State pageIndex: number = 0;

顺便把 Tabs 组件换成条件渲染(更保守,不依赖 Tabs 内部行为):

Row({ space: 8 }) {
  Button('运行日志')
    .backgroundColor(this.pageIndex === 0 ? '#4caf50' : '#3a3a3a')
    .onClick(() => { this.pageIndex = 0; })
  Button('Python 执行器')
    .backgroundColor(this.pageIndex === 1 ? '#2196f3' : '#3a3a3a')
    .onClick(() => { this.pageIndex = 1; })
}

if (this.pageIndex === 0) {
  // 日志页 Column
} else {
  // 代码页 Column
}

编译通过:BUILD SUCCESSFUL


六、Python 执行器:让 NAPI runCode 落地

6.1 NAPI 早就暴露了 runCode,UI 没接出来

thonny_napi.cpp 第 352-358 行:

static napi_value RunCode(napi_env env, napi_callback_info info) {
    std::string code = GetArg0String(env, info);
    if (code.empty()) { code = "print('ok')\n"; }
    return MakeStr(env, RunPythonCode(code, "P2"));
}

能力有了,UI 没人接Index.ets 只调了 getBuildInfo / setPythonHome / runTest 三个方法。

6.2 加输入框 + 执行按钮

在执行器页加:

TextArea({ text: this.codeInput })
  .height(130).fontFamily('monospace')
  .onChange((value: string) => { this.codeInput = value; })

Row({ space: 8 }) {
  Button('执行代码').onClick(() => { this.runUserCode(); })
  Button('示例').onClick(() => { this.codeInput = DEFAULT_CODE; })
  Button('清空输出').onClick(() => { this.codeOutput = ''; })
}

runUserCode() 关键逻辑:

runUserCode(): void {
  if (this.codeRunning) return;
  this.codeRunning = true;
  try {
    thonnyNative.setPythonHome(this.pythonHome);
    const t0 = new Date().getTime();
    const result = thonnyNative.runCode(this.codeInput);
    const ms = new Date().getTime() - t0;
    this.codeOutput = `${result}\n[${this.codeInput.split('\n').length} 行 · 耗时 ${ms} ms]`;
  } finally { this.codeRunning = false; }
}

6.3 解释器只初始化一次

thonny_napi.cppEnsurePyInitLocked()

if (g_pyInited) return "already";   // ← 关键守卫
...
Py_InitializeEx(0);
g_pyInited = true;

RunPythonCode() 外面还套了 std::lock_guard<std::mutex> lock(g_pyMu)。这意味着反复调用 runCode 没有重复初始化的开销,且全局变量与 sys.modules 跨次保留——可以做交互式 REPL


七、实机验收(7.0.0(26.0.0) 系统下)

7.1 首次启动:解压 stdlib

应用主界面 P2 Ready

界面状态:

  • Status: P2 Ready — tap Run Test ← 绿色
  • 左页签「运行日志」激活,右页签「Python 执行器」待选
  • 日志显示解压流程:
[runtime] copying rawfile ohos_python_stdlib.zip...
[runtime] source existing /data/storage/el2/base/haps/entry/files/ohos_python (os.py+thonny openable)
[native] setPythonHome → home=/data/storage/el2/base/haps/entry/files/ohos_python home_access=home_dir=y lib_dir=y os.py=y thonny=y

注意页首的核心 Tag:

Thonny Native (real compile port)
Target: OHOS aarch64
Python: cross-compiled CPython 3.12 (static libpython)
Thonny: upstream 4.1.7 (vendored site-packages)
Phase: P2 — real Thonny source headless import (1.0.4 gate)

设备路径 /data/storage/el2/base/haps/entry/files/,与设计一致(filesDir 不存可执行文件,纯数据)。

7.2 Run Test:通过 P2 闸门

点「运行日志」页的 Run Test 按钮:

P2 SUCCESS 日志

完整 stdout:

[P2] real CPython 3.12 (static embed, cross-built aarch64)
[P2] PyRun_SimpleString rc=0
--- stdout ---
Hello from real CPython on OHOS!
python 3.12.9
thonny 4.1.7
common_ok True
thonny_file /data/storage/el2/base/haps/entry/files/ohos_python/lib/python3.12/site-packages/thonny/__init__.py
count = 1
count = 2
count = 3
1+1
2
Done.
[P2] SUCCESS: real CPython imported real Thonny 4.x source (headless).

所有 P2 闸门条件都满足

  • Hello from real CPython on OHOS!
  • python 3.12.9
  • thonny 4.1.7
  • common_ok True(thonny.common 子模块可调用)
  • thonny_file 指向真实的源码路径,确认是上游 vendored 的源码
  • [P2] SUCCESS 结论行

Status 变为 P2 SUCCESS(绿色)。

日志里有一个 backend_soft skipped: ImportError loading shared library ... lib-dynload/math.cpython —— 这是 README 记录的"static + lib-dynload 已知限制":静态链接的 libpython 无法 dlopen math.so 等 C 扩展。但只测纯 Python 路径就能过闸,这是设计如此。

7.3 Python 执行器:自定义代码

切到「Python 执行器」页,点「示例」(已预填):

Python 执行器运行

执行代码:

import sys
print('python', sys.version.split()[0])
import thonny
print('thonny', thonny.get_version())
print('hello from real CPython on HarmonyOS!')
print([x * x for x in range(5)])

输出:

python 3.12.9
thonny 4.1.7
hello from real CPython on HarmonyOS!
[0, 1, 4, 9, 16]

[7 行 · 耗时 2 ms]

7 行代码,2ms 跑完——解释器初始化已完成(g_pyInited=true),每次只跑 PyRun_SimpleString

7.4 性能验证:500 元素 list comprehension

执行器 500 元素

把示例代码里的 range(5) 改成 range(500)

print([x * x for x in range(500)])

屏幕被 500 个平方数刷屏:

[0, 1, 4, 9, 16, 25, 36, 49, ..., 248001, 248649, 249001]

纯 Python 路径(list comprehension)性能完全没问题,符合预期。C 扩展(math.so)才会触发 dlopen 失败。

7.5 HiLog 视图(辅助)

HiLog 事件流

DevEco 切到 HiLog 视图,能看到大量 C039 标签的 Ace*Input / AceTextField / InputKeyFlow 事件。这是 ArkTS 应用在接收输入事件流的正常表现,说明 UI 框架完全激活,不是死页面


八、UI 起不来的"玄学"——最终归因

前面几轮调试(不在这次截图范围内,但属于适配背景)一直有一个反复出现又无法定位的问题:EntryAbility 不实例化

具体表现:

  • 进程能 fork(ps 查得到)
  • EntryAbility.onCreate 的 hilog 一条都没有
  • files/ 目录为空(解压从未执行)
  • 无 jscrash、无 faultlog、无 JS 异常栈
  • 进程稳定存活不退出

8.1 排查路径

  • ✅ 不是 UI 改动 —— 回退成最保守的条件渲染,同样不显示
  • ✅ 不是签名问题 —— signed 包装上了
  • ✅ 不是 so 缺依赖 —— NEEDED 全是标准鸿蒙库(libace_napi.z.so / libhilog_ndk.z.so / libc++_shared.so / libc.so
  • ✅ 不是 EntryAbility 代码 —— 没动过,且连第一行日志都没机会打
  • ✅ 不是 JS 崩溃 —— 没有任何异常栈

8.2 真正的根因:设备系统版本

设备系统升级到 HarmonyOS 7.0.0(26.0.0) 后,链路全部恢复正常。回顾:

  • 之前用 aa start 命令行启动失败,是因为旧系统对 native so 的加载流程有兼容性差异
  • 现在 DevEco 走 OhosDebugTask 调试启动,配合 7.0.0 系统,能正确进入 native 加载 → onCreate → loadContent → aboutToAppear → 解压 → setPythonHome → P2 Ready

8.3 经验

设备系统版本是隐藏的第一坑——比任何代码改动都优先。每次新设备调试:

  1. 确认设备系统版本 ≥ 工程要求的 SDK
  2. 优先用 DevEco Run(不是 aa start
  3. DevEco Run 失败时,先看 HiLog 找 EntryAbility 生命周期埋点
  4. 进程在但 EntryAbility 不实例化 → 多半是 native 加载阶段卡住,优先排查设备系统版本

8.4 这轮排查沉淀的方法论

回头看,这次问题定位花了好几轮,是因为缺少系统性的二分法。总结一套可直接复用的流程:

第一步:日志有没有?EntryAbility 的每个生命周期回调里埋 hilog.info(onCreate / onWindowStageCreate / loadContent 成功与否)。一条日志都没有 → 死在类实例化之前,问题在 native 加载或系统层;有 onCreate 没有 loadContent → 问题在窗口创建。

第二步:进程什么状态? ps -ef 查 PID。进程不存在 → 启动即崩,找 faultlog;进程存在但静默 → 加载卡住或等待,查 so 依赖与符号。

第三步:so 依赖干净吗? 用 DevEco 自带的 llvm-readelf 查 NEEDED 列表,和设备系统库比对。静态链接大库(如 libpython)时尤其注意 strip 配置。

第四步:换个变量重试。 换启动方式(aa start ↔ DevEco Run)、换设备、换系统版本——这次最终就是靠"系统升级"这个外部变量解决的。当代码侧全部排除后,环境变量就是唯一嫌疑。

九、常见问题 FAQ

把评论区最可能被问到的、以及我实际踩过的问题,先在这里答了。

Q1:安装报 9568320 no signature file,但我明明做了自动签名?

九成是 signingConfig 引用断了。 看产物名:只要叫 entry-default-**unsigned**.hap,就说明 SignHap 任务压根没执行。

打开 build-profile.json5 检查两处:

"signingConfigs": [ { "name": "default", ... } ],   // 密钥材料在这
"products": [ { "signingConfig": "" } ]              // ← 空字符串 = 引用断开

products[].signingConfig 必须填 signingConfigs 里的 name(本项目是 "default")。DevEco 的自动签名只负责生成材料,不保证把引用填上——这是个真实的坑。

Q2:为什么我的桌面图标还是鸿蒙默认的红板子?

图标有两个位置,桌面图标不在 entry 里

位置作用
AppScope/resources/base/media/app_icon.png桌面图标app.json5 引用)
entry/src/main/resources/base/media/app_icon.pngability 图标(module.json5 引用)
entry/.../startIcon.png启动闪屏

只改 entry 等于没改桌面图标。三处都要换成同一个文件(本项目用上游自带的 src/thonny/res/thonny.png)。

Q3:改了图标/资源,重新构建后 HAP 里还是旧文件?

资源缓存没失效。不要只删 entry/build/default/intermediates/res——会报 00308018 Unknown Error(构建工具状态不一致)。正确姿势:

hvigorw --stop-daemon          # 必须先停守护进程(否则 uv_cwd 坑)
rm -rf .hvigor entry/build     # 再完整清理

Q4:应用安装成功、进程也在,但界面就是不显示?

这正是本文第八章的"玄学"。快速自查三件事:

  1. hilogEntryAbility.onCreate 有没有日志?一条都没有 = 死在类实例化之前,问题在 native 加载或系统层
  2. files/ 目录是不是空的?空 = aboutToAppear 没执行,解压从未开始
  3. 设备系统版本是多少? 本次问题的最终答案就是系统版本——旧系统对 22MB 静态链接 so 的加载有兼容差异,升级到 HarmonyOS 7.0.0(26.0.0) 后全部恢复正常。当代码侧全部排除后,环境就是唯一嫌疑。

Q5:执行 Python 代码时报 math.so 之类的加载失败?

这是"静态链接 libpython"的已知限制,不是 bug。

静态链入的 libpython3.12.a 无法 dlopen lib-dynload/ 下的 C 扩展(math_ssl_sqlite3_ctypes 等)。纯 Python 代码(list comprehension、字符串处理、绝大多数标准库纯 Python 部分)完全没问题——本文 7.4 节 500 元素测试就是证明。

要完整扩展支持,需要后续改用 shared libpython(.so) 或把常用扩展内建编译,这是路线图上的事。

Q6:别人 clone 这个仓库能直接编译吗?

能,但有前提。 仓库已包含构建 HAP 的全部必需件:

文件大小状态
prebuilt/libpython3.12.a33 MB✅ 已入库
python_inc/1.7 MB✅ 已入库
rawfile/ohos_python_stdlib.zip11 MB✅ 已入库
native/build/(644MB 交叉编译全产物)🚫 忽略

clone 之后不需要自己交叉编译 CPython(B 路线),但仍需:装 DevEco Studio + 做一次自动签名(生成他自己设备的签名材料)。

⚠️ 注意:如果你 fork 的版本 .gitignore 里还有 prebuilt/python_inc/ 两行,说明拿到的是旧版仓库,那两行要删掉。

Q7:这个项目和你之前的 ohos_Thonny 是什么关系?

同一个目标的两个完全独立的实现,互不共享代码

ohos_Thonny(壳版)ohos_Thonny_native(本文)
UIArkTS 重写菜单/编辑器/Shell上游 Tkinter(P4 未做,当前 headless)
解释器内嵌 libpython3.12.so交叉编译的静态 libpython3.12.a
业务代码自写 ArkTS上游 Thonny 4.1.7 源码 vendored
诚实口径“像 Thonny 的壳”“真 CPython + 真 Thonny 源码”

壳版界面可用但不是上游代码;本文版跑的是真 Thonny 运行时栈。两套并存,各有价值。

Q8:那什么时候能看到真正的 Thonny 图形界面(Tk 窗口)?

这是 P4 阶段的问题,目前未做,且需要单独决策

卡点在于:Tk 的显示后端只有 X11 / Win32 / Aqua 三种,鸿蒙没有原生 Tk 后端。可行路径取决于设备是否提供 X11 兼容层。当前策略(用户已拍板)是先把 P0-P2 真编译本体跑通,GUI 后置——即使窗口永远不渲染,"交叉编译解释器 + 上游源码"链路已被证明成立,这条路本身就有价值。

Q9:为什么推荐用 DevEco Run,而不是 hdc shell aa start

两者走的启动链路不同:

  • DevEco Run:走 OhosDebugTask,带调试会话,能正确触发 native 库加载和应用生命周期
  • aa start:命令行直接拉起,某些环境下(尤其老系统)对大体积静态 so 的加载流程有差异

本文的 UI 启动问题在两种方式下表现不同,最终结论是:验证应用以 DevEco Run 为准。另外注意 DevEco 的运行配置类型要选 OhosDebugTask——如果 IDE 报错,删掉 ohos_hap/.idea/ 让它重新生成。

Q10:我想参与鸿蒙 PC 生态适配,从哪里开始?

三个入口:

  1. 社区:https://harmonypc.csdn.net/ —— 了解动态、找组织
  2. 项目申请:https://atomgit.com/OpenHarmonyPCDeveloper —— 申请新建适配项目
  3. 代码托管:AtomGit —— fork 先例工程改起来

选项目的三条原则:生态刚需(开发者天天要用的)、技术典型(拿下它等于拿下一大类)、依赖干净(零原生 addon 的最容易跑通)。

结语:真编译移植值得做

aa start 后 UI 起不来,到系统升级后 P2 SUCCESS——4 个核心截图加上 3 张工具截图,记录的就是这条路。

真编译移植的成本

  • 1 个 22MB 静态链接的 libthonny_native.so
  • 11MB 的 stdlib + Thonny 源码 zip
  • 一些 NAPI 胶水代码
  • 一堆编译签名坑

真编译移植的价值

  • 跑的是真实 CPython(不是阉割版)+ 真实 Thonny 源码(不是仿写)
  • 加 1 个 TextArea 就变成 Python 交互执行器(NAPI runCode 早就等好了
  • 未来可以往 P3(极薄宿主)+ P4(Tcl/Tk 显示层)扩展,最终形态是真实 Thonny 桌面 GUI

鸿蒙 PC 生态还在快速生长。每一份真编译移植的代码,都在拓宽这条路的边界

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐