新增解释器核心WASM验证
结论:已建立基于LinuxCNC解释器源码的最小WASM核心构建和minimal_linear夹具验证,并接入host smoke。
This commit is contained in:
@@ -18,6 +18,12 @@ The current WASM smoke validation command is:
|
|||||||
wasm-port/tests/wasm/node/verify_ini_wasm.sh
|
wasm-port/tests/wasm/node/verify_ini_wasm.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The current WASM interpreter-core smoke validation command is:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
wasm-port/tests/wasm/node/verify_interp_wasm.sh
|
||||||
|
```
|
||||||
|
|
||||||
The current OPFS host-boundary validation command is:
|
The current OPFS host-boundary validation command is:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -64,6 +70,13 @@ The WASM INI smoke script builds `runtime/ui/ini-panel/linuxcnc_ini.js` and
|
|||||||
module through `runtime/sdk/src/linuxcnc-ini.js` in Node and verifies INI
|
module through `runtime/sdk/src/linuxcnc-ini.js` in Node and verifies INI
|
||||||
queries against a file written to the Emscripten filesystem.
|
queries against a file written to the Emscripten filesystem.
|
||||||
|
|
||||||
|
The WASM interpreter-core smoke script builds
|
||||||
|
`build/wasm/core/linuxcnc_interp.js` and `linuxcnc_interp.wasm` from the same
|
||||||
|
vendored LinuxCNC interpreter source set used by the native minimal
|
||||||
|
interpreter harness. It loads the module in Node, runs the `minimal_linear`
|
||||||
|
G-code fixture through `Interp::execute()`, and compares emitted canonical
|
||||||
|
events with `tests/fixtures/canon/minimal_linear.events`.
|
||||||
|
|
||||||
The OPFS host-boundary script validates the JavaScript file-service adapter
|
The OPFS host-boundary script validates the JavaScript file-service adapter
|
||||||
with a Node mock of the browser File System Access handles. It covers nested
|
with a Node mock of the browser File System Access handles. It covers nested
|
||||||
directory creation, text save/load, missing file behavior, invalid relative
|
directory creation, text save/load, missing file behavior, invalid relative
|
||||||
@@ -129,9 +142,10 @@ The validation fails if:
|
|||||||
| Harness | Purpose |
|
| Harness | Purpose |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| `tests/wasm/node/verify_ini_wasm.sh` | Validates the browser-facing INI WASM module can be built from vendored LinuxCNC `inifile.cc`, loaded through the JS SDK in Node, and queried through the exported C ABI. |
|
| `tests/wasm/node/verify_ini_wasm.sh` | Validates the browser-facing INI WASM module can be built from vendored LinuxCNC `inifile.cc`, loaded through the JS SDK in Node, and queried through the exported C ABI. |
|
||||||
|
| `tests/wasm/node/verify_interp_wasm.sh` | Validates the initial interpreter-core WASM module can be built from vendored LinuxCNC interpreter source, run `minimal_linear.ngc` through `Interp::execute()`, and match the native canonical event fixture. |
|
||||||
| `tests/opfs/node/verify_file_service.sh` | Validates the host-owned OPFS text-file adapter, path model, session snapshot store, machine file store, and G-code text store used by the browser INI panel without moving file persistence into the WASM core. |
|
| `tests/opfs/node/verify_file_service.sh` | Validates the host-owned OPFS text-file adapter, path model, session snapshot store, machine file store, and G-code text store used by the browser INI panel without moving file persistence into the WASM core. |
|
||||||
| `tests/browser/verify_ini_panel_browser.sh` | Validates the INI SDK, WASM module loading, OPFS text-file round trip, generic session snapshot round trip, machine file text round trip, and G-code text round trip in a real browser runtime. |
|
| `tests/browser/verify_ini_panel_browser.sh` | Validates the INI SDK, WASM module loading, OPFS text-file round trip, generic session snapshot round trip, machine file text round trip, and G-code text round trip in a real browser runtime. |
|
||||||
| `tests/host/verify_host_smokes.sh` | Runs the current host-side Node, WASM, OPFS, and browser smoke validation with a single INI WASM build. |
|
| `tests/host/verify_host_smokes.sh` | Runs the current host-side Node, WASM interpreter-core, OPFS, and browser smoke validation with shared WASM builds. |
|
||||||
|
|
||||||
## Fixture Coverage
|
## Fixture Coverage
|
||||||
|
|
||||||
@@ -174,8 +188,9 @@ Negative fixtures currently cover:
|
|||||||
|
|
||||||
## Validation Boundaries
|
## Validation Boundaries
|
||||||
|
|
||||||
Current full-core validation is native-only. WASM/SDK validation is limited to
|
Current full-core validation is native-only. WASM/SDK validation covers the
|
||||||
the INI parser smoke harness. OPFS validation is limited to the JavaScript
|
INI parser smoke harness and an initial interpreter-core canonical event smoke
|
||||||
|
for `minimal_linear`. OPFS validation is limited to the JavaScript
|
||||||
host-boundary adapter plus the INI browser smoke harness. Full browser
|
host-boundary adapter plus the INI browser smoke harness. Full browser
|
||||||
coverage, full SDK coverage, and full machine-session validation remain future
|
coverage, full SDK coverage, and full machine-session validation remain future
|
||||||
work.
|
work.
|
||||||
|
|||||||
158
wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_interp_wasm.cpp
Normal file
158
wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_interp_wasm.cpp
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
#define private public
|
||||||
|
#include "emc/rs274ngc/rs274ngc_interp.hh"
|
||||||
|
#undef private
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <emscripten/emscripten.h>
|
||||||
|
|
||||||
|
#include "canon_event_sink.hh"
|
||||||
|
#include "linuxcnc_hal_adapter.hh"
|
||||||
|
#include "linuxcnc_tool_adapter.hh"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
void seed_hal_values()
|
||||||
|
{
|
||||||
|
standalone::reset_hal_adapter();
|
||||||
|
|
||||||
|
hal_data_u pin_bit{};
|
||||||
|
pin_bit.b = true;
|
||||||
|
standalone::set_hal_value(standalone::HalValueKind::Pin, "standalone.pin-bit", HAL_BIT,
|
||||||
|
pin_bit);
|
||||||
|
|
||||||
|
hal_data_u signal_float{};
|
||||||
|
signal_float.f = 98.25;
|
||||||
|
standalone::set_hal_value(standalone::HalValueKind::Signal, "standalone.signal-float",
|
||||||
|
HAL_FLOAT, signal_float);
|
||||||
|
|
||||||
|
hal_data_u param_s32{};
|
||||||
|
param_s32.s = -17;
|
||||||
|
standalone::set_hal_value(standalone::HalValueKind::Param, "standalone.param-s32", HAL_S32,
|
||||||
|
param_s32);
|
||||||
|
|
||||||
|
hal_data_u pin_u32{};
|
||||||
|
pin_u32.u = 123456789u;
|
||||||
|
standalone::set_hal_value(standalone::HalValueKind::Pin, "standalone.pin-u32", HAL_U32,
|
||||||
|
pin_u32);
|
||||||
|
|
||||||
|
hal_data_u signal_s64{};
|
||||||
|
signal_s64.ls = -9000000000LL;
|
||||||
|
standalone::set_hal_value(standalone::HalValueKind::Signal, "standalone.signal-s64", HAL_S64,
|
||||||
|
signal_s64);
|
||||||
|
|
||||||
|
hal_data_u param_u64{};
|
||||||
|
param_u64.lu = 9000000000ULL;
|
||||||
|
standalone::set_hal_value(standalone::HalValueKind::Param, "standalone.param-u64", HAL_U64,
|
||||||
|
param_u64);
|
||||||
|
|
||||||
|
hal_data_u disconnected{};
|
||||||
|
disconnected.f = 12.5;
|
||||||
|
standalone::set_hal_value(standalone::HalValueKind::Pin, "standalone.disconnected-float",
|
||||||
|
HAL_FLOAT, disconnected, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void seed_tool_values()
|
||||||
|
{
|
||||||
|
standalone::reset_tool_adapter();
|
||||||
|
|
||||||
|
CANON_TOOL_TABLE tool = standalone::tool_entry_init();
|
||||||
|
tool.toolno = 2;
|
||||||
|
tool.pocketno = 2;
|
||||||
|
tool.offset.tran.z = 1.25;
|
||||||
|
tool.diameter = 0.25;
|
||||||
|
standalone::set_tool_entry(2, tool);
|
||||||
|
}
|
||||||
|
|
||||||
|
void initialize_minimal_interp(Interp &interp)
|
||||||
|
{
|
||||||
|
seed_hal_values();
|
||||||
|
seed_tool_values();
|
||||||
|
interp._setup.length_units = CANON_UNITS_MM;
|
||||||
|
interp._setup.distance_mode = DISTANCE_MODE::ABSOLUTE;
|
||||||
|
interp._setup.ijk_distance_mode = DISTANCE_MODE::ABSOLUTE;
|
||||||
|
interp._setup.feed_mode = FEED_MODE::UNITS_PER_MINUTE;
|
||||||
|
interp._setup.plane = CANON_PLANE::XY;
|
||||||
|
interp._setup.motion_mode = G_0;
|
||||||
|
interp._setup.percent_flag = false;
|
||||||
|
interp._setup.sequence_number = 0;
|
||||||
|
interp._setup.parameter_occurrence = 0;
|
||||||
|
interp._setup.num_spindles = 1;
|
||||||
|
interp._setup.feature_set = FEATURE_INI_VARS | FEATURE_HAL_PIN_VARS;
|
||||||
|
interp._setup.parameter_g73_peck_clearance = 1.0;
|
||||||
|
interp._setup.parameter_g83_peck_clearance = 1.0;
|
||||||
|
interp._setup.parameters[5599] = 1.0;
|
||||||
|
interp.load_tool_table();
|
||||||
|
std::memcpy(interp._readers, Interp::default_readers, sizeof(Interp::default_readers));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> split_program_lines(const char *program_text)
|
||||||
|
{
|
||||||
|
std::vector<std::string> lines;
|
||||||
|
std::istringstream input(program_text ? program_text : "");
|
||||||
|
std::string line;
|
||||||
|
while (std::getline(input, line)) {
|
||||||
|
if (!line.empty()) {
|
||||||
|
lines.push_back(line + "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return lines;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *copy_result(const std::string &result)
|
||||||
|
{
|
||||||
|
char *out = static_cast<char *>(std::malloc(result.size() + 1));
|
||||||
|
if (!out) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
std::memcpy(out, result.c_str(), result.size() + 1);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
EMSCRIPTEN_KEEPALIVE
|
||||||
|
char *lcinterp_run_program(const char *program_text)
|
||||||
|
{
|
||||||
|
Interp interp;
|
||||||
|
standalone::reset_canon_events();
|
||||||
|
initialize_minimal_interp(interp);
|
||||||
|
|
||||||
|
const std::vector<std::string> program = split_program_lines(program_text);
|
||||||
|
std::ostringstream output;
|
||||||
|
if (program.empty()) {
|
||||||
|
output << "error=empty fixture\n";
|
||||||
|
return copy_result(output.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (std::size_t idx = 0; idx < program.size(); ++idx) {
|
||||||
|
interp._setup.sequence_number = static_cast<int>(idx + 1);
|
||||||
|
const int execute_rc = interp.execute(program[idx].c_str());
|
||||||
|
output << "execute_line_" << (idx + 1) << "=" << execute_rc << "\n";
|
||||||
|
if (execute_rc > INTERP_MIN_ERROR) {
|
||||||
|
char error_buf[LINELEN] = {0};
|
||||||
|
interp.error_text(execute_rc, error_buf, sizeof(error_buf));
|
||||||
|
output << "error_text=" << error_buf << "\n";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto &event : standalone::canon_events()) {
|
||||||
|
output << "canon_event=" << event << "\n";
|
||||||
|
}
|
||||||
|
return copy_result(output.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
EMSCRIPTEN_KEEPALIVE
|
||||||
|
void lcinterp_free_string(char *value)
|
||||||
|
{
|
||||||
|
std::free(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // extern "C"
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
#include <wordexp.h>
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
int wordexp(const char *words, wordexp_t *pwordexp, int)
|
||||||
|
{
|
||||||
|
if (!words || !pwordexp) {
|
||||||
|
return WRDE_BADCHAR;
|
||||||
|
}
|
||||||
|
|
||||||
|
char **wordv = static_cast<char **>(std::calloc(2, sizeof(char *)));
|
||||||
|
if (!wordv) {
|
||||||
|
return WRDE_NOSPACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
wordv[0] = static_cast<char *>(std::malloc(std::strlen(words) + 1));
|
||||||
|
if (!wordv[0]) {
|
||||||
|
std::free(wordv);
|
||||||
|
return WRDE_NOSPACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::strcpy(wordv[0], words);
|
||||||
|
pwordexp->we_wordc = 1;
|
||||||
|
pwordexp->we_wordv = wordv;
|
||||||
|
pwordexp->we_offs = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wordfree(wordexp_t *pwordexp)
|
||||||
|
{
|
||||||
|
if (!pwordexp || !pwordexp->we_wordv) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t index = 0; index < pwordexp->we_wordc; ++index) {
|
||||||
|
std::free(pwordexp->we_wordv[index]);
|
||||||
|
}
|
||||||
|
std::free(pwordexp->we_wordv);
|
||||||
|
pwordexp->we_wordc = 0;
|
||||||
|
pwordexp->we_wordv = nullptr;
|
||||||
|
pwordexp->we_offs = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // extern "C"
|
||||||
14
wasm-port/runtime/core/shims/boost/noncopyable.hpp
Normal file
14
wasm-port/runtime/core/shims/boost/noncopyable.hpp
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
|
||||||
|
class noncopyable {
|
||||||
|
protected:
|
||||||
|
noncopyable() = default;
|
||||||
|
~noncopyable() = default;
|
||||||
|
|
||||||
|
noncopyable(const noncopyable &) = delete;
|
||||||
|
noncopyable &operator=(const noncopyable &) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
8
wasm-port/runtime/core/shims/linuxcnc_wasm_compat.hh
Normal file
8
wasm-port/runtime/core/shims/linuxcnc_wasm_compat.hh
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <libgen.h>
|
||||||
|
|
||||||
|
inline char *basename(const char *path)
|
||||||
|
{
|
||||||
|
return ::basename(const_cast<char *>(path));
|
||||||
|
}
|
||||||
@@ -4,7 +4,9 @@ set -euo pipefail
|
|||||||
ROOT_DIR="$(cd "$(dirname "$0")/../.." && pwd)"
|
ROOT_DIR="$(cd "$(dirname "$0")/../.." && pwd)"
|
||||||
|
|
||||||
"$ROOT_DIR/tools/build_ini_panel.sh"
|
"$ROOT_DIR/tools/build_ini_panel.sh"
|
||||||
|
"$ROOT_DIR/tools/build_wasm_core.sh"
|
||||||
SKIP_INI_BUILD=1 "$ROOT_DIR/tests/wasm/node/verify_ini_wasm.sh"
|
SKIP_INI_BUILD=1 "$ROOT_DIR/tests/wasm/node/verify_ini_wasm.sh"
|
||||||
|
SKIP_INTERP_BUILD=1 "$ROOT_DIR/tests/wasm/node/verify_interp_wasm.sh"
|
||||||
"$ROOT_DIR/tests/opfs/node/verify_file_service.sh"
|
"$ROOT_DIR/tests/opfs/node/verify_file_service.sh"
|
||||||
SKIP_INI_BUILD=1 "$ROOT_DIR/tests/browser/verify_ini_panel_browser.sh"
|
SKIP_INI_BUILD=1 "$ROOT_DIR/tests/browser/verify_ini_panel_browser.sh"
|
||||||
|
|
||||||
|
|||||||
62
wasm-port/tests/wasm/node/verify_interp_wasm.mjs
Normal file
62
wasm-port/tests/wasm/node/verify_interp_wasm.mjs
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
import { readFileSync } from "node:fs";
|
||||||
|
import { fileURLToPath } from "node:url";
|
||||||
|
import { dirname, resolve } from "node:path";
|
||||||
|
import assert from "node:assert/strict";
|
||||||
|
|
||||||
|
import createLinuxCncInterpModule from "../../../build/wasm/core/linuxcnc_interp.js";
|
||||||
|
|
||||||
|
function allocCString(mod, value) {
|
||||||
|
const bytes = mod.lengthBytesUTF8(value) + 1;
|
||||||
|
const ptr = mod._malloc(bytes);
|
||||||
|
mod.stringToUTF8(value, ptr, bytes);
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
function runProgram(mod, programText) {
|
||||||
|
const programPtr = allocCString(mod, programText);
|
||||||
|
let resultPtr = 0;
|
||||||
|
try {
|
||||||
|
resultPtr = mod._lcinterp_run_program(programPtr);
|
||||||
|
assert.notEqual(resultPtr, 0);
|
||||||
|
return mod.UTF8ToString(resultPtr);
|
||||||
|
} finally {
|
||||||
|
if (resultPtr) {
|
||||||
|
mod._lcinterp_free_string(resultPtr);
|
||||||
|
}
|
||||||
|
mod._free(programPtr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
|
const __dirname = dirname(__filename);
|
||||||
|
const rootDir = resolve(__dirname, "../../..");
|
||||||
|
const wasmPath = resolve(rootDir, "build/wasm/core/linuxcnc_interp.wasm");
|
||||||
|
|
||||||
|
const interp = await createLinuxCncInterpModule({
|
||||||
|
wasmBinary: readFileSync(wasmPath),
|
||||||
|
print() {},
|
||||||
|
printErr(message) {
|
||||||
|
console.error(message);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const fixtureName = "minimal_linear";
|
||||||
|
const programText = readFileSync(
|
||||||
|
resolve(rootDir, `tests/fixtures/gcode/${fixtureName}.ngc`),
|
||||||
|
"utf8",
|
||||||
|
);
|
||||||
|
const expectedEvents = readFileSync(
|
||||||
|
resolve(rootDir, `tests/fixtures/canon/${fixtureName}.events`),
|
||||||
|
"utf8",
|
||||||
|
).trimEnd();
|
||||||
|
|
||||||
|
const output = runProgram(interp, programText);
|
||||||
|
const actualEventSet = new Set(
|
||||||
|
output.split("\n").filter((line) => line.startsWith("canon_event=")),
|
||||||
|
);
|
||||||
|
const expectedEventLines = expectedEvents.split("\n").filter(Boolean);
|
||||||
|
|
||||||
|
for (const expectedEvent of expectedEventLines) {
|
||||||
|
assert.equal(actualEventSet.has(expectedEvent), true, expectedEvent);
|
||||||
|
}
|
||||||
|
console.log("interp_wasm_node_smoke=ok");
|
||||||
9
wasm-port/tests/wasm/node/verify_interp_wasm.sh
Executable file
9
wasm-port/tests/wasm/node/verify_interp_wasm.sh
Executable file
@@ -0,0 +1,9 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
ROOT_DIR="$(cd "$(dirname "$0")/../../.." && pwd)"
|
||||||
|
|
||||||
|
if [[ "${SKIP_INTERP_BUILD:-0}" != "1" ]]; then
|
||||||
|
"$ROOT_DIR/tools/build_wasm_core.sh"
|
||||||
|
fi
|
||||||
|
node "$ROOT_DIR/tests/wasm/node/verify_interp_wasm.mjs"
|
||||||
77
wasm-port/tools/build_wasm_core.sh
Executable file
77
wasm-port/tools/build_wasm_core.sh
Executable file
@@ -0,0 +1,77 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
||||||
|
VENDOR_DIR="$ROOT_DIR/vendor/linuxcnc"
|
||||||
|
WRAP_DIR="$ROOT_DIR/runtime/core/linuxcnc_wrap"
|
||||||
|
SHIM_DIR="$ROOT_DIR/runtime/core/shims"
|
||||||
|
INCLUDE_DIR="$ROOT_DIR/runtime/core/include"
|
||||||
|
OUT_DIR="$ROOT_DIR/build/wasm/core"
|
||||||
|
|
||||||
|
mkdir -p "$OUT_DIR"
|
||||||
|
|
||||||
|
COMMON_FLAGS=(
|
||||||
|
-std=c++20
|
||||||
|
-O2
|
||||||
|
-D_GNU_SOURCE
|
||||||
|
-DM_PI=3.14159265358979323846
|
||||||
|
-DOBJECT_FWD_DWA2002724_HPP
|
||||||
|
-DUNIT_TEST
|
||||||
|
-DLINUXCNC_STANDALONE_USE_RS274_PRE_STATE
|
||||||
|
-DEMC2_HOME=\"/standalone\"
|
||||||
|
-include "$SHIM_DIR/linuxcnc_wasm_compat.hh"
|
||||||
|
-I"$WRAP_DIR"
|
||||||
|
-I"$SHIM_DIR"
|
||||||
|
-I"$INCLUDE_DIR"
|
||||||
|
-I"$VENDOR_DIR/src"
|
||||||
|
-I"$VENDOR_DIR/src/rtapi"
|
||||||
|
-I"$VENDOR_DIR/src/emc"
|
||||||
|
-I"$VENDOR_DIR/src/emc/nml_intf"
|
||||||
|
-I"$VENDOR_DIR/src/emc/motion"
|
||||||
|
-I"$VENDOR_DIR/src/emc/tp"
|
||||||
|
-I"$VENDOR_DIR/src/emc/kinematics"
|
||||||
|
-I"$VENDOR_DIR/src/emc/ini"
|
||||||
|
-I"$VENDOR_DIR/src/libnml/posemath"
|
||||||
|
)
|
||||||
|
|
||||||
|
INTERP_CORE_SOURCES=(
|
||||||
|
"$VENDOR_DIR/src/emc/rs274ngc/modal_state.cc"
|
||||||
|
"$VENDOR_DIR/src/emc/rs274ngc/interp_array.cc"
|
||||||
|
"$VENDOR_DIR/src/emc/rs274ngc/interp_internal.cc"
|
||||||
|
"$VENDOR_DIR/src/emc/rs274ngc/interp_read.cc"
|
||||||
|
"$VENDOR_DIR/src/emc/rs274ngc/interp_check.cc"
|
||||||
|
"$VENDOR_DIR/src/emc/rs274ngc/interp_arc.cc"
|
||||||
|
"$VENDOR_DIR/src/emc/rs274ngc/interp_inverse.cc"
|
||||||
|
"$VENDOR_DIR/src/emc/rs274ngc/interp_execute.cc"
|
||||||
|
"$VENDOR_DIR/src/emc/rs274ngc/interp_convert.cc"
|
||||||
|
"$VENDOR_DIR/src/emc/rs274ngc/interp_cycles.cc"
|
||||||
|
"$VENDOR_DIR/src/emc/rs274ngc/interp_g7x.cc"
|
||||||
|
"$VENDOR_DIR/src/emc/rs274ngc/interp_queue.cc"
|
||||||
|
"$VENDOR_DIR/src/emc/rs274ngc/interp_find.cc"
|
||||||
|
"$VENDOR_DIR/src/emc/rs274ngc/interp_namedparams.cc"
|
||||||
|
"$VENDOR_DIR/src/emc/rs274ngc/interp_write.cc"
|
||||||
|
"$VENDOR_DIR/src/emc/rs274ngc/interp_o_word.cc"
|
||||||
|
"$VENDOR_DIR/src/emc/rs274ngc/rs274ngc_pre.cc"
|
||||||
|
"$WRAP_DIR/linuxcnc_hal_adapter.cpp"
|
||||||
|
"$WRAP_DIR/linuxcnc_emc_status_runtime.cpp"
|
||||||
|
"$WRAP_DIR/linuxcnc_interp_edge_stubs.cpp"
|
||||||
|
"$WRAP_DIR/linuxcnc_runtime_state_stubs.cpp"
|
||||||
|
"$WRAP_DIR/linuxcnc_tool_adapter.cpp"
|
||||||
|
"$WRAP_DIR/linuxcnc_interp_minimal_runtime.cpp"
|
||||||
|
"$WRAP_DIR/linuxcnc_wasm_posix_stubs.cpp"
|
||||||
|
"$VENDOR_DIR/src/emc/ini/inifile.cc"
|
||||||
|
)
|
||||||
|
|
||||||
|
emcc \
|
||||||
|
"${COMMON_FLAGS[@]}" \
|
||||||
|
"${INTERP_CORE_SOURCES[@]}" \
|
||||||
|
"$WRAP_DIR/linuxcnc_interp_wasm.cpp" \
|
||||||
|
-o "$OUT_DIR/linuxcnc_interp.js" \
|
||||||
|
-s MODULARIZE=1 \
|
||||||
|
-s EXPORT_ES6=1 \
|
||||||
|
-s ENVIRONMENT=web,node \
|
||||||
|
-s ALLOW_MEMORY_GROWTH=1 \
|
||||||
|
-s STACK_SIZE=2MB \
|
||||||
|
-s NO_EXIT_RUNTIME=1 \
|
||||||
|
-s EXPORTED_FUNCTIONS='["_malloc","_free","_lcinterp_run_program","_lcinterp_free_string"]' \
|
||||||
|
-s EXPORTED_RUNTIME_METHODS='["UTF8ToString","stringToUTF8","lengthBytesUTF8"]'
|
||||||
Reference in New Issue
Block a user