This file provides guidance to AI agents when working with code in this repository.
This is a Nix flake library providing reusable functions for building Rust projects with cross-compilation, Docker images, and development environments. It is designed to be imported as a flake input by other projects.
nix fmtnix developnix build .#example-shellUse a local path reference in the consuming project's flake:
inputs.nix-lib.url = "path:../nix-lib";The library has the following input dependencies:
- Core: nixpkgs, flake-utils, rust-overlay, crane
- Optional for flakeModule: treefmt-nix, flake-parts
If consuming projects don't use nix-lib.flakeModules.default, the treefmt-nix
input is not required and can be removed for lighter dependency graphs. Most
consuming projects will want the flakeModule for automatic formatting
configuration, making treefmt-nix a practical requirement in practice.
The library is organized as a flake that exposes functions through
lib.${system}. All functions are defined in lib/ and exported through
lib/default.nix.
Entry point: lib/default.nix imports and re-exports all library functions.
- Two-layer design:
rust-builders.nixprovides high-level platform-specific builders (local, x86_64-linux, aarch64-linux, etc.), whilerust-builder.nixis the low-level factory that creates individual builders - mkAllBuilders: Returns an attrset with pre-configured builders for all supported platforms (local, localNightly, x86_64-linux, aarch64-linux, x86_64-darwin, aarch64-darwin)
- Cross-compilation: Uses nixpkgs cross-compilation with musl for static Linux binaries
- Toolchain support: Can use rust-toolchain.toml, nightly toolchain, or stable
- Builder pattern: Each builder has a
callPackagemethod that wraps rust-package.nix with the appropriate cross-compilation environment variables (CARGO_BUILD_TARGET, linker settings, RUSTFLAGS for static linking)
- Three source types:
mkDepsSrc: Minimal source for dependency resolution (Cargo.toml, Cargo.lock, .cargo/config.toml)mkSrc: Full source for building (adds .rs files, README.md)mkTestSrc: Source with test data
- Purpose: Reduces build closure size and improves caching by filtering files
- Low-level builder: Called via
builder.callPackagefrom consumer projects - Multi-mode: Supports release builds, tests (runTests), clippy (runClippy), docs (buildDocs), and benchmarks (runBench)
- Configurable test arguments: The
cargoTestExtraArgsparameter (default:"--workspace") controls what flags are passed tocargo test. This enables splitting unit tests (--lib) and integration tests (--test '*') into separate Nix derivations, each independently cacheable by Nix. TheprependPackageNameflag (default:true) controls whether-p ${pname}is prepended tocargoExtraArgs; set tofalsefor workspace-wide operations - Cargo profiles: Controlled via CARGO_PROFILE (release/dev/test)
- Cross-compilation handling:
- Patches interpreter for cross-compiled Linux binaries (patchelf)
- Darwin-specific setup hooks for cross-compilation from macOS
- Static linking via RUSTFLAGS with crt-static feature
- Dependencies: Uses crane's two-phase build (buildDepsOnly for caching dependencies, then buildPackage)
- Creates OCI-compliant layered images using nixpkgs dockerTools
- Default includes minimal base packages (cacert, tzdata, glibc/musl)
- Must use Linux packages (handles cross-building from Darwin)
- Provides Rust toolchain, build tools, and optional PostgreSQL
- Integrates with treefmt for code formatting
- mkCheckApp: Runs nix flake checks
- mkAuditApp: Runs cargo-audit for security scanning
- mkFindPortApp: Finds available ports for CI testing
- mkUpdateGithubLabelsApp: Updates GitHub labels based on crate structure
-
Per-system library instantiation: The flake uses
eachSystemMapto create a library instance for each system, accessible vianix-lib.lib.${system} -
Builder factory pattern: Builders are created with platform-specific settings, then consumers call
builder.callPackageto build packages with those settings -
Source separation: Dependencies and main source are built separately for better caching (depsSrc vs src)
-
Environment variable injection: Cross-compilation settings are injected via overrideAttrs on both the main derivation and cargoArtifacts
-
Optional toolchain file: Most functions accept an optional
rustToolchainFileparameter for reproducible Rust versions -
Split test derivations: Tests are built by Nix (not inside
nix develop) to leverage Nix's caching. Unit tests and integration tests are separate derivations viacargoTestExtraArgs, exposed as both packages (nix build) and checks (nix flake check). Arguments after--(e.g.,--test-threads=1) can be included incargoTestExtraArgs
- This is a library, not an application. Changes should maintain backward compatibility.
- All platform-specific logic is in
rust-builder.nix(Darwin build hooks, static linking flags, linker selection). - Docker images must use Linux packages;
mkDockerImagehandles this automatically. - Cross-compilation from macOS to Linux is supported, but macOS targets must be built on Darwin for code signing.
- The library exposes both high-level conveniences (
mkRustBuilders) and low-level building blocks (mkRustBuilder,mkRustPackage).