5 releases
Uses new Rust 2024
| new 0.2.4 | May 14, 2026 |
|---|---|
| 0.2.3 | May 14, 2026 |
| 0.2.2 | May 14, 2026 |
| 0.2.1 | May 14, 2026 |
| 0.2.0 | May 13, 2026 |
#251 in macOS and iOS APIs
Used in heddle-cli
2MB
41K
SLoC
mount
Heddle's content-addressed mount. The crate exposes virtualized threads as a directory tree backed by the object store.
Architecture
PlatformShell trait ← thin platform adapters
(FuseShell, FSKitShell) (one per OS)
↓
ContentAddressedMount ← pure Rust core
↓
crates/repo + crates/objects
The trait is in src/shell.rs. The core is in src/core.rs. Each
adapter is its own cfg-gated module.
Cargo features
| Feature | Platform | Effect |
|---|---|---|
fuse |
Linux | Compiles fuser and the FuseShell adapter. |
fskit |
macOS | Compiles the Swift adapter and the FSKitShell. |
Both are off by default. The default build of the workspace runs on every OS and produces a crate with the trait + core only — no mountable shell.
# Linux dev box
cargo build -p mount --features fuse
# macOS dev box
cargo build -p mount --features fskit
macOS install requirements (FSKit)
The FSKit shell needs:
-
macOS 15.4+ at runtime. The Swift adapter compiles against the 14.0 SDK and weak-links FSKit, so the build works on older SDKs too — but
mount_backgroundwill fail at runtime on anything below 15.4. UseFSKitShell::is_runtime_available()to probe. -
Xcode command line tools (
xcode-select --install). Thebuild.rsinvokesswiftcto compileswift/HeddleFSKit/HeddleFSKit.swiftinto a static library. Override the path viaHEDDLE_SWIFTC=/path/to/swiftcand the Swift runtime location viaHEDDLE_SWIFT_RUNTIME=/path/to/usr/lib/swift/macosx. -
The
com.apple.developer.fskit.fsmoduleentitlement on the binary that loads the FSKit module. Apple gates this entitlement to apps with a paid Developer account; the binary must be code-signed with a provisioning profile that grants it. For distribution, that means a Developer ID certificate + the FSKit entitlement attached to the heddle CLI binary. -
A code-signed build.
codesign --entitlements heddle.entitlements --sign "Developer ID Application: ..." target/release/heddle. For local development you can self-sign with an ad-hoc identity, but the kernel will refuse to load an FSKit module from an unsigned binary on production macOS configurations. -
(Optional) Disable SIP for local development if you want to skip the entitlement requirement. Not recommended; only useful for proof-of-concept work on a dev VM.
Running the FSKit tests locally
The unit tests in src/fskit/mod.rs and the smoke test in
tests/fskit_smoke.rs are all #[ignore] by default. To run:
# Unit lifecycle test (no real mount; just constructor + drop)
cargo test -p mount --features fskit fskit::tests -- --ignored
# Full mount smoke test (requires macOS 15.4 + entitlements)
HEDDLE_FSKIT_AVAILABLE=1 \
cargo test -p mount --features fskit --test fskit_smoke -- --ignored
The integration test will skip itself unless HEDDLE_FSKIT_AVAILABLE=1
is set, so a generic CI runner won't fail on it accidentally.
Status
- Linux FUSE shell: production. Used by the heddle CLI when
--features mountis enabled. - macOS FSKit shell: scaffolded. The C ABI between the Swift
adapter and the Rust trampolines is wired end-to-end; the
PlatformShelldispatch is exercised by the unit test. TheFSModuleHost.register(...)step that publishes the volume to the kernel is stubbed — the Swiftmount(at:)returnsENOSYStoday. Finishing this needs a.fsmodulebundle and the FSKit entitlement, which are release-engineering tasks. - Windows ProjFS / CfAPI shell: not started.
CLI integration
The CLI's mount lifecycle (crates/cli/src/cli/commands/mount_lifecycle.rs)
currently dispatches through FuseShell only — it's gated on
#[cfg(all(target_os = "linux", feature = "mount"))]. Adding
FSKit dispatch is a follow-up:
- Add a
#[cfg(all(target_os = "macos", feature = "mount"))]sibling module that mirrors the existinglinuxmodule but usesFSKitShellandFSKitSession. - Re-export
MountHandle/spawn_mount_for_thread/unmount_thread_if_mountedfrom whichever module is compiled in. - Add the
fskitfeature to the CLI'smountfeature propagation incrates/cli/Cargo.toml.
The trait layer means the dispatch site stays one line per
backend; nothing in mount_lifecycle.rs's consumer code needs to
change.
Dependencies
~59–87MB
~1.5M SLoC