Reference
Cargo compatibility
Manifests, dependencies, features, build scripts, toolchains, profiles and the registry — and the known limits.
On this page
Rune reads your existing Cargo.toml (or a Rune.toml with
the same contents, including TOML 1.1: multi-line inline tables, trailing
commas), builds with rustc directly, writes a Cargo-format Cargo.lock and
understands .cargo/config.toml. A project keeps working with plain cargo.
What is supported
Manifests and workspaces. Every compilation-relevant [package] field,
[workspace] (members, exclude, default-members, resolver 1/2/3),
workspace = true inheritance for packages, dependencies, lints and metadata —
including packages that inherit from a foreign workspace (a git repository
with its own [workspace]). [lib] crate-type (rlib, dylib, cdylib,
staticlib, proc-macro, several at once), [[bin]]/[[example]]/[[test]]/
[[bench]] with required-features, harness, doctest, target
auto-discovery, autolib/autobins/….
Dependencies. Registry, alternative registries, git (branch/tag/rev, pinned
to an exact commit, submodules included), path, several locations at once,
renamed (package = "..."), target-specific (cfg(...) evaluated against the
real target), build- and dev-dependencies, [patch] and [replace] (from the
manifest and from configuration), source replacement (replace-with a
mirror, a vendor directory or a local-registry).
Features. The full model — default, optional dependencies, dep:, weak
dep?/feat, foo/bar, default-features = false, required-features — resolved
per selection and per role: -p a no longer enables features only b
asked for, and (resolver 2/3) a build script's or proc-macro's dependencies get
their own feature set, separate from the same crate compiled for the target.
Host vs. target. Build scripts, proc-macros and everything only they use are
compiled for the host; the rest for --target. CARGO_CFG_* describes the
target as rustc --print=cfg reports it (custom target JSONs are keyed by
their normalized content).
Build scripts. The full cargo:: contract: rustc-link-lib/search/arg*,
rustc-cdylib-link-arg, rustc-flags, rustc-cfg, rustc-check-cfg,
rustc-env, metadata/DEP_*, warning, error, rerun-if-*; the real
environment (TARGET, HOST, OUT_DIR, CARGO_PKG_*, CARGO_FEATURE_*,
CARGO_ENCODED_RUSTFLAGS, …); one run per package shared by its library,
binaries and tests; links conflicts detected.
C, C++ and other bindings. Everything the binding ecosystem relies on
works as with Cargo, verified with real crates on macOS: cc (C and C++),
bindgen, cxx/cxx-build, bundled C libraries (rusqlite with bundled),
libz-sys/flate2, frameworks (core-foundation), pyo3 both as a Python
extension module and embedding Python, cbindgen headers, and cdylib plugins
loaded with libloading. In particular:
- native library directories a
-syscrate's build script reports reach every crate that links it, however far up (a dynamic-lpython3.9, OpenSSL from Homebrew), and doc tests; rune run/rune testfind dynamic libraries built by build scripts and by the workspace (DYLD_FALLBACK_LIBRARY_PATH,LD_LIBRARY_PATHorPATH);- a workspace library's
staticlib/cdylib/dylib/rlibalso appears under Cargo's names intarget/debug/(libfoo.a,libfoo.so/.dylib,foo.dll), where C build systems, Python packaging and plugin loaders look; - doc tests and
rune docsee the build script'sOUT_DIR(generated bindings),cfgs and environment; - warnings from dependencies' build scripts are silenced, as Cargo does.
Toolchain and configuration. RUSTC, RUSTC_WRAPPER,
RUSTC_WORKSPACE_WRAPPER, RUSTFLAGS, CARGO_ENCODED_RUSTFLAGS,
rust-toolchain(.toml) (resolved through rustup), and the hierarchical
.cargo/config.toml: [build] (rustc, wrappers, rustflags, target,
rustdocflags), [target.<triple|cfg>] (linker, runner, rustflags),
[env], [registries], [source], [patch], tokens and
credential-provider = "cargo:token-from-stdout …".
Profiles. dev/release/test/bench, custom profiles with inherits,
[profile.*.package.<name|*>] and [profile.*.build-override] (by default
build scripts and proc-macros compile unoptimized, as in Cargo), also from
.cargo/config.toml and CARGO_PROFILE_<NAME>_<KEY>. The key uses the
effective profile of each unit. On Apple targets, split-debuginfo defaults
to unpacked like Cargo's (no dsymutil run per binary).
Resolution. Newest compatible versions, seeded by Cargo.lock (which stays
the source of truth: a lockfile changed by git pull or cargo update is
respected), MSRV-aware with resolver 3, and one version per semver-compatible
range as Cargo requires: when a stricter requirement turns up late, resolution
settles on the version every requirement accepts, or backtracks to an older
release of the crate that brought the conflict in. A fresh lockfile for Rune's
own 229-package workspace is byte-identical to cargo generate-lockfile's.
Index entries a lockfile names are fetched in one concurrent wave rather than
level by level (rune update: 3.2 s → 0.7–1.2 s, faster than Cargo's 1.7 s).
Registry workflow. rune install (crates.io, --git, --path; tracked in
Cargo's own .crates.toml, so cargo install --list/uninstall agree),
package (normalized manifest, workspace inheritance resolved, path/git
dependencies turned into registry ones, .cargo_vcs_info.json, verification
build), publish (then waits until the index has it), login/logout (in
Cargo's credentials.toml), yank, owner, search, info, vendor (with
.cargo-checksum.json, so Cargo accepts the directory too; vendored git
dependencies included).
Known limits
Rune targets Cargo compatibility, so these are the things it does not do (yet):
- Only sparse registries. Git-based registry indexes (
registry+https://…) and replacing a source with a git source are rejected with an explanation. - Credential providers other than a plain token and
cargo:token-from-stdout(e.g. OS keychains) are not implemented. - Undeclared external reads. Inputs are learned from what a unit declares.
A build script that reads the outside world without declaring it (no
rerun-if-*) is treated like Cargo treats it, which cannot be detected without tracing or sandboxing — planned. - Packages are identified by name and version. A workspace crate whose dev-dependencies use its published release of exactly the same version gets the local crate there too; Cargo keeps the two apart. (With any other version they are kept apart, as in Cargo.)
- Git dependencies need
gitonPATH(Rune uses your own git, so your credential helpers andinsteadOfrules just work). - Structured diagnostics. Warnings are replayed as rendered text.
- Linux is the platform this was developed on; the test suite also passes on macOS (Apple Silicon). Windows has not been exercised.
denyis not built in (rune auditis); installed as the usualcargo-deny, it works asrune deny, like anycargo-<name>plugin (external subcommands getCARGOpointing at the realcargo, since plugins are written against it;RUNE_PLUGIN_CARGO=runepoints them at Rune).
See ROADMAP.md for the full status against the compatibility specification and what comes next.