nixGL icon indicating copy to clipboard operation
nixGL copied to clipboard

Perfecting NixGL Wrappers for Home-Manager Use

Open RicSanOP opened this issue 3 months ago • 4 comments

Hello Everyone,

I am new to using nix and home-manager and have been enjoying tinkering around with functional package management. I have reached the point where I can more or less read nix code (like the wrappers in #114). I have gone through the process of setting up home-manager on a non-nixOS distro (Pop_OS! in my case) and have rewritten @ntsanov wrapper code from #114 into the following functions

{ pkgs }:

{
  # This nix file contains helper functions for wrapping other
  # graphical nix packages with nixGL calls depending on the
  # graphics library and graphics chip of choice
  nixIntelWrap = glib: pkg:
  let
    gpkg = "nix${glib}Intel";
    bins = "${pkg}/bin";
  in
  pkgs.buildEnv {
    name = "${gpkg}-${pkg.name}";
    paths =
      [ pkg ] ++
      (map
        (bin: pkgs.hiPrio (
	  pkgs.writeShellScriptBin bin ''
exec "${pkgs.nixgl.${gpkg}}/bin/${gpkg}" "${bins}/${bin}" "$@"
	  ''
	))
	(builtins.attrNames (builtins.readDir bins))
      );
  };
  nixNvidiaWrap = glib: ndv: pkg:
  let
    gpkg = "nix${glib}Nvidia";
    gcmd = "${gpkg}-${ndv}";
    bins = "${pkg}/bin";
  in
  pkgs.buildEnv {
    name = "${gpkg}-${pkg.name}";
    paths =
      [ pkg ] ++
      (map
        (bin: pkgs.hiPrio (
	  pkgs.writeShellScriptBin bin ''
export __NV_PRIME_RENDER_OFFLOAD=1 
export __GLX_VENDOR_LIBRARY_NAME=nvidia
exec "${pkgs.nixgl.auto.${gpkg}}/bin/${gcmd}" "${bins}/${bin}" "$@"
	  ''
	))
	(builtins.attrNames (builtins.readDir bins))
      );
  };
}

Here are some successful usages of these wrapper functions in my home.nix file:

home.packages = [
    # # Adds the 'hello' command to your environment. It prints a friendly
    # # "Hello, world!" when run.
    # pkgs.hello

    # # It is sometimes useful to fine-tune packages, for example, by applying
    # # overrides. You can do that directly here, just don't forget the
    # # parentheses. Maybe you want to install Nerd Fonts with a limited number of
    # # fonts?
    # (pkgs.nerdfonts.override { fonts = [ "FantasqueSansMono" ]; })

    # # You can also create simple shell scripts directly inside your
    # # configuration. For example, this adds a command 'my-hello' to your
    # # environment:
    # (pkgs.writeShellScriptBin "my-hello" ''
    #   echo "Hello, ${config.home.username}!"
    # '')

    # nixGL packages for running OpenGL and Vulkan nix packages
    # using either an Nvidia driver or Intel driver (Nvidia is default)
    pkgs.nixgl.auto.nixGLNvidia
    pkgs.nixgl.auto.nixVulkanNvidia
    pkgs.nixgl.nixGLIntel
    pkgs.nixgl.nixVulkanIntel
    
    # terminal-shell-editor environment
    #(nixgl.nixNvidiaWrap "GL" nvidiaDriverVersion pkgs.wezterm)
    #(nixgl.nixNvidiaWrap "GL" nvidiaDriverVersion pkgs.alacritty)
    pkgs.zsh
    pkgs.neovim

    # setup podman for container workloads
    pkgs.podman
    pkgs.docker-compose
    pkgs.podman-compose

    # productivity and workflow packages
    (nixgl.nixNvidiaWrap "GL" nvidiaDriverVersion pkgs.vivaldi)
    (nixgl.nixNvidiaWrap "GL" nvidiaDriverVersion pkgs.obsidian)
  ];

  programs.wezterm = {
    enable = true;
    package = nixgl.nixNvidiaWrap "GL" nvidiaDriverVersion pkgs.wezterm;
  };

  programs.alacritty = {
    enable = true;
    package = nixgl.nixNvidiaWrap "GL" nvidiaDriverVersion pkgs.alacritty;
    settings = {
    };
  };

Now as you may have noticed, the nixgl wrap around pkgs.alacritty and pkgs.wezterm have been commented out from home.packages as they are required in their respective programs.__TERMINAL__.package attributes. Providing the nixgl wrapped derivation has worked fine for wezterm, but unfortunately hasn't worked for alacritty due to the following error:

error:
       … while evaluating a branch condition

         at /nix/store/adkf0aw7d4yfxspb1h23zkhxlskidfpi-source/lib/lists.nix:56:9:

           55|       fold' = n:
           56|         if n == len
             |         ^
           57|         then nul

       … while calling the 'length' builtin

         at /nix/store/adkf0aw7d4yfxspb1h23zkhxlskidfpi-source/lib/lists.nix:54:13:

           53|     let
           54|       len = length list;
             |             ^
           55|       fold' = n:

       (stack trace truncated; use '--show-trace' to show the full trace)

       error: attribute 'version' missing

       at /nix/store/ddnh5dcx1z38990c7h3fzzcy1vq7g9la-source/modules/programs/alacritty.nix:7:32:

            6|   cfg = config.programs.alacritty;
            7|   useToml = lib.versionAtLeast cfg.package.version "0.13";
             |                                ^
            8|   tomlFormat = pkgs.formats.toml { };

It is clear that the wrapper function I use somehow loses the version attribute which is set in nixpkgs at https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/terminal-emulators/alacritty/default.nix and referenced in home-manager at https://github.com/nix-community/home-manager/blob/master/modules/programs/alacritty.nix as can be seen in the error line useToml = lib.versionAtLeast cfg.package.version "0.13";. I came to understand this after playing around with the builtins.trace function and seeing that the wrapped output did not have a version parameter.

Even though I understand the issue, I am very much at a loss on how to re-add the version attribute to the nixgl wrapped derivation. Even if a hacky, I would deeply appreciate any help on navigating this issue and getting the nixgl wrapped version of alacritty to work with home-manager. Thank you to any and all in advance.

RicSanOP avatar Mar 13 '24 19:03 RicSanOP