Wrapping an executable dependency that a package uses

I wish to wrap an executable of package B when it is being used in another package A.
When run, package A calls an executable in ${lib.getBin pkgB}.
I would like to have it execute another command first and set some environment variables, before calling that executable.

I know that I likely need to override package A to accomplish this, I also know of the makeWrapper script, but I am not quite sure how to use it and where.
Do I also need to override package B? Or can I get away with overriding the command of package B inside package A?

self: super: {
  pkgA.override {
    pkgB = // what to do here? overrideAttrs maybe?
  };
};

(Specifically I want to wrap the java executable in the minecraft package to make it always run on my nvidia graphics card, but I am not sure if that’s important for the question.)

I did an example of this earlier using makeWrapper: https://github.com/NixOS/nixpkgs/pull/128516/commits/8fc5a7f07b04f3894eae856ed0bfadabbb359d9a

In your overlay, you could just modify package B, and then all references to it would be fixed. However, this may cause a lot of rebuilds, and overriding just packageA might be easier on your machine.d

1 Like

Thanks a lot for your answer.

The change should only affect the instance of package B that is being used in package A. Changing it elsewhere would probably break things. (I don’t think I wanna run every instance of the JVM on my dedicated GPU, haha)

I have wound up with this, but I haven’t gotten around to testing it yet:

  primecraft = pkgs.minecraft.override {
    jre = pkgs.jre.overrideAttrs (old: {
      nativeBuildInputs = old.nativeBuildInputs ++ [ pkgs.makeWrapper pkgs.primus ];
      postFixup = ''
        wrapProgram $out/bin/java \
          --set vblank_mode 0
          --run primusrun
      '';
    });
  };

I am not quite sure if this will work tho. It isn’t exactly an overlay. I have seen people use .override on packages before even without creating one. Also I am not sure if the postFixup hook will be ran without additional config.
My hope here is that it will create a new package of the original with the changes only applied to it.

It is late now tho. I will test this tomorrow.