mit einem Klick
cargo2nix
cargo2nix Skill
Mit Codex oder Claude installieren Kopieren Sie diesen Prompt, fügen Sie ihn in Codex, Claude oder einen anderen Assistant ein und lassen Sie die Skill-Seite prüfen und installieren.
Menü
cargo2nix Skill
Mit Codex oder Claude installieren Kopieren Sie diesen Prompt, fügen Sie ihn in Codex, Claude oder einen anderen Assistant ein und lassen Sie die Skill-Seite prüfen und installieren.
Basierend auf der SOC-Berufsklassifikation
Read, write, search and reorganise notes in the local Obsidian vaults. Use for anything touching ~/Documents/R3_vault, ~/Documents/Synechron or ~/Documents/My_Obsidian_Vault/Privat — finding notes, adding or editing content, renaming/moving notes without breaking links, and daily notes. Triggers on "my notes", "my vault", "Obsidian", "write this up in my notes", or a request to look something up in personal documentation.
Manage DNS records for the user's GoDaddy-registered domains. Add/upsert, delete, list, look up specific records, verify a stored record matches an expected value, and check public DNS resolution via dig. Triggers on `/dns`, requests to add/change/check A, AAAA, CNAME, MX, TXT, NS, SRV records on the user's domains, debugging DNS propagation, or auditing what's set at GoDaddy vs what's resolving in the wild.
Operate Google Workspace from the terminal via the `gog` CLI (gogcli). Use for checking and replying to Gmail, managing Google Tasks, reading and creating Calendar events, Google Chat (spaces/DMs/messages), Meet spaces, Contacts, Drive/Docs/Sheets, and more. Triggers on `/gog`, `/gog mail`, `/gog tasks`, `/gog events`, `/gog chat`, `/gog meet`, or any request to check/read/reply/send email, list or add tasks, see today's agenda, or message someone on Chat for the user's Google account.
Agenix Skill
COSMIC Desktop Environment Skill
DankMaterialShell (DMS) Skill
| name | cargo2nix |
| version | 1 |
| description | cargo2nix Skill |
Expert guidance for packaging Rust applications with Nix Granular per-crate builds with reproducible, cacheable dependencies
cargo2nix is a tool that brings Nix dependency management to Rust projects, enabling reproducible builds, efficient per-crate caching, and complete control over the build environment. Unlike simpler approaches, cargo2nix creates individual Nix derivations for each crate, allowing fine-grained dependency sharing across projects and optimal build caching.
Key Features:
Project Status:
The Rust/Nix ecosystem offers 8+ different solutions. Understanding when to use cargo2nix is critical:
| Tool | Derivations | Generated Files | Best For | Trade-offs |
|---|---|---|---|---|
| buildRustPackage | 1 (monolithic) | None | Simple projects, nixpkgs integration | No dependency caching |
| naersk | 2 (deps + project) | None | Better caching than buildRustPackage | Less granular than cargo2nix |
| crane | Composable | None | Modern approach, Cargo-driven | Bundles dependencies together |
| crate2nix | Per-crate | Yes (Cargo.nix) | Fine-grained caching | Experimental cross-compilation |
| cargo2nix | Per-crate | Yes (Cargo.nix) | Shared deps, custom toolchains | Requires Cargo.nix maintenance |
| dream2nix | Varies | Varies | Multi-language projects | Additional abstraction layer |
Shared Dependencies Across Projects
Fine-Grained Build Control
Advanced Caching Requirements
Custom Rust Toolchains
Use buildRustPackage if:
Use crane if:
Use naersk if:
Use crate2nix if:
Cargo.toml and Cargo.lockGenerate Cargo.nix (one-time):
# Using nix run
nix run github:cargo2nix/cargo2nix
# Or in development shell
nix develop github:cargo2nix/cargo2nix#bootstrap
cargo2nix
# Commit the generated file
git add Cargo.nix
git commit -m "Add Cargo.nix for cargo2nix"
Update Cargo.nix (when Cargo.lock changes):
nix run github:cargo2nix/cargo2nix
git add Cargo.nix
git commit -m "Update Cargo.nix"
Specify cargo2nix version in flake.nix:
{
inputs = {
# Latest release (recommended)
cargo2nix.url = "github:cargo2nix/cargo2nix";
# Specific version (stable)
cargo2nix.url = "github:cargo2nix/cargo2nix/release-0.12";
# Development version (unstable)
cargo2nix.url = "github:cargo2nix/cargo2nix/main";
};
}
Update specific version:
nix flake lock --update-input cargo2nix
{
description = "Rust project using cargo2nix";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
cargo2nix = {
url = "github:cargo2nix/cargo2nix/release-0.12";
inputs.nixpkgs.follows = "nixpkgs";
};
flake-utils.url = "github:numtide/flake-utils";
};
outputs = { self, nixpkgs, cargo2nix, flake-utils, ... }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = import nixpkgs {
inherit system;
overlays = [ cargo2nix.overlays.default ];
};
# Build Rust package set
rustPkgs = pkgs.rustBuilder.makePackageSet {
rustVersion = "1.75.0";
packageFun = import ./Cargo.nix;
};
in {
packages = {
# Expose your binary
myapp = rustPkgs.workspace.myapp {};
default = self.packages.${system}.myapp;
};
# Development shell
devShells.default = rustPkgs.workspaceShell {
packages = with pkgs; [
rust-analyzer
cargo-watch
cargo-edit
];
};
}
);
}
# Build your project
nix build
# Run the binary
./result/bin/myapp
# Enter development shell
nix develop
# Inside dev shell
cargo build
cargo test
cargo run
cargo2nix fully supports Cargo workspaces:
# Cargo.toml (workspace root)
[workspace]
members = [
"crates/mylib",
"crates/mybin",
"crates/common",
]
Flake Configuration:
{
outputs = { self, nixpkgs, cargo2nix, flake-utils, ... }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = import nixpkgs {
inherit system;
overlays = [ cargo2nix.overlays.default ];
};
rustPkgs = pkgs.rustBuilder.makePackageSet {
rustVersion = "1.75.0";
packageFun = import ./Cargo.nix;
# Workspace-wide features
rootFeatures = [ "mylib/default" "mybin/cli" ];
};
in {
packages = {
# Expose individual workspace members
mylib = rustPkgs.workspace.mylib {};
mybin = rustPkgs.workspace.mybin {};
common = rustPkgs.workspace.common {};
# Default to main binary
default = self.packages.${system}.mybin;
};
devShells.default = rustPkgs.workspaceShell {
packages = with pkgs; [
rust-analyzer
cargo-nextest # Modern test runner
];
};
}
);
}
# Workspace crates
rustPkgs.workspace.myapp {}
rustPkgs.workspace.mylib {}
# Registry crates (dependencies)
rustPkgs."registry+https://github.com/rust-lang/crates.io-index".serde."1.0.193" {}
rustPkgs."registry+https://github.com/rust-lang/crates.io-index".tokio."1.35.1" {}
# Git dependencies
rustPkgs."git+https://github.com/user/repo".mycrate."0.1.0" {}
rustPkgs = pkgs.rustBuilder.makePackageSet {
# Rust version (REQUIRED)
rustVersion = "1.75.0"; # Specific version
# OR
rustVersion = "2024-01-15"; # Nightly date
# Rust channel (default: "stable")
rustChannel = "stable"; # or "beta", "nightly"
# Rust profile (default: "default")
rustProfile = "minimal"; # or "default" (includes docs, rustfmt)
# Additional components
extraRustComponents = [
"rust-analyzer"
"clippy"
"rustfmt"
"miri"
];
# Package function (REQUIRED)
packageFun = import ./Cargo.nix;
# Workspace source override
workspaceSrc = ./.; # Default: uses Cargo.toml location
# Root features
rootFeatures = [
"default"
"mylib/serde"
"mybin/cli"
];
# Package overrides
packageOverrides = pkgs: [
(pkgs.rustBuilder.rustLib.makeOverride {
name = "openssl-sys";
overrideAttrs = drv: {
propagatedBuildInputs = drv.propagatedBuildInputs or [] ++ [
pkgs.openssl
pkgs.pkg-config
];
};
})
];
# Cross-compilation target
target = "x86_64-unknown-linux-musl";
};
# Stable (specific version)
rustVersion = "1.75.0";
# Stable (latest from nixpkgs)
rustVersion = pkgs.rustc.version;
# Nightly (specific date)
rustVersion = "2024-01-15";
rustChannel = "nightly";
# Beta
rustChannel = "beta";
# Using rust-overlay for latest nightly
inputs.rust-overlay.url = "github:oxalica/rust-overlay";
rustToolchain = pkgs.rust-bin.nightly.latest.default.override {
extensions = [ "rust-src" "rust-analyzer" ];
};
packageOverrides = pkgs: pkgs.rustBuilder.overrides.all ++ [
# OpenSSL
(pkgs.rustBuilder.rustLib.makeOverride {
name = "openssl-sys";
overrideAttrs = drv: {
propagatedBuildInputs = drv.propagatedBuildInputs or [] ++ [
pkgs.openssl
pkgs.pkg-config
];
};
})
# libsqlite3
(pkgs.rustBuilder.rustLib.makeOverride {
name = "libsqlite3-sys";
overrideAttrs = drv: {
propagatedBuildInputs = drv.propagatedBuildInputs or [] ++ [
pkgs.sqlite
];
};
})
# onig (for syntect)
(pkgs.rustBuilder.rustLib.makeOverride {
name = "onig_sys";
overrideAttrs = drv: {
buildInputs = drv.buildInputs or [] ++ [ pkgs.oniguruma ];
};
})
# PostgreSQL
(pkgs.rustBuilder.rustLib.makeOverride {
name = "pq-sys";
overrideAttrs = drv: {
propagatedBuildInputs = drv.propagatedBuildInputs or [] ++ [
pkgs.postgresql
];
};
})
# libgit2
(pkgs.rustBuilder.rustLib.makeOverride {
name = "libgit2-sys";
overrideAttrs = drv: {
buildInputs = drv.buildInputs or [] ++ [
pkgs.libgit2
pkgs.pkg-config
];
};
})
];
Use Existing Overrides:
packageOverrides = pkgs: pkgs.rustBuilder.overrides.all;
Combine with Custom Overrides:
packageOverrides = pkgs: pkgs.rustBuilder.overrides.all ++ [
(pkgs.rustBuilder.rustLib.makeOverride {
name = "my-custom-crate";
overrideAttrs = drv: {
# Custom build dependencies
nativeBuildInputs = drv.nativeBuildInputs or [] ++ [
pkgs.cmake
pkgs.protobuf
];
# Environment variables
LIBCLANG_PATH = "${pkgs.llvmPackages.libclang.lib}/lib";
# Pre-build script
preConfigure = ''
export CUSTOM_VAR="value"
'';
};
})
];
packageOverrides = pkgs: [
(pkgs.rustBuilder.rustLib.makeOverride {
name = "ring";
overrideAttrs = drv: {
# Only on aarch64-darwin
buildInputs = drv.buildInputs or [] ++
pkgs.lib.optionals pkgs.stdenv.isDarwin [
pkgs.darwin.apple_sdk.frameworks.Security
];
};
})
];
rustPkgs = pkgs.rustBuilder.makePackageSet {
rustVersion = "1.75.0";
packageFun = import ./Cargo.nix;
# Cross-compile to x86_64 musl (static binary)
target = "x86_64-unknown-linux-musl";
};
# Static Linux binary (musl)
target = "x86_64-unknown-linux-musl";
# ARM 64-bit Linux
target = "aarch64-unknown-linux-gnu";
# Windows
target = "x86_64-pc-windows-gnu";
# macOS ARM (M1/M2)
target = "aarch64-apple-darwin";
# WebAssembly
target = "wasm32-unknown-unknown";
{
outputs = { self, nixpkgs, cargo2nix, flake-utils, ... }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = import nixpkgs {
inherit system;
overlays = [ cargo2nix.overlays.default ];
};
mkApp = target:
(pkgs.rustBuilder.makePackageSet {
rustVersion = "1.75.0";
packageFun = import ./Cargo.nix;
inherit target;
}).workspace.myapp {};
in {
packages = {
default = mkApp null; # Native
linux-musl = mkApp "x86_64-unknown-linux-musl";
linux-arm = mkApp "aarch64-unknown-linux-gnu";
windows = mkApp "x86_64-pc-windows-gnu";
};
}
);
}
devShells.default = rustPkgs.workspaceShell {
packages = with pkgs; [
# Development tools
rust-analyzer
cargo-watch
cargo-edit
cargo-udeps
cargo-audit
# Additional utilities
just # Command runner
bacon # Background Rust compiler
];
};
devShells.default = rustPkgs.workspaceShell {
packages = with pkgs; [
rust-analyzer
cargo-nextest
cargo-llvm-cov # Code coverage
];
shellHook = ''
echo "🦀 Rust development environment loaded"
echo "Rust version: ${rustPkgs.rustVersion}"
# Set up environment
export RUST_BACKTRACE=1
export RUST_LOG=debug
# Aliases
alias t='cargo nextest run'
alias b='cargo build'
alias r='cargo run'
alias c='cargo check'
# Display workspace info
echo ""
echo "Workspace members:"
cargo metadata --no-deps | jq -r '.workspace_members[]'
'';
};
devShells.default = rustPkgs.workspaceShell {
packages = with pkgs; [
rust-analyzer
postgresql_15
diesel-cli
];
shellHook = ''
# Set up PostgreSQL
export PGDATA="$PWD/.pgdata"
export DATABASE_URL="postgresql://localhost/myapp_dev"
if [ ! -d "$PGDATA" ]; then
echo "Initializing PostgreSQL database..."
initdb --no-locale --encoding=UTF8
echo "unix_socket_directories = '$PWD/.pgdata'" >> "$PGDATA/postgresql.conf"
pg_ctl start -l "$PGDATA/server.log"
psql -d postgres -c "CREATE DATABASE myapp_dev;"
else
pg_ctl start -l "$PGDATA/server.log"
fi
echo "Database ready at $DATABASE_URL"
'';
};
Enter the exact build environment cargo2nix uses:
# Get derivation path
nix build --print-out-paths .#myapp
# Enter isolated build environment
nix develop --ignore-environment /nix/store/...-myapp-0.1.0
# Inside, run build hooks
runHook preConfigure
runHook configureCargo
runHook runCargo
# Check what Cargo.nix was generated from
head -n 20 Cargo.nix
# Verify Cargo.lock hash matches
nix eval .#rustPkgs.workspace.myapp.cargoLockHash
# Inspect package set
nix repl
> :lf .
> rustPkgs.workspace
> rustPkgs."registry+https://github.com/rust-lang/crates.io-index".serde
# Build with verbose output
nix build -L # Show build logs
nix log .#myapp # View previous build log
# Add debug output to overrides
packageOverrides = pkgs: [
(pkgs.rustBuilder.rustLib.makeOverride {
name = "problematic-crate";
overrideAttrs = drv: {
# Print all environment variables
preBuild = ''
echo "=== Build Environment ==="
env | sort
echo "=== Build Inputs ==="
echo "nativeBuildInputs: $nativeBuildInputs"
echo "buildInputs: $buildInputs"
'';
};
})
];
Problem: Error: "Cargo.lock needs to be updated but --locked was passed"
Solution:
# Update Cargo.lock
cargo update
# Regenerate Cargo.nix
nix run github:cargo2nix/cargo2nix
# Commit both files
git add Cargo.lock Cargo.nix
git commit -m "Update dependencies"
Problem: Cargo.nix hash doesn't match Cargo.lock
Temporary Workaround:
rustPkgs = pkgs.rustBuilder.makePackageSet {
rustVersion = "1.75.0";
packageFun = import ./Cargo.nix;
# Disable hash check (NOT RECOMMENDED for production)
ignoreLockHash = true;
};
Proper Solution:
# Regenerate Cargo.nix from current Cargo.lock
nix run github:cargo2nix/cargo2nix
Problem: build.rs fails with "library not found"
Solution: Add package override
packageOverrides = pkgs: pkgs.rustBuilder.overrides.all ++ [
(pkgs.rustBuilder.rustLib.makeOverride {
name = "failing-crate-sys";
overrideAttrs = drv: {
propagatedBuildInputs = drv.propagatedBuildInputs or [] ++ [
pkgs.the-missing-library
pkgs.pkg-config
];
};
})
];
Problem: Can't fetch private git dependencies
Solution:
# Use builtins.fetchGit with SSH
packageOverrides = pkgs: [
(pkgs.rustBuilder.rustLib.makeOverride {
name = "private-crate";
overrideAttrs = drv: {
src = builtins.fetchGit {
url = "git@github.com:org/private-repo.git";
ref = "main";
rev = "abc123...";
};
};
})
];
Note: Cannot use with --restrict-eval
Problem: Binary output differs between builds
Solution:
rustPkgs.workspace.myapp {
# Prefer local build (don't use binary cache)
preferLocalBuild = true;
}
Problem: Complex cfg() attributes fail to parse
Solution: Use newer cargo2nix version
cargo2nix.url = "github:cargo2nix/cargo2nix/release-0.12";
Problem: Specific Rust version not in nixpkgs
Solution: Use rust-overlay
{
inputs = {
rust-overlay.url = "github:oxalica/rust-overlay";
};
outputs = { nixpkgs, rust-overlay, cargo2nix, ... }:
let
pkgs = import nixpkgs {
overlays = [
rust-overlay.overlays.default
cargo2nix.overlays.default
];
};
rustPkgs = pkgs.rustBuilder.makePackageSet {
# Use rust-overlay for any version
rustToolchain = pkgs.rust-bin.stable."1.75.0".default;
packageFun = import ./Cargo.nix;
};
in { ... };
}
Problem: Slow builds in CI/CD
Solutions:
# 1. Use binary cache
nix.settings = {
substituters = [ "https://cache.nixos.org" ];
trusted-public-keys = [ "cache.nixos.org-1:..." ];
};
# 2. Enable distributed builds
nix.distributedBuilds = true;
nix.buildMachines = [ ... ];
# 3. Optimize build cores
nix.settings = {
max-jobs = "auto";
cores = 0; # Use all cores
};
Do: Version control the generated file
git add Cargo.nix
git commit -m "Add/update Cargo.nix"
Why: Essential for reproducible builds, team collaboration
Do: Use specific release branch
cargo2nix.url = "github:cargo2nix/cargo2nix/release-0.12";
Why: Avoid breaking changes, ensure stability
Do: Start with built-in overrides
packageOverrides = pkgs: pkgs.rustBuilder.overrides.all ++ [
# Your custom overrides
];
Why: Handles 90% of common system dependencies
Do: Update Cargo.nix when dependencies change
cargo update
nix run github:cargo2nix/cargo2nix
git add Cargo.lock Cargo.nix
Why: Keeps Nix expressions in sync with Cargo
Do: Leverage generated dev shell
devShells.default = rustPkgs.workspaceShell {
packages = [ pkgs.rust-analyzer ];
};
Why: Automatically includes all dependencies
Do: Add cross-compile targets in CI
packages = {
default = rustPkgs.workspace.myapp {};
static = mkApp "x86_64-unknown-linux-musl";
};
Why: Catch platform issues before release
Do: Add comments explaining why overrides exist
packageOverrides = pkgs: [
# Required for OpenSSL 3.0 compatibility
(pkgs.rustBuilder.rustLib.makeOverride {
name = "openssl-sys";
# ...
})
];
Why: Future maintainers understand decisions
Do: Commit flake.lock
git add flake.lock
git commit -m "Lock dependencies"
Why: Ensures identical builds across machines
Do: Use dev-dependencies in Cargo.toml
[dev-dependencies]
criterion = "0.5" # Benchmarking
proptest = "1.4" # Property testing
Why: Production builds exclude dev dependencies
Do: Test nix builds in CI pipeline
- name: Build with Nix
run: nix build -L
- name: Run tests
run: nix develop -c cargo test
Why: Catch Nix-specific issues early
Don't: Update Cargo.lock without updating Cargo.nix
# Bad
cargo update
git add Cargo.lock
git commit # Missing Cargo.nix update!
Why: Builds will fail with hash mismatches
Do Instead:
cargo update
nix run github:cargo2nix/cargo2nix
git add Cargo.lock Cargo.nix
Don't: Disable hash verification
# Bad: Disables safety checks
rustPkgs = pkgs.rustBuilder.makePackageSet {
ignoreLockHash = true;
};
Why: Loses reproducibility guarantees
Do Instead: Fix root cause (regenerate Cargo.nix)
Don't: Use floating reference
# Bad: Could break unexpectedly
cargo2nix.url = "github:cargo2nix/cargo2nix";
Why: Unstable, breaking changes
Do Instead: Pin to release branch
cargo2nix.url = "github:cargo2nix/cargo2nix/release-0.12";
Don't: Ignore existing overrides
# Bad: Reinventing the wheel
packageOverrides = pkgs: [
# Manually writing openssl-sys override...
];
Why: Duplicates work, misses updates
Do Instead: Use pkgs.rustBuilder.overrides.all
Don't: Track result symlinks
# Bad
git add result
Why: Not reproducible, wastes space
Do Instead: Add to .gitignore
result
result-*
Don't: Use rustup inside nix shell
# Bad: In nix develop
rustup install nightly
Why: Defeats Nix reproducibility
Do Instead: Use cargo2nix's rustVersion/rustToolchain
Don't: Use absolute paths in overrides
# Bad: Not portable
LIBCLANG_PATH = "/usr/lib/llvm-15/lib";
Why: Breaks on other systems
Do Instead: Use Nix packages
LIBCLANG_PATH = "${pkgs.llvmPackages.libclang.lib}/lib";
Don't: Only build, never test
# Bad: No testing
- run: nix build
Why: Misses test failures
Do Instead: Run tests in Nix environment
- run: nix develop -c cargo test
Don't: Rely on impure evaluation
# Bad: Breaks reproducibility
nix build --impure
Why: Not reproducible, defeats Nix purpose
Do Instead: Fix evaluation to be pure
Don't: Suppress or ignore warnings
# Bad: Hiding problems
RUSTFLAGS = "-A warnings"
Why: Masks real issues
Do Instead: Fix warnings, use deny in CI
RUSTFLAGS = "-D warnings" # Deny warnings
Project Structure:
my-cli/
├── Cargo.toml
├── Cargo.lock
├── Cargo.nix # Generated
├── flake.nix
├── flake.lock
└── src/
└── main.rs
Cargo.toml:
[package]
name = "my-cli"
version = "0.1.0"
edition = "2021"
[dependencies]
clap = { version = "4.4", features = ["derive"] }
serde = { version = "1.0", features = ["derive"] }
flake.nix:
{
description = "My CLI tool";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
cargo2nix.url = "github:cargo2nix/cargo2nix/release-0.12";
flake-utils.url = "github:numtide/flake-utils";
};
outputs = { self, nixpkgs, cargo2nix, flake-utils, ... }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = import nixpkgs {
inherit system;
overlays = [ cargo2nix.overlays.default ];
};
rustPkgs = pkgs.rustBuilder.makePackageSet {
rustVersion = "1.75.0";
packageFun = import ./Cargo.nix;
};
in {
packages = {
my-cli = rustPkgs.workspace.my-cli {};
default = self.packages.${system}.my-cli;
};
devShells.default = rustPkgs.workspaceShell {
packages = with pkgs; [ rust-analyzer ];
};
apps.default = {
type = "app";
program = "${self.packages.${system}.my-cli}/bin/my-cli";
};
}
);
}
Usage:
# Generate Cargo.nix
nix run github:cargo2nix/cargo2nix
git add Cargo.nix
# Build
nix build
# Run
nix run
# Development
nix develop
cargo run -- --help
Project Structure:
my-workspace/
├── Cargo.toml # Workspace root
├── Cargo.lock
├── Cargo.nix # Generated
├── flake.nix
├── crates/
│ ├── server/
│ │ ├── Cargo.toml
│ │ └── src/main.rs
│ ├── client/
│ │ ├── Cargo.toml
│ │ └── src/main.rs
│ └── common/
│ ├── Cargo.toml
│ └── src/lib.rs
└── flake.lock
flake.nix:
{
description = "My multi-binary workspace";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
cargo2nix.url = "github:cargo2nix/cargo2nix/release-0.12";
flake-utils.url = "github:numtide/flake-utils";
};
outputs = { self, nixpkgs, cargo2nix, flake-utils, ... }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = import nixpkgs {
inherit system;
overlays = [ cargo2nix.overlays.default ];
};
rustPkgs = pkgs.rustBuilder.makePackageSet {
rustVersion = "1.75.0";
packageFun = import ./Cargo.nix;
rootFeatures = [
"server/default"
"client/default"
"common/default"
];
};
in {
packages = {
server = rustPkgs.workspace.server {};
client = rustPkgs.workspace.client {};
common = rustPkgs.workspace.common {};
default = self.packages.${system}.server;
# Bundle both binaries
all = pkgs.symlinkJoin {
name = "my-workspace-all";
paths = [
self.packages.${system}.server
self.packages.${system}.client
];
};
};
devShells.default = rustPkgs.workspaceShell {
packages = with pkgs; [
rust-analyzer
cargo-nextest
cargo-watch
];
};
apps = {
server = {
type = "app";
program = "${self.packages.${system}.server}/bin/server";
};
client = {
type = "app";
program = "${self.packages.${system}.client}/bin/client";
};
};
}
);
}
flake.nix (PostgreSQL + OpenSSL):
{
outputs = { self, nixpkgs, cargo2nix, flake-utils, ... }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = import nixpkgs {
inherit system;
overlays = [ cargo2nix.overlays.default ];
};
rustPkgs = pkgs.rustBuilder.makePackageSet {
rustVersion = "1.75.0";
packageFun = import ./Cargo.nix;
# System dependency overrides
packageOverrides = pkgs: pkgs.rustBuilder.overrides.all ++ [
# PostgreSQL native library
(pkgs.rustBuilder.rustLib.makeOverride {
name = "pq-sys";
overrideAttrs = drv: {
propagatedBuildInputs = drv.propagatedBuildInputs or [] ++ [
pkgs.postgresql
];
};
})
# OpenSSL
(pkgs.rustBuilder.rustLib.makeOverride {
name = "openssl-sys";
overrideAttrs = drv: {
propagatedBuildInputs = drv.propagatedBuildInputs or [] ++ [
pkgs.openssl
pkgs.pkg-config
];
};
})
];
};
in {
packages.default = rustPkgs.workspace.myapp {};
devShells.default = rustPkgs.workspaceShell {
packages = with pkgs; [
rust-analyzer
postgresql_15
diesel-cli
];
shellHook = ''
export DATABASE_URL="postgresql://localhost/myapp_dev"
echo "Database: $DATABASE_URL"
'';
};
}
);
}
Remember: cargo2nix provides fine-grained per-crate builds at the cost of maintaining Cargo.nix. For simpler projects, consider buildRustPackage or crane. For maximum caching and shared dependencies across projects, cargo2nix is the right choice.