How to use a modified library in a flake configuration?

Greetings.

I am struggling to find documentation which could help me achieve my goal. My wish is to play around with a bs2b audio plugin’s code and see how much I could improve it.

I want to replace the nixpkgs’ version of libbs2b with the one modified by me. How do I do this?

So far, I understand, that I have to:

  1. create a repository for the hacked variant;
  2. write a flake describing the above repository ( how? ) ;
  3. include the above flake in my system configuration flake ( I think I could figure this one out myself ) .

Has anyone attempted this kind of experiment before me?

You don’t have to do this separately from your system config, though creating a separate flake repository is nice if you want to allow others to try it out :slight_smile:

You’d want to create an overlay on top of nixpkgs that replaces the library with your implementation. If you haven’t come across them, overlays are basically functions that are given a nixpkgs, and allow you to modify this nixpkgs, before it is used in your system.

Flakes actually have support for these, so your flake containing libbs2b could look something like this:

{
  outputs = { nixpkgs, ... }: {
    overlay = final: prev: {
      # `prev` refers to nixpkgs *before* this overlay was applied; so
      # we can use it to provide our `callPackage`, which in turn will
      # automatically provide args you ask for in libbs2b.nix.
      libbs2b = prev.callPackage ./path/to/libbs2b.nix { };
    };
  };
}

Depending on your exact use case, it might make sense to specify some of the other flake outputs, too.

You could then use this overlay in a downstream flake like so:

{
  outputs = { nixpkgs, libbs2b, ... }:
    let overlays = [ libbs2b.overlay ];
    in {
      nixosConfigurations = {
        hostname = let
          system = "<arch>";
          pkgs = import nixpkgs { inherit overlays system; };
        in pkgs.lib.nixosSystem { modules = [ ./some/config.nix ]; };
      };
    };
}

Everything referring to nixpkgs’ libbs2b should then refer to your custom libbs2b.

If you wanted to do it all in one flake, you could just put the overlay output in the system flake, and use the self input (which refers to the current flake) instead of libbs2b.

Thank you for your reply. I apologize it took me this long to respond; I had some personal issues to take care of.

I do not understand nix language well enough to use the overlay properly. I ended up forking nixpkgs and rewriting the libbs2b/default.nix to point directly to the hacked library archive. I am still struggling to make it pure, but at least I got the effect I wanted. Here is the current scope of changes I made:

  #src = fetchurl {
  #  url = "mirror://sourceforge/bs2b/${pname}-${version}.tar.bz2";
  #  sha256 = "0vz442kkjn2h0dlxppzi4m5zx8qfyrivq581n06xzvnyxi5rg6a7";
  #};
  
  # src = /home/marek/Git/system/libbs2b-3.1.0-hack.tar.gz ;
  
  src = fetchurl {
    url = "https://github.com/Obikawa/nixpkgs/blob/3e36fb7de6c0fac78810b96140724c59410273a8/pkgs/development/libraries/audio/libbs2b/libbs2b-3.1.0-hack.tar";
    sha256 = "F7ivJH4UweXPKlNsYVygCSHKWyAZex6FGZ2x1L1uZwM=";
  };
  
  unpackPhase = ''
    cp $src libbs2b.tar
    tar -xf libbs2b.tar
  '' ;

I think you could do it like so:

{
  inputs = {
    libbs2b = {
      # Assuming you cloned libbs2b there
      url = "/home/marek/Git/system/libbs2b/";
      flake = false;
    };
  };

  outputs = { nixpkgs, libbs2b, ... }:
    let
      overlays = [
        (final: prev: {
          libbs2b = prev.libbs2b.overrideAttrs (old: {
            src = libbs2b;
          });
        })
      ];

    in {
      nixosConfigurations = {
        hostname = let
          system = "x86_64-linux";
          pkgs = import nixpkgs { inherit overlays system; };
        in pkgs.lib.nixosSystem {
          # <snip>
        };
      };
    };
}

I might be wrong, but I thought inputs with flake = false act like normal paths. It’s not documented in the wiki, though.

If not, you would need to create a flake for libbs2b in your clone
of that project, putting the overlay in there and depending on it like
a normal flake. Something like this:

{
  outputs = { nixpkgs, ... }: {
    overlay = final: prev: {
      libbs2b = prev.libbs2b.overrideAttrs (old: {
        src = ./.;
      });
    };
  };
}

And then using it like sketched in my original comment.