208 lines
3.9 KiB
Markdown
208 lines
3.9 KiB
Markdown
|
---
|
||
|
marp: true
|
||
|
lang: en-US
|
||
|
title: Marp CLI example
|
||
|
description: Hosting Marp slide deck on the web
|
||
|
theme: nix_talk
|
||
|
transition: fade
|
||
|
paginate: true
|
||
|
_paginate: 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`
|
||
|
<!-- This prevents conflicts and allows various versions to be installed at ones. -->
|
||
|
|
||
|
---
|
||
|
|
||
|
# Nix flake
|
||
|
|
||
|
- Unstable, but widely used
|
||
|
- New way of creating nix derivations
|
||
|
- Lock file version pinning
|
||
|
- Allows reproducibility
|
||
|
|
||
|
---
|
||
|
|
||
|
```nix
|
||
|
{
|
||
|
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](https://github.com/ursi/numtide-flake-utils)
|
||
|
- [Hercules CI: Flake Parts](https://flake.parts/)
|
||
|
|
||
|
<!-- Both are fairly lightweight and remove boilerplate. -->
|
||
|
|
||
|
---
|
||
|
|
||
|
# Flake parts - Minimal modular framework
|
||
|
## Dev environment management
|
||
|
- Devshell
|
||
|
- Devenv
|
||
|
## Rust project building
|
||
|
- NCI (Nix cargo integration)
|
||
|
|
||
|
---
|
||
|
# Basic flake parts project
|
||
|
```nix
|
||
|
{
|
||
|
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
|
||
|
```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";
|
||
|
};
|
||
|
};
|
||
|
```
|
||
|
|
||
|
---
|
||
|
|
||
|
```nix
|
||
|
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
|
||
|
```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
|
||
|
|
||
|
---
|
||
|
```nix
|
||
|
packages.container = pkgs.dockerTools.streamLayeredImage {
|
||
|
name = crateName;
|
||
|
tag = "latest";
|
||
|
contents = [ ];
|
||
|
config = {
|
||
|
Cmd = [ "${crateOutputs.packages.release}/bin/my-crate" ];
|
||
|
};
|
||
|
};
|
||
|
```
|