Skip to content

Commit e5abd27

Browse files
committed
feat(target): HarmonyOS/OpenHarmony via a retargetable clang + the platform SDK
RFC / 探针 —— 不要合入。方案与实测数据: .agents/docs/2026-08-04-harmonyos-target-design.md 鸿蒙 SDK 自带的编译器 mcpp 永远用不了:实测 SDK 6.1(API 23,2026-03)仍是 clang 15.0.4,比 C++20 模块所需的 -fmodule-output(clang 16)差一代,比 import std(libc++ 19+)差四代。而 GCC 根本没有 ohos target。 所以鸿蒙是第一个「只能走 config②、且只能用 clang」的目标 —— mcpp 自带编译器, 平台只提供 sysroot。这逼出了仓库里早就记着待做的那件事: # cross-build-test.yml # * llvm/clang cross : … Wire the clang cross path first, then add a row. 本 commit 就是 wire 那条缝(Toolchain::crossTarget:--target= + 外部 sysroot + 目标 libc++ + 链接侧 -resource-dir),鸿蒙只是第一个非它不可的消费者。 三个不显然的决定: * `ohos` 是 env 不是 os(与上游 LLVM 一致)。内核确实是 Linux,已有包里的 cfg(os = "linux") / cfg(family = "unix") 必须继续匹配;拼成新 os 会让那些段 静默失配。反过来 is_musl() 返回 false —— OHOS libc 是 musl 的 fork,但 mcpp 里 "musl" 处处指上游 musl,产物不可互换 ⇒ ABI 上 libc = "ohos" 自成取值。 * -resource-dir 只在链接侧。它供给目标的 compiler-rt/crt*,但同一个 flag 也换掉 内建头,让新 clang 读 clang-15 的内建头是另一个安静得多的 bug。 * std.cppm 由 provider 给,不由 driver 探。driver 答的是它自己的 libc++,交叉时 那是宿主的 —— 拿去编 std BMI 不报错,只产出面向错误平台的 BMI。 两档,mcpp 自动识别并明说在哪一档:原版 SDK ⇒ 具名模块可用、import std 不可用 (有明确提示);再配一份为目标编译的 libc++($MCPP_OHOS_LIBCXX)⇒ import std 也可用。两档都有 e2e,都在 qemu-aarch64 下真跑。 验证:e2e 全量 178 passed / 0 failed / 8 skipped;单测 56 个二进制全绿(新增 16 条 host-independent 用例);自举构建正常 —— 宿主路径零行为变化, OhosCross.HostToolchainIsUntouchedByTheseChanges 是这条的回归闸。 CI 证明不了:.hnp/.hap 打包、链接平台 NDK 库、任何需要真机或模拟器的行为。 qemu-user 跑的是指令集不是 HarmonyOS。
1 parent fd3a0b1 commit e5abd27

27 files changed

Lines changed: 1973 additions & 23 deletions

.agents/docs/2026-08-04-harmonyos-target-design.md

Lines changed: 278 additions & 0 deletions
Large diffs are not rendered by default.

.github/workflows/ci-harmonyos.yml

Lines changed: 271 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,271 @@
1+
name: ci-harmonyos
2+
3+
# mcpp → HarmonyOS / OpenHarmony (aarch64-linux-ohos), verified end to end.
4+
#
5+
# ── What this proves, and why it needs its own workflow ────────────────────
6+
#
7+
# cross-build-test.yml is the home of "which cross targets does mcpp support",
8+
# and it carries this comment:
9+
#
10+
# * llvm/clang cross : clang is inherently a cross-compiler, but mcpp does
11+
# not yet inject `-target <triple>` + a cross sysroot
12+
# for a clang toolchain; cross `--target` resolves to
13+
# gcc musl only. Wire the clang cross path first, then
14+
# add a row.
15+
#
16+
# HarmonyOS is the target that forces that row to exist: GCC has no `ohos`
17+
# target at all, so the gcc-musl shape mcpp's other cross rows use cannot be
18+
# spelled here. This workflow is deliberately SEPARATE from
19+
# cross-build-test.yml for one reason — it depends on a ~2.5 GB vendor SDK
20+
# that mcpp does not and cannot ship, so a failure here must never be
21+
# confusable with a failure of mcpp's own cross matrix.
22+
#
23+
# ── The two tiers ─────────────────────────────────────────────────────────
24+
#
25+
# tier compiler C++ stdlib import std
26+
# ------------ ---------------- ------------------------- ----------
27+
# stock SDK mcpp's llvm@20 SDK's libc++ 15.0.4 no
28+
# + overlay mcpp's llvm@20 libc++ built for the yes
29+
# target from LLVM sources
30+
#
31+
# Both are built and RUN under qemu-aarch64. The second job builds the overlay
32+
# from source in ~10 minutes, which is expensive — but it is the only way to
33+
# show that the "no import std" limit is a missing PAYLOAD, not a missing
34+
# capability, and that distinction is the whole argument of
35+
# .agents/docs/2026-08-04-harmonyos-target-design.md.
36+
#
37+
# ── What is NOT proven here ───────────────────────────────────────────────
38+
#
39+
# qemu-user runs the artefact's instructions, not HarmonyOS. It says nothing
40+
# about the .hnp/.hap packaging path, about linking the platform's own NDK
41+
# libraries (libace_napi.z.so and friends), or about anything that touches
42+
# a real device. Those need hardware or the emulator and stay out of scope —
43+
# see the design doc's "what CI can and cannot show" section. Verification
44+
# here is the same claim the aarch64-linux-musl row makes: this artefact is
45+
# for the right machine and it really executes.
46+
47+
on:
48+
pull_request:
49+
branches: [ main ]
50+
paths:
51+
- 'src/toolchain/**'
52+
- 'src/build/**'
53+
- 'tests/e2e/10[34]_harmonyos*'
54+
- 'tests/unit/test_ohos_target.cpp'
55+
- 'examples/05-harmonyos/**'
56+
- '.github/workflows/ci-harmonyos.yml'
57+
workflow_dispatch:
58+
59+
concurrency:
60+
group: ci-${{ github.workflow }}-${{ github.ref }}
61+
cancel-in-progress: true
62+
63+
jobs:
64+
# ── Tier 1: stock SDK, named modules ──────────────────────────────────────
65+
harmonyos-cross:
66+
name: HarmonyOS cross-build + qemu run (stock SDK)
67+
runs-on: ubuntu-24.04
68+
timeout-minutes: 60
69+
env:
70+
MCPP_HOME: /home/runner/.mcpp
71+
MCPP_VERBOSE: "1"
72+
steps:
73+
- uses: actions/checkout@v4
74+
75+
# Do NOT restore target/ in a cross job: this job builds twice (host,
76+
# then aarch64-linux-ohos) and a restored BMI tree makes the second
77+
# build read `std` BMIs that no longer match what the rest was compiled
78+
# against — `import 'std' has CRC mismatch`. Same rule as
79+
# windows-host-linux-cross in cross-build-test.yml, same reason.
80+
- uses: ./.github/actions/bootstrap-mcpp
81+
with:
82+
cache-target: 'false'
83+
84+
- name: Install qemu-user-static
85+
run: |
86+
sudo apt-get update -qq
87+
sudo apt-get install -y qemu-user-static
88+
qemu-aarch64-static --version | head -1
89+
90+
- name: Setup OpenHarmony SDK
91+
id: ohos
92+
uses: openharmony-rs/setup-ohos-sdk@v1.0.1
93+
with:
94+
version: '6.1'
95+
components: 'native'
96+
97+
- name: Point mcpp at the SDK
98+
run: |
99+
NATIVE="${{ steps.ohos.outputs.ohos_sdk_native }}"
100+
test -d "$NATIVE" || { echo "FAIL: action produced no native dir"; exit 1; }
101+
# The two files mcpp's own detection requires; asserted here so a
102+
# layout change in the action fails with a clear message instead of
103+
# inside a compile command 10 minutes later.
104+
test -f "$NATIVE/sysroot/usr/include/stdlib.h"
105+
test -d "$NATIVE/llvm/lib/aarch64-linux-ohos"
106+
echo "OHOS_NDK_HOME=$NATIVE" >> "$GITHUB_ENV"
107+
echo "== SDK =="
108+
cat "$NATIVE/oh-uni-package.json" || true
109+
# Recorded, not used: this is the fact the whole design rests on.
110+
# If a future SDK ships a modern clang, this line is where it shows.
111+
echo "== the SDK's own clang (mcpp does NOT use it) =="
112+
"$NATIVE/llvm/bin/clang++" --version | head -1
113+
114+
- name: Build mcpp from source (self-host)
115+
run: |
116+
export MCPP_VENDORED_XLINGS="$XLINGS_BIN"
117+
"$MCPP" self config --mirror GLOBAL 2>/dev/null || true
118+
"$MCPP" build
119+
# Newest, not first: target/ keeps a directory per build fingerprint,
120+
# so `find | head -1` can hand back a previous build's binary.
121+
MCPP_SELF=$(find target -type f -name mcpp -path '*/bin/*' \
122+
-printf '%T@ %p\n' | sort -rn | head -1 | cut -d' ' -f2-)
123+
test -x "$MCPP_SELF"
124+
MCPP_SELF=$(realpath "$MCPP_SELF")
125+
"$MCPP_SELF" --version
126+
echo "MCPP=$MCPP_SELF" >> "$GITHUB_ENV"
127+
128+
- name: "Target is listed as available once the SDK is present"
129+
run: |
130+
export MCPP_VENDORED_XLINGS="$XLINGS_BIN"
131+
"$MCPP" toolchain list | tee /tmp/tclist.txt
132+
# `available`, not `planned`: host_can_serve() answers this by
133+
# probing for the SDK, so this asserts the detection wired up — the
134+
# same row reads `planned` on a runner without the SDK.
135+
grep -q "aarch64-linux-ohos" /tmp/tclist.txt \
136+
|| { echo "FAIL: ohos target not listed"; exit 1; }
137+
138+
- name: "e2e: cross-build + qemu run"
139+
run: |
140+
export MCPP_VENDORED_XLINGS="$XLINGS_BIN"
141+
bash tests/e2e/103_harmonyos_cross_qemu.sh
142+
143+
- name: "Example project builds for HarmonyOS"
144+
run: |
145+
export MCPP_VENDORED_XLINGS="$XLINGS_BIN"
146+
cd examples/05-harmonyos
147+
"$MCPP" build --target aarch64-linux-ohos
148+
BIN=$(find target/aarch64-linux-ohos -type f -path '*/bin/*' | head -1)
149+
file "$BIN"
150+
file "$BIN" | grep -q "ARM aarch64"
151+
qemu-aarch64-static "$BIN"
152+
153+
# ── Tier 2: + a libc++ built for the target ⇒ import std ──────────────────
154+
harmonyos-import-std:
155+
name: HarmonyOS import std (libc++ built for the target)
156+
runs-on: ubuntu-24.04
157+
timeout-minutes: 90
158+
env:
159+
MCPP_HOME: /home/runner/.mcpp
160+
MCPP_VERBOSE: "1"
161+
# Must match the LLVM the target pin resolves to
162+
# (triple::pins::kOhosLlvm). A libc++ built by one clang and used by
163+
# another is a version skew that works until it does not; keeping the
164+
# two equal is what makes this job evidence rather than anecdote.
165+
LLVM_TAG: llvmorg-20.1.7
166+
steps:
167+
- uses: actions/checkout@v4
168+
- uses: ./.github/actions/bootstrap-mcpp
169+
with:
170+
cache-target: 'false'
171+
172+
- name: Install qemu-user-static + build tools
173+
run: |
174+
sudo apt-get update -qq
175+
sudo apt-get install -y qemu-user-static cmake ninja-build
176+
qemu-aarch64-static --version | head -1
177+
178+
- uses: openharmony-rs/setup-ohos-sdk@v1.0.1
179+
id: ohos
180+
with:
181+
version: '6.1'
182+
components: 'native'
183+
184+
- name: Build mcpp from source (self-host)
185+
run: |
186+
export MCPP_VENDORED_XLINGS="$XLINGS_BIN"
187+
echo "OHOS_NDK_HOME=${{ steps.ohos.outputs.ohos_sdk_native }}" >> "$GITHUB_ENV"
188+
"$MCPP" self config --mirror GLOBAL 2>/dev/null || true
189+
"$MCPP" build
190+
MCPP_SELF=$(find target -type f -name mcpp -path '*/bin/*' \
191+
-printf '%T@ %p\n' | sort -rn | head -1 | cut -d' ' -f2-)
192+
MCPP_SELF=$(realpath "$MCPP_SELF")
193+
"$MCPP_SELF" --version
194+
echo "MCPP=$MCPP_SELF" >> "$GITHUB_ENV"
195+
196+
- name: Locate mcpp's LLVM payload
197+
run: |
198+
export MCPP_VENDORED_XLINGS="$XLINGS_BIN"
199+
# Installing it explicitly rather than letting the first ohos build
200+
# do it: the runtimes build below needs the same clang, and taking
201+
# it from anywhere else would silently reintroduce the skew the
202+
# LLVM_TAG comment warns about.
203+
"$MCPP" toolchain install llvm 20.1.7
204+
CLANGXX=$(find "$MCPP_HOME/registry/data/xpkgs/xim-x-llvm/20.1.7" \
205+
-type f -name 'clang++' | head -1)
206+
test -x "$CLANGXX" || { echo "FAIL: no clang++ in the llvm payload"; exit 1; }
207+
echo "OHOS_CLANGXX=$CLANGXX" >> "$GITHUB_ENV"
208+
echo "OHOS_CLANG=${CLANGXX%++}" >> "$GITHUB_ENV"
209+
"$CLANGXX" --version | head -1
210+
211+
- name: Cache the target libc++
212+
id: libcxx-cache
213+
uses: actions/cache@v4
214+
with:
215+
path: ~/ohos-libcxx
216+
key: ohos-libcxx-${{ env.LLVM_TAG }}-sdk6.1-v1
217+
218+
- name: Build libc++/libc++abi for aarch64-linux-ohos
219+
if: steps.libcxx-cache.outputs.cache-hit != 'true'
220+
run: |
221+
set -euo pipefail
222+
NATIVE="${{ steps.ohos.outputs.ohos_sdk_native }}"
223+
RES=$(find "$NATIVE/llvm/lib/clang" -maxdepth 1 -mindepth 1 -type d | sort | tail -1)
224+
# Sparse: the runtimes build needs cmake/, runtimes/, the three
225+
# runtime trees, llvm/cmake and libc/ (libc++'s charconv includes
226+
# `shared/fp_bits.h` from it — a missing `libc` fails ~1800 objects
227+
# into the build, which is an expensive way to learn that).
228+
git clone --depth 1 --branch "$LLVM_TAG" --filter=blob:none --sparse \
229+
https://github.com/llvm/llvm-project /tmp/llvm-src
230+
git -C /tmp/llvm-src sparse-checkout set \
231+
cmake runtimes libcxx libcxxabi libunwind libc llvm/cmake third-party
232+
233+
cmake -G Ninja -S /tmp/llvm-src/runtimes -B /tmp/build-ohos-libcxx \
234+
-DCMAKE_BUILD_TYPE=Release \
235+
-DCMAKE_INSTALL_PREFIX="$HOME/ohos-libcxx" \
236+
-DCMAKE_C_COMPILER="$OHOS_CLANG" \
237+
-DCMAKE_CXX_COMPILER="$OHOS_CLANGXX" \
238+
-DCMAKE_C_COMPILER_TARGET=aarch64-linux-ohos \
239+
-DCMAKE_CXX_COMPILER_TARGET=aarch64-linux-ohos \
240+
-DCMAKE_SYSROOT="$NATIVE/sysroot" \
241+
-DCMAKE_SYSTEM_NAME=Linux -DCMAKE_SYSTEM_PROCESSOR=aarch64 \
242+
-DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY \
243+
-DCMAKE_C_FLAGS="--no-default-config" \
244+
-DCMAKE_CXX_FLAGS="--no-default-config" \
245+
-DCMAKE_EXE_LINKER_FLAGS="-resource-dir=$RES -fuse-ld=lld" \
246+
-DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind" \
247+
-DLLVM_INCLUDE_TESTS=OFF -DLIBCXX_INCLUDE_TESTS=OFF \
248+
-DLIBCXX_INCLUDE_BENCHMARKS=OFF -DLIBCXXABI_INCLUDE_TESTS=OFF \
249+
-DLIBUNWIND_INCLUDE_TESTS=OFF \
250+
-DLIBCXX_CXX_ABI=libcxxabi \
251+
-DLIBCXX_HAS_MUSL_LIBC=ON \
252+
-DLIBCXX_ENABLE_SHARED=OFF -DLIBCXXABI_ENABLE_SHARED=OFF \
253+
-DLIBUNWIND_ENABLE_SHARED=OFF \
254+
-DLIBCXXABI_USE_LLVM_UNWINDER=ON \
255+
-DLIBCXX_INSTALL_MODULES=ON
256+
ninja -C /tmp/build-ohos-libcxx install
257+
258+
# The runtimes build compiles libunwind's .S sources for the HOST
259+
# (CMake's ASM language does not inherit CMAKE_CXX_COMPILER_TARGET),
260+
# so the installed libunwind.a carries x86_64 objects and lld
261+
# rejects it with "incompatible with aarch64linux". The platform's
262+
# own unwinder is the right one to use anyway; removing the broken
263+
# archive is what makes `-L<overlay> -L<sdk>` resolve to it.
264+
rm -f "$HOME/ohos-libcxx/lib/libunwind.a"
265+
test -f "$HOME/ohos-libcxx/share/libc++/v1/std.cppm"
266+
267+
- name: "e2e: import std on HarmonyOS + qemu run"
268+
run: |
269+
export MCPP_VENDORED_XLINGS="$XLINGS_BIN"
270+
export MCPP_OHOS_LIBCXX="$HOME/ohos-libcxx"
271+
bash tests/e2e/104_harmonyos_import_std.sh

.github/workflows/cross-build-test.yml

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,17 @@ name: cross-build-test
3939
# ci-linux.yml's "Toolchain: musl-gcc" step, and release.yml for the static
4040
# release artefact. Keep them there; this file is cross-arch only.
4141
#
42+
# ── Related, but deliberately NOT here ────────────────────────────────────
43+
# * llvm/clang cross : WIRED — Toolchain::crossTarget retargets a clang
44+
# driver with `--target=` + an external sysroot. Its
45+
# first consumer is HarmonyOS, and that row lives in
46+
# ci-harmonyos.yml rather than this matrix for one
47+
# reason: it needs a ~2.5 GB vendor SDK mcpp cannot
48+
# ship, and a failure to obtain that SDK must never be
49+
# confusable with a failure of mcpp's own cross matrix.
50+
# See .agents/docs/2026-08-04-harmonyos-target-design.md.
51+
#
4252
# ── Planned cross rows (documented; NOT yet wired in mcpp — keep as comments) ─
43-
# * llvm/clang cross : clang is inherently a cross-compiler, but mcpp does not
44-
# yet inject `-target <triple>` + a cross sysroot for a
45-
# clang toolchain; cross `--target` resolves to gcc musl
46-
# only. Wire the clang cross path first, then add a row.
4753
# * riscv64-linux-musl: add once xim:riscv64-linux-musl-gcc ships to
4854
# xlings-res + xim-pkgindex.
4955

CHANGELOG.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,43 @@
33
> 本文件追踪 `mcpp-community/mcpp` 公开仓的版本演进。
44
> 格式参考 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/)
55
6+
## [Unreleased] — RFC:HarmonyOS / OpenHarmony 目标
7+
8+
> **本节对应一个探针 PR,不打算合入。** 引擎改动已实现并端到端验证;
9+
> 设计与实测数据见 `.agents/docs/2026-08-04-harmonyos-target-design.md`
10+
11+
### 新增
12+
13+
- **`aarch64-linux-ohos`(HarmonyOS / OpenHarmony)成为一等目标。** 设好
14+
`OHOS_NDK_HOME`,`mcpp build --target aarch64-linux-ohos` 产出静态 aarch64
15+
鸿蒙 ELF,CI 在 `qemu-aarch64`**真的执行**它。C++23 具名模块对着原版 SDK
16+
即可用;再配一份为该目标编译的 libc++(`MCPP_OHOS_LIBCXX`),`import std;`
17+
也可用 —— 两档都有 e2e。
18+
19+
**mcpp 只把 SDK 当 sysroot,不当工具链。** 这不是偏好:实测 OpenHarmony SDK
20+
**6.1(API 23)自带 clang 仍是 15.0.4**,比 C++20 模块所需的
21+
`-fmodule-output`(clang 16)差一代,比 `import std` 差四代。而 GCC 根本没有
22+
`ohos` target。所以 `.agents/docs/2026-07-24-embedded-platform-support-design.md`
23+
的 config②(mcpp 带编译器 + 消费外部 sysroot)在这里从「两种可行架构之一」
24+
变成**唯一解**,并且只能用 clang —— 决策 #8 存档的那条路线被现实提前触发。
25+
26+
- **clang 交叉通道(driver retarget)。** `cross-build-test.yml` 里那条
27+
"llvm/clang cross: … Wire the clang cross path first" 的注释现在有实现了:
28+
`Toolchain::crossTarget` 让一个 clang driver 带着 `--target=` + 外部 sysroot
29+
+ 目标 libc++ 工作。**这不是鸿蒙专用的** —— 鸿蒙只是第一个非它不可的消费者,
30+
`aarch64-linux-gnu`(树莓派滩头)之后可以走同一条缝。
31+
32+
### 注意
33+
34+
- `ohos` 在 triple 语言里是 **env 而非 os**(`aarch64` + `linux` + `ohos`),
35+
与上游 LLVM 一致:内核确实是 Linux,所以已有包里的 `cfg(os = "linux")` /
36+
`cfg(family = "unix")` 必须继续匹配。反过来,ABI 维度上 `libc = "ohos"` 自成
37+
取值、`is_musl()` 返回 **false** —— OHOS libc 是 musl 的 fork,但与上游 musl
38+
产物不可互换,而 mcpp 里 "musl" 处处指的是后者。
39+
- CI 验证的是「产物面向正确的机器且真的执行」,与 `aarch64-linux-musl` 同级。
40+
****覆盖 `.hnp`/`.hap` 打包、链接平台 NDK 库、或任何需要真机/模拟器的
41+
行为。
42+
643
## [2026.8.4.1] — 2026-08-04
744

845
### 修复

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,9 +306,12 @@ the right toolchain payload is resolved and installed automatically.
306306
| `x86_64-windows-gnu` | gcc 16 MinGW-w64 — native on Windows, cross from Linux (wine-verified) *(Windows default without Visual Studio)* ||
307307
| `x86_64-windows-msvc` | `msvc@system` (detected VS/BuildTools) or llvm ¹ *(Windows default with Visual Studio)* ||
308308
| `aarch64-macos` | llvm *(macOS default)* ||
309+
| `aarch64-linux-ohos` | llvm 20 + OpenHarmony SDK sysroot ² — cross from any host (qemu-verified) ||
309310
| `riscv64-linux-musl` || 🔄 |
310311
| `aarch64-linux-gnu` || 🔄 |
311312
| `x86_64-macos` || 🔄 |
313+
| `x86_64-linux-ohos` | llvm 20 + OpenHarmony SDK sysroot ² | 🔄 |
314+
| `arm-linux-ohos` | llvm 20 + OpenHarmony SDK sysroot ² | 🔄 |
312315

313316
✅ verified — CI builds **and executes** the artifact end-to-end (qemu/wine included) | 🔄 planned
314317

@@ -326,6 +329,16 @@ the right toolchain payload is resolved and installed automatically.
326329
> or configure; `mcpp new && mcpp build` just works on a stock Windows box.
327330
> An explicit `[toolchain]` in `mcpp.toml` is always respected as written —
328331
> mcpp revises its own default, never yours.
332+
>
333+
> ² HarmonyOS / OpenHarmony is the one target where mcpp needs something it
334+
> cannot ship: the platform SDK. Point `OHOS_NDK_HOME` at the unpacked
335+
> `native` directory and `mcpp build --target aarch64-linux-ohos` works.
336+
> mcpp uses the SDK for its **sysroot and runtime libraries only** — the
337+
> compiler stays mcpp's own LLVM, because the SDK's bundled clang is 15.0.4
338+
> even in SDK 6.1 (API 23) and cannot build C++20 modules at all. Named
339+
> modules work against a stock SDK; `import std` additionally needs a libc++
340+
> built for the target — see
341+
> [Toolchain Management](docs/03-toolchains.md#harmonyos--openharmony).
329342
330343
## Documentation
331344

docs/01-examples.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ examples.
2626
| 01 | [`examples/01-hello`](../examples/01-hello/) | Minimal single-file project with `import std` | The minimal package shape (`mcpp new` also emits `tests/test_smoke.cpp`) |
2727
| 02 | [`examples/02-with-deps`](../examples/02-with-deps/) | Adds the `mcpplibs.cmdline` dependency to parse command-line arguments | `[dependencies]`, SemVer, `mcpp.lock` |
2828
| 03 | [`examples/03-pack-static`](../examples/03-pack-static/) | Produces a fully static release package via `mcpp pack --mode static` | `[target.<triple>]` and `[pack]` configuration |
29+
| 05 | [`examples/05-harmonyos`](../examples/05-harmonyos/) | Cross-builds a C++23 named-module program for HarmonyOS/OpenHarmony | `--target aarch64-linux-ohos`, consuming an external platform SDK as a sysroot |
2930

3031
## Suggested Reading Order
3132

0 commit comments

Comments
 (0)