[package] name = "kache" version = "0.13.0" edition = "2024" description = "Zero-copy, content-addressed build cache for Rust, C/C++ and more, with S3 and shared-filesystem remotes." license = "Apache-2.0" repository = "https://github.com/kunobi-ninja/kache" homepage = "https://kunobi.ninja/docs/kache" keywords = ["build-cache", "rustc-wrapper", "blake3", "cargo"] categories = ["development-tools::build-utils", "caching"] rust-version = "1.95" [workspace] members = ["crates/kache-core", "crates/kache-e2e", "crates/kache-service"] # scenarios/e2e-*/source and test-projects/* are not listed: each declares its own empty # `[workspace]` so cargo treats them as standalone, which is what the # e2e harness (and the integration tests) need to drive them as # realistic standalone consumers of kache. resolver = "3" [dependencies] blake3 = "1" bytes = "1" # OpenDAL 0.58 publishes its modules as separate crates. Depending on only the # core, S3, filesystem, retry, and reqwest transport modules keeps Kache's # supported backend set explicit and avoids compiling unused services. opendal = { package = "opendal-core", version = "=0.58.0", default-features = false, features = ["executors-tokio"] } opendal-http-transport-reqwest = { version = "=0.58.0", default-features = false, features = ["rustls-no-provider"] } opendal-layer-retry = { version = "=0.58.0", default-features = false } opendal-service-fs = { version = "=0.58.0", default-features = false } opendal-service-s3 = { version = "=0.58.0", default-features = false } # OpenDAL exposes a custom credential chain but not a profile-name shortcut. # These published reqsign APIs preserve Kache's explicit profile selection # (including SSO and credential_process) without a git-only patch. reqsign-aws-v4 = { version = "=3.0.2", default-features = false } reqsign-core = { version = "=3.1.0", default-features = false } # Direct dep so OpenDAL/reqwest can use ring without reintroducing aws-lc. rustls = { version = "0.23", default-features = false, features = ["ring"] } kache-core = { version = "0.13.0", path = "crates/kache-core", default-features = false, features = ["planning"] } async-trait = "0.1" tokio = { version = "1", features = ["rt", "rt-multi-thread", "macros", "process", "fs", "io-util", "net", "time", "signal", "sync"] } serde = { version = "1", features = ["derive"] } serde_json = "1" toml = "1" clap = { version = "4", features = ["derive"] } clap_complete = "4" rusqlite = { version = "0.40", features = ["bundled"] } ratatui = "0.30" crossterm = "0.29" filetime = "0.2" anyhow = "1" tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter", "fmt", "registry"] } zstd = "0.13" bytesize = "2" chrono = { version = "0.4", features = ["serde"] } dirs = "6" tar = "0.4" futures = "0.3" glob = "0.3" guppy = "0.17" libc = "0.2" tempfile = "3" reqwest = { version = "0.13", default-features = false, features = ["json", "rustls-no-provider"] } interprocess = { version = "2.4.2", features = ["tokio"] } unicode-normalization = "0.1" # Used by `src/compiler/flags.rs` (the cc / future Swift / future MSVC # flag classifier). The `regex` crate is linear-time by construction # (no backtracking, no lookarounds) — matters because the wrapper runs # the classifier on every cc compile argument; bounded cost is a design # requirement. regex = { version = "1", default-features = false, features = ["std", "perf"] } [target.'cfg(windows)'.dependencies] # `pure` drops blake3's C SIMD (`c/blake3_neon.c` / SSE intrinsics), whose # arm64 NEON path doesn't cross-compile under cargo-xwin's clang + MSVC # sysroot. Windows-only so native/Linux/macOS keep the fast C SIMD backend. blake3 = { version = "1", features = ["pure"] } windows-sys = { version = "0.61", features = [ "Win32_Foundation", "Win32_System_Threading", "Win32_Storage_FileSystem", # ReFS block-cloning (FSCTL_DUPLICATE_EXTENTS_TO_FILE) for zero-copy, # write-isolated restore on a Dev Drive — see link::try_reflink (#429). "Win32_System_IO", "Win32_System_Ioctl", # FILE_SUPPORTS_BLOCK_REFCOUNTING — ask the volume whether it block-clones # instead of inferring "no CoW" from one failed clone (#508). "Win32_System_SystemServices", ] } [dev-dependencies] assert_cmd = "2" predicates = "3" serde_json = "1" bytes = "1" # `{ archive-suffix }` resolves from each target's pkg-fmt (".tar.gz" for # tgz, ".zip" for zip) — never hardcode the extension here: the release # workflow (_release-rust.yml) packages Windows targets as .zip and # everything else as .tar.gz (see #311). Guarded by # tests/binstall_metadata_test.rs. [package.metadata.binstall] pkg-url = "{ repo }/releases/download/v{ version }/{ name }-{ target }{ archive-suffix }" pkg-fmt = "tgz" [package.metadata.binstall.overrides.x86_64-pc-windows-msvc] pkg-fmt = "zip" [package.metadata.binstall.overrides.aarch64-pc-windows-msvc] pkg-fmt = "zip" # Debian packaging (cargo-deb). Read by the _workflows build_deb step to # produce kache__{amd64,arm64}.deb, which package-publish.yml then # pushes into the apt repo on R2. cargo-deb reads this regardless of the # --target passed, so the same config drives both amd64 and arm64 builds. [package.metadata.deb] maintainer = "Kunobi Ninja " copyright = "2026, Zondax AG" license-file = ["LICENSE", "0"] extended-description = """\ kache is a zero-copy, content-addressed build cache for Rust, C/C++ and more. \ It avoids file \ copies and wasted disk by hardlinking artifacts locally and sharing them \ via S3-compatible object storage or a shared filesystem.""" section = "utils" priority = "optional" # CRITICAL: empty depends. kache is built as a static musl binary, so it has # no shared-library runtime dependencies. An auto-resolved or non-empty # `depends` would pin glibc and break install on musl/minimal systems. depends = "" assets = [ ["target/release/kache", "usr/bin/kache", "755"], ["README.md", "usr/share/doc/kache/README", "644"], ] [profile.release] lto = "fat" codegen-units = 1 strip = "symbols" [lints.rust] warnings = "deny" [lints.clippy] permissions_set_readonly_false = "allow" too_many_arguments = "allow"