{
  pkgs,
  lib,
  fenix,
  selfPkgs,
  ...
}:
let
  version = "0.15.0";
  mkServicepoint =
    rustPlatform:
    rustPlatform.buildRustPackage (finalAttrs: {
      inherit version;

      pname = "servicepoint-binding-c";
      src = lib.filter {
        root = ./.;
        include = [
          ./Cargo.lock
          ./Cargo.toml
          ./src
          ./build.rs
          ./LICENSE
          ./cbindgen.toml
        ];
      };
      cargoLock.lockFile = ./Cargo.lock;
      useFetchCargoVendor = true;
      meta = {
        description = "C bindings for the servicepoint crate.";
        homepage = "https://git.berlin.ccc.de/servicepoint/servicepoint-binding-c";
        license = lib.licenses.gpl3Plus;
        pkgConfigModules = [ "servicepoint" ];
      };
      nativeBuildInputs = [ pkgs.pkg-config ];
      buildInputs = [ pkgs.xz ];

      preBuild = ''
        mkdir -p include
        export SERVICEPOINT_HEADER_OUT=$(realpath "include")

        echo "Rust version: $(rustc --version)"
        echo "preBuild hook: set SERVICEPOINT_HEADER_OUT to $SERVICEPOINT_HEADER_OUT"
      '';
      postInstall = ''
        cp -r include $out

        mkdir -p $out/lib/pkgconfig
        sed "s:\$out:$out:g" ${./servicepoint.pc.in} | sed "s:\$version:$version:g" > $out/lib/pkgconfig/servicepoint.pc
      '';
    });
  mkExample =
    { name, servicepointBinding }:
    pkgs.stdenv.mkDerivation {
      inherit version;
      pname = "servicepoint-c-example-${name}";
      nativeBuildInputs = [ pkgs.pkg-config ];
      buildInputs = [
        servicepointBinding
        pkgs.xz
      ];
      src = ./example/src;
      buildPhase = ''
        set -e
        set -x
        mkdir -p $out/bin
        gcc ${name}.c $(pkg-config --libs --cflags servicepoint) $(pkg-config --libs --cflags liblzma) $EXTRA_CFLAGS -o $out/bin/${name}
      '';
    };
  rustPlatform-stable = pkgs.rustPlatform;
  rustPlatform-unstable = pkgs.makeRustPlatform {
    cargo = fenix.minimal.cargo;
    rustc = fenix.minimal.rustc;
  };
  examples = [
    "announce"
    "brightness_tester"
    "header_logger"
    "moving_line"
    "random_stuff"
    "wiping_clear"
  ];
in
rec {
  servicepoint-binding-c-stable-release = mkServicepoint rustPlatform-stable;
  servicepoint-binding-c-nightly-release = mkServicepoint rustPlatform-unstable;
  servicepoint-binding-c-nightly-size = servicepoint-binding-c-nightly-release // {
    buildType = "size_optimized";
    buildNoDefaultFeatures = true;
    # TODO: do these override the nix flags?
    #CARGOFLAGS = ''-Zbuild-std="core,std,alloc,proc_macro,panic_abort" -Zbuild-std-features="panic_immediate_abort"'';
    # TODO: those override the nix flags
    # NIX_CFLAGS_COMPILE = builtins.toString ["-Oz" "-fwrapv" "-fomit-frame-pointer" "-fno-stack-protector" "-fno-unroll-loops" "-fno-unwind-tables" "-fno-asynchronous-unwind-tables" "-fmerge-all-constants" "-fvisibility=hidden" "-Bsymbolic" "-fno-ident" "-fno-exceptions" "-ffunction-sections" "-fdata-sections"];
    # NIX_CFLAGS_LINK = builtins.toString ["Wl,-z,norelro" "-Wl,--hash-style=gnu" "-Wl,--gc-sections" "-Wl,--exclude-libs,ALL"];
  };
  servicepoint-binding-c = servicepoint-binding-c-stable-release;

  all-examples = pkgs.symlinkJoin {
    name = "servicepoint-all-examples";
    paths = builtins.map (e: selfPkgs."${e}") examples;
  };
  all-examples-size = pkgs.symlinkJoin {
    name = "servicepoint-all-examples-size";
    paths = builtins.map (e: selfPkgs."${e}-size") examples;
  };
}
# construct one package per example
// (lib.genAttrs examples (
  name:
  mkExample {
    inherit name;
    servicepointBinding = selfPkgs.servicepoint-binding-c;
  }
))
# construct another pakage per example, but with a different name and compiler options
// (lib.mapAttrs'
  (
    name: value:
    lib.nameValuePair ("${name}-size") (
      value
      // {
        EXTRA_CFLAGS = builtins.toString [
          "-Oz"
          "-fwrapv"
          "-fomit-frame-pointer"
          "-fno-stack-protector"
          "-fno-unroll-loops"
          "-fno-unwind-tables"
          "-fno-asynchronous-unwind-tables"
          "-fmerge-all-constants"
          "-fvisibility=hidden"
          "-Bsymbolic"
          "-fno-ident"
          "-fno-exceptions"
          "-ffunction-sections"
          "-fdata-sections"
          "-Wl,-z,norelro"
          "-Wl,--hash-style=gnu"
          "-Wl,--gc-sections"
          "-Wl,--exclude-libs,ALL"
        ];
      }
    )
  )
  (
    lib.genAttrs examples (
      name:
      mkExample {
        inherit name;
        servicepointBinding = selfPkgs.servicepoint-binding-c-nightly-size;
      }
    )
  )
)