atagen

headroom

public
Star0
Watch0
9de515ea3b0766e46f3f383ac3721debb042c85f
1
ssh://brewery@pls.lobotomise.me:33/atagen/headroom.git

Blame: flake.nix

b449da897c0fatagen2026-05-27 15:49 UTC1
{
b449da897c0fatagen2026-05-27 15:49 UTC2
  description = "automatic loudness and per-app volume control (pipewire)";
b449da897c0fatagen2026-05-27 15:49 UTC3
b449da897c0fatagen2026-05-27 15:49 UTC4
  inputs = {
b449da897c0fatagen2026-05-27 15:49 UTC5
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
b449da897c0fatagen2026-05-27 15:49 UTC6
  };
b449da897c0fatagen2026-05-27 15:49 UTC7
b449da897c0fatagen2026-05-27 15:49 UTC8
  outputs =
b449da897c0fatagen2026-05-27 15:49 UTC9
    {
b449da897c0fatagen2026-05-27 15:49 UTC10
      self,
b449da897c0fatagen2026-05-27 15:49 UTC11
      nixpkgs,
b449da897c0fatagen2026-05-27 15:49 UTC12
    }:
b449da897c0fatagen2026-05-27 15:49 UTC13
    let
b449da897c0fatagen2026-05-27 15:49 UTC14
      systems = [
b449da897c0fatagen2026-05-27 15:49 UTC15
        "x86_64-linux"
b449da897c0fatagen2026-05-27 15:49 UTC16
        "aarch64-linux"
b449da897c0fatagen2026-05-27 15:49 UTC17
      ];
b449da897c0fatagen2026-05-27 15:49 UTC18
      forAllSystems = nixpkgs.lib.genAttrs systems;
b449da897c0fatagen2026-05-27 15:49 UTC19
b449da897c0fatagen2026-05-27 15:49 UTC20
      pkgsFor =
b449da897c0fatagen2026-05-27 15:49 UTC21
        system:
b449da897c0fatagen2026-05-27 15:49 UTC22
        import nixpkgs {
b449da897c0fatagen2026-05-27 15:49 UTC23
          inherit system;
b449da897c0fatagen2026-05-27 15:49 UTC24
        };
b449da897c0fatagen2026-05-27 15:49 UTC25
b449da897c0fatagen2026-05-27 15:49 UTC26
      perSystem =
b449da897c0fatagen2026-05-27 15:49 UTC27
        system:
b449da897c0fatagen2026-05-27 15:49 UTC28
        let
b449da897c0fatagen2026-05-27 15:49 UTC29
          pkgs = pkgsFor system;
b449da897c0fatagen2026-05-27 15:49 UTC30
b449da897c0fatagen2026-05-27 15:49 UTC31
          # native libs the audio crates link against
b449da897c0fatagen2026-05-27 15:49 UTC32
          nativeAudioBuildInputs = with pkgs; [
b449da897c0fatagen2026-05-27 15:49 UTC33
            pipewire
b449da897c0fatagen2026-05-27 15:49 UTC34
            pipewire.dev
b449da897c0fatagen2026-05-27 15:49 UTC35
          ];
b449da897c0fatagen2026-05-27 15:49 UTC36
b449da897c0fatagen2026-05-27 15:49 UTC37
          nativeBuildTools = with pkgs; [
b449da897c0fatagen2026-05-27 15:49 UTC38
            pkg-config
b449da897c0fatagen2026-05-27 15:49 UTC39
            clang
b449da897c0fatagen2026-05-27 15:49 UTC40
          ];
b449da897c0fatagen2026-05-27 15:49 UTC41
b449da897c0fatagen2026-05-27 15:49 UTC42
          # system libs iced (wgpu/winit/cosmic-text) compiles + dlopens at runtime.
b449da897c0fatagen2026-05-27 15:49 UTC43
          # wayland-only (x11 feature off); re-add libx11/libxcursor/libxi/libxrandr/libxcb if x11 re-enabled
b449da897c0fatagen2026-05-27 15:49 UTC44
          guiLibs = with pkgs; [
b449da897c0fatagen2026-05-27 15:49 UTC45
            vulkan-loader
b449da897c0fatagen2026-05-27 15:49 UTC46
            libxkbcommon
b449da897c0fatagen2026-05-27 15:49 UTC47
            wayland
b449da897c0fatagen2026-05-27 15:49 UTC48
            libGL
b449da897c0fatagen2026-05-27 15:49 UTC49
            fontconfig
b449da897c0fatagen2026-05-27 15:49 UTC50
          ];
b449da897c0fatagen2026-05-27 15:49 UTC51
b449da897c0fatagen2026-05-27 15:49 UTC52
          commonEnv = {
b449da897c0fatagen2026-05-27 15:49 UTC53
            LIBCLANG_PATH = "${pkgs.libclang.lib}/lib";
b449da897c0fatagen2026-05-27 15:49 UTC54
            PKG_CONFIG_PATH = "${pkgs.pipewire.dev}/lib/pkgconfig";
b449da897c0fatagen2026-05-27 15:49 UTC55
          };
b449da897c0fatagen2026-05-27 15:49 UTC56
        in
b449da897c0fatagen2026-05-27 15:49 UTC57
        {
b449da897c0fatagen2026-05-27 15:49 UTC58
          # nix develop — dev environment
b449da897c0fatagen2026-05-27 15:49 UTC59
          devShell = pkgs.mkShell (
b449da897c0fatagen2026-05-27 15:49 UTC60
            {
b449da897c0fatagen2026-05-27 15:49 UTC61
              name = "headroom-dev";
b449da897c0fatagen2026-05-27 15:49 UTC62
b449da897c0fatagen2026-05-27 15:49 UTC63
              nativeBuildInputs = nativeBuildTools ++ [
b449da897c0fatagen2026-05-27 15:49 UTC64
                pkgs.cargo
b449da897c0fatagen2026-05-27 15:49 UTC65
                pkgs.clippy
b449da897c0fatagen2026-05-27 15:49 UTC66
                pkgs.rust-analyzer
b449da897c0fatagen2026-05-27 15:49 UTC67
                pkgs.rustc
b449da897c0fatagen2026-05-27 15:49 UTC68
                pkgs.rustfmt
b449da897c0fatagen2026-05-27 15:49 UTC69
              ];
b449da897c0fatagen2026-05-27 15:49 UTC70
b449da897c0fatagen2026-05-27 15:49 UTC71
              buildInputs =
b449da897c0fatagen2026-05-27 15:49 UTC72
                nativeAudioBuildInputs
b449da897c0fatagen2026-05-27 15:49 UTC73
                ++ guiLibs
b449da897c0fatagen2026-05-27 15:49 UTC74
                ++ (with pkgs; [
b449da897c0fatagen2026-05-27 15:49 UTC75
                  socat # poke the ipc socket
b449da897c0fatagen2026-05-27 15:49 UTC76
                  jq # pretty-print json
b449da897c0fatagen2026-05-27 15:49 UTC77
                  pipewire # pw-cli, pw-cat, etc.
b449da897c0fatagen2026-05-27 15:49 UTC78
                  wireplumber
b449da897c0fatagen2026-05-27 15:49 UTC79
                ]);
b449da897c0fatagen2026-05-27 15:49 UTC80
b449da897c0fatagen2026-05-27 15:49 UTC81
              shellHook = ''
b449da897c0fatagen2026-05-27 15:49 UTC82
                echo "headroom dev shell — rustc $(rustc --version | cut -d' ' -f2)"
b449da897c0fatagen2026-05-27 15:49 UTC83
                echo "  cargo build / cargo test for iteration."
b449da897c0fatagen2026-05-27 15:49 UTC84
                echo "  nix build  .#headroom  for the packaged binary."
b449da897c0fatagen2026-05-27 15:49 UTC85
                echo "  cargo run -p headroom-gui  for the GUI (needs a display)."
b449da897c0fatagen2026-05-27 15:49 UTC86
                export RUST_BACKTRACE=1
b449da897c0fatagen2026-05-27 15:49 UTC87
                export RUST_LOG=headroom=debug,info
b449da897c0fatagen2026-05-27 15:49 UTC88
                # iced/wgpu dlopen vulkan/wayland/xkbcommon at runtime
b449da897c0fatagen2026-05-27 15:49 UTC89
                export LD_LIBRARY_PATH="${pkgs.lib.makeLibraryPath guiLibs}''${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
b449da897c0fatagen2026-05-27 15:49 UTC90
              '';
b449da897c0fatagen2026-05-27 15:49 UTC91
            }
b449da897c0fatagen2026-05-27 15:49 UTC92
            // commonEnv
b449da897c0fatagen2026-05-27 15:49 UTC93
          );
b449da897c0fatagen2026-05-27 15:49 UTC94
b449da897c0fatagen2026-05-27 15:49 UTC95
          # nix build — packaged daemon + cli
b449da897c0fatagen2026-05-27 15:49 UTC96
          headroom = pkgs.rustPlatform.buildRustPackage (
b449da897c0fatagen2026-05-27 15:49 UTC97
            {
b449da897c0fatagen2026-05-27 15:49 UTC98
              pname = "headroom";
b449da897c0fatagen2026-05-27 15:49 UTC99
              # workspace version (per-crate manifests use version.workspace = true)
b449da897c0fatagen2026-05-27 15:49 UTC100
              version =
b449da897c0fatagen2026-05-27 15:49 UTC101
                (builtins.fromTOML (builtins.readFile ./Cargo.toml)).workspace.package.version
b449da897c0fatagen2026-05-27 15:49 UTC102
                + "-"
b449da897c0fatagen2026-05-27 15:49 UTC103
                + (toString self.lastModifiedDate);
b449da897c0fatagen2026-05-27 15:49 UTC104
b449da897c0fatagen2026-05-27 15:49 UTC105
              src = ./.;
b449da897c0fatagen2026-05-27 15:49 UTC106
b449da897c0fatagen2026-05-27 15:49 UTC107
              cargoLock = {
b449da897c0fatagen2026-05-27 15:49 UTC108
                lockFile = ./Cargo.lock;
b449da897c0fatagen2026-05-27 15:49 UTC109
                # allowBuiltinFetchGit = true;
b449da897c0fatagen2026-05-27 15:49 UTC110
              };
b449da897c0fatagen2026-05-27 15:49 UTC111
b449da897c0fatagen2026-05-27 15:49 UTC112
              nativeBuildInputs = nativeBuildTools;
b449da897c0fatagen2026-05-27 15:49 UTC113
              buildInputs = nativeAudioBuildInputs;
b449da897c0fatagen2026-05-27 15:49 UTC114
b449da897c0fatagen2026-05-27 15:49 UTC115
              # one binary: `headroom` (cli + daemon)
b449da897c0fatagen2026-05-27 15:49 UTC116
              cargoBuildFlags = [
b449da897c0fatagen2026-05-27 15:49 UTC117
                "-p"
b449da897c0fatagen2026-05-27 15:49 UTC118
                "headroom-cli"
b449da897c0fatagen2026-05-27 15:49 UTC119
              ];
b449da897c0fatagen2026-05-27 15:49 UTC120
              doCheck = true;
b449da897c0fatagen2026-05-27 15:49 UTC121
              # exclude headroom-gui from the test sweep — pulls iced's gpu stack, not part of the daemon
b449da897c0fatagen2026-05-27 15:49 UTC122
              cargoTestFlags = [
b449da897c0fatagen2026-05-27 15:49 UTC123
                "--workspace"
b449da897c0fatagen2026-05-27 15:49 UTC124
                "--exclude"
b449da897c0fatagen2026-05-27 15:49 UTC125
                "headroom-gui"
b449da897c0fatagen2026-05-27 15:49 UTC126
              ];
b449da897c0fatagen2026-05-27 15:49 UTC127
b449da897c0fatagen2026-05-27 15:49 UTC128
              # systemd user unit (@bindir@ templated to this derivation's bin, not PATH)
b449da897c0fatagen2026-05-27 15:49 UTC129
              # + canonical profiles under share/headroom/profiles (daemon finds via $XDG_DATA_DIRS)
b449da897c0fatagen2026-05-27 15:49 UTC130
              postInstall = ''
b449da897c0fatagen2026-05-27 15:49 UTC131
                install -Dm644 contrib/systemd/headroom.service \
b449da897c0fatagen2026-05-27 15:49 UTC132
                  "$out/lib/systemd/user/headroom.service"
b449da897c0fatagen2026-05-27 15:49 UTC133
                substituteInPlace "$out/lib/systemd/user/headroom.service" \
b449da897c0fatagen2026-05-27 15:49 UTC134
                  --replace-fail '@bindir@' "$out/bin"
b449da897c0fatagen2026-05-27 15:49 UTC135
b449da897c0fatagen2026-05-27 15:49 UTC136
                mkdir -p "$out/share/headroom/profiles"
b449da897c0fatagen2026-05-27 15:49 UTC137
                cp -r profiles/. "$out/share/headroom/profiles/"
b449da897c0fatagen2026-05-27 15:49 UTC138
              '';
b449da897c0fatagen2026-05-27 15:49 UTC139
b449da897c0fatagen2026-05-27 15:49 UTC140
              meta = with pkgs.lib; {
b449da897c0fatagen2026-05-27 15:49 UTC141
                description = "automatic loudness and per-app volume control (pipewire)";
b449da897c0fatagen2026-05-27 15:49 UTC142
                license = licenses.gpl3Plus;
b449da897c0fatagen2026-05-27 15:49 UTC143
                platforms = platforms.linux;
b449da897c0fatagen2026-05-27 15:49 UTC144
                mainProgram = "headroom";
b449da897c0fatagen2026-05-27 15:49 UTC145
              };
b449da897c0fatagen2026-05-27 15:49 UTC146
            }
b449da897c0fatagen2026-05-27 15:49 UTC147
            // commonEnv
b449da897c0fatagen2026-05-27 15:49 UTC148
          );
b449da897c0fatagen2026-05-27 15:49 UTC149
b449da897c0fatagen2026-05-27 15:49 UTC150
          # `nix build .#headroom-gui` — optional iced GUI monitor.
b449da897c0fatagen2026-05-27 15:49 UTC151
          # separate package so the default build stays graphics-free. iced/wgpu
b449da897c0fatagen2026-05-27 15:49 UTC152
          # dlopen vulkan/libGL/wayland/xkbcommon at runtime → wrap with LD_LIBRARY_PATH.
b449da897c0fatagen2026-05-27 15:49 UTC153
          # also ships the .desktop entry.
b449da897c0fatagen2026-05-27 15:49 UTC154
          headroom-gui = pkgs.rustPlatform.buildRustPackage (
b449da897c0fatagen2026-05-27 15:49 UTC155
            {
b449da897c0fatagen2026-05-27 15:49 UTC156
              pname = "headroom-gui";
b449da897c0fatagen2026-05-27 15:49 UTC157
              version =
b449da897c0fatagen2026-05-27 15:49 UTC158
                (builtins.fromTOML (builtins.readFile ./Cargo.toml)).workspace.package.version
b449da897c0fatagen2026-05-27 15:49 UTC159
                + "-"
b449da897c0fatagen2026-05-27 15:49 UTC160
                + (toString self.lastModifiedDate);
b449da897c0fatagen2026-05-27 15:49 UTC161
b449da897c0fatagen2026-05-27 15:49 UTC162
              src = ./.;
b449da897c0fatagen2026-05-27 15:49 UTC163
b449da897c0fatagen2026-05-27 15:49 UTC164
              cargoLock = {
b449da897c0fatagen2026-05-27 15:49 UTC165
                lockFile = ./Cargo.lock;
b449da897c0fatagen2026-05-27 15:49 UTC166
              };
b449da897c0fatagen2026-05-27 15:49 UTC167
b449da897c0fatagen2026-05-27 15:49 UTC168
              # makeWrapper for the LD_LIBRARY_PATH wrap. gui doesn't link pipewire
b449da897c0fatagen2026-05-27 15:49 UTC169
              # (talks to the daemon over the socket via headroom-client) → no pipewire/clang
b449da897c0fatagen2026-05-27 15:49 UTC170
              nativeBuildInputs = [
b449da897c0fatagen2026-05-27 15:49 UTC171
                pkgs.pkg-config
b449da897c0fatagen2026-05-27 15:49 UTC172
                pkgs.makeWrapper
b449da897c0fatagen2026-05-27 15:49 UTC173
              ];
b449da897c0fatagen2026-05-27 15:49 UTC174
              buildInputs = guiLibs;
b449da897c0fatagen2026-05-27 15:49 UTC175
b449da897c0fatagen2026-05-27 15:49 UTC176
              cargoBuildFlags = [
b449da897c0fatagen2026-05-27 15:49 UTC177
                "-p"
b449da897c0fatagen2026-05-27 15:49 UTC178
                "headroom-gui"
b449da897c0fatagen2026-05-27 15:49 UTC179
              ];
b449da897c0fatagen2026-05-27 15:49 UTC180
              # gui tests drive iced view/update; no display in the sandbox.
b449da897c0fatagen2026-05-27 15:49 UTC181
              # run them via `cargo test -p headroom-gui` in the dev shell instead
b449da897c0fatagen2026-05-27 15:49 UTC182
              doCheck = false;
b449da897c0fatagen2026-05-27 15:49 UTC183
b449da897c0fatagen2026-05-27 15:49 UTC184
              postInstall = ''
b449da897c0fatagen2026-05-27 15:49 UTC185
                install -Dm644 contrib/desktop/headroom-gui.desktop \
b449da897c0fatagen2026-05-27 15:49 UTC186
                  "$out/share/applications/headroom-gui.desktop"
b449da897c0fatagen2026-05-27 15:49 UTC187
                substituteInPlace "$out/share/applications/headroom-gui.desktop" \
b449da897c0fatagen2026-05-27 15:49 UTC188
                  --replace-fail '@bindir@' "$out/bin"
b449da897c0fatagen2026-05-27 15:49 UTC189
              '';
b449da897c0fatagen2026-05-27 15:49 UTC190
b449da897c0fatagen2026-05-27 15:49 UTC191
              postFixup = ''
b449da897c0fatagen2026-05-27 15:49 UTC192
                wrapProgram "$out/bin/headroom-gui" \
b449da897c0fatagen2026-05-27 15:49 UTC193
                  --prefix LD_LIBRARY_PATH : "${pkgs.lib.makeLibraryPath guiLibs}"
b449da897c0fatagen2026-05-27 15:49 UTC194
              '';
b449da897c0fatagen2026-05-27 15:49 UTC195
b449da897c0fatagen2026-05-27 15:49 UTC196
              meta = with pkgs.lib; {
b449da897c0fatagen2026-05-27 15:49 UTC197
                description = "automatic loudness and per-app volume control (pipewire)";
b449da897c0fatagen2026-05-27 15:49 UTC198
                license = licenses.eupl12;
b449da897c0fatagen2026-05-27 15:49 UTC199
                platforms = platforms.linux;
b449da897c0fatagen2026-05-27 15:49 UTC200
                mainProgram = "headroom-gui";
b449da897c0fatagen2026-05-27 15:49 UTC201
              };
b449da897c0fatagen2026-05-27 15:49 UTC202
            }
b449da897c0fatagen2026-05-27 15:49 UTC203
            // commonEnv
b449da897c0fatagen2026-05-27 15:49 UTC204
          );
b449da897c0fatagen2026-05-27 15:49 UTC205
        };
b449da897c0fatagen2026-05-27 15:49 UTC206
    in
b449da897c0fatagen2026-05-27 15:49 UTC207
    {
b449da897c0fatagen2026-05-27 15:49 UTC208
      devShells = forAllSystems (system: {
b449da897c0fatagen2026-05-27 15:49 UTC209
        default = (perSystem system).devShell;
b449da897c0fatagen2026-05-27 15:49 UTC210
      });
b449da897c0fatagen2026-05-27 15:49 UTC211
b449da897c0fatagen2026-05-27 15:49 UTC212
      packages = forAllSystems (
b449da897c0fatagen2026-05-27 15:49 UTC213
        system:
b449da897c0fatagen2026-05-27 15:49 UTC214
        let
b449da897c0fatagen2026-05-27 15:49 UTC215
          ps = perSystem system;
b449da897c0fatagen2026-05-27 15:49 UTC216
        in
b449da897c0fatagen2026-05-27 15:49 UTC217
        rec {
b449da897c0fatagen2026-05-27 15:49 UTC218
          default = headroom;
b449da897c0fatagen2026-05-27 15:49 UTC219
          headroom = ps.headroom;
b449da897c0fatagen2026-05-27 15:49 UTC220
          headroom-gui = ps.headroom-gui;
b449da897c0fatagen2026-05-27 15:49 UTC221
        }
b449da897c0fatagen2026-05-27 15:49 UTC222
      );
b449da897c0fatagen2026-05-27 15:49 UTC223
b449da897c0fatagen2026-05-27 15:49 UTC224
      formatter = forAllSystems (system: (pkgsFor system).nixpkgs-fmt);
b449da897c0fatagen2026-05-27 15:49 UTC225
b449da897c0fatagen2026-05-27 15:49 UTC226
      # System-independent outputs — modules.
b449da897c0fatagen2026-05-27 15:49 UTC227
      nixosModules.default = import ./nix/nixos-module.nix self;
b449da897c0fatagen2026-05-27 15:49 UTC228
    };
b449da897c0fatagen2026-05-27 15:49 UTC229
}