3.9 KiB
3.9 KiB
marp | lang | title | description | theme | transition | paginate | _paginate |
---|---|---|---|---|---|---|---|
true | en-US | Marp CLI example | Hosting Marp slide deck on the web | nix_talk | fade | true | false |
Nix for Rustaceans
Kateřina "Kate" Churanová
What is Nix
- Purely functional programming language
- Package manager
- Linux distribution (NixOS)
- multiplatform (Linux, Mac OS, BSD-ish)
What is Nix NOT
- Easy to learn
- Well documented
- Opinionated
Nix derivation
- "Package"
- evaluates to store derivation in
/nix/store/
2n45ikclc8d5fhzkvg1197qlc2zk3s64-rustc-1.77.2.drv
Nix flake
- Unstable, but widely used
- New way of creating nix derivations
- Lock file version pinning
- Allows reproducibility
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
};
outputs =
{ self, nixpkgs }:
{
packages.x86_64-linux.default = nixpkgs.legacyPackages.x86_64-linux.hello;
packages.x86_64-linux.foobar = nixpkgs.legacyPackages.x86_64-linux.fortune;
};
}
Nix developer shell
nix develop
- builds all flake dependencies, but not the flake itself
- sets up the development environment
Nix direnv
- https://github.com/nix-community/nix-direnv
- Activates developer shell automatically
Frameworks
- Pure nix solution is usable, but tedious with ugly boilerplate
- Numtide: flake-utils
- Hercules CI: Flake Parts
Flake parts - Minimal modular framework
Dev environment management
- Devshell
- Devenv
Rust project building
- NCI (Nix cargo integration)
Basic flake parts project
{
inputs = {
flake-parts.url = "github:hercules-ci/flake-parts";
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
};
outputs = inputs@{ flake-parts, ... }:
flake-parts.lib.mkFlake { inherit inputs; } {
imports = [
# Modules go here
];
systems = [ "x86_64-linux" "aarch64-linux" "aarch64-darwin" "x86_64-darwin" ];
perSystem = { config, self', inputs', pkgs, system, ... }: {
packages.default = pkgs.hello;
};
};
}
Fun begins with Rust
flake.nix
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
nci = {
url = "github:yusdacra/nix-cargo-integration";
inputs.nixpkgs.follows = "nixpkgs";
};
flake-parts = {
url = "github:hercules-ci/flake-parts";
inputs.nixpkgs-lib.follows = "nixpkgs";
};
};
outputs = inputs @ {
flake-parts,
nci,
...
}:
flake-parts.lib.mkFlake {inherit inputs;} {
systems = ["x86_64-linux"];
imports = [
nci.flakeModule
./crates.nix
];
perSystem = {
pkgs,
config,
...
}: let
crateName = "my-crate"
crateOutputs = config.nci.outputs.${crateName};
in {
devShells.default = crateOutputs.devShell;
packages.default = crateOutputs.packages.release;
};
};
crates.nix
{...}: {
perSystem = {
pkgs,
config,
...
}: let
crateName = "my-crate";
in {
nci.projects."simple".path = ./.;
nci.crates.${crateName} = {};
};
}
Why all of this though?
- Reproducible environment with pinned Rust version
- Predictable dependencies
- Plenty of other tools for your disposal
- Extremely simple generation of lightweight OCI containers
packages.container = pkgs.dockerTools.streamLayeredImage {
name = crateName;
tag = "latest";
contents = [ ];
config = {
Cmd = [ "${crateOutputs.packages.release}/bin/my-crate" ];
};
};