Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Easy automagic patching of applications #140

Open
piegamesde opened this issue Aug 7, 2023 · 2 comments
Open

Easy automagic patching of applications #140

piegamesde opened this issue Aug 7, 2023 · 2 comments

Comments

@piegamesde
Copy link

I want to patch all my applications that require OpenGL to automatically start within the NixGL wrapper. I think that applying it should be as easy as providing a list of packages to be patched. This could for example be done by simply injecting a hook into the nativeBuildInputs via overrideAttrs which then does all of the work.

This is similar to #16 (comment), but deserves its own issue IMO.

@lierdakil
Copy link

lierdakil commented Feb 18, 2024

I'm using the following overlay:

final: prev:
let
  wrapGeneric = wrapper: pkg: { additionalBinaries ? [] }:
    let
      mainPrograms = if builtins.hasAttr "mainProgram" pkg.meta then [ pkg.meta.mainProgram ] else [];
      bins = mainPrograms ++ additionalBinaries;
    in if builtins.length bins == 0
      then builtins.throw "No mainProgram defined and no additionalBinaries for ${pkg.name}"
      else final.symlinkJoin {
        name = "${pkg.name}-with-nixgl";
        paths = let
          wrapBin = bin: final.writeShellScriptBin bin ''
            exec ${wrapper} ${pkg}/bin/${bin} "$@"
          ''; in (map wrapBin bins) ++ [ pkg ];
        inherit (pkg) meta;
      };
  wrapNixGL = wrapGeneric "${final.nixgl.nixGLIntel}/bin/nixGLIntel";
  wrapVulkanGL = wrapGeneric "${final.nixgl.nixVulkanIntel}/bin/nixVulkanIntel ${final.nixgl.nixGLIntel}/bin/nixGLIntel";
  go = builtins.mapAttrs (n: wrapNixGL prev.${n});
  goVulkan = builtins.mapAttrs (n: wrapVulkanGL prev.${n});
in go {
  # things work fine when meta.mainProgram is specified
  firefox = {};
  # when it isn't, need to specify the binaries to wrap
  anydesk.additionalBinaries = [ "anydesk" ];
} // goVulkan { # adds vulkan env in addition to gl (but I didn't test this extensively)
  steam = {};
}

If you wanted always wrap all binaries, you could try getting the list of files in ${pkg}/bin/, but it doesn't seem like the best idea necessarily.

You'll need to tweak wrapper paths if you're targeting Nvidia proprietary drivers.

In theory, you could overrideAttrs to add wrapProgram to postFixup directly, but nixGL only exposes wrapper scripts, so I went with wrapper scripts and symlinkJoin here. Also, cache is invalidated by overrideAttrs, so you'd end up rebuilding things like firefox and chromium, which isn't fun.

@williamvds
Copy link

I started with a similar approach to the above - trying to work out the main program and wrapping just that.

But I've found wrapping all executables is useful, because apps like Sway provide auxiliary binaries which are required.

My new approach involves symbolic linking all the package's directories, then wrapping all the files in bin/

{ pkgs, lib, ... }:

pkg:
pkgs.stdenv.mkDerivation {
  name = "${pkg.name}-nixgl-wrapped";
  unpackPhase = "true";
  subject = pkg;
  buildPhase = ''
    mkdir $out

    for d in $subject/*/; do
      ln -s --target-directory=$out $d
    done

    rm $out/bin
    mkdir $out/bin
    for f in $subject/bin/*; do
      wrapper="$out/bin/$(basename "$f")"

      echo "#! @shell@ -e" > "$wrapper"
      echo "${pkgs.nixgl.nixGLIntel}/bin/nixGLIntel $f \"\$@\"" >> "$wrapper"

      chmod +x $wrapper
      substituteAllInPlace $wrapper
    done
  '';
}

Import this function and call it with a package to wrap nixGLIntel around it.

Issues:

  • wrapping libexec executables?
  • fix references to to binaries in the other directories, particularly .desktop files. Maybe copy everything from the original package?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants