Repository navigation
Compile resources in-tree, cut the SDK surface to two binaries, implement product variants - #43
Merged
Merged
Conversation
…with hvigor
`.gitignore`'s unanchored `build/` pattern also matched `src/build/`, so the
compiler's own source tree (63 .rs files) was never committed. Anchor it to
`/build/` and commit the split (`src/{build,cli,device,project,sdk,sign,support}`).
Compiler work in this change:
- `.ets` preprocessing gains the imported `@Builder` names and the file's own
`struct` names: the `entry` module now lowers 124/124 sources (was 120/124),
and a bare call to a same-file component keeps its child block rewritten.
- import rewriting: a read in a type position keeps its binding, so the
`import type` split no longer drops a specifier the lowering erased; an
explicit `X as X` alias survives oxc_codegen's same-name folding.
- `module.json` writes `routerMap` when the module ships `route_map.json`, and
the staged `route_map.json` is filled with `ohmurl`/`bundleName`/`moduleName`
per entry. Without `ohmurl` the installer resolves the route name but crashes
on the module record.
- `{page,line,col}` carries the source coordinate: the child-block rewrite's
column widening is subtracted back, and a call site the lowering cannot find
keeps a real position instead of `0,0`.
- `@Extend` helpers merge by parser coordinate, so an `export default` keeps the
source order the reference emits.
- the V2 emitter keeps a `readonly` the source wrote.
- full bytecode verdict on clashbox: 298/298 reference files equal on all four
axes; `cargo test` 461 passed; oracle 135 PASS / 2 FAIL (comment text only).
…'s mode A flat project produced a HAP with no `.so` at all, so every NAPI module read as `undefined` on the device (`export objects of native so is undefined, so name is @Normalized:Y&&&libflclash.so&`) and the proxy core never loaded. Three causes: - precompiled libraries were never copied: the packer reads one flat `libs/<abi>/`, while a module keeps its own under `<module>/libs/<abi>/`. - the flat layout's native sources were never compiled: `build_all` only looked for `libs/<name>/CMakeLists.txt`, not `<module>/cpp/CMakeLists.txt`. - the C++ runtime was never shipped: `xb_components` builds with `CMAKE_CXX_STANDARD 20` and cannot be dlopen-ed without `libc++_shared.so`. Also build native code at the project's own build mode. Release inlined away every `NapiUtils::toNapiValue<…>` instantiation, which halved `libxb_components.so` (92 552 vs 206 608 bytes) and dropped 178 exported symbols. After: all four libraries are packed; `libproxy_core.so`, `libxb_components.so` and `libc++_shared.so` match the reference byte-for-byte in size, and all four have an identical defined-symbol set (42/275/122, md5 equal).
…laims The CLI has been calling these commands build and migrate for a while; the documents still described the old names and two flows that no longer exist (the hvigorw handoff, the lint section). Also records what the build actually produces: build/*-unsigned.hap rather than output/, hvolt device list rather than device targets, and run's real semantics (push+launch; build+sign only when [app.signing] is set).
Behaviour is unchanged: the variant, the dispatch arm and the progress line carry the new name. The old one described a one-way copy, which the command is not — it folds the hvigor manifests into hvolt.toml.
A migrated project kept four hvigor manifests beside its sources: route_map.json, form_config.json, backup_config.json and the main entry in oh-package.json5. They are fields on the module table now, so the only configuration a project carries is hvolt.toml; migrate fills them from the originals and reports the keys it could not express. Nothing reads them yet — the next commits wire the consumers.
A migrated project no longer carries route_map.json, so the build has to produce it and the lowering has to register the same routes. Both now read one resolver (deps::routes): the table when the module declares one, the manifest on disk otherwise. Resolution refuses rather than guesses. A route names one page and one builder; a file can declare several global builders (Log.ets has LogBuilder and LogDetailsBuilder), so 'the file's first builder' would register LogDetails against LogBuilder and open the wrong page with no output saying so. Every ambiguous case is an error naming the entry. Measured on clashbox-flat: 19/19 routes resolve to the manifest's page and buildFunction, 19 files carry NavigationBuilderRegister. Also in this file set: the resource stage is rebuilt (and app-stage with it) instead of merged into the previous run, so a deleted resource stops reappearing in the HAP; empty resource directories are skipped because restool rejects a directory with nothing under it.
A native module lived at libs/<name> by convention, so a dependency declared as path = "mylib" was never built — the HAP shipped without its .so and nothing said so. build_all now takes the resolved directory and refuses when it holds no CMakeLists.txt. examples/hello-native now packs libs/arm64-v8a/libhello.so (6168 B); before this change the archive held only libc++_shared.so.
Three classes of repair, all found by walking the CLI as someone who has never seen it: - Messages that sent the reader somewhere useless: 'run hvolt build first' after a successful build that produced only an unsigned package, 'run hvolt dep sync' for a command that does not exist, and a signing remedy that reopened the staleness it was meant to fix. The unsigned path now says build → sign → push in that order. - Silent staleness: a signed package older than the newest build, or older than the sources, is refused instead of installed. project-mode sign --local refuses before signing, because re-signing refreshes the mtime and defeats every mtime check downstream. - Tooling that reported the wrong thing: doctor claimed all checks passed while printing warnings, sdk list showed one installation as three rows, check printed Chinese among English output, and the help's first example could not run. Also gates the parse/USB trace output behind HVOLT_DEBUG_PARSE and HVOLT_USB_DEBUG.
coverage_map.rs (165 lines) had no callers: it read .scratch/hvigor-oracle/coverage-map.json through include_str!, and .scratch/ is gitignored, so a clean clone could not compile the test target at all. examples/*/build and examples/*/.hvigor held 183 tracked files (11.2 MB) of hvigor output; /examples/*/build/ is now ignored next to the anchored /build/.
res_ids reproduces restool's id allocation and res_index_build + res_index_write reproduce resources.index byte for byte; both agree with the tool on a real project. rpcid.sc is encoded by rpcid_sc.rs instead of syscap_tool. The SDK tool stays reachable from cfg(test) only, so the comparison channel survives while a release build has no path to it.
- cmake and ninja now come from the host PATH; the SDK copies are the fallback - es2abc is probed under build-win, build-mac and build, replacing the hard-coded build-mac that made every Linux build stop at 'es2abc not found' (the npm package ships linux-x64 and linux-arm64) - cli/build.rs calls ets_assemble::sdk_es2abc instead of keeping a second copy of the same resolution, so one place decides where the compiler is
The five platform packages and the optionalDependencies entries were still at 26.0.0-7 while Cargo.toml and the launcher package were 26.0.0-8, so installing 26.0.0-8 resolved 26.0.0-7 binaries. optionalDependencies also listed three platforms while npm/stage.mjs packs five: darwin-x64 and linux-arm64 users got the launcher with no binary behind it.
- ADR: es2abc stays (no compiler backend in this crate); the data files stay version-bound to the SDK, because hvolt supports several SDK versions - SDK surface report re-measured: 6 platform binaries -> 2 (es2abc, llvm-strip) - clean-code 13: the semver mirrors the SDK version and six places must agree - .gitignore: examples/*/build/ beside the anchored /build/
[products.<name>] overrides the artifact identity (bundle / name / version / version_code / vendor / icon), the signing config, and the resource directories; unwritten fields inherit from the root table. sdk_version, runtime_os, members and dependencies describe the project rather than the artifact, so they cannot vary per product. migrate carries products and their signing configs over from the root build-profile.json5, and doctor takes --product to validate the one a build would select.
- device flow: when the build host cannot reach the device, relay the signed HAP to a host that can instead of rebuilding or re-signing elsewhere - skill reference: hvolt log / screenshot / exec, including that exec --shell is the way to start an installed package and run rebuilds it - changelog: dep sync, abc-records, and the build no longer reading a hvigor manifest
The decision predates the implementation; the file was never tracked.
res_ids reproduces restool's id allocation, res_index_build + res_index_write reproduce resources.index, rpcid_sc encodes rpcid.sc, abc_records lists modules.abc records without ark_disasm, sdk_bytecode carries the API level to bytecode version table, id_check compares the in-tree index with the SDK tool. res_compile.rs referenced these from an earlier commit but none of them had ever been tracked, so that commit did not build from a clean clone.
*.abc kept every golden modules.abc out of the repository, so on a clean clone fixtures/foreach/golden/modules.abc was missing and the abc_records test had nothing to read. The golden files are baselines rather than build artifacts, so they are tracked now; each fixture's actual/ stays ignored.
Five strings carried a run of spaces where a line had been joined, so the message a user saw read 'hvolt builds the same module set for every product'.
The build path spelled sdk_root/default/openharmony/<comp> by hand in sdk_es2abc, native_root, the toolchains lookup, syscap's device-define dir and rpcid_sc's encoder search. manage::component_dir already owned the version-dir form of that knowledge, but it serves the download path only. component_root(sdk_root, comp) is now the single place that knows the shape and the five callers name a component instead. sdk_facts::platform_root keeps its three-shape probe on purpose: accepting an SDK that is not laid out as sdk_root/default is what that module is for.
real_file_scan read a file under a private home directory, so the test failed anywhere but one machine. It now reads a tracked fixture. a_system_resource_resolves_to_the_sdk_id resolved through sysResource.js, which a clean checkout and CI do not have; without it every system reference is reported missing. Skip when that table is absent and say how to run it (HVOLT_SYS_RESOURCE).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What and why
The SDK surface this tool depends on was 6 platform binaries, and the build path ignored the platform list the npm package itself ships.
restoolandsyscap_toolare now replaced by in-tree implementations (res_ids,res_index_build,res_index_write,rpcid_sc),cmakeandninjacome from the host PATH with the SDK copies as fallback, andsdk_es2abcprobesbuild-win,build-macandbuildinstead of assumingbuild-mac. Linux SDKs name that directorybuild, so both Linux targets the npm package ships stopped ates2abc not found.Alongside that: the npm platform packages are aligned to 26.0.0-8 and all five are declared (two were missing, so those users installed a launcher with no binary behind it), the SDK layout is defined in one place (
manage::component_root), product variants are implemented, and the hvigor build leftovers are out of the tree.Three changes restructure the tool itself.
src/went from a flat layout to domain modules, and the compiler output now matches what hvigor produces, so the two build paths agree (d4677e2, breaking). The CLI verbs arebuildandmigrateinstead ofassembleandimport, with the docs and help text following.hvolt.tomlcarriesroutes,widgets,backupandmain, the route manifest is generated from it, and the native libraries ship with the package and build at the project's mode.Two defects made a clean clone unusable:
coverage_map.rsread a gitignored path throughinclude_str!, socargo testcould not compile, and 138golden/modules.abcbaselines were excluded by*.abc, leavingabc_recordswithout input.Checks
cargo fmt --all --checkis cleancargo clippy --all-targets -- -D warningsfinishes without warningscargo testpasses--helptext and comments naming a changed command are updatedCHANGELOG.mdhas an entry if the CLI surface or project format changedTested with
hvolt 26.0.0-8, macOS darwin-arm64, SDK v26.0.0.23, device PLR-AL00 (API 26) over the relay host.
Behaviour changes carry their own measurement:
es2abc_resolves_under_each_host_layoutcovers the three host layouts,lists_the_records_of_a_golden_abccovers the tracked golden byte-code, and the npm version alignment is checked by theclean-code.md§13 command set (three version strings identical, platform coverage 5 = 5).