This re-invokes the original package (whose path you need to know of course) but overrides the call to
rustPlatform.buildRustPackage
such that it modifies the args before passing them along.
Packages created with callPackage
automatically get a .override
function (technically speaking, a functor, an attribute set which behaves like a function thanks to its __functor
attribute), since lib.callPackageWith
uses lib.makeOverridable
to make packages overridable.
nix-repl> pkgs.ffsend.override
{ __functionArgs = { ... }; __functor = «lambda @ /nix/store/gzf4zwcakda1nykn6h0avh45xhjhvsz4-source/lib/trivial.nix:440:19»; }
Since lib.callPackageWith
takes either a function or a path,
callPackageWith = autoArgs: fn: args:
let
f = if isFunction fn then fn else import fn;
one can use super.callPackage super.ffsend.override
instead of super.callPackage <nixpkgs/pkgs/tools/misc/ffsend>
. This avoids the lookup path impurity and allows overlaying packages that don’t have their own dedicated file (e.g. pkgs.xorg.xorgserver
) or come from a flake.
I (ab)use this trick significantly when patching out /bin/sh
. For example, tectonic can be overlayed like
final: prev:
{
tectonic-unwrapped = final.callPackage prev.tectonic-unwrapped.override {
rustPlatform = final.rustPlatform // {
buildRustPackage = args: final.rustPlatform.buildRustPackage (args // {
src = final.fetchFromGitHub {
owner = "tectonic-typesetting";
repo = "tectonic";
rev = "78fd97716ee111861bd981a45e6816589d16f504";
sha256 = "sha256-pKx2fzBllkv3fzUfhv9qKlPqD4JKdEN74+gsLbmwZ/o=";
};
cargoHash = "sha256-BcVepSoFogh/OU0DoQNnT8X9bNc74rMDT+3zelmfwkY=";
# https://github.com/NixOS/nixpkgs/pull/291770
buildFeatures = [ "external-harfbuzz" ];
});
};
};
}