Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 115 additions & 0 deletions modules/misc/nixgl.nix
Original file line number Diff line number Diff line change
@@ -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.
'';
};
};

@rycee rycee Apr 27, 2024

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can just set the binary option directly in the submodule:

Suggested change
};
};
config = {
binary = mkOptionDefault (config.package.meta.mainProgram or getName config.package);
};

Can then remove allowing null values.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not able to get this to work. It says attribute "package" missing. I tried binary = mkOptionDefault (config: (config.package.meta.mainProgram or getName config.package)); hoping the function would be evaluated, but it doesn't.

};
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 {
Comment thread
michaelCTS marked this conversation as resolved.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the binary ever called something other than nixGL?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, seems like nixGLNvidia, nixGLNvidiaBumblebee, and others exist.

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;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the paths are stable in nixGL then perhaps this could be enum [ "nixGLDefault" "nixGLNvidia" "nixGLNvidiaBumblebee" "nixGLIntel" ]? The module can know the corresponding attribute path.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If so then can rename the option to something like wrapperFlavor or something.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure, honestly. There seems to also be nixGLNvidiaBumblebee and nixVulkanNividia according to the README. If we introduced an enum that would make users unable to target them.

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;
};

}

1 change: 1 addition & 0 deletions tests/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down