Skip to content
Joachim Schiele edited this page Jul 25, 2024 · 45 revisions

Motivation

libnix: We start with rust/cargo on linux to make it work with nix as backend:

we could have a .envrc/direnv like concept with a file build-environment.nix in the cargo based project dir. When you enter the directory /home/joachim/myrustproject you will see the rust tools like: cargo-clippy / cargo-fmt / cargo / rust-analyzer / rust-gdb / rust-lldb / rustc / rustdoc / rustfmt. When you leave this directory the tools won't be in the shell anymore.

This myrustproject specific .envrc should only contain the bare minimum to describe the environment needed for the rust project. So a flake could make use to build an output from the rust project but if said flake could contain several rust projects and each would have a specific definition of rust compiler settings.

The same set of tools will be used by cargo when spawning a build, this gives use reproducability in builds since this might require more than just cargo/rustc. For instance a c compiler or some other useful third-party tool.

See also:

Working branch

https://github.com/nixcloud/cargo/tree/libnix-0.79.0

parts of both folders ~/.cargo and target have been replaced by the nix store.

Let's see what is in them!

~/.cargo

[nixos@nixos:~/cargo]$ du -sh ~/.cargo
239M    /home/nixos/.cargo

[nixos@nixos:~/cargo]$ ls ~/.cargo/
registry

[nixos@nixos:~/cargo]$ ls ~/.cargo/registry/
cache  CACHEDIR.TAG  index  src

cargo/target

The example is the cargo project itself, the tool coming with the rust toolchain, since we hack on it.

[nixos@nixos:~/cargo]$ du -sh target/
2.3G    target/

[nixos@nixos:~/cargo]$ ls target/
CACHEDIR.TAG  debug

[nixos@nixos:~/cargo]$ ls target/debug/
build  cargo  cargo.d  deps  examples  incremental  libcargo.d  libcargo.rlib

Plan

libnix backend in cargo needs to get these things working:

  • no use of ~/.cargo, everything in /nix/store
  • target/debug/* needs to come from /nix/store, eventually symlinked or transparently from the store

figure out what these are:

  • target/debug/build

.fingerprint

target/debug/.fingerprint -> https://doc.rust-lang.org/nightly/nightly-rustc/cargo/core/compiler/fingerprint/index.html

[nixos@nixos:~/cargo]$ ls target/debug/.fingerprint/der-d0714c795318982b/
dep-lib-der  invoked.timestamp  lib-der  lib-der.json

[nixos@nixos:~/cargo]$ cat target/debug/.fingerprint/der-d0714c795318982b/lib-der
6b2cf10d51d11828

[nixos@nixos:~/cargo]$ cat target/debug/.fingerprint/der-d0714c795318982b/lib-der.json  | jq
{
  "rustc": 18217185010275080438,
  "features": "[\"alloc\", \"oid\", \"pem\", \"std\", \"zeroize\"]",
  "declared_features": "",
  "target": 4346314333490370059,
  "profile": 12206360443249279867,
  "path": 16879011525611689376,
  "deps": [
    [
      1724196337906130016,
      "pem_rfc7468",
      false,
      5466269655917579261
    ],
    [
      2676387858222833023,
      "const_oid",
      false,
      2852573652909154018
    ],
    [
      15098350142499636151,
      "zeroize",
      false,
      14469829910961900562
    ]
  ],
  "local": [
    {
      "CheckDepInfo": {
        "dep_info": "debug/.fingerprint/der-d0714c795318982b/dep-lib-der"
      }
    }
  ],
  "rustflags": [],
  "metadata": 12456048820742377390,
  "config": 2202906307356721367,
  "compile_kind": 0
}

[nixos@nixos:~/cargo]$ cat target/debug/.fingerprint/der-d0714c795318982b/dep-lib-der

finally:

  • get a crate compiled without dependencies
  • get one with nested dependencies
  • get one with c library usage (like cargo itself)

how nix builds rust packages ATM

BuildContext

Some fields that might be interesting:

let bcx : BuildContext = create_bcx(ws, options, &interner)? // Line 153 in cargo/ops/cargo_compile/mod.rs
bcx.ws.gctx.home_path;
bcx.ws.gctx.cwd;
bcx.ws.gctx.ws_roots;
bcx.ws.current_manifest;
bcx.ws.packages.gctx;
bcx.ws.packages.packages; // HashMap<PackageId, LazyCell<Package>>

Compilation outcomes

Where do we need to grab the compilation results that we want to move into the nix store?

https://docs.rs/cargo/latest/src/cargo/core/compiler/build_runner/mod.rs.html#135

Can we just use the Compilation outcome?

With Rust nightly we can see build plan:

cargo build -Z unstable-options --build-plan | jq
Clone this wiki locally