Nixpkgs/Patching Nixpkgs: Difference between revisions

Perchun (talk | contribs)
Add multiple other options to choose from
Perchun (talk | contribs)
m nixpkgs -> Nixpkgs
 
Line 1: Line 1:
Sometimes it may be required to patch a copy of nixpkgs directly, rather than use an overlay to patch an individual package. One scenario of where this might happen is if nixpkgs doesn't contain a change you need, but you find some
Sometimes it may be required to patch a copy of Nixpkgs directly, rather than use an overlay to patch an individual package. One scenario of where this might happen is if Nixpkgs doesn't contain a change you need, but you find some
existing PR that has yet to be merged, and so want to leverage those changes prior to them being merged.
existing PR that has yet to be merged, and so want to leverage those changes prior to them being merged.


There are many ways to patch nixpkgs, each with its own advantages and disadvantages. We will go through the most popular ones:
There are many ways to patch Nixpkgs, each with its own advantages and disadvantages. We will go through the most popular ones:
{| class="wikitable" style="text-align: center; width: 500px;"
{| class="wikitable" style="text-align: center; width: 500px;"
|-
|-
Line 21: Line 21:


For the sake of example, let's say you are using the software package [https://ghidra-sre.org/ Ghidra], and the latest version available on
For the sake of example, let's say you are using the software package [https://ghidra-sre.org/ Ghidra], and the latest version available on
nixpkgs unstable is [https://search.nixos.org/packages?channel=unstable&from=0&size=50&sort=relevance&type=packages&query=ghidra 11.1.2].
Nixpkgs unstable is [https://search.nixos.org/packages?channel=unstable&from=0&size=50&sort=relevance&type=packages&query=ghidra 11.1.2].
You know that the Ghidra developers have recently released 11.2, and want to use it before it's in nixpkgs. You could try to create an overlay and manually update the package, but maybe in the process, you realize it is not a
You know that the Ghidra developers have recently released 11.2, and want to use it before it's in Nixpkgs. You could try to create an overlay and manually update the package, but maybe in the process, you realize it is not a
trivial update. You may find there is already a pending PR to nixpkgs with the updated version and
trivial update. You may find there is already a pending PR to Nixpkgs with the updated version and
changes you want, such as [https://github.com/NixOS/nixpkgs/pull/344917 this PR]. If you didn't
changes you want, such as [https://github.com/NixOS/nixpkgs/pull/344917 this PR]. If you didn't
want to wait for that PR to be merged into nixpkgs, you could apply the PR patch directly to your nixpkgs instead. There are, of course, other reasons you may wish to use a patched nixpkgs, and the method applies to any of those cases.
want to wait for that PR to be merged into Nixpkgs, you could apply the PR patch directly to your Nixpkgs instead. There are, of course, other reasons you may wish to use a patched Nixpkgs, and the method applies to any of those cases.


To get your patch, you will usually need to find a list of commits from the desired PR and fetch them. Try to avoid fetching something like https://github.com/NixOS/nixpkgs/pull/344917.diff, as it can change if the PR is still open. If you are fetching from GitHub, don't forget to add <code>?full_index=1</code> at the end of the URL for better reproducibility.
To get your patch, you will usually need to find a list of commits from the desired PR and fetch them. Try to avoid fetching something like https://github.com/NixOS/nixpkgs/pull/344917.diff, as it can change if the PR is still open. If you are fetching from GitHub, don't forget to add <code>?full_index=1</code> at the end of the URL for better reproducibility.
Line 50: Line 50:
=== Using <code>[https://github.com/NixOS/nixpkgs/blob/f6e07eb0e1e42c38f8e0b6ffc221b7bf73bece4b/pkgs/build-support/trivial-builders/default.nix#L981 applyPatches]</code> function ===
=== Using <code>[https://github.com/NixOS/nixpkgs/blob/f6e07eb0e1e42c38f8e0b6ffc221b7bf73bece4b/pkgs/build-support/trivial-builders/default.nix#L981 applyPatches]</code> function ===


<code>applyPatches</code> is a nixpkgs function that applies a list of patches to a source directory. Internally, it just creates a new derivation via <code>stdenv.mkDerivation</code> and passes all of the patches to the usual <code>[https://github.com/NixOS/nixpkgs/blob/12c894cb74171bcec130756cc0f77720fca6587d/pkgs/stdenv/generic/setup.sh#L1371-L1404 patchPhase]</code>.
<code>applyPatches</code> is a Nixpkgs function that applies a list of patches to a source directory. Internally, it just creates a new derivation via <code>stdenv.mkDerivation</code> and passes all of the patches to the usual <code>[https://github.com/NixOS/nixpkgs/blob/12c894cb74171bcec130756cc0f77720fca6587d/pkgs/stdenv/generic/setup.sh#L1371-L1404 patchPhase]</code>.


<syntaxhighlight lang="nix">
<syntaxhighlight lang="nix">
let
let
   # to access the `applyPatches` function, you will need
   # to access the `applyPatches` function, you will need
   # to import unpatched nixpkgs first
   # to import unpatched Nixpkgs first
   pkgs = import <nixpkgs> {
   pkgs = import <nixpkgs> {
     # with flakes, you may also need to hardcode the system
     # with flakes, you may also need to hardcode the system
Line 75: Line 75:
</syntaxhighlight>
</syntaxhighlight>


In the above example, we create a derivation with the patch applied, called <code>nixpkgs-344917-drv</code>. Pay attention, we take the <code>src</code> attribute to get back the original (unpatched) nixpkgs. We then import that new derivation, which we assign to <code>nixpkgs-344917</code>. Now we can use <code>nixpkgs-344917</code> to access the Ghidra 11.2 package, as well as any other packages normally available in nixpkgs.
In the above example, we create a derivation with the patch applied, called <code>nixpkgs-344917-drv</code>. Pay attention, we take the <code>src</code> attribute to get back the original (unpatched) Nixpkgs. We then import that new derivation, which we assign to <code>nixpkgs-344917</code>. Now we can use <code>nixpkgs-344917</code> to access the Ghidra 11.2 package, as well as any other packages normally available in Nixpkgs.


=== Using [https://github.com/gepbird/nixpkgs-patcher nixpkgs-patcher] ===
=== Using [https://github.com/gepbird/nixpkgs-patcher nixpkgs-patcher] ===
Line 113: Line 113:
=== Using [https://github.com/katrinafyi/nix-patcher nix-patcher] ===
=== Using [https://github.com/katrinafyi/nix-patcher nix-patcher] ===


nix-patcher is a script that automatically gets a list of patches from your <code>flake.nix</code> and applies them to your nixpkgs fork sequentially.
nix-patcher is a script that automatically gets a list of patches from your <code>flake.nix</code> and applies them to your Nixpkgs fork sequentially.


<syntaxhighlight lang="nix"># flake.nix
<syntaxhighlight lang="nix"># flake.nix
Line 150: Line 150:
</syntaxhighlight>
</syntaxhighlight>


Very similar to [https://wiki.nixos.org/wiki/Nixpkgs/Patching_Nixpkgs#Using_nix-patcher nix-patcher], it maintains a fork of nixpkgs and applies the patches on it sequentially. The main difference is that it doesn't operate on patch files, but runs <code>[https://git-scm.com/docs/git-cherry-pick git cherry-pick]</code> directly through GitHub API. This is a huge advantage, since Git can automatically rebase commits instead of forcing you to do that.
Very similar to [https://wiki.nixos.org/wiki/Nixpkgs/Patching_Nixpkgs#Using_nix-patcher nix-patcher], it maintains a fork of Nixpkgs and applies the patches on it sequentially. The main difference is that it doesn't operate on patch files, but runs <code>[https://git-scm.com/docs/git-cherry-pick git cherry-pick]</code> directly through GitHub API. This is a huge advantage, since Git can automatically rebase commits instead of forcing you to do that.


== Resources ==
== Resources ==