结论:明确禁止继续扩展自写 CNC 主体语义,最小 runtime 仅保留为迁移探针;新增 interp_convert.cc 源码直连编译探针,并以最小 emcStatus 状态边界 shim 暴露 native runtime 阻塞点。检查:git diff --check 通过;wasm-port/tests/native/verify_native_probes.sh 通过,linuxcnc_interp_convert_source_probe exitcode=0。
692 lines
21 KiB
Markdown
692 lines
21 KiB
Markdown
# LinuxCNC WASM Porting Steps
|
||
|
||
## Goal
|
||
|
||
Build a separate WASM-based CNC simulation program that:
|
||
|
||
- uses LinuxCNC source as the semantic source of truth,
|
||
- does not modify the original `linuxcnc/` source tree,
|
||
- is managed independently from native LinuxCNC,
|
||
- provides HTML + JavaScript frontend plus OPFS persistence,
|
||
- matches LinuxCNC software behavior as closely as practical except for realtime hardware driving.
|
||
|
||
## Non-Negotiable Constraints
|
||
|
||
1. `linuxcnc/` is upstream and read-only for the port effort.
|
||
2. Any source adaptation needed for WASM happens on copied or generated files under `wasm-port/`.
|
||
3. No direct edits inside `linuxcnc/src`, `linuxcnc/lib`, `linuxcnc/tests`, or `linuxcnc/web` are part of the port workflow.
|
||
4. LinuxCNC GUI code is reference-only. The migrated UI is rebuilt in HTML + JavaScript.
|
||
5. LinuxCNC compute logic should be reused before any reimplementation is considered.
|
||
|
||
## Workspace Structure
|
||
|
||
Create and keep these directories under `wasm-port/`:
|
||
|
||
- `docs/`
|
||
Planning, architecture, and validation documents.
|
||
- `vendor/linuxcnc/`
|
||
Copied source files selected for the port.
|
||
- `patches/`
|
||
Patch files against the vendored copies.
|
||
- `tools/`
|
||
Scripts that extract files from `../linuxcnc`, apply patches, and verify drift.
|
||
- `runtime/core/`
|
||
WASM-targeted C/C++ code and wrappers.
|
||
- `runtime/sdk/`
|
||
JavaScript/TypeScript wrapper over the WASM module.
|
||
- `runtime/ui/`
|
||
HTML + JavaScript frontend.
|
||
- `runtime/opfs/`
|
||
Browser file adapter.
|
||
- `tests/native/`
|
||
Native extracted-core regression tests.
|
||
- `tests/browser/`
|
||
Browser/WASM regression and smoke tests.
|
||
|
||
## Ported Program Directory Structure
|
||
|
||
The migrated program itself should be managed as a standalone product under
|
||
`wasm-port/`, with LinuxCNC acting as an upstream source provider.
|
||
|
||
The recommended final structure is:
|
||
|
||
```text
|
||
wasm-port/
|
||
├── docs/
|
||
├── vendor/
|
||
│ └── linuxcnc/
|
||
│ └── src/
|
||
│ ├── emc/
|
||
│ │ ├── ini/
|
||
│ │ ├── kinematics/
|
||
│ │ ├── rs274ngc/
|
||
│ │ └── tp/
|
||
│ ├── hal/
|
||
│ │ └── components/
|
||
│ └── libnml/
|
||
│ └── posemath/
|
||
├── patches/
|
||
├── tools/
|
||
├── runtime/
|
||
│ ├── core/
|
||
│ │ ├── include/
|
||
│ │ ├── shims/
|
||
│ │ ├── adapters/
|
||
│ │ ├── canon/
|
||
│ │ ├── session/
|
||
│ │ ├── simulation/
|
||
│ │ ├── linuxcnc_wrap/
|
||
│ │ └── c_api/
|
||
│ ├── sdk/
|
||
│ │ └── src/
|
||
│ ├── ui/
|
||
│ │ ├── public/
|
||
│ │ └── src/
|
||
│ │ ├── panels/
|
||
│ │ ├── preview/
|
||
│ │ ├── state/
|
||
│ │ ├── machine/
|
||
│ │ └── files/
|
||
│ └── opfs/
|
||
├── tests/
|
||
│ ├── native/
|
||
│ ├── wasm/
|
||
│ └── fixtures/
|
||
├── build/
|
||
│ ├── native/
|
||
│ └── wasm/
|
||
└── dist/
|
||
├── sdk/
|
||
└── web/
|
||
```
|
||
|
||
### Directory Responsibilities
|
||
|
||
- `vendor/linuxcnc/`
|
||
Holds extracted upstream LinuxCNC source files. These are copied or
|
||
generated from `../linuxcnc` and are the only place where source-level
|
||
port patches are applied.
|
||
- `patches/`
|
||
Stores every patch applied to vendored LinuxCNC files. Patches are tracked
|
||
here instead of being mixed into the original source tree.
|
||
- `tools/`
|
||
Holds extraction, sync, verification, manifest generation, and
|
||
compatibility-check scripts.
|
||
- `runtime/core/`
|
||
The standalone simulation runtime. This is where vendored LinuxCNC source
|
||
is wrapped, adapted, and exposed to the rest of the ported program.
|
||
- `runtime/core/include/`
|
||
Public internal headers for the standalone runtime.
|
||
- `runtime/core/shims/`
|
||
Small compatibility headers and implementation stubs required to compile
|
||
vendored LinuxCNC code outside the native runtime.
|
||
- `runtime/core/adapters/`
|
||
Host boundary adapters such as file IO, logging, simulation HAL, and
|
||
runtime-state providers.
|
||
- `runtime/core/canon/`
|
||
Canonical motion event collection and serialization.
|
||
- `runtime/core/session/`
|
||
Per-simulation session ownership for interpreter state, planner state,
|
||
machine state, and controller state.
|
||
- `runtime/core/simulation/`
|
||
Higher-level simulation orchestration built on top of reused LinuxCNC
|
||
compute modules.
|
||
- `runtime/core/linuxcnc_wrap/`
|
||
Thin wrappers around vendored LinuxCNC entry points. Prefer wrappers here
|
||
over editing vendored source directly.
|
||
- `runtime/core/c_api/`
|
||
Stable C ABI exported to the WASM layer.
|
||
- `runtime/sdk/`
|
||
JavaScript/TypeScript SDK that calls the WASM module and hides memory
|
||
management and ABI details from the frontend.
|
||
- `runtime/ui/`
|
||
The actual CNC simulation web application built with HTML + JavaScript.
|
||
- `runtime/ui/src/panels/`
|
||
Operator panels, machine configuration panels, parameter editors, and
|
||
controller-status panels.
|
||
- `runtime/ui/src/preview/`
|
||
2D/3D path preview, 5-axis visualization, joint/world overlays, and
|
||
playback views.
|
||
- `runtime/ui/src/state/`
|
||
Browser-side state management for session lifecycle and UI coordination.
|
||
- `runtime/ui/src/machine/`
|
||
Machine-model-specific UI logic.
|
||
- `runtime/ui/src/files/`
|
||
File import/export and project/session handling UI logic.
|
||
- `runtime/opfs/`
|
||
OPFS-backed file services, snapshot persistence, and path mapping.
|
||
- `tests/native/`
|
||
Native extracted-core regression tests run before WASM build validation.
|
||
- `tests/wasm/`
|
||
WASM tests for Node and browser environments.
|
||
- `tests/fixtures/`
|
||
Shared INI, G-code, parameter, tool-table, and machine fixtures.
|
||
- `build/`
|
||
Intermediate build output. This is disposable.
|
||
- `dist/`
|
||
Deliverable artifacts such as generated web bundles and SDK packages.
|
||
|
||
### Source Ownership Rule
|
||
|
||
The ported program's own source code is expected to live under:
|
||
|
||
- `runtime/core/`
|
||
- `runtime/sdk/`
|
||
- `runtime/ui/`
|
||
- `runtime/opfs/`
|
||
- `tests/`
|
||
- `tools/`
|
||
- `docs/`
|
||
|
||
Vendored LinuxCNC code must live under:
|
||
|
||
- `vendor/linuxcnc/`
|
||
|
||
The original upstream tree must remain outside the ported program's source
|
||
ownership boundary:
|
||
|
||
- `../linuxcnc/`
|
||
|
||
### Patch Placement Rule
|
||
|
||
If a LinuxCNC source file needs adaptation:
|
||
|
||
1. extract it into `vendor/linuxcnc/`;
|
||
2. patch the vendored copy only;
|
||
3. record the patch in `patches/`;
|
||
4. document why the patch exists in `docs/` or in the patch header.
|
||
|
||
Do not place LinuxCNC source patches under `runtime/`.
|
||
|
||
### Build Graph Rule
|
||
|
||
The standalone build should flow like this:
|
||
|
||
1. `tools/` extracts upstream files into `vendor/`
|
||
2. `patches/` are applied to vendored copies
|
||
3. `runtime/core/` compiles vendored files plus wrappers
|
||
4. `runtime/sdk/` consumes the generated WASM module
|
||
5. `runtime/ui/` consumes the SDK
|
||
6. `runtime/opfs/` provides browser persistence services
|
||
7. `tests/` validate native and browser behavior
|
||
|
||
This ensures the ported program remains independently buildable while still
|
||
tracking LinuxCNC as the semantic source of truth.
|
||
|
||
## Phase 0: Freeze Upstream Reference
|
||
|
||
Purpose:
|
||
Make the LinuxCNC source baseline explicit before extraction starts.
|
||
|
||
Steps:
|
||
|
||
1. Record the exact upstream commit from `linuxcnc/.git`.
|
||
2. Record local build assumptions:
|
||
- compiler version
|
||
- emscripten version
|
||
- python version
|
||
- node version
|
||
3. Record the first supported LinuxCNC fixture set:
|
||
- one 3-axis machine
|
||
- one non-trivial kinematics case
|
||
- one 5-axis machine
|
||
4. Record the first G-code feature set:
|
||
- linear motion
|
||
- arc motion
|
||
- canned cycles
|
||
- offsets and coordinate systems
|
||
- subroutines
|
||
- numeric and named variables
|
||
- representative 5-axis programs
|
||
|
||
Outputs:
|
||
|
||
- upstream revision note
|
||
- supported feature baseline
|
||
- supported machine baseline
|
||
|
||
## Phase 1: Build the Source Reuse Map
|
||
|
||
Purpose:
|
||
Identify exactly which LinuxCNC source files are needed.
|
||
|
||
Steps:
|
||
|
||
1. Map each required capability to LinuxCNC files:
|
||
- G-code interpreter:
|
||
`../linuxcnc/src/emc/rs274ngc/*`
|
||
- parameter tables and named variables:
|
||
`../linuxcnc/src/emc/rs274ngc/interp_*`
|
||
- INI parsing:
|
||
`../linuxcnc/src/emc/ini/inifile.*`
|
||
- planner:
|
||
`../linuxcnc/src/emc/tp/*`
|
||
- kinematics:
|
||
`../linuxcnc/src/emc/kinematics/*`
|
||
and selected files from `../linuxcnc/src/hal/components/*.comp`
|
||
- posemath:
|
||
`../linuxcnc/src/libnml/posemath/*`
|
||
2. For each file, classify it:
|
||
- copy unchanged
|
||
- copy plus shim
|
||
- copy plus light patch
|
||
- not included in phase 1
|
||
3. For each file, record dependencies:
|
||
- HAL
|
||
- RTAPI
|
||
- NML
|
||
- native file IO
|
||
- Python
|
||
- GUI
|
||
4. Save the mapping as a table under `wasm-port/docs/`.
|
||
|
||
Outputs:
|
||
|
||
- file-level reuse matrix
|
||
- dependency matrix
|
||
|
||
## Phase 2: Build the Extraction Pipeline
|
||
|
||
Purpose:
|
||
Keep LinuxCNC source untouched while making port-specific copies available.
|
||
|
||
Steps:
|
||
|
||
1. Write extraction scripts in `wasm-port/tools/`.
|
||
2. Copy selected upstream files into `wasm-port/vendor/linuxcnc/`.
|
||
3. Preserve relative structure where useful, for example:
|
||
- `vendor/linuxcnc/src/emc/rs274ngc/...`
|
||
- `vendor/linuxcnc/src/emc/ini/...`
|
||
4. Store every modification as:
|
||
- a patch in `wasm-port/patches/`, or
|
||
- a thin wrapper outside the vendored file
|
||
5. Add a verification script that compares upstream file hashes against the vendored source list.
|
||
|
||
Rules:
|
||
|
||
- if upstream changes, re-run extraction;
|
||
- reapply patches only in the standalone workspace;
|
||
- never patch `../linuxcnc` directly.
|
||
|
||
Outputs:
|
||
|
||
- reproducible extraction pipeline
|
||
- vendored source tree
|
||
|
||
## Phase 3: Build the Native Extracted Core
|
||
|
||
Purpose:
|
||
Prove the reusable LinuxCNC compute code works outside the full runtime.
|
||
|
||
Steps:
|
||
|
||
1. Create `wasm-port/runtime/core/` as the portable core layer.
|
||
2. Add wrapper translation units instead of editing vendored files where possible.
|
||
3. Start with these subsystems in order:
|
||
- INI parser
|
||
- numeric parameter table
|
||
- named parameter logic
|
||
- interpreter core
|
||
- planner
|
||
- kinematics
|
||
4. Build a native CLI harness first, before any WASM build.
|
||
5. Replace host edges with abstractions:
|
||
- file provider
|
||
- HAL adapter
|
||
- runtime state provider
|
||
- logging adapter
|
||
|
||
Outputs:
|
||
|
||
- portable native core
|
||
- native harness executable
|
||
|
||
Current verified progress:
|
||
|
||
- `tools/build_native_probes.sh` builds the INI parser probe, interpreter
|
||
state probe, named-parameter harness, RS274 compile probe, and the minimal
|
||
interpreter harness from the standalone `wasm-port/` workspace.
|
||
- `tests/native/verify_native_probes.sh` validates that all native probe
|
||
exit codes are zero and that the minimal interpreter harness emits a
|
||
`STRAIGHT_TRAVERSE` canonical event for `G0 X1.0 Y2.0`, plus
|
||
`SET_FEED_RATE` and `STRAIGHT_FEED` canonical events for
|
||
`G1 X3.0 Y4.0 F120.0`.
|
||
- The same validation is now fixture-driven through
|
||
`tests/fixtures/gcode/minimal_linear.ngc` and
|
||
`tests/fixtures/canon/minimal_linear.events`.
|
||
- `tests/fixtures/gcode/modal_incremental.ngc` and
|
||
`tests/fixtures/canon/modal_incremental.events` add `G90`/`G91`
|
||
distance-mode switching plus modal `G1` carry-forward coverage. The
|
||
temporary wrapper behavior is based on LinuxCNC
|
||
`interp_convert.cc::convert_distance_mode()` and
|
||
`interp_convert.cc::convert_straight()`.
|
||
- `tests/fixtures/gcode/position_params.ngc` and
|
||
`tests/fixtures/canon/position_params.events` cover Z-axis motion plus
|
||
current-position parameter visibility for `#5420`, `#5421`, and `#5422`.
|
||
The parameter source basis is LinuxCNC
|
||
`interp_parameter_def.hh` and `interp_namedparams.cc`.
|
||
- `tests/fixtures/gcode_errors/g1_zero_feed.ngc` and
|
||
`tests/fixtures/canon_errors/g1_zero_feed.expected` pin the negative
|
||
`G1` zero-feed case. The source basis is LinuxCNC
|
||
`interp_convert.cc::convert_straight()` and
|
||
`rs274ngc_return.hh::NCE_CANNOT_DO_G1_WITH_ZERO_FEED_RATE`.
|
||
- This proves the current extracted interpreter slice can parse and execute a
|
||
small fixture set through a standalone canonical event sink.
|
||
- Important direction change: the minimal wrapper behavior is a migration
|
||
probe, not the program body. Do not expand it into a separate CNC
|
||
implementation. The next work must retire hand-written wrapper semantics and
|
||
move execution through vendored LinuxCNC interpreter source such as
|
||
`interp_convert.cc`, `interp_read.cc`, `interp_check.cc`, and
|
||
`interp_execute.cc`.
|
||
- `tools/build_native_probes.sh` now includes
|
||
`linuxcnc_interp_convert_source_probe`, which directly compiles vendored
|
||
`interp_convert.cc`. The required `emcStatus` shim is limited to the native
|
||
status boundary used by `tag_arc()` for machine units; it is not a
|
||
project-authored CNC behavior implementation.
|
||
|
||
## Phase 4: Port INI Parsing Without Editing Upstream
|
||
|
||
Purpose:
|
||
Move LinuxCNC config parsing into the standalone runtime.
|
||
|
||
Steps:
|
||
|
||
1. Vendor:
|
||
- `../linuxcnc/src/emc/ini/inifile.cc`
|
||
- `../linuxcnc/src/emc/ini/inifile.hh`
|
||
- `../linuxcnc/src/emc/ini/inifile.h`
|
||
2. Add shim headers under `wasm-port/runtime/core/shims/` for small dependencies only.
|
||
3. Replace file loading through:
|
||
- wrapper-level adapter, preferred
|
||
- minimal vendored patch only if unavoidable
|
||
4. Preserve:
|
||
- `#INCLUDE`
|
||
- relative includes
|
||
- recursion checks
|
||
- line continuation
|
||
- duplicate section merge behavior
|
||
- typed query behavior
|
||
5. Add tests for INI semantics under `tests/native/`.
|
||
|
||
Involved LinuxCNC source:
|
||
|
||
- `src/emc/ini/inifile.cc`
|
||
- `src/emc/ini/inifile.hh`
|
||
- `src/emc/ini/inifile.h`
|
||
|
||
## Phase 5: Port Parameter Tables and Variable Files
|
||
|
||
Purpose:
|
||
Preserve LinuxCNC numeric parameter behavior exactly enough for simulation.
|
||
|
||
Steps:
|
||
|
||
1. Vendor:
|
||
- `../linuxcnc/src/emc/rs274ngc/interp_parameter_def.hh`
|
||
- `../linuxcnc/src/emc/rs274ngc/interp_array.cc`
|
||
- `../linuxcnc/src/emc/rs274ngc/interp_internal.hh`
|
||
- `../linuxcnc/src/emc/rs274ngc/rs274ngc_pre.cc`
|
||
2. Extract:
|
||
- `setup.parameters[]`
|
||
- `required_parameters[]`
|
||
- `readonly_parameters[]`
|
||
- parameter file load/save logic
|
||
3. Replace native file writes with a standalone file service abstraction.
|
||
4. Keep LinuxCNC’s parameter text format in phase 1.
|
||
5. Add regression tests for:
|
||
- missing file
|
||
- out-of-order parameters
|
||
- zero-fill behavior
|
||
- required parameter persistence
|
||
- read-only protection
|
||
|
||
Involved LinuxCNC source:
|
||
|
||
- `src/emc/rs274ngc/interp_parameter_def.hh`
|
||
- `src/emc/rs274ngc/interp_array.cc`
|
||
- `src/emc/rs274ngc/interp_internal.hh`
|
||
- `src/emc/rs274ngc/rs274ngc_pre.cc`
|
||
|
||
## Phase 6: Port Named Parameters and Interpreter State
|
||
|
||
Purpose:
|
||
Preserve LinuxCNC variable semantics and controller-visible state.
|
||
|
||
Steps:
|
||
|
||
1. Vendor:
|
||
- `../linuxcnc/src/emc/rs274ngc/interp_namedparams.cc`
|
||
- `../linuxcnc/src/emc/rs274ngc/interp_internal.hh`
|
||
- `../linuxcnc/src/emc/rs274ngc/interp_fwd.hh`
|
||
- selected interpreter files needed by setup/state handling
|
||
2. Preserve:
|
||
- `context.named_params`
|
||
- `PA_READONLY`
|
||
- `PA_GLOBAL`
|
||
- `PA_USE_LOOKUP`
|
||
- `PA_FROM_INI`
|
||
- built-in named parameters from `init_named_parameters()`
|
||
3. Preserve lookup order:
|
||
- local
|
||
- global
|
||
- `_ini[...]`
|
||
- `_hal[...]`
|
||
- optional Python providers later
|
||
4. Export state outward rather than redesigning it in JS.
|
||
5. Add regression cases for:
|
||
- local/global scoping
|
||
- built-in state variables
|
||
- `_ini[...]`
|
||
- `_hal[...]`
|
||
- read-only errors
|
||
|
||
Involved LinuxCNC source:
|
||
|
||
- `src/emc/rs274ngc/interp_namedparams.cc`
|
||
- `src/emc/rs274ngc/interp_internal.hh`
|
||
- `src/emc/rs274ngc/interp_fwd.hh`
|
||
- `src/emc/rs274ngc/interpmodule.cc`
|
||
|
||
## Phase 7: Replace HAL Runtime With a Simulation HAL Adapter
|
||
|
||
Purpose:
|
||
Keep LinuxCNC interpreter-visible HAL behavior without migrating HAL itself.
|
||
|
||
Steps:
|
||
|
||
1. Do not vendor the whole HAL runtime as a target runtime dependency.
|
||
2. Use LinuxCNC HAL source as reference only for interface semantics:
|
||
- `../linuxcnc/src/hal/hal.h`
|
||
- `../linuxcnc/src/hal/halmodule.cc`
|
||
- `../linuxcnc/src/emc/ini/inihal.cc`
|
||
3. Define a standalone HAL adapter interface:
|
||
- lookup by name
|
||
- typed numeric value
|
||
- connection/existence status
|
||
4. Make `_hal[...]` reads resolve through this adapter.
|
||
5. Seed the adapter from simulation config and runtime state.
|
||
6. Add tests for:
|
||
- existing names
|
||
- missing names
|
||
- disconnected signals
|
||
- type conversion
|
||
|
||
Involved LinuxCNC source:
|
||
|
||
- `src/hal/hal.h`
|
||
- `src/hal/halmodule.cc`
|
||
- `src/emc/rs274ngc/interp_namedparams.cc`
|
||
- `src/emc/ini/inihal.cc`
|
||
|
||
## Phase 8: Port the Interpreter Core
|
||
|
||
Purpose:
|
||
Build the standalone G-code execution engine without touching upstream files.
|
||
|
||
Steps:
|
||
|
||
1. Vendor selected files from `../linuxcnc/src/emc/rs274ngc/`.
|
||
2. Keep original source as intact as possible in `vendor/`.
|
||
3. Add wrappers or minimal patches only in the standalone area.
|
||
4. Replace these external edges:
|
||
- file open/read
|
||
- world sync
|
||
- HAL reads
|
||
- logging
|
||
- runtime callbacks
|
||
5. Preserve:
|
||
- modal state
|
||
- subroutines
|
||
- offsets
|
||
- tool handling
|
||
- parameter interactions
|
||
- error semantics
|
||
6. Add a canonical event sink interface in standalone code.
|
||
|
||
Involved LinuxCNC source:
|
||
|
||
- `src/emc/rs274ngc/interp_execute.cc`
|
||
- `src/emc/rs274ngc/interp_read.cc`
|
||
- `src/emc/rs274ngc/interp_check.cc`
|
||
- `src/emc/rs274ngc/interp_convert.cc`
|
||
- `src/emc/rs274ngc/interp_cycles.cc`
|
||
- `src/emc/rs274ngc/interp_find.cc`
|
||
- `src/emc/rs274ngc/interp_write.cc`
|
||
- `src/emc/rs274ngc/interp_o_word.cc`
|
||
- `src/emc/rs274ngc/rs274ngc_pre.cc`
|
||
- `src/emc/rs274ngc/rs274ngc_interp.hh`
|
||
|
||
## Phase 9: Port Planner and Kinematics
|
||
|
||
Purpose:
|
||
Preserve LinuxCNC motion planning and 5-axis simulation behavior.
|
||
|
||
Steps:
|
||
|
||
1. Vendor selected planner files from `../linuxcnc/src/emc/tp/`.
|
||
2. Vendor selected kinematics files from:
|
||
- `../linuxcnc/src/emc/kinematics/`
|
||
- selected `.comp` sources mirrored into standalone code where needed
|
||
3. Replace loadable-module assumptions with a registry in the standalone runtime.
|
||
4. Keep original math and state logic intact as far as practical.
|
||
5. Add tests for:
|
||
- planner outputs
|
||
- forward/inverse kinematics
|
||
- 5-axis world/joint transforms
|
||
|
||
Involved LinuxCNC source:
|
||
|
||
- `src/emc/tp/tp.c`
|
||
- `src/emc/tp/tc.c`
|
||
- `src/emc/tp/tcq.c`
|
||
- `src/emc/tp/blendmath.c`
|
||
- `src/emc/tp/sp_scurve.c`
|
||
- `src/emc/tp/ruckig_wrapper.c`
|
||
- `src/emc/kinematics/*.c`
|
||
- `src/hal/components/xyzab_tdr_kins.comp`
|
||
- `src/hal/components/xyzacb_trsrn.comp`
|
||
- `src/hal/components/xyzbca_trsrn.comp`
|
||
|
||
## Phase 10: Build the Standalone WASM Program
|
||
|
||
Purpose:
|
||
Keep the migrated program completely outside native LinuxCNC management.
|
||
|
||
Steps:
|
||
|
||
1. Build the standalone native core first.
|
||
2. Add a standalone WASM export layer under:
|
||
- `wasm-port/runtime/core/`
|
||
- `wasm-port/runtime/sdk/`
|
||
3. Use `vendor/` sources plus standalone wrappers as build input.
|
||
4. Do not compile from `../linuxcnc` directly in the final WASM product build.
|
||
5. Emit:
|
||
- `wasm` module
|
||
- JS loader
|
||
- standalone SDK
|
||
|
||
Outputs:
|
||
|
||
- independently managed WASM simulation core
|
||
|
||
## Phase 11: Build the Frontend and OPFS Layer
|
||
|
||
Purpose:
|
||
Keep the standalone port program separate from LinuxCNC GUI code and storage.
|
||
|
||
Steps:
|
||
|
||
1. Build frontend files under:
|
||
- `wasm-port/runtime/ui/`
|
||
- `wasm-port/runtime/opfs/`
|
||
2. Implement:
|
||
- HTML shell
|
||
- JavaScript control panel
|
||
- OPFS persistence
|
||
- file import/export
|
||
- machine/controller state views
|
||
3. Keep LinuxCNC GUI code reference-only.
|
||
4. Ensure the frontend depends only on the standalone SDK, not on native LinuxCNC binaries.
|
||
|
||
Outputs:
|
||
|
||
- standalone browser program
|
||
|
||
## Phase 12: Validate Drift Against Upstream
|
||
|
||
Purpose:
|
||
Prove the standalone port still tracks LinuxCNC behavior.
|
||
|
||
Steps:
|
||
|
||
1. Use native LinuxCNC tests and fixtures as semantic baselines.
|
||
2. Compare:
|
||
- LinuxCNC native behavior
|
||
- standalone native extracted core
|
||
- standalone WASM behavior
|
||
3. Maintain a drift report.
|
||
4. Re-run extraction if upstream source changes.
|
||
5. Keep patches small and traceable.
|
||
|
||
Outputs:
|
||
|
||
- drift report
|
||
- compatibility regression suite
|
||
|
||
## Management Rules For Daily Development
|
||
|
||
Use these rules continuously:
|
||
|
||
1. Never edit files under `linuxcnc/` as part of the port.
|
||
2. Any needed modification to upstream logic must be applied to vendored copies only.
|
||
3. Any upstream sync must be script-driven and repeatable.
|
||
4. Every shim must be documented.
|
||
5. Every local patch against vendored source must be stored as a patch file or clearly isolated wrapper.
|
||
|
||
## Recommended Document Set
|
||
|
||
Keep these documents under `wasm-port/docs/`:
|
||
|
||
- `scope-and-baseline.md`
|
||
- `source-reuse-map.md`
|
||
- `state-porting-strategy.md`
|
||
- `wasm-build-strategy.md`
|
||
- `frontend-architecture.md`
|
||
- `opfs-file-model.md`
|
||
- `compatibility-validation.md`
|
||
- `drift-report.md`
|
||
|
||
## Immediate Next Step
|
||
|
||
Continue expanding the standalone interpreter core from the verified minimal
|
||
traverse path:
|
||
|
||
1. replace the temporary minimal `convert_g()` implementation with calls into
|
||
vendored LinuxCNC interpreter conversion code.
|
||
2. identify and shim the native runtime symbols blocking direct compilation of
|
||
`interp_convert.cc`, `interp_execute.cc`, and related interpreter files.
|
||
3. keep fixture coverage as regression protection while deleting temporary
|
||
hand-written semantics.
|
||
4. keep all source changes inside `wasm-port/` and leave `../linuxcnc/`
|
||
read-only.
|