Nix

Coders Only

Who are we?

We are a registered association in Zürich dedicated to software developers.

What do we do?

  • SoCraTes Day CH
  • Global Day of Coderetreat Bern & Zürich
  • Book study groups (like Crafting Interpreters)
  • Software Craft Study Group
  • Girl Coders get together
  • Coders Monthly
  • Regular meetups

Sponsors

bbv bring! labs ergon finnova house of test megazord

$ sh <(curl -L https://codersonly.org/members/join)

Nix

This evening's goals

  • Me being exposed to questions
  • You learning at least something new

What we've done so far

  • Deep dive into the expression language
  • Introduction to flakes

Schedule

  1. Introduction to derivations
  2. The mkDerivation function
  3. Creating your own derivation
  4. Higher level derivation functions
  5. Building a Python package

Nix derivations

https://nix.dev/manual/nix/2.25/language/derivations

What is a derivation?

[...] a specification [...] to repeatably produce output files at uniquely determined file system paths.

What's the structure of a derivation

{
  "/nix/store/<cryptographic hash>-<name>.drv": {
    "outputs": {
      "out": {
        "path": "/nix/store/<cryptographic hash>-<name>"
      }
    },
    "inputSrcs": [ <paths of input sources> ],
    "inputDrvs": {},
    "platform": "<platform>",
    "builder": "<path/to/builder>",
    "args": [],
    "env": {
      "builder": "mybuilder",
      "name": "myname",
      "out": "/nix/store/40s0qmrfb45vlh6610rk29ym318dswdr-myname",
      "system": "mysystem"
    }
  }
}

Nix Pill on derivations

For a deeper dive:

https://nixos.org/guides/nix-pills/06-our-first-derivation.html

Defining your first derivation

stdenv.mkDerivation {
  pname = "<derivation-name>";
  version = "<semver>";
  src = ./path/to/files;
  buildPhase = ''
    # <commands>
  '';
  installPhase = ''
    # <commands>
  '';
}

mkDerivation is very adaptable

https://nixos.org/manual/nixpkgs/stable/#part-stdenv

...but this can become cumbersome!

stdenv.mkDerivation rec {
  pname = "solo5";
  version = "0.7.5";

  src = fetchurl {
    url = "https://github.com/Solo5/solo5/releases/download/v${version}/solo5-v${version}.tar.gz";
    hash = "sha256-viwrS9lnaU8sTGuzK/+L/PlMM/xRRtgVuK5pixVeDEw=";
  };

  nativeBuildInputs = [
    makeWrapper
    pkg-config
  ];

  buildInputs = [ libseccomp ];

  postInstall = ''
    substituteInPlace $out/bin/solo5-virtio-mkimage \
      --replace-fail "/usr/lib/syslinux" "${syslinux}/share/syslinux" \
      --replace-fail "/usr/share/syslinux" "${syslinux}/share/syslinux" \
      --replace-fail "cp " "cp --no-preserve=mode "

    wrapProgram $out/bin/solo5-virtio-mkimage \
      --prefix PATH : ${
        lib.makeBinPath [
          dosfstools
          mtools
          parted
          syslinux
        ]
      }
  '';

  doCheck = true;
  nativeCheckInputs = [
    util-linux
    qemu
  ];
  checkPhase = ''[elided]'';
}

Higher level derivation functions

Nix comes with

buildGoModule,
buildNpmPackage,
buildPythonPackage,
buildRustPackage,

and many more!

Building a Python package

python3Packages.buildPythonPackage {
  name = "<name>";
  format = "pyproject";
  src = ./path/to/sources;
  propagatedBuildInputs = with python3Packages; [
    <packages>
  ];
}

Building packages from GitHub

We can fetch the sources from a Git repository on GitHub!

fetchFromGitHub {
  owner = "<github-user>";
  repo = "<repository-name>";
  rev = "<revision>";
  sha256 = "<sha256>";
};

For example:

{
  fetchFromGitHub,
  pkgs,
  ...
}:
with pkgs;
  python3Packages.buildPythonPackage {
    name = "ical2json";
    format = "pyproject";
    src = fetchFromGitHub {
      owner = "codersonlych";
      repo = "ical2json";
      rev = "b4692550f0c3e27d9c2dd386931a5148c280f817";
      sha256 = "sha256-5b/6vkiaLvbxACSEqf322XjMr8Q7VtaZVSZ68PO2Xe8=";
    };
    propagatedBuildInputs = with python3Packages; [
      docopt
      hatchling
      icalendar
      requests
    ];
  }

Now try on your own!

Repository: https://github.com/escodebar/exercises.git
Branch with the Nix flake: nix/buildPythonPackage
Branch with the Python Package: python/HelloCoders

Thank you!

and if you enjoyed this content... consider becoming a member

$ sh <(curl -L https://codersonly.org/members/join)