[workspace] # Keep source-only members discoverable in Maturin's dependency-pruned archive, # including the separately packaged UniFFI generator. members = ["demo/carla/bridge", "rs/*", "rs/kio/macros", "rs/moq-clock/macros", "rs/moq-net/fuzz", "rs/moq-quic/fuzz"] default-members = [ "rs/bench-harness", "rs/kio", "rs/kio/macros", "rs/hang", # "rs/moq-c", # requires C toolchain "rs/moq-clock", "rs/moq-clock/macros", "rs/moq-congestion", "rs/moq-archive", "rs/moq-auth", "rs/moq-boy", "rs/moq-audio", "rs/moq-bench", "rs/moq-cli", "rs/moq-e2ee", # "rs/moq-ffi", # requires Python/maturin # "rs/moq-gst", # requires GStreamer "rs/moq-hls", "rs/moq-ice", "rs/moq-json", "rs/moq-loc", "rs/moq-msf", "rs/moq-net", "rs/moq-net-tests", "rs/moq-mux", "rs/moq-native", "rs/moq-nvenc", "rs/moq-pattern", "rs/moq-quic", "rs/moq-relay", "rs/moq-room", "rs/moq-rtc", "rs/moq-rtmp", "rs/moq-rtsp", "rs/moq-scene", "rs/moq-shaper", "rs/moq-sock", "rs/moq-srt", "rs/moq-stats", "rs/moq-studio", "rs/moq-tokio", "rs/moq-transcode", "rs/moq-uring", "rs/moq-v4l", "rs/moq-video", # "rs/moq-wasm", # wasm32-unknown-unknown target only "rs/qmux", "rs/test-env", # Maturin runs the workspace's `uniffi-bindgen` binary from the root to # generate the Python wheel, and that only searches default members. Its # `cli` feature keeps a plain check from compiling the generator. "rs/uniffi-bindgen", ] resolver = "2" [workspace.metadata.cargo-shear] # Feature-only dependency selecting the wasm_js backend for browser consumers. ignored = ["getrandom"] [workspace.package] # Floor for the library surface: iroh 1.0 (via moq-tokio) needs 1.91. This is # what consumers of moq-net / hang / moq-tokio / etc. see. moq-relay overrides # it to 1.95 (sysinfo 0.39), and moq-cli does too because it depends on that # library. Those crates are applications; the point of the per-crate override # is to keep the bump off the libraries others actually build on. The nix flake # / rust-toolchain.toml pin the build toolchain to a fixed version rather than # latest stable, which keeps the relay's ceiling from creeping up unnoticed. # That pin sits above every MSRV here; rust-toolchain.toml says why. rust-version = "1.91" [workspace.lints.rust] # kio and moq-net model-check their primitives under `--cfg loom`. unexpected_cfgs = { level = "warn", check-cfg = ['cfg(loom)'] } [workspace.lints.clippy] # Every suppression says why, so the next lint audit can judge it. allow_attributes_without_reason = "warn" [workspace.dependencies] anyhow = "1" ash = "0.38" async-trait = "0.1" aws-lc-rs = "1" # Keep axum's defaults except tower-log, which enables tracing-to-log macros workspace-wide. axum = { version = "0.8", default-features = false, features = [ "form", "http1", "json", "matched-path", "original-uri", "query", "tokio", "tracing", ] } axum-server = { version = "0.8", features = ["tls-rustls"] } base64 = "0.23" bitflags = "2" block2 = "0.6.2" bytes = "1" clap = { version = "4", features = ["derive"] } # CUDA driver bindings for the NVENC/NVDEC path. dlopen'd at runtime # (`fallback-dynamic-loading`), so nothing links against libcuda at build time. cudarc = { version = "0.19", default-features = false, features = ["driver", "fallback-dynamic-loading", "cuda-12020"] } dispatch2 = "0.3.1" ebml-iterable = "0.7.1" flate2 = { version = "1.1", default-features = false } futures = "0.3" getrandom = { version = "0.4", features = ["wasm_js"] } h2 = "0.4" hang = { version = "0.21.11", path = "rs/hang" } hashbrown = { version = "0.17.1", default-features = false } hashlink = "0.12.2" hex = "0.4" # HMAC-SHA256 for the mDNS membership proofs (moq-tokio's `mdns` feature). hmac = "0.13" humantime = "2.3" humantime-serde = "1.1.1" hyper-util = { version = "0.1.21", features = ["tokio"] } # Interface addresses for WebRTC host candidates (moq-tokio's `webrtc` feature). if-addrs = "0.15" indexmap = "2.14.2" io-uring = "0.7.15" jsonwebtoken = "11" kio = { version = "0.6.2", path = "rs/kio" } kio-macros = { version = "0.1.0", path = "rs/kio/macros" } libc = "0.2" libloading = "0.9" linux-raw-sys = { version = "0.12.1", features = ["ioctl"] } # Permutation testing for the kio primitives (and everything built on them). # Only compiled under `--cfg loom`; see `just rs loom`. loom = { version = "0.7.2", features = ["futures"] } # DNS-SD advertisement and browsing for LAN peer discovery (moq-tokio's `mdns` feature). # `async` awaits the event channel instead of blocking a thread on it. mdns-sd = { version = "0.21", features = ["async"] } moq-archive = { version = "0.0.11", path = "rs/moq-archive" } moq-audio = { version = "0.1.10", path = "rs/moq-audio", default-features = false } moq-auth = { version = "0.2.1", path = "rs/moq-auth" } moq-clock = { version = "0.11.0", path = "rs/moq-clock" } moq-clock-macros = { version = "0.1.0", path = "rs/moq-clock/macros" } moq-congestion = { version = "0.1.0", path = "rs/moq-congestion" } moq-hls = { version = "0.5.11", path = "rs/moq-hls", default-features = false } moq-ice = { version = "0.1.0", path = "rs/moq-ice" } moq-json = { version = "0.5.8", path = "rs/moq-json" } moq-loc = { version = "0.2.19", path = "rs/moq-loc" } moq-msf = { version = "0.5.1", path = "rs/moq-msf" } moq-mux = { version = "0.10.11", path = "rs/moq-mux" } moq-net = { version = "0.3.10", path = "rs/moq-net" } # NVENC bindings, forked from ViliamVadocz/nvidia-video-codec-sdk to dlopen the # driver at runtime. Compiles on any platform (macOS included) but only actually # used by moq-video on Linux. moq-nvenc = { version = "0.1.2", path = "rs/moq-nvenc" } moq-pattern = { version = "0.1.2", path = "rs/moq-pattern" } # default-features off so each consumer picks its crypto provider. moq-quic = { version = "0.1.0", path = "rs/moq-quic", default-features = false } moq-relay = { version = "0.17.2", path = "rs/moq-relay", default-features = false } moq-rtc = { version = "0.3.12", path = "rs/moq-rtc" } moq-rtmp = { version = "0.3.11", path = "rs/moq-rtmp" } moq-rtsp = { version = "0.1.0", path = "rs/moq-rtsp" } moq-scene = { version = "0.1.0", path = "rs/moq-scene" } moq-sock = { version = "0.2.0", path = "rs/moq-sock" } moq-srt = { version = "0.3.11", path = "rs/moq-srt" } moq-stats = { version = "0.2.12", path = "rs/moq-stats" } moq-tokio = { version = "0.19.23", path = "rs/moq-tokio", default-features = false } # Default features off on moq-transcode and moq-video so each workspace consumer # chooses native codecs and rendering explicitly. OpenH264 is opt-in everywhere: # each consumer forwards an `openh264` feature that release builds turn on. # VAAPI is opt-in everywhere; its decoder is hardware-validated, while its # encoder is not yet. moq-transcode = { version = "0.1.10", path = "rs/moq-transcode", default-features = false } # default-features off (the `quic` backend) so the consumer opts into the QUIC # stack the io_uring path compiles; cargo features are additive, so a default-on # backend could not be opted out of. moq-uring = { version = "0.0.12", path = "rs/moq-uring", default-features = false } # In-tree fork of `v4l` with the videodev2.h bindings checked in, so moq-video's # `capture` and `v4l2` need no libclang or kernel headers. Linux only; an empty # stub elsewhere. moq-v4l = { version = "0.1.0", path = "rs/moq-v4l" } # Standalone crate (moq-dev/vaapi); vendored from cros-libva + cros-codecs. # dlopen's libva at runtime (no libva-dev at build, no NEEDED libva in the binary). moq-vaapi = "0.1.0" # `default-features = false` is here for `capture` (V4L2, libclang), which the # cross-compiled Python, Swift, Kotlin, and Go builds have no use for: adding # `features = ["capture"]` to a consumer that ships in those bindings pulls the # whole device graph into every one of them. Codec features are independent of # that argument, so moq-ffi and moq-c opt NVIDIA and VAAPI back in (OpenH264 # through their own `openh264` feature, which release builds enable). moq-video = { version = "0.1.10", path = "rs/moq-video", default-features = false } nix = { version = "0.31.3", features = ["net", "socket", "uio"] } # Upstream noq-proto, only for iroh's controller factory types. noq-proto = { version = "1.2", default-features = false } num_enum = "0.7" objc2 = "0.6.4" objc2-av-foundation = "0.3.2" objc2-core-media = "0.3.2" objc2-foundation = "0.3.2" objc2-screen-capture-kit = "0.3.2" # Default features off so a consumer that only needs InMemory does not pull the # local-filesystem stack; `fs` (and cloud backends) are opted in by the caller. object_store = { version = "0.14", default-features = false } percent-encoding = "2" pkcs1 = { version = "0.7.5", features = ["alloc"] } pkcs8 = "0.11.0" pollster = "1.0" # default-features off to skip the fork and timeout machinery; crates opt into what they use. proptest = { version = "1.12.0", default-features = false, features = ["std"] } qmux = { version = "0.7.0", path = "rs/qmux", default-features = false } rand = "0.10.1" rand_pcg = "0.10" rangemap = "1.8" # default-features off so each consumer picks its crypto provider. rcgen = { version = "0.14", default-features = false } # default-features off so each consumer picks its own TLS backend and body # features; nothing here wants the default native-tls stack. reqwest = { version = "0.13", default-features = false } rustc-hash = "2.1.3" sd-notify = "0.5" send_wrapper = "0.6" serde = { version = "1", features = ["derive"] } serde_json = "1" serde_with = "3" sha2 = "0.11" slab = "0.4.12" socket2 = "0.6" # Sans-IO WebRTC. The default `examples` feature pulls in a web server, and aws-lc-rs # is the provider rustls already brings. str0m = { version = "0.24.1", default-features = false, features = ["aws-lc-rs"] } stun-types = "2.0.3" subtle = "2.6" tempfile = "3" thiserror = "2" time = "0.3" tokio = "1.48" tokio-rustls = { version = "0.26", default-features = false } tokio-util = "0.7" toml = "1.1" tower-http = { version = "0.7", features = ["cors"] } tracing = "0.1" tracing-subscriber = "0.3" tracing-test = "0.2" # Runtime used by the published moq-ffi crate. The unpublished bindgen CLI # carries generator-only patches against this release in its own manifest. uniffi = "0.32" url = "2" usage-rs = "7.1.0" uuid = { version = "1.26", features = ["v7"] } web-async = { version = "0.1.5", features = ["tracing"] } web-transport-iroh = "0.8.3" web-transport-proto = "0.6" web-transport-trait = "0.5" web-transport-wasm = "0.8" x11rb = { version = "0.14.0", features = ["randr", "xfixes"] } x509-parser = "0.18" zeroize = { version = "1", features = ["derive"] } [patch.crates-io] # web-transport-iroh depends on kio from crates.io. Without # this, the lock carries a second kio whose pin drifts behind the member, and the # next publish that reaches both fails to resolve a single version (#3551). kio = { path = "rs/kio" } [profile.dev] # Full DWARF is what makes a debug build enormous: the debug `libmoq_ffi.a` # measured 619 MiB against a 100 MiB ceiling for the published one, and a # workspace of those fills a laptop (and a CI runner) fast. Line tables keep # what we actually read -- file and line in every backtrace and panic -- and # drop the variable and type records only an interactive debugger uses. Reach # for `debug = true` in a temporary edit if you need to step through something # in lldb. `profile.test` inherits this. debug = "line-tables-only" # Optimize the bignum crates even in dev/test builds. RSA keygen is bignum # arithmetic in a loop, and unoptimized it is orders of magnitude slower: the # moq-auth key tests spend ~16s generating 2048-bit keys, versus well under a # second here. These are dependencies we never step through in a debugger, so # optimizing them costs nothing an unoptimized build was buying us, and the # tests keep exercising production key sizes rather than being weakened to # stay fast. `profile.test` inherits these overrides. [profile.dev.package.num-bigint-dig] opt-level = 3 [profile.dev.package.crypto-bigint] opt-level = 3 [profile.dev.package.rsa] opt-level = 3 # Same for the sonora echo canceller. Its hot loops are `core::arch` NEON/SSE # intrinsics, which at opt-level 0 compile to out-of-line calls carrying the # debug UB preconditions of `read_unaligned` and `copy_nonoverlapping`: a # profile of `aec::tests::survives_a_moving_echo_delay` spends 65% of its # samples in those checks and intrinsic shims and only 20% in sonora's own # arithmetic. Unoptimized, cancelling 15 seconds of audio costs 12 seconds of # CPU, which is slower than the realtime callback this runs in and leaves the # test no headroom under the nextest timeout. [profile.dev.package.sonora] opt-level = 3 [profile.dev.package.sonora-aec3] opt-level = 3 [profile.dev.package.sonora-agc2] opt-level = 3 [profile.dev.package.sonora-common-audio] opt-level = 3 [profile.dev.package.sonora-fft] opt-level = 3 [profile.dev.package.sonora-ns] opt-level = 3 [profile.dev.package.sonora-simd] opt-level = 3 # The Go mirror stores native staticlibs in Git, whose per-file limit is 100 MB. # Keep all release entry points on the same compact native profile. [profile.release] lto = "fat" codegen-units = 1 strip = "symbols" # UniFFI reads ELF's regular symbol table to generate bindings, including in # maturin and downstream generators. Remove debug data but retain that metadata. [profile.release.package.moq-ffi] strip = "debuginfo" [profile.profiling] inherits = "release" debug = "line-tables-only" strip = "none" # frame pointers: pass RUSTFLAGS="-C force-frame-pointers=yes" when building # Package overrides are inherited too and take precedence over the profile. [profile.profiling.package.moq-ffi] strip = "none" [profile.release-with-debug] inherits = "release" debug = true strip = "none" [profile.release-with-debug.package.moq-ffi] strip = "none" # Size-optimized build for the browser/WASM bindings (rs/moq-wasm). Shipping over # the wire, so optimize for size, not speed (~579KB -> ~471KB gzipped vs the # default release profile). `just js wasm` builds with `--profile wasm-release`. [profile.wasm-release] inherits = "release" opt-level = "z"