[package]
name = "supermachine"
version = "0.7.78"
edition.workspace = true
rust-version.workspace = true
# This package's own source is purely Apache-2.0. The transitive
# dep on `supermachine-kernel` brings in GPL-2.0-only kernel data
# and MIT musl in init-oci; consumers redistributing the combined
# binary must satisfy those licenses on the data blobs (see
# `supermachine-kernel`'s NOTICE for the GPL §3(b) source offer).
# Per Cargo convention, the `license` field describes this
# package's contents only.
license = "Apache-2.0"
publish = true
description = "Run any OCI/Docker image as a hardware-isolated microVM on macOS HVF (Linux KVM and Windows WHP in progress). Single library API, zero flags for the common case, sub-100 ms cold-restore from snapshot."
documentation = "https://docs.rs/supermachine"
readme = "README.md"
keywords = ["microvm", "hypervisor", "oci", "docker", "snapshot"]
categories = ["virtualization", "api-bindings", "command-line-utilities"]

# Whitelist what ships in the published .crate. Excluded: large
# binary fixtures (`oci/init-oci*`, `test-initramfs/`, baked
# snapshots, profiling output) which are dev-only artifacts and
# would push the package past crates.io's 10 MiB cap. The init
# shim source `oci/init-oci.c` ships so embedders building from
# source can rebuild it; the prebuilt binary travels through the
# `supermachine-kernel` crate instead.
include = [
    "src/**/*.rs",
    "examples/**/*.rs",
    "entitlements.plist",
    "oci/init-oci.c",
    "Cargo.toml",
    "README.md",
    "LICENSE-APACHE",
]

[lib]
name = "supermachine"
path = "src/lib.rs"

[[bin]]
name = "supermachine"
path = "src/bin/cli.rs"

[[bin]]
name = "supermachine-worker"
path = "src/bin/worker.rs"

[[bin]]
name = "supermachine-router"
path = "src/bin/router.rs"

[[bin]]
name = "cargo-supermachine"
path = "src/bin/cargo_plugin.rs"

[features]
# Default off so Apache-style consumers don't pull tokio
# transitively. Opt-in adds an async wrapper surface that
# `spawn_blocking`s the sync API onto tokio's worker pool.
default = []
tokio = ["dep:tokio"]

[dependencies]
serde.workspace = true
serde_json.workspace = true
libc.workspace = true
log = "0.4"
env_logger = "0.11"
# Structured tracing for embedders. We emit `tracing::info_span!`
# spans + events from the public API entry points (bake, acquire,
# snapshot capture, exec) so embedders can wire a
# `tracing-subscriber` JSON layer and get phase-by-phase metrics
# without us having to ship a custom format. Enabled by default;
# zero overhead when no subscriber is installed.
tracing = "0.1"
mio = { version = "1", features = ["net", "os-poll"] }
rustls = { version = "0.23", default-features = false, features = ["std", "tls12", "ring", "aws-lc-rs"] }
rustls-pemfile = "2"
# Bundled Mozilla root certificates for the builder's self-contained
# `ADD <url>` HTTPS fetch (no subprocess curl, no OS trust-store dependency).
webpki-roots = "0.26"
# SHA-256 used only for content-hashing the bundled kernel /
# init-oci / agent bytes so the per-version extracted-asset cache
# under $XDG_DATA_HOME/supermachine/ invalidates when the bytes
# change without a CARGO_PKG_VERSION bump (e.g. a maintainer
# rebuilds kernel.xz via a path dep). `ring` is already a
# transitive dep via rustls, so adding it as a direct dep here
# is effectively free in compile-time terms.
ring = "0.17"
# Optional async surface — see the `tokio` feature.
tokio = { version = "1", default-features = false, features = ["rt", "rt-multi-thread", "sync"], optional = true }
# Hard dep: kernel + init shim ride inside our binary so
# `cargo install supermachine` produces a CLI that just works,
# zero manual setup. Pinned with `=` because the snapshot format
# is keyed to the kernel build; any drift would invalidate baked
# snapshots. Override with $SUPERMACHINE_KERNEL_PATH at runtime
# for custom kernels.
#
# Licensing: `supermachine-kernel` is `Apache-2.0 AND GPL-2.0-only
# AND MIT` because it bundles the Linux kernel (GPL) and the musl
# libc statically linked into init-oci (MIT). This crate's own
# source stays pure Apache-2.0 — the GPL component arrives as a
# transitive runtime data dependency. Consumers redistributing a
# binary that pulls supermachine in must comply with GPL-2.0 on
# the kernel blob (point downstream at the kernel-build/ recipe
# in our repo for source); their own code is unaffected since the
# kernel runs as guest data in a separate VM, not as linked code.
supermachine-kernel = { version = "=0.7.68", path = "../supermachine-kernel" }
# OCI bake pipeline: read layer-tar headers to recover original uid/gid
# (macOS BSD `tar -xf` strips ownership to the running user since
# non-root can't chown(); we feed the original metadata to mksquashfs
# via `-pseudo-file`). Pure-Rust, no system deps.
tar = { version = "0.4", default-features = false }
flate2 = { version = "1", default-features = false, features = ["rust_backend"] }
# mimalloc — used as the global allocator in our binaries
# (supermachine-worker, supermachine, supermachine-router) and in
# the napi cdylib. Replaces macOS's `system malloc`. Net wins:
#
#   * 5-15% on alloc-heavy hot paths (tokio task queues, async
#     state buffers, JSON parsing during bake).
#   * -5 to -10 MiB per-worker phys_footprint (less fragmentation
#     metadata + smaller arena overhead).
#   * Better thread-local cache behavior under the worker's
#     multi-threaded vCPU + IO mix.
#
# Per-binary opt-in: set `#[global_allocator]` in each binary's
# main file (worker.rs, cli.rs, router.rs, lib.rs for the napi
# cdylib). Library consumers of `supermachine` as a crate aren't
# forced to switch their allocator.
mimalloc = { version = "0.1", default-features = false }
ruzstd = "^0.7"
# backhand — pure-Rust squashfs writer, replacing the `mksquashfs`
# subprocess (the one bake-path tool NOT bundled with macOS — it
# needed a separate `brew install squashfs`). `zstd` feature keeps the
# exact compression the guest kernel already mounts (squashfs-zstd),
# so this is a drop-in with zero guest-side risk. zstd-sys vendors +
# compiles the C, so the binary stays self-contained (same as ring /
# mimalloc). 0.23 declares MSRV 1.84 (we build on 1.85.1).
backhand = { version = "0.23", default-features = false, features = ["zstd"] }

[target.'cfg(all(target_os = "macos", target_arch = "aarch64"))'.dependencies]
applevisor-sys = { version = "1.0", features = ["macos-15-0"] }
vm-fdt = "0.3"

# KVM backend (Linux/x86_64). The hypervisor seam's KVM binding lives in
# `crate::kvm`; these are the in-kernel /dev/kvm ioctls + bindings.
[target.'cfg(all(target_os = "linux", target_arch = "x86_64"))'.dependencies]
kvm-ioctls = "0.23"
kvm-bindings = "0.13"
# EventFd for ioeventfd/irqfd (must match the version kvm-ioctls 0.23 uses so
# the `&EventFd` we pass to register_ioevent/register_irqfd is the same type).
vmm-sys-util = "0.14"

[dev-dependencies]
# For the async-API integration tests under
# `tests/integration_async.rs`, gated on the `tokio` feature.
tokio = { version = "1", default-features = false, features = ["rt-multi-thread", "macros", "time"] }
# Used by `examples/_tracing_demo.rs` to demonstrate the public
# tracing surface. Embedders pick whichever subscriber they want;
# this is just for the example.
tracing-subscriber = { version = "0.3", features = ["env-filter", "fmt"] }
# Used by `examples/_flame_graph.rs` to emit folded-stack-format
# output that `inferno-flamegraph` (or chrome://tracing if you
# convert to JSON) renders as an SVG flame graph. Optional —
# embedders who want flame graphs install this themselves.
tracing-flame = "0.2"
# Property-based testing for the wire parsers (virtqueue descriptor
# chains, exec frame framing). Runs in ordinary `cargo test` on the
# pinned stable toolchain; dev-only, so it never reaches the published
# crate's dependency set or downstream consumers. See the proptest!
# blocks in `queue.rs` and `exec.rs`.
proptest = "1"

# loom — exhaustive interleaving model checker for the concurrency
# primitives that have driven the recent reliability churn (the
# virtqueue avail/used-ring fence cadence, the vsock muxer credit
# pause/resume race). Compiled ONLY when the `sm_loom` cfg is set, so
# it is invisible to every normal build/test:
#
#   RUSTFLAGS="--cfg sm_loom" cargo test --test loom_models --release
#
# (release keeps the state-space exploration fast). The models live in
# `tests/loom_models.rs`, fully gated by `#![cfg(sm_loom)]`.
#
# NB: we deliberately do NOT name the cfg `loom`. `--cfg loom` set via
# RUSTFLAGS leaks into every crate in the build graph — and tokio (a
# dev-dependency here) has its own `cfg(loom)` code paths that fail to
# compile unless loom is *its* dependency. A privately-named cfg keeps
# the model checker scoped to our own code.
[target.'cfg(sm_loom)'.dev-dependencies]
loom = "0.7"

[lints.rust]
unsafe_op_in_unsafe_fn = "warn"
# `--cfg sm_loom` is a deliberate custom cfg (see the loom dev-dep
# above); tell the cfg-checker it's expected so it doesn't warn.
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(sm_loom)'] }

# Clippy is gated in CI (`-D warnings`). The lints below are the
# legacy-adoption baseline: they are either pervasively present in the
# existing hand-written style (this crate predates clippy gating) or
# low-value/cosmetic, so we allow them crate-wide rather than churn
# ~60k LOC. Genuine-bug lints (suspicious_open_options, if_same_then_else,
# not_unsafe_ptr_arg_deref, …) were FIXED, not allowed, and still gate.
# Trim this list opportunistically.
[lints.clippy]
type_complexity = "allow"             # deliberate concrete types on hot paths
too_many_arguments = "allow"          # VMM constructors carry many knobs
needless_range_loop = "allow"         # index loops are clearer in places here
doc_lazy_continuation = "allow"       # doc-comment cosmetic
comparison_chain = "allow"            # explicit if/else-if reads fine
while_let_loop = "allow"              # loop+match is intentional in places
format_collect = "allow"              # cosmetic
field_reassign_with_default = "allow" # cosmetic
items_after_test_module = "allow"     # file organization
len_without_is_empty = "allow"        # device traits don't model emptiness
needless_doctest_main = "allow"       # doctest style
duplicated_attributes = "allow"       # redundant inner #![cfg] on test mods; harmless
assertions_on_constants = "allow"     # deliberate compile-time sanity guards
