Nix-shell and patching a package

I have a custom development environment where nix-shell is used to provide the build inputs.

# shell.nix
{ pkgs ? import <nixpkgs> {} }:
  pkgs.mkShell {
    # nativeBuildInputs is usually what you want -- tools you need to run
    nativeBuildInputs = with pkgs.buildPackages; [ rustup qemu uefi-run ];
}

with one of the build inputs, QEMU. I need to apply a patch to modify some of its code so it can be more tightly integrated with my build environment.

Whats the best way of going about this? Only thing I can find is how to write a custom package and modify its source code with applyPatch but I cant find anything on how to apply it to a nix-shell environment.

If you look at the derivation for qemu on GitHub you will see it comes with a section for patches:

So I’d say my first idea would be this: try to add your patch to that list of patches. One way of doing this is to define your own qemu in a let .. in block which you put before calling mkShell and override its attribute set using the overrideAttrs function. Then you use your newly defined version of qemu in your shell.

So think something like this:

let
   qemu-with-patches = pkgs.qemu.overrideAttrs (finalAttrs: previousAttrs: {
      patches = previousAttrs.patches ++ [ put paths to your patches here ]; 
   });
in

A nice explanation of this pattern can be found in Overriding | nixpkgs under the section for <pkg>.overrideAttrs.

Btw. if it doesn’t work directly, I haven’t tested your thing. Maybe it needs some tweaking. I just wrote it down quickly :slight_smile:

1 Like

Not quite what was needed but this is atleast forcing QEMU to rebuild from source when enter the environment. No idea if its gonna work but my shitty laptop is gonna ensure it will be multiple hours until i do XD

# shell.nix
{ pkgs ? import <nixpkgs> { overlays = [ (import ./QEMU/overlay.nix) ]; } }:
  
  pkgs.mkShell {
    # nativeBuildInputs is usually what you want -- tools you need to run
    nativeBuildInputs = with pkgs.buildPackages; [ rustup patched-qemu uefi-run ];
}
# ./QEMU/Overlay.nix
final: prev: {
      patched-qemu = prev.qemu.overrideAttrs (previousAttrs: {
        patches = previousAttrs.patches ++ [ 
          ./IO-Exit.patch 
        ];
      });
}

I’d be interested to know if you find a better way for doing the same thing.

Let’s hope it works though! Let me know how it went :slight_smile:

Everything worked correctly and there are no rebuilds on enter the environment.

I have a question about patching firefox. I came here following this reddit question and tried above solution. I have a version of above solution working in /etc/nixos/configuration.nix for glusterfs, but not for firefox, it is nixpkgs.overlays = [(import ./overlays_xdej/gluster.nix) (import ./overlays_xdej/firefox.nix)];environment.systemPackages = with pkgs; [glusterfs firefox] with gluster.nix containing:

self: super:
{
glusterfs = super.glusterfs.overrideAttrs (old: {
patches = (old.patches or []) ++ [
  ./glusterfsd-10.0_force_bind_to_10.54.4.1.patch
];
});
}

I tried with firefox.nix containing:

self: super:
{   
firefox = super.firefox.overrideAttrs (old: { 
patches = (old.patches or []) ++ [
  ./firefox.patch
];
});
}

But my patch is ignored and firefox is not rebuild from sources by nixos-rebuild -K build. How can I run a patched version of firefox, with nix-shell, or at least from /etc/nixos/configuration.nix ?