把 Typst 搬上开源鸿蒙 PC:一次“干净”的移植记录
欢迎加入开源鸿蒙 PC 社区:https://harmonypc.csdn.net/
欢迎在 PC 社区平台申请新建项目:https://atomgit.com/OpenHarmonyPCDeveloper
适配开源地址(AtomGit):https://atomgit.com/OpenHarmonyPCDeveloper/ohos_typst
目录
| 项目 | 说明 |
|---|---|
| 适配软件 | typst(命令行排版引擎,CLI,无图形界面) |
| 开源协议 | Apache-2.0 |
| 源码版本 | v0.15.1 |
| 目标平台 | 鸿蒙 PC(x86_64)与 arm64 设备(鸿蒙 PC / 平板 / 开发板) |
| 交叉目标 | x86_64-unknown-linux-ohos、aarch64-unknown-linux-ohos |
| 构建宿主 | Linux x86_64(Ubuntu 24) |
| 工具链 | rustup stable ≥ 1.92(实测 1.98.1)+ zig-patch 0.16.0(zig cc / zig c++ / zig ar) |
| 上游改动 | 源码零修改,仅修改 Cargo.lock 以使用更高版本依赖 |
| 产物 | out/x86_64/typst(strip 后约 52 MB)、out/aarch64/typst(strip 后约 48 MB) |
| 验证方式 | 静态检查与实机测试 |
| 上游地址 | https://github.com/typst/typst |
| 适配仓库 | https://atomgit.com/OpenHarmonyPCDeveloper/ohos_typst |
Typst 简介
Typst 是一个新兴的基于标记语言的开源排版系统。Typst 首个版本发布于 2023 年,允许使用一种类似于 Markdown 的标记语言对文档内容进行排版,并生成 PDF、SVG、PNG 和 HTML 等格式产物。
该领域过去长期使用 LaTeX,但其诸多问题已被诟病多年:报错信息可读性极差、工具链臃肿复杂、编译速度较慢、与现代编辑器集成度较差等等。Typst 极大改善了这些问题。
本次适配的目标与产物
本次适配基于 typst v0.15.1,面向 API 24~26 的鸿蒙 PC 设备,构建环境为 Linux x86_64。适配过程遵守一条约束:上游 typst 源码树保持零修改。适配内容全部放在仓库自己的脚本与配置里,升级上游版本时只需要重新走一遍构建,不需要重新合并改动。
| 产物 | 路径 | 说明 |
|---|---|---|
| 鸿蒙 PC | out/x86_64/typst | x86_64-unknown-linux-ohos,PIE,仅依赖 libc.so |
| arm64 设备 | out/aarch64/typst | aarch64-unknown-linux-ohos,同上 |
| 宿主基线 | 由宿主 cargo build 得到 | x86_64-linux-gnu,用于对拍 |
| 设备测试包 | out/typst-ohos-0.15.1-{x86_64,aarch64}-device-test.tar.gz | 产物 + 中英文样例 + 随包子集字体 + run.sh 自检脚本 |
不需要自己编译时,也可以直接下载预构建版:

移植路线:所有修改均在构建部分
Typst 主体使用 rust 编写,源码里没有对鸿蒙进行特别适配。编译工作完全由 rustc:Rust 官方为 aarch64-unknown-linux-ohos 与 x86_64-unknown-linux-ohos 提供 Tier 2 支持,同时提供这两个目标平台预编译的标准库,无需自行构建。C/C++ 编译和链接由 zig 提供的 zig cc / zig c++,编译产物的外部依赖只有 libc.so。
| 层次 | 上游预期 | 鸿蒙侧的处理方式 |
|---|---|---|
| Rust 编译 | 环境 rustc | rustup 安装 ohos 目标平台的标准库 |
| C/C++ 编译 | 环境 cc | CC_<triple> / AR_<triple> 指向 build/wrapper/<arch>/zig-cc 与 zig-ar |
| 链接 | 环境 cc | CARGO_TARGET_<TRIPLE>_LINKER 指向 build/wrapper/<arch>/zig-c++ |
| C 标准库 | glibc | 修改的 muslc,链接时附加 build/shim/shim-ohos-<arch>.o |
| 依赖树 | Cargo.lock 中锁定的版本 | 升级 cc 与 shlex 两个条目的版本 |
build.sh 按以下步骤进行一次构建:
- 下载解压 typst v0.15.1 源代码到
typst-0.15.1/,解压 zig-patch 到build/zig-ohos/; - 应用
patches/下的代码补丁文件; - 用
zig cc用于编译符号补齐的 shim 代码; - 执行
cargo build --release --package typst-cli --features vendor-openssl --target <triple>编译; - 将产物复制到
out/<arch>/typst,调用build/strip.sh移除符号; - 静态核查产出的可执行文件。
准备工具链
Rust
Typst 主要使用 Rust 语言开发,编译时需要使用 rustc 和 cargo 项目管理器。这里使用 rustup 简化安装。
# 配置镜像源,后续所有涉及 rustup 的命令均需要重复配置
export RUSTUP_DIST_SERVER=https://mirrors.ustc.edu.cn/rust-static
export RUSTUP_UPDATE_ROOT=https://mirrors.ustc.edu.cn/rust-static/rustup
# 安装 rustup 与 Rust
curl --proto '=https' --tlsv1.2 -sSf https://mirrors.ustc.edu.cn/misc/rustup-install.sh | sh
为了加快下载进度,这里使用中国科学技术大学 Linux 用户协会提供的镜像源,替换 Rust 官方的链接。
Typst v0.15.1 的 workspace 声明了 rust-version = "1.92",edition 为 2024,因此宿主的 rustc 需要 1.92 或更高(本次实测 1.98.1)。Rust 默认安装只包含本机的工具链,我们还需要单独安装鸿蒙目标平台标准库(可能需要新打开一个终端以使用更新后的环境变量):
rustup target add aarch64-unknown-linux-ohos # arm64,必须
rustup target add x86_64-unknown-linux-ohos # x86_64,鸿蒙 PC 与虚拟机使用
检查本机 Rust 环境:
rustc --version
cargo --version
若输出版本号则环境正常。
此外需要从系统包管理器安装一些包:
# Ubuntu 24
sudo apt update && sudo apt install -y git patch curl tar xz-utils perl binutils llvm
# Arch Linux
sudo pacman -Syu --noconfirm git patch curl tar xz perl binutils llvm
其中 patch 用于应用 patches/,binutils 提供 readelf 与 nm,llvm 提供 llvm-objcopy(用于移除符号)。
HarmonyOS SDK
编译过程中需要使用 HarmonyOS SDK,可从华为开发者联盟官网下载:

下载完成后,自行解压到特定目录即可。本移植版本的编译流程不使用 HarmonyOS SDK 提供的 C/C++ 编译器。HarmonyOS SDK 只用于使用 llvm-objcopy 清理编译符号,和提供鸿蒙环境中的 libc.a 用于静态检查符号覆盖。
Zig
这里使用对鸿蒙专门进行适配的 zig-patch 发行版,版本为 0.16.0:

build.sh 会自动下载到 downloads/zig-patch-0.16.0.tar.xz 并解压到 build/zig-ohos/,离线环境可以预先下载。
依赖与改动部分
Typst 主要使用 Rust ,仅少量依赖需要 C/C++ 或汇编编译器参与。具体来说(当指定 --package typst-cli --features vendor-openssl 时)只有 psm 与 openssl-src 两个依赖库需要,以及一个对编译器调用封装的 crate cc:
| 依赖 | 版本 | 使用到的非 rust 语言 | 在本次构建里承担什么 | 需要处理的事项 |
|---|---|---|---|---|
psm | 0.1.24 | 汇编 | 提供上下文切换能力 | CC_<triple> / AR_<triple> 需正确指向包装脚本 |
openssl-sys 和 openssl-src | 0.9.116 / 300.4.1+3.4.0 | C | 包系统的网络支持 | 需要 perl |
cc | 1.4.5 | 无 | 上面两项都通过它使用编译器能力 | 上游默认版本较旧 |
其余用于压缩、字体、文件监控等等功能的依赖(flate2 + libz-rs-sys、fdeflate、fontdb、notify 等)均完全使用 Rust 实现,无需额外处理。
只做一处对上游提供的文件的改动,放在 patches/0001-cargo-lock-cc-bump.patch 里,内容是升级 Cargo.lock 中的两个依赖项版本:
cc 1.2.11 -> 1.4.5 (同时引入 find-msvc-tools 0.1.12)
shlex 1.3.0 -> 2.0.1
这个补丁只修改配置文件 Cargo.lock,不改上游任意源码,即「源码树零修改」。观察构建日志里确认指定的升级版本确实被采用:
Compiling shlex v2.0.1
Compiling cc v1.4.5
Compiling openssl-src v300.4.1+3.4.0
Compiling psm v0.1.24
适配中遇到的问题
宿主 rustc 版本低于 typst 的要求
现象。 编译环境默认提供的 rustc 版本为 1.88.0,直接执行 cargo build 会立即终止:
error: package requires rustc 1.92 or newer
原因。 typst v0.15.1 的 workspace Cargo.toml 声明了 rust-version = "1.92",同时在清单文件中指定的 edition 2024 也要求较新的工具链。
处理。 使用 rustup 更新环境 rustc 等组件:执行 rustup toolchain install stable 升级到 1.98.1,再重新 rustup target add 两个 ohos 目标平台。Rust 官方的 ohos target 都是 2 级支持,可直接下载对应平台标准库。
验证。 rustc --version 输出 1.98.1,cargo build 不再出现相关错误报告。
zig cc 的接线:三元组改写与两套环境变量
现象。 把 CC 直接指向 zig cc 之后,psm 的汇编文件仍然由宿主 cc 编译,报 error occurred in cc-rs: command did not execute successfully ... "cc";vendored OpenSSL 的 Configure 也从环境里拿到了宿主的编译器。
原因有两个。
- 目标平台的写法差异。rustc 与 cc-rs 传给 C 编译器的是 Rust 三元组
--target=aarch64-unknown-linux-ohos,而 zig 则要求--target=aarch64-linux-ohos。使用一个 shell 包装脚本给zig cc传递其预期的参数:
# build/wrapper/aarch64/zig-cc 部分内容
for a in "$@"; do
case "$a" in
--target=*-unknown-linux-ohos) args+=("--target=aarch64-linux-ohos") ;;
*) args+=("$a") ;;
esac
done
exec "$ZIG" cc -target aarch64-linux-ohos "${args[@]}"
- 具体选择使用 C/C++ 编译器的流程不同。调用 C 编译器不由 Cargo 直接调用,而是在对应依赖库的构建脚本中调用构建(这里通过
cc-rs);Cargo 仅负责将链接器与归档器参数传递给 rustc。于是需要指定两部分变量:
- Cargo 侧:
CARGO_TARGET_<TRIPLE 大写>_LINKER、CARGO_TARGET_<TRIPLE 大写>_AR; - cc-rs 侧:
CC_<triple>、AR_<triple>,其中三元组里的-换成_。
处理。 build.sh 导出所有需要的变量, cc-rs 部分同时提供小写与全大写两个版本,以适应不同库的差异查找规则:
export "CC_$TRIPLE_LOWER=$CC" "CC_$TRIPLE_UPPER=$CC"
export "CXX_$TRIPLE_LOWER=$CXX" "CXX_$TRIPLE_UPPER=$CXX"
export "AR_$TRIPLE_LOWER=$AR" "AR_$TRIPLE_UPPER=$AR"
export "CARGO_TARGET_${TRIPLE_UPPER}_LINKER=$CC"
export "CARGO_TARGET_${TRIPLE_UPPER}_AR=$AR"
其中 LINKER 指向的是 zig-c++,这一点在后面还会提到。
验证。 构建日志显示 psm 与 openssl-src 正确编译完成,且 psm 相关的编译产物使用目标平台架构。
依赖库引用了 musl 不导出的 mmap64
现象。 链接阶段报错,找不到 mmap64 的定义。
原因。 Typst 间接依赖了 memmap2 库 的 v0.9.5 版本。在 src/unix.rs 里,其使用下面判定决定具体调用符号:
#[cfg(any(
target_os = "android",
all(target_os = "linux", not(target_env = "musl"))
))]
use libc::{mmap64 as mmap, off64_t as off_t};
Rust 的 ohos 目标平台的编译信息为 target_os = "linux"、target_env = "ohos",没有被条件编译选项排除,于是 memmap2 把鸿蒙视为 glibc 环境,使用 libc::mmap64。而鸿蒙实际使用 musl ,其只导出 mmap,mmap64 没有提供。参考 alpine 的 muslc 信息:
$ readelf -Ws downloads/alpine-x64-root/lib/ld-musl-x86_64.so.1 | grep -w mmap
471: 00000000000564e7 197 FUNC WEAK DEFAULT 11 mmap
处理。 编译一个 C shim 把 mmap64 转发到 mmap:
#include <sys/mman.h>
void *mmap64(void *addr, size_t length, int prot, int flags, int fd, long long offset) {
return mmap(addr, length, prot, flags, fd, (off_t)offset);
}
关键细节:这个 shim 通过封装脚本参与链接。 build/wrapper/<arch>/zig-c++ 把编译好的 shim 目标文件追加进链接参数,zig-cc 则没有:
# build/wrapper/aarch64/zig-c++(节选)
SHIM="$SELF/../../shim/shim-ohos-aarch64.o"
extra=()
[ -f "$SHIM" ] && extra+=("$SHIM")
exec "$ZIG" c++ -target aarch64-linux-ohos "${extra[@]}" "${args[@]}"
之所以只在 zig-c++ 封装脚本中参与,原因是 build.sh 把 CARGO_TARGET_<TRIPLE>_LINKER 指向了这个脚本,整个程序的链接通过该脚本完成,缺失符号也会在这步导致链接失败。
验证。 链接完成后,产物里 mmap64 不再是未定义符号,只剩 musl 提供的 mmap:
$ readelf -Ws out/aarch64/typst | grep -wE "mmap64|mmap"
2: 0000000000000000 0 FUNC GLOBAL DEFAULT UND mmap
这条经验可以推广。 依赖中所有 not(target_env = "musl") 形式的平台判定,在鸿蒙上都会判别为 glibc 分支,因为 ohos 的 target_env 取值是 ohos,与 gnu、musl 都不相同。遇到链接阶段缺符号时,先尝试检索存不存在相同问题。
Zig SDK 不提供 objcopy,转为使用 HarmonyOS SDK 提供的 strip 能力
现象。 zig-patch 的发行目录内有 zig、lib 与文档,没有 llvm-objcopy,缺失移除符号的能力。
处理。 build/strip.sh 按顺序尝试搜索:HarmonyOS SDK 自带的 llvm-objcopy、宿主 PATH 里的 llvm-objcopy、objcopy,若存在任一可用项就执行 --strip-all。
验证。 strip 之后 file 检查输出含 stripped 标记,产物体积(48 MB / 52 MB)极大减小。
Cargo.lock 里 cc 与 shlex 的版本
现象。 上游 v0.15.1 锁定的 cc 版本是 1.2.11,shlex 版本是 1.3.0。
处理。 补丁把 cc 升为 1.4.5(同时引入 find-msvc-tools 0.1.12)、shlex 升到 2.0.1,只改 Cargo.lock。
验证。 构建日志中出现 Compiling shlex v2.0.1 与 Compiling cc v1.4.5 说明确实使用升级后的版本。
产物的静态核查
交叉编译产物真的在鸿蒙平台上可以运行吗?在编译环境通过几个方法快速检查:build.sh 在结束处打印架构、NEEDED 与 interpreter,同时 build/check-symbols.sh 提供完整的完全静态的符号检查。
| 核查项 | aarch64 产物 | x86_64 产物 |
|---|---|---|
file 命令输出 | ELF 64-bit LSB pie executable, ARM aarch64, stripped | ELF 64-bit LSB pie executable, x86-64, stripped |
| interpreter | /lib/ld-musl-aarch64.so.1 | /lib/ld-musl-x86_64.so.1 |
| NEEDED | 仅 libc.so | 仅 libc.so |
| RUNPATH / RPATH | 无 | 无 |
| ELF 标志 | BIND_NOW、NOW PIE | 同 |
| 首个 LOAD 段的页边界 | 0x10000 | 0x1000 |
| 动态未定义符号总数 | 234 | 229 |
其中 HarmonyOS SDK libc.a 不存在的 | 0 | 0 |
| 其中 Alpine musl 不存在的 | 0 | 0 |
| 弱引用外部符号 | 4 | 4 |
符号覆盖检查的具体方法:获取产物符号表里所有 UND 符号,检查在 OHOS SDK sysroot 里的 libc.a、 Alpine musl 1.2.5 中是否存在。所有符号均存在,说明产物需要的外部符号,设备端与验证环境两端都具备。四个弱引用未定义符号是 copy_file_range、getentropy、getrandom、gettid,装载器找不到时按可选处理:
$ OHOS_SDK=/opt/ohos-sdk/sdk/default/openharmony ./build/check-symbols.sh out/aarch64/typst
UND 符号数: 234
== 缺失于 OHOS SDK libc.a: 0 ==
== 缺失于 Alpine musl 1.2.5(qemu 运行环境): 0 ==
== WEAK UND 符号数: 4 ==
copy_file_range
getentropy
getrandom
gettid
NEEDED 只有 libc.so,说明 libc++、compiler-rt 与 OpenSSL 都是静态链接的,不依赖设备上预装其它运行库。两个架构的首个 LOAD 段页边界不同(aarch64 是 0x10000,x86_64 是 0x1000),为指令集各自的默认页大小,均为 4096 的整数倍。
功能验证:与上游版本 9 项比对
Typst 的行为是否与其它平台一致,靠逐项比较验证来判定。做法是在编译环境上额外构建一份 x86_64-linux-gnu 产物作为参照版,OHOS 产物放在 qemu-user + Alpine musl 1.2.5 的运行环境里执行,两者跑同一批样例,比对输出。
鸿蒙设备环境模拟使用 qemu-user 9.2.1 与 Alpine musl 1.2.5 的 rootfs,本次复用自同机的前置适配项目,放在 downloads/ 下,不纳入版本管理;换到别的机器上需要比照时,准备同样的 qemu-aarch64 / qemu-x86_64 与 Alpine rootfs 即可。
对拍前做了两处修改,避免把无关的随机量算成差异:
- 样例文档里加
#set document(date: none),消除编译时间戳; - PDF 的 XMP
InstanceID/DocumentID每次编译都会重新生成,比对前替换成占位符。
SVG、PNG 与文本输出不做归一化,逐字节比对。验证脚本与样例文档(baseline/run-alignment.sh 与 test-project/ 里的拉丁样例、中文样例、查询样例与随包子集字体)随适配工作目录提供,本节列出的输出都由它产生。
| 序号 | 比对项 | 比对方式 | aarch64 | x86_64 |
|---|---|---|---|---|
| 1 | --version | 逐字节 | PASS | PASS |
| 2 | --help | 逐字节 | PASS | PASS |
| 3 | fonts --ignore-system-fonts | 逐字节 | PASS | PASS |
| 4 | 拉丁样例导出 PDF / SVG / PNG | SVG、PNG 逐字节;PDF 归一化随机 ID | PASS | PASS |
| 5 | 中文样例导出 PDF(随包子集字体) | 归一化随机 ID | PASS | PASS |
| 6 | eval 查询(heading / figure) | 逐字节 | PASS | PASS |
| 7 | 错误路径(即编译不存在的文件) | 退出码 + 报错文本 | PASS | PASS |
| 8 | 无 HOME 环境下的行为 | 退出码 + 输出 | PASS | PASS |
| 9 | 包系统实际工作:真实下载 @preview 包 | 日志 + 缓存落位 + 编译结果 | PASS | PASS |
第 4、5 项:产物完全一致。 拉丁样例两页的 SVG 与 PNG 在两个平台上的摘要完全一致:
$ cd baseline/align-out
$ md5sum host/latin-1.png aarch64/latin-1.png
6a85352873d5944047220ca0be15e390 host/latin-1.png
6a85352873d5944047220ca0be15e390 aarch64/latin-1.png
$ md5sum host/latin-2.svg aarch64/latin-2.svg
f3f2e103325d3e1dc4ec0de1b845a0d5 host/latin-2.svg
f3f2e103325d3e1dc4ec0de1b845a0d5 aarch64/latin-2.svg
PDF 在去除随机 ID 影响后同样一致,说明字体子集、坐标与结构树都是逐项相同的。
第 9 项:包系统实际运行测试。 样例引用 @preview/a2c-nums:0.0.1,编译时 Typst 会发起请求请求下载该包:
typst compile pkg-test.typ pkg.pdf
这一项同时验证了 typst 网络部分模块能正常工作,输出:
downloading @preview/a2c-nums:0.0.1
0 B / 2.5 KiB ( 0 %), 24.7 KiB/s, ETA: 0 s
2.5 KiB / 2.5 KiB (100 %), 24.7 KiB/s, ETA: 0 s
下载完成后包被写入 ~/.cache/typst/packages/preview/a2c-nums/0.0.1/,文档里 int-to-cn-num(123456789) 渲染出 一亿二千三百四十五万六千七百八十九。两个架构在这一项上都是通过。
功能划分
状态依据适配仓库里的功能核查记录与上面测试结果填写。
T0 基础
| 功能 | 状态 | 备注 |
|---|---|---|
| CLI 参数解析与子命令分发 | 支持 | |
源码解析与求值(typst-syntax / typst-eval) | 支持 | |
排版引擎(typst-layout) | 支持 | |
内嵌字体(typst-assets) | 支持 | 随二进制分发,无需外部字体文件 |
| PDF / SVG / PNG 导出 | 支持 | SVG 与 PNG 与宿主位级一致 |
| 错误诊断输出 | 支持 | 退出码与报错文本与宿主一致 |
标准输入与标准输出(-) | 支持 | stdin → stdout 导出 PDF 正常 |
T1 核心
| 功能 | 状态 | 备注 |
|---|---|---|
| 中文(CJK)排版 | 支持 | 需要 --font-path 或 TYPST_FONT_PATHS 指定中文字体 |
| 数学排版、表格、图形、交叉引用、脚注 | 支持 | |
eval 子命令与查询 | 支持 | |
包系统(@preview 下载) | 支持 | 依赖 HOME 或 TYPST_PACKAGE_CACHE_PATH |
| 包缓存与数据目录 | 支持 | 无 HOME 时的行为与其它平台一致 |
watch 模式 | 支持 | inotify 后端 |
| 自定义字体路径 | 支持 | --font-path / TYPST_FONT_PATHS |
模板初始化(init) | 支持 | 与包系统共用下载与缓存路径 |
T2 其它与边界
| 功能 | 状态 | 备注 |
|---|---|---|
| 系统字体自动扫描 | 不支持 | fontdb 扫描的是标准 Linux 字体目录,鸿蒙的系统字体位于 /system/fonts,需要用 --font-path /system/fonts 或 TYPST_FONT_PATHS 显式指定 |
--open 打开外部查看器 | 不支持 | 鸿蒙系统不支持 |
shell 补全(completions) | 支持 | bash 补全脚本生成正常 |
info 子命令 | 支持 | 输出正常,含特性开关状态 |
| PDF 标准与 tagged PDF | 支持 | |
| HTML 与 bundle 导出 | 支持 | |
编译性能参数(-j / --timings / --deps) | 支持 | |
自定义 CA 证书(--cert) | 支持 |
在鸿蒙 PC 上验证
以下内容在鸿蒙 PC 真机上执行(设备型号、分辨率与系统版本待填)。
准备
在系统设置应用「隐私和安全 > 高级」中开启「运行外部来源的扩展程序」开关,并从应用商店安装【BiShengJDK17-OH】与【DevBox】。
执行文件签名
鸿蒙 PC 要求所有可执行文件在执行前都必须签名,这里使用调试签名。把可执行文件传输到设备后:
# 假设传输的可执行文件名为 typst_unsign
binary-sign-tool sign -inFile typst_unsign -outFile typst -selfSign "1"
chmod 755 ./typst
# typst 为签名后的可运行的可执行文件
真机快速核查
设备测试目录里提供测试脚本 run.sh,运行该脚本即可进行完全测试:
tar xzf typst-ohos-0.15.1-x86_64-device-test.tar.gz
cd typst-ohos-device-test
sh run.sh ./typst
脚本覆盖:产物版本、内嵌字体列表、拉丁样例导出 PDF/SVG/PNG、中文样例导出 PDF、eval 查询、产物目录清单。

图中终端窗口顶部是设备桌面与任务栏,可以看到签名命令与自检脚本从 --version 一路执行到 DEVICE TEST DONE,out/ 目录下生成了 sample-cjk.pdf、sample-latin-1.svg、sample-latin-1.png、sample-latin-2.svg、sample-latin-2.png 与 sample-latin.pdf。
签名完成之后,即可参考官网文档开始排版工作。
常见问题(FAQ)
Q1:产物拷到设备上执行报权限错误(Operation not permitted)。
鸿蒙 PC 要求可执行文件先签名。用 binary-sign-tool sign -selfSign "1" 做一次调试签名,并对文件执行 chmod 755。
Q2: 产物在第三方终端中签名后运行仍报错权限错误。
鸿蒙 PC 对自签类型可执行文件的限制,建议使用系统内置终端应用。
Q3:含中文项目编译出来汉字不显示。
默认只使用内嵌字体,内嵌字体不含中文字形。加 --font-path fonts 指定随包子集字体,或 TYPST_FONT_PATHS=/system/fonts 使用设备系统字体。
Q4:包里引用的 @preview 包下载失败。
确认正确设置 HOME环境变量。需要网络代理时设置 http_proxy / https_proxy,包系统会读取这两个环境变量。
Q5:产物在本机 qemu 里运行失败。
产物动态链接的是 musl 的 libc.so,用 qemu-user 执行时需要提供对应的 musl 运行环境,靠 -L 指定根目录:
./downloads/qemu-u92-root/usr/bin/qemu-aarch64 -L ./downloads/alpine-root out/aarch64/typst --version
未准备好 Alpine rootfs 时,运行会失败,这与产物本身无关;按上面的命令准备好 rootfs,或者直接到真机上验证。
后续
后续拟继续推进的方向:
- 系统字体自动扫描:目前中文排版要显式给出字体路径。
fontdb扫描的是标准 Linux 字体目录,拟推动支持/system/fonts。 --open的外部查看器:鸿蒙设备目前不向终端应用开放类似xdg-open的权限。
参考资料:
- Rust 官方 ohos target 说明:https://doc.rust-lang.org/rustc/platform-support/openharmony.html
- zig-patch 发行版:https://github.com/openharmony-zig/zig-patch/releases/tag/0.16.0
- typst 上游仓库:https://github.com/typst/typst
- memmap2:https://github.com/RazrFalcon/memmap2-rs
- 适配仓库:https://atomgit.com/OpenHarmonyPCDeveloper/ohos_typst
更多推荐


所有评论(0)