synth-cli 0.31.0

CLI for Synth, the WebAssembly-to-ARM Cortex-M AOT compiler
[package]
name = "synth-cli"
version.workspace = true
edition.workspace = true
authors.workspace = true
license.workspace = true
repository.workspace = true
homepage.workspace = true
keywords.workspace = true
categories.workspace = true
description = "CLI for Synth, the WebAssembly-to-ARM Cortex-M AOT compiler"

[[bin]]
name = "synth"
path = "src/main.rs"

[features]
default = ["riscv"]
awsm = ["synth-backend-awsm"]
wasker = ["synth-backend-wasker"]
riscv = ["synth-backend-riscv"]
verify = ["synth-verify"]
# Uncomment when loom crate is available:
# loom = ["dep:loom-opt"]

[dependencies]
# Path deps carry `version` so `cargo publish` rewrites them to the
# crates.io coordinate. Bumping the workspace version requires
# updating these in lockstep — see docs/release-process.md.
synth-core = { path = "../synth-core", version = "0.31.0" }
synth-frontend = { path = "../synth-frontend", version = "0.31.0" }
synth-synthesis = { path = "../synth-synthesis", version = "0.31.0" }
synth-backend = { path = "../synth-backend", version = "0.31.0" }

# AArch64 host-native backend (#538) — small pure-Rust crate, always on.
synth-backend-aarch64 = { path = "../synth-backend-aarch64", version = "0.31.0" }

# Optional external backends
synth-backend-awsm = { path = "../synth-backend-awsm", version = "0.31.0", optional = true }
synth-backend-wasker = { path = "../synth-backend-wasker", version = "0.31.0", optional = true }
synth-backend-riscv = { path = "../synth-backend-riscv", version = "0.31.0", optional = true }

# Optional translation validation — pure-Rust ordeal engine by default (#553),
# no C++ toolchain needed. For the Z3 differential oracle build with
# `--features verify,synth-verify/z3-solver` (+ SYNTH_SOLVER_DIFF=1 at runtime).
synth-verify = { path = "../synth-verify", version = "0.31.0", optional = true, features = ["arm"] }

# Optional PulseEngine WASM optimizer
# Uncomment when loom crate is available:
# loom-opt = { workspace = true, optional = true }

clap.workspace = true
anyhow.workspace = true
tracing.workspace = true
tracing-subscriber.workspace = true
serde_json.workspace = true
wat.workspace = true
wast.workspace = true

[dev-dependencies]
object.workspace = true
# VCR-DBG-001 Tier-1 (#394) — oracle E parses the INPUT wasm's `.debug_*` custom
# sections independently (mirroring the production reader) to derive, at runtime,
# the real source basenames its `.debug_line` rows reference — so the emitted
# file-table check is robust vs hardcoding. Test-only; matches synth-core's pin.
# Bazel globs src/ only, so no MODULE.bazel pin is needed for a dev-dependency.
wasmparser.workspace = true
# VCR-ORACLE-001 (#242) — the frozen-codegen byte gate hashes each fixture's
# `.text` to lock it against accidental drift (e.g. a dependabot parser bump
# shifting lowering). Already in the lock tree; test-only ⇒ no production pull,
# no MODULE.bazel pin (Bazel globs src/ only).
sha2 = "0.11"
# VCR-DBG-001 step 4 (#394) — oracle B parses the EMITTED `.debug_line` back with
# gimli::read to prove the section is real debugger-readable DWARF (addresses in
# `.text` range, lines non-zero). Test-only; the production read+emit lives in
# synth-core. Matches synth-core's gimli pin.
gimli = { version = "0.34", default-features = false, features = ["read", "std"] }
# VCR-MEM-001 (#383) layer-2 substrate: scry's sound shadow-stack-depth analysis,
# verified in-tree against a real module. DEV-dependency only — the production
# binary does not pull scry until the gated consumption step (the .bss shrink /
# prologue elision) lands. Test-only ⇒ Bazel (which globs src/ only) never sees
# it, so no MODULE.bazel pin is needed yet. See scry#51.
# Tracks scry 2.x (SCPV v3): the major bump reshaped the provenance wire format,
# but synth's consumed surface (call_graph / function_summaries / stack_usage /
# reachable_from_exports / operand_stack) is unchanged and additive-only, so the
# bump is transparent here. See scry#63 / scry v2.0.0. Empirically re-verified
# against scry v2.3.0, v2.5.0 (2026-06-27), then v2.6.0 (2026-06-30, lockfile
# bumped) — scry_shadow_stack_budget stays GREEN, so the "transparent" claim is
# tested, not just asserted. v2.4.0 (FEAT-038) models memory.size/grow; v2.5.0
# (FEAT-039) makes reachable_from_exports sound in the open world (escaped
# funcref) — the superset synth's shadow-stack pruning relies on; pinned by
# scry_reachable_superset_is_open_world_sound_383_feat039. v2.6.0 adds the
# machine-readable `gaps` field (FEAT-040) + hardens the shadow-stack bound by the
# resolved call_indirect target set (FEAT-043); consumed surface unchanged
# (msgq_put Bytes(32) bound unchanged), now re-verified with a gap-observability
# assertion (value-domain gaps ⇒ the finite bound is sound).
scry-sai-core = "3.0"