From de92ec7debb33d4ff21371e2b2e51ca424aa2d92 Mon Sep 17 00:00:00 2001 From: Michael Vogel Date: Wed, 24 Apr 2024 10:12:03 +0000 Subject: [PATCH] target.genericLinux.nixgl: Add module The option allows packages to be wrapped by nixgl in order to make GUI applications work when installed with home-manager It also adds a wrapper to individually wrap packages --- modules/misc/nixgl.nix | 115 +++++++++++++++++++++++++++++++++++++++++ tests/default.nix | 1 + 2 files changed, 116 insertions(+) create mode 100644 modules/misc/nixgl.nix diff --git a/modules/misc/nixgl.nix b/modules/misc/nixgl.nix new file mode 100644 index 00000000..6a45ae87 --- /dev/null +++ b/modules/misc/nixgl.nix @@ -0,0 +1,115 @@ +{ config, pkgs, lib, ... }: + +let + cfg = config.targets.genericLinux.nixgl; + + # Expects a packageConfiguration hashset + # Adapted from https://nixos.wiki/wiki/Nix_Cookbook + wrapWithNixGL = pkgConfig: + (let + binary = if (builtins.hasAttr "binary" pkgConfig) then + pkgConfig.binary + else + null; + package = pkgConfig.package; + + bin = if binary == null then package.pname else binary; + nixGL = import cfg.src { inherit pkgs; }; + wrapperPkg = lib.attrsets.getAttrFromPath cfg.wrapperPkgPath nixGL; + wrapperBinPath = "${wrapperPkg}/bin/${cfg.wrapperBinName}"; + in pkgs.runCommand "nixgl-${package.pname}" { + buildInputs = [ pkgs.makeWrapper ]; + } '' + mkdir $out + # Link every top-level folder from pkgs.hello to our new target + ln -s ${package}/* $out + # Except the bin folder + rm $out/bin + mkdir $out/bin + # We create the bin folder ourselves and link every binary in it + ln -s ${package}/bin/* $out/bin + # Except the target binary + rm $out/bin/${bin} + # Because we create this ourself, by creating a wrapper + makeWrapper ${wrapperBinPath} $out/bin/${bin} \ + --add-flags ${package}/bin/${bin} + ''); + packageConfiguration = with lib; + types.submodule { + options = { + binary = mkOption { + type = types.nullOr types.str; + example = "alacritty"; + default = null; + description = '' + Name of the binary in bin/ of the package. + By default this uses `package.pname`. + ''; + }; + package = mkOption { + type = types.package; + example = "pkgs.alacritty"; + description = '' + The package to be wrapped. + It's expected to have a `pname` attribute. + ''; + }; + }; + }; +in { + meta.maintainers = with lib.maintainers; [ michaelCTS ]; + + options.targets.genericLinux.nixgl = { + + src = lib.mkOption { + type = lib.types.package; + example = '' + pkgs.fetchFromGithub { + owner = "nix-community"; + repo = "nixGL"; + rev = "v1.3"; + hash = "SOMEHASH-HERE"; + } + ''; + description = '' + Path to a downloaded source of nixGL. + You can download the nixGL version of your choice and point to it here. + ''; + }; + + wrapperBinName = lib.mkOption { + type = lib.types.str; + example = "nixGL"; + default = "nixGL"; + description = + "Name of the nixGL binary to be called from within the wrapper package"; + }; + + wrapperPkgPath = lib.mkOption { + type = lib.types.listOf lib.types.str; + example = [ "auto" "nixGLNvidia" ]; + default = [ "auto" "nixGLDefault" ]; + description = "Attribute path within `src` attrset to the nixGL package"; + }; + + packages = lib.mkOption { + type = lib.types.listOf packageConfiguration; + default = [ ]; + example = "[{ package = pkgs.alacritty; }]"; + description = '' + List of packages that will be wrapped with nixGL in order to be able to use nixgl. + Without the wrapper, graphical applications cannot access nixgl and thus have no + graphical acceleration. + ''; + }; + + }; + + config = { + lib.nixGl.wrap = wrapWithNixGL; + home.packages = builtins.map config.lib.nixGl.wrap + config.targets.genericLinux.nixgl.packages; + }; + +} + diff --git a/tests/default.nix b/tests/default.nix index 4b7b6ebf..49fa18f9 100644 --- a/tests/default.nix +++ b/tests/default.nix @@ -49,6 +49,7 @@ in import nmtSrc { ./modules/misc/fontconfig ./modules/misc/manual ./modules/misc/nix + ./modules/misc/nixgl ./modules/misc/specialisation ./modules/programs/aerc ./modules/programs/alacritty