| 1 | # HarmonyOS 与 OpenHarmony |
| 2 | |
| 3 | > 英文原文:[HarmonyOS.md](../HarmonyOS.md)。 |
| 4 | > 最后与英文同步日期(last synced with English revision):2026-09-29。 |
| 5 | |
| 6 | 本文讲 Codewhale 在 HarmonyOS PC 上运行,以及 OpenHarmony 的交叉编译环境。 |
| 7 | |
| 8 | ## 支持层级 |
| 9 | |
| 10 | | 目标 | Codewhale 层级 | CI 覆盖 | 分发方式 | |
| 11 | | --- | --- | --- | --- | |
| 12 | | 用户空间兼容 glibc 的 HarmonyOS PC | Tier 1 Linux ARM64 运行时 | 由 Linux ARM64 发布构建覆盖 | GitHub 发布的二进制文件;npm 为次要途径 | |
| 13 | | `aarch64-unknown-linux-ohos`(OpenHarmony) | Tier 2 交叉编译目标 | `codewhale-tui` 会用真实的 OpenHarmony 原生 SDK/sysroot 检查 | 从源码构建;没有预编译发布产物 | |
| 14 | |
| 15 | Tier 2 的意思是:每一处相关的源码改动都会过一遍编译检查,但维护者不承诺提供发布二进制文件, |
| 16 | 也不承诺做完整的设备级运行时测试。CI 任务使用已发布的 OpenHarmony 6.1 原生 SDK; |
| 17 | 如果 SDK、Clang 或 sysroot 不可用,它会刻意失败, |
| 18 | 而不是改用宿主头文件,或者用一个可能误报成功的桩(stub)来替代。 |
| 19 | |
| 20 | ## 在 HarmonyOS PC 上运行 |
| 21 | |
| 22 | 用户空间兼容时,HarmonyOS PC 可以直接用 Linux ARM64 发布版。 |
| 23 | 在 Linux 环境里做全新安装,用官方 GitHub 安装脚本: |
| 24 | |
| 25 | ```bash |
| 26 | curl -fsSL https://codewhale.net/install.sh | sh |
| 27 | "$HOME/.local/bin/codewhale" --version |
| 28 | ``` |
| 29 | |
| 30 | [已发布的 v0.9.11 版本](https://github.com/codewhale-hq/CodeWhale/releases/tag/v0.9.11) |
| 31 | 包含 `codewhale-linux-arm64` 和 `codew-linux-arm64`;有产物存在,并不代表它兼容每一台 |
| 32 | HarmonyOS 设备。各版本的具体要求和 Cargo 兜底方案见 |
| 33 | [Linux ARM64 可移植性](./INSTALL.md#linux-arm64-可移植性)。 |
| 34 | 已经直接安装过的,用 `codewhale update`。目录已被占用,或者由包管理器管理的安装, |
| 35 | 见[迁移到全新目录](./INSTALL.md#migrating-from-npm-cargo-or-another-installation)。 |
| 36 | npm 仍是次要的打包途径。`codewhale-tui-linux-arm64` 这个文件名只为兼容旧版更新器而保留, |
| 37 | 并不是第三条命令。 |
| 38 | |
| 39 | ## 交叉编译到 OpenHarmony |
| 40 | |
| 41 | 仓库不把机器相关的 SDK 路径纳入版本控制。把 `OHOS_NATIVE_SDK` 设成 OpenHarmony |
| 42 | 原生 SDK 目录,也就是包含 `llvm/bin`、`sysroot` 和 |
| 43 | `build/cmake/ohos.toolchain.cmake` 的那个目录。 |
| 44 | |
| 45 | Windows PowerShell: |
| 46 | |
| 47 | ```powershell |
| 48 | $env:OHOS_NATIVE_SDK="<path-to-openharmony-native-sdk>" |
| 49 | . .\scripts\ohos-env.ps1 |
| 50 | rustup target add aarch64-unknown-linux-ohos |
| 51 | cargo build --target aarch64-unknown-linux-ohos -p codewhale-cli |
| 52 | ``` |
| 53 | |
| 54 | Linux 或 macOS: |
| 55 | |
| 56 | ```bash |
| 57 | export OHOS_NATIVE_SDK=/path/to/openharmony/native |
| 58 | . ./scripts/ohos-env.sh |
| 59 | rustup target add aarch64-unknown-linux-ohos |
| 60 | cargo build --target aarch64-unknown-linux-ohos -p codewhale-cli |
| 61 | ``` |
| 62 | |
| 63 | 这些环境准备脚本会为 `aarch64-unknown-linux-ohos` 导出 Cargo 的目标专用 |
| 64 | `linker`、`AR`、`CC`、`CXX`、`CFLAGS`、`CXXFLAGS`、`CARGO_ENCODED_RUSTFLAGS`、 |
| 65 | `CC_SHELL_ESCAPED_FLAGS`,以及 CMake 工具链变量。它们还会把 `bindgen` 指向 SDK 的 |
| 66 | `libclang` 和 sysroot,好让 `rquickjs-sys` 生成 OpenHarmony 绑定; |
| 67 | `rquickjs-sys` 本身并不附带这些绑定的预生成版本。 |
| 68 | |
| 69 | 在 Windows 上,`ohos-env.ps1` 让 Cargo 使用仓库里的 `ohos-clang.cmd` 启动器。 |
| 70 | 该启动器再委托给 `ohos-clang.ps1`,所以不只 C/C++ 编译和 |
| 71 | bindgen,最终那次 Rust 链接也总会带上 `-target aarch64-linux-ohos`、 |
| 72 | SDK sysroot 和 `-D__MUSL__`,同时保留 Cargo 的链接器参数和退出状态。启动器转发前会重新给每个参数加引号, |
| 73 | 所以就算 SDK 路径里带空格(比如默认的 `D:\DevEco Studio\...` 安装), |
| 74 | 到最终链接时 `--sysroot` 依然完好。 |
| 75 | |
| 76 | ## 编译器包装脚本 |
| 77 | |
| 78 | 临时手动调用编译器时,用 `scripts/ohos/` 里的包装脚本。它们读取同一个 |
| 79 | `OHOS_NATIVE_SDK` 变量,脚本里不含本机路径。 |
| 80 | |
| 81 | Windows PowerShell: |
| 82 | |
| 83 | ```powershell |
| 84 | .\scripts\ohos\ohos-clang.ps1 --version |
| 85 | .\scripts\ohos\ohos-clangxx.ps1 --version |
| 86 | ``` |
| 87 | |
| 88 | Linux 或 macOS: |
| 89 | |
| 90 | ```bash |
| 91 | sh ./scripts/ohos/ohos-clang.sh --version |
| 92 | sh ./scripts/ohos/ohos-clangxx.sh --version |
| 93 | ``` |
| 94 | |
| 95 | 如果你想直接用 `./scripts/ohos/ohos-clang.sh` 这样运行 POSIX 包装脚本, |
| 96 | 先给它们加上可执行权限: |
| 97 | |
| 98 | ```bash |
| 99 | chmod +x ./scripts/ohos/ohos-clang.sh ./scripts/ohos/ohos-clangxx.sh |
| 100 | ``` |
| 101 | |
| 102 | ## 链接器与工具链路径 |
| 103 | |
| 104 | 仓库不把 Cargo 链接器路径或 CMake 工具链路径纳入版本控制。Cargo 无法展开 `linker` |
| 105 | 值或 CMake 工具链路径值里的环境变量,所以这些值改由 `scripts/ohos-env.ps1` 和 |
| 106 | `scripts/ohos-env.sh` 导出。 |
| 107 | |
| 108 | ## 依赖守卫 |
| 109 | |
| 110 | 发布准备阶段会跑一次不依赖 SDK 的依赖检查: |
| 111 | |
| 112 | ```bash |
| 113 | ./scripts/release/check-ohos-deps.sh |
| 114 | ``` |
| 115 | |
| 116 | 这个守卫会校验 Windows 最终链接包装脚本的约定,证明 OHOS 会启用 `rquickjs-sys` 的 |
| 117 | bindgen feature,解析 `codewhale-tui` 在 `aarch64-unknown-linux-ohos` 下的依赖图, |
| 118 | 并且在不受支持的宿主/UI crate 重新进入该依赖图时失败:`nix` 0.28/0.29、 |
| 119 | `portable-pty`、`starlark`、`arboard` 或 `keyring`。这项无 SDK 检查不能代替真实的 |
| 120 | SDK/sysroot 构建,但能在发布前抓住已知的链接器、bindgen、 |
| 121 | `starlark -> rustyline -> nix` 以及 PTY/keyring 回归。 |
| 122 | |
| 123 | 因为 OpenHarmony 的依赖图有意不含 `portable-pty`,常驻的 `terminal/*` PTY 工具 |
| 124 | 在该目标上不会注册。普通的 `exec_shell` 工具仍然可用,走的是非 PTY 的进程实现。 |
| 125 | |
| 126 | 仅 Linux 的沙箱实现(bubblewrap、seccomp 和 `prctl` 进程加固)只为 |
| 127 | `all(target_os = "linux", not(target_env = "ohos"))` 编译。因此 OpenHarmony |
| 128 | 会报告“没有本地操作系统沙箱”,而不是去探测自己并不支持的 Linux 内核路径或系统调用。 |
| 129 | 配置好之后,外部 OpenSandbox 执行仍可单独使用。 |
| 130 | |
| 131 | 原生桌面剪贴板库和 Wayland 辅助库也不进入 OpenHarmony 的依赖图。 |
| 132 | 文本复制降级为终端客户端路径(OSC 52;在 tmux 里则是 tmux 的 `load-buffer -w`); |
| 133 | 粘贴由终端提供,走普通输入或 bracketed 输入。图像剪贴板读取在该目标上不可用。 |
| 134 | 如果终端无法接受 OSC 52,复制会返回一条明确的“Clipboard unavailable”错误, |
| 135 | 而不是 panic,也不会谎称成功。 |
| 136 |