{
  pkgs,
  lib,
  fenix,
  selfPkgs,
  ...
}:
let
  version = "0.15.0";
  mkServicepoint =
    {
      rustPlatform,
      pkgs,
      buildType ? "release",
      buildNoDefaultFeatures ? false,
      cargoBuildFlags ? [ ],
      nativeBuildInputs ? [],
      stdlib ? false,

    }:
    rustPlatform.buildRustPackage (finalAttrs: {
      inherit version buildType cargoBuildFlags stdlib;

      pname = "servicepoint-binding-c";
      src = lib.filter {
        root = ./.;
        include = [
          ./Cargo.lock
          ./Cargo.toml
          ./src
          ./include
          ./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 ] ++ nativeBuildInputs;
      buildInputs = [ pkgs.xz ];
      postInstall = ''
        cp -r $src/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,
      EXTRA_CFLAGS ? "",
      static ? false,
    }:
    let
      staticPkgConfigParam = if static then "--static" else "";
    in
    pkgs.gccStdenv.mkDerivation {
      inherit version EXTRA_CFLAGS;
      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
        $CC ${name}.c ${if static then "-static" else ""} $CFLAGS $EXTRA_CFLAGS \
          $(pkg-config --libs --cflags ${staticPkgConfigParam} servicepoint) \
          $(pkg-config --libs --cflags ${staticPkgConfigParam} liblzma) \
          -o $out/bin/${name}
      '';
    };
  examples = [
    "announce"
    "brightness_tester"
    "header_logger"
    "moving_line"
    "random_stuff"
    "wiping_clear"
  ];
  mkAllExamples =
    suffix:
    pkgs.symlinkJoin {
      name = "servicepoint-all-examples";
      paths = builtins.map (e: selfPkgs."${e}${suffix}") examples;
    };
  size-cflags = [
    "-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"
  ];
  rustPlatform-stable = pkgs.rustPlatform;
  rustPlatform-nightly = pkgs.makeRustPlatform fenix.complete;
  rustPlatform-musl-stable = pkgs.pkgsMusl.rustPlatform;
  rustPlatform-musl-nightly = pkgs.pkgsMusl.makeRustPlatform fenix.complete;
  stable-release-args = {
    inherit pkgs;
    rustPlatform = rustPlatform-stable;
  };
  nightly-release-args = {
    inherit pkgs;
    rustPlatform = rustPlatform-nightly;
  };
  musl-stable-release-args = {
    pkgs = pkgs.pkgsMusl;
    rustPlatform = rustPlatform-musl-stable;
  };
  musl-nightly-release-args = {
    pkgs = pkgs.pkgsMusl;
    rustPlatform = rustPlatform-musl-nightly;
  };
  stable-size-args = {
    buildType = "size_optimized";
    buildNoDefaultFeatures = true;
  };
  nightly-size-args = {
    cargoBuildFlags = [
      "-Zbuild-std=core,std,alloc,proc_macro,panic_abort"
      "-Zbuild-std-features=panic_immediate_abort"
    ];
    stdlib = true;
    # TODO: remove hard-coded target
    nativeBuildInputs = [fenix.targets."x86_64-unknown-linux-gnu".latest.rust-std];
    # 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"];
  };
in
rec {
  servicepoint-binding-c-stable-release = mkServicepoint stable-release-args;
  servicepoint-binding-c-nightly-release = mkServicepoint nightly-release-args;
  servicepoint-binding-c-musl-stable-release = mkServicepoint musl-stable-release-args;
  servicepoint-binding-c-musl-nightly-release = mkServicepoint musl-nightly-release-args;

  servicepoint-binding-c-stable-size = mkServicepoint (stable-release-args // stable-size-args);
  servicepoint-binding-c-nightly-size = mkServicepoint (
    nightly-release-args // stable-size-args // nightly-size-args
  );
  servicepoint-binding-c-musl-stable-size = mkServicepoint (
    musl-stable-release-args // stable-size-args
  );
  servicepoint-binding-c-musl-nightly-size = mkServicepoint (
    musl-nightly-release-args // stable-size-args // nightly-size-args
  );

  # default variants
  servicepoint-binding-c = servicepoint-binding-c-stable-release;
  servicepoint-binding-c-musl = servicepoint-binding-c-musl-stable-release;

  all-examples = mkAllExamples "";
  all-examples-size = mkAllExamples "-size";
  all-examples-nightly-size = mkAllExamples "-nightly-size";
  # TODO: musl targets do not work on darwin
  all-examples-musl = mkAllExamples "-musl";
  all-examples-musl-static = mkAllExamples "-musl-static";
  all-examples-musl-static-size = mkAllExamples "-musl-static-size";
}
# construct one package per example
// (lib.genAttrs examples (
  name:
  mkExample {
    inherit name pkgs;
    servicepointBinding = selfPkgs.servicepoint-binding-c;
  }
))
# construct another pakage per example, but optimized for size with stable rust
// (lib.mapAttrs' (name: value: lib.nameValuePair ("${name}-size") value) (
  lib.genAttrs examples (
    name:
    mkExample {
      inherit name pkgs;
      servicepointBinding = selfPkgs.servicepoint-binding-c-stable-size;
      EXTRA_CFLAGS = builtins.toString size-cflags;
    }
  )
))
# construct another pakage per example, but optimized for size with unstable rust
// (lib.mapAttrs' (name: value: lib.nameValuePair ("${name}-unstable-size") value) (
  lib.genAttrs examples (
    name:
    mkExample {
      inherit name pkgs;
      servicepointBinding = selfPkgs.servicepoint-binding-c-nightly-size;
      EXTRA_CFLAGS = builtins.toString size-cflags;
    }
  )
))
# construct another pakage per example, but with musl
// (lib.mapAttrs' (name: value: lib.nameValuePair ("${name}-musl") value) (
  lib.genAttrs examples (
    name:
    mkExample {
      inherit name;
      pkgs = pkgs.pkgsMusl;
      servicepointBinding = selfPkgs.servicepoint-binding-c-musl-stable-release;
    }
  )
))
# construct another pakage per example, but statically linked with musl
// (lib.mapAttrs' (name: value: lib.nameValuePair ("${name}-musl-static") value) (
  lib.genAttrs examples (
    name:
    mkExample {
      inherit name;
      pkgs = pkgs.pkgsMusl;
      servicepointBinding = selfPkgs.servicepoint-binding-c-musl-stable-release;
      static = true;
    }
  )
))
# construct another pakage per example, but statically linked with musl and size optimized
// (lib.mapAttrs' (name: value: lib.nameValuePair ("${name}-musl-static-size") value) (
  lib.genAttrs examples (
    name:
    mkExample {
      inherit name;
      pkgs = pkgs.pkgsMusl;
      servicepointBinding = selfPkgs.servicepoint-binding-c-musl-stable-size;
      static = true;
      EXTRA_CFLAGS = builtins.toString size-cflags;
    }
  )
))