mirror of
https://github.com/nix-community/home-manager.git
synced 2025-12-02 23:21:02 +01:00
generic-linux-gpu: add module
This commit is contained in:
parent
066874efb5
commit
193e44d316
10 changed files with 332 additions and 1 deletions
|
|
@ -26,6 +26,7 @@ in
|
||||||
)
|
)
|
||||||
(lib.mkRenamedOptionModule [ "nixGL" ] [ "targets" "genericLinux" "nixGL" ])
|
(lib.mkRenamedOptionModule [ "nixGL" ] [ "targets" "genericLinux" "nixGL" ])
|
||||||
./generic-linux/nixgl.nix
|
./generic-linux/nixgl.nix
|
||||||
|
./generic-linux/gpu
|
||||||
];
|
];
|
||||||
|
|
||||||
options.targets.genericLinux = {
|
options.targets.genericLinux = {
|
||||||
|
|
|
||||||
155
modules/targets/generic-linux/gpu/default.nix
Normal file
155
modules/targets/generic-linux/gpu/default.nix
Normal file
|
|
@ -0,0 +1,155 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
|
||||||
|
{
|
||||||
|
options.targets.genericLinux.gpu =
|
||||||
|
let
|
||||||
|
inherit (lib)
|
||||||
|
mkOption
|
||||||
|
mkEnableOption
|
||||||
|
types
|
||||||
|
literalExpression
|
||||||
|
;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = config.targets.genericLinux.enable && config.targets.genericLinux.nixGL.packages == null;
|
||||||
|
defaultText = literalExpression "config.targets.genericLinux.enable && config.targets.genericLinux.nixGL.packages == null";
|
||||||
|
example = true;
|
||||||
|
description = "Whether to enable GPU driver integration for non-NixOS systems.";
|
||||||
|
};
|
||||||
|
|
||||||
|
packages = mkOption {
|
||||||
|
type = types.attrs;
|
||||||
|
default = pkgs;
|
||||||
|
defaultText = literalExpression "pkgs";
|
||||||
|
description = "The Nixpkgs package set where drivers are taken from.";
|
||||||
|
};
|
||||||
|
|
||||||
|
nvidia = {
|
||||||
|
enable = mkEnableOption "proprietary Nvidia drivers";
|
||||||
|
|
||||||
|
version = mkOption {
|
||||||
|
type = types.nullOr (types.strMatching "[0-9]{3}\\.[0-9]{2,3}\\.[0-9]{2}");
|
||||||
|
default = null;
|
||||||
|
example = literalExpression "550.163.01";
|
||||||
|
description = ''
|
||||||
|
The exact version of Nvidia drivers to use. This version **must**
|
||||||
|
match the version of the driver used by the host OS.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
sha256 = mkOption {
|
||||||
|
type = types.nullOr (types.strMatching "sha256-.*=");
|
||||||
|
default = null;
|
||||||
|
example = literalExpression "sha256-hfK1D5EiYcGRegss9+H5dDr/0Aj9wPIJ9NVWP3dNUC0=";
|
||||||
|
description = ''
|
||||||
|
The hash of the downloaded driver file. It can be obtained by
|
||||||
|
running, for example,
|
||||||
|
|
||||||
|
```sh
|
||||||
|
nix store prefetch-file https://download.nvidia.com/XFree86/Linux-x86_64/@VERSION@/NVIDIA-Linux-x86_64-@VERSION@.run
|
||||||
|
```
|
||||||
|
|
||||||
|
where `@VERSION@` is replaced with the exact driver version.
|
||||||
|
If you are on ARM, replace Linux-x86_64 with Linux-aarch64.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
nixStateDirectory = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
default = "/nix/var/nix";
|
||||||
|
example = "/var/lib/nix";
|
||||||
|
description = ''
|
||||||
|
The path to the Nix state directory. This only needs to be changed
|
||||||
|
from default if the path was overridden, e.g., by setting the
|
||||||
|
`NIX_STATE_DIR` environment variable.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config =
|
||||||
|
let
|
||||||
|
cfg = config.targets.genericLinux.gpu;
|
||||||
|
|
||||||
|
# This builds the driver archive downloaded from download.nvidia.com
|
||||||
|
nvidia =
|
||||||
|
(cfg.packages.linuxPackages.nvidiaPackages.mkDriver {
|
||||||
|
version = cfg.nvidia.version;
|
||||||
|
sha256_64bit = cfg.nvidia.sha256;
|
||||||
|
sha256_aarch64 = cfg.nvidia.sha256;
|
||||||
|
useSettings = false;
|
||||||
|
usePersistenced = false;
|
||||||
|
}).override
|
||||||
|
{
|
||||||
|
libsOnly = true;
|
||||||
|
kernel = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
drivers = cfg.packages.callPackage ./gpu-libs-env.nix {
|
||||||
|
addNvidia = cfg.nvidia.enable;
|
||||||
|
nvidia_x11 = nvidia; # Only used if addNvidia is enabled
|
||||||
|
};
|
||||||
|
|
||||||
|
setupPackage = cfg.packages.callPackage ./setup {
|
||||||
|
inherit (cfg) nixStateDirectory;
|
||||||
|
nonNixosGpuEnv = drivers;
|
||||||
|
};
|
||||||
|
|
||||||
|
in
|
||||||
|
lib.mkIf cfg.enable {
|
||||||
|
assertions = lib.optionals cfg.nvidia.enable [
|
||||||
|
{
|
||||||
|
assertion = !isNull cfg.nvidia.version;
|
||||||
|
message = ''
|
||||||
|
Nvidia proprietary driver is enabled, version must be given.
|
||||||
|
Please set targets.genericLinux.gpu.nvidia.version.
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
{
|
||||||
|
assertion = !isNull cfg.nvidia.sha256;
|
||||||
|
message = ''
|
||||||
|
Nvidia proprietary driver is enabled, driver hash must be given.
|
||||||
|
Please set targets.genericLinux.gpu.nvidia.sha256.
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
warnings = lib.optional (config.targets.genericLinux.nixGL.packages != null) ''
|
||||||
|
Both targets.genericLinux.gpu and targets.genericLinux.nixGL are enabled.
|
||||||
|
This is an unsupported configuration. Only mix the two if you know what
|
||||||
|
you are doing!
|
||||||
|
'';
|
||||||
|
|
||||||
|
home.packages = [ setupPackage ];
|
||||||
|
|
||||||
|
home.activation.checkExistingGpuDrivers =
|
||||||
|
let
|
||||||
|
# Absolute path is needed for use with sudo which doesn't have the user's
|
||||||
|
# home environment.
|
||||||
|
setupPath = "${lib.getExe setupPackage}";
|
||||||
|
in
|
||||||
|
lib.hm.dag.entryAnywhere ''
|
||||||
|
existing=$(readlink /run/opengl-driver || true)
|
||||||
|
new=${drivers}
|
||||||
|
verboseEcho Existing drivers: ''${existing}
|
||||||
|
verboseEcho New drivers: ''${new}
|
||||||
|
if [[ -z "''${existing}" ]] ; then
|
||||||
|
warnEcho "This non-NixOS system is not yet set up to use the GPU"
|
||||||
|
warnEcho "with Nix packages. To set up GPU drivers, run"
|
||||||
|
warnEcho " sudo ${setupPath}"
|
||||||
|
elif [[ "''${existing}" != "''${new}" ]] ; then
|
||||||
|
warnEcho "GPU drivers require an update, run"
|
||||||
|
warnEcho " sudo ${setupPath}"
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
meta.maintainers = with lib.hm.maintainers; [ exzombie ];
|
||||||
|
}
|
||||||
24
modules/targets/generic-linux/gpu/gpu-libs-env.nix
Normal file
24
modules/targets/generic-linux/gpu/gpu-libs-env.nix
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
{
|
||||||
|
lib,
|
||||||
|
buildEnv,
|
||||||
|
mesa,
|
||||||
|
libvdpau-va-gl,
|
||||||
|
intel-media-driver,
|
||||||
|
nvidia-vaapi-driver,
|
||||||
|
linuxPackages,
|
||||||
|
nvidia_x11 ? linuxPackages.nvidia_x11,
|
||||||
|
addNvidia ? false,
|
||||||
|
}:
|
||||||
|
|
||||||
|
buildEnv {
|
||||||
|
name = "non-nixos-gpu";
|
||||||
|
paths = [
|
||||||
|
mesa
|
||||||
|
libvdpau-va-gl
|
||||||
|
intel-media-driver
|
||||||
|
]
|
||||||
|
++ lib.optionals addNvidia [
|
||||||
|
nvidia_x11
|
||||||
|
nvidia-vaapi-driver
|
||||||
|
];
|
||||||
|
}
|
||||||
30
modules/targets/generic-linux/gpu/setup/default.nix
Normal file
30
modules/targets/generic-linux/gpu/setup/default.nix
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
{
|
||||||
|
lib,
|
||||||
|
stdenv,
|
||||||
|
nixStateDirectory,
|
||||||
|
nonNixosGpuEnv,
|
||||||
|
}:
|
||||||
|
|
||||||
|
stdenv.mkDerivation {
|
||||||
|
name = "non-nixos-gpu";
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
description = "GPU driver setup for Nix on non-NixOS Linux systems";
|
||||||
|
homepage = "https://github.com/exzombie/non-nixos-gpu";
|
||||||
|
license = lib.licenses.mit;
|
||||||
|
mainProgram = "non-nixos-gpu-setup";
|
||||||
|
};
|
||||||
|
|
||||||
|
src = ./.;
|
||||||
|
patchPhase = ''
|
||||||
|
substituteInPlace non-nixos-gpu* \
|
||||||
|
--replace '@@resources@@' "$out/resources" \
|
||||||
|
--replace '@@statedir@@' '${nixStateDirectory}' \
|
||||||
|
--replace '@@env@@' "${nonNixosGpuEnv}"
|
||||||
|
'';
|
||||||
|
installPhase = ''
|
||||||
|
mkdir -p $out/{bin,resources}
|
||||||
|
cp non-nixos-gpu-setup $out/bin
|
||||||
|
cp non-nixos-gpu.service $out/resources
|
||||||
|
'';
|
||||||
|
}
|
||||||
13
modules/targets/generic-linux/gpu/setup/non-nixos-gpu-setup
Executable file
13
modules/targets/generic-linux/gpu/setup/non-nixos-gpu-setup
Executable file
|
|
@ -0,0 +1,13 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Install the systemd service file and ensure that the store path won't be
|
||||||
|
# garbage-collected as long as it's installed.
|
||||||
|
unit_path=/etc/systemd/system/non-nixos-gpu.service
|
||||||
|
ln -sf @@resources@@/non-nixos-gpu.service "$unit_path"
|
||||||
|
ln -sf "$unit_path" "@@statedir@@"/gcroots/non-nixos-gpu.service
|
||||||
|
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl enable non-nixos-gpu.service
|
||||||
|
systemctl restart non-nixos-gpu.service
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
[Unit]
|
||||||
|
Description=GPU driver setup for Nix on non-NixOS Linux systems
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=ln -nsf @@env@@ /run/opengl-driver
|
||||||
|
RemainAfterExit=yes
|
||||||
|
|
@ -1 +1,6 @@
|
||||||
{ targets-generic-linux = ./generic-linux.nix; }
|
{
|
||||||
|
targets-generic-linux = ./generic-linux.nix;
|
||||||
|
targets-generic-linux-gpu-basic = ./generic-linux-gpu/basic-enable.nix;
|
||||||
|
targets-generic-linux-gpu-setup-contents = ./generic-linux-gpu/setup-package-contents.nix;
|
||||||
|
targets-generic-linux-gpu-nvidia = ./generic-linux-gpu/nvidia-enabled.nix;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
targets.genericLinux.gpu.enable = true;
|
||||||
|
|
||||||
|
nmt.script = ''
|
||||||
|
assertFileExists home-path/bin/non-nixos-gpu-setup
|
||||||
|
assertFileContains activate "checkExistingGpuDrivers"
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
|
||||||
|
let
|
||||||
|
mockNvidiaDriver = config.lib.test.mkStubPackage {
|
||||||
|
buildScript = ''
|
||||||
|
mkdir -p $out/lib
|
||||||
|
echo "MOCK_NVIDIA_DRIVER_FOR_TESTING" > $out/lib/nvidia-test-marker
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
# Override the package set to provide our mock driver. This also tests that a
|
||||||
|
# custom package set can be used with this module. The mock driver needs to
|
||||||
|
# support .override because the module calls it.
|
||||||
|
customPkgs = pkgs // {
|
||||||
|
linuxPackages = pkgs.linuxPackages // {
|
||||||
|
nvidiaPackages = pkgs.linuxPackages.nvidiaPackages // {
|
||||||
|
mkDriver = args: lib.makeOverridable (_: mockNvidiaDriver) { };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
targets.genericLinux.gpu = {
|
||||||
|
enable = true;
|
||||||
|
packages = customPkgs;
|
||||||
|
nvidia = {
|
||||||
|
enable = true;
|
||||||
|
version = "550.163.01";
|
||||||
|
sha256 = "sha256-hfK1D5EiYcGRegss9+H5dDr/0Aj9wPIJ9NVWP3dNUC0=";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
nmt.script = ''
|
||||||
|
setupScript="$TESTED/home-path/bin/non-nixos-gpu-setup"
|
||||||
|
assertFileExists "$setupScript"
|
||||||
|
|
||||||
|
# Find the resources directory
|
||||||
|
resourcesPath=$(grep -oP '/nix/store/[^/]+-non-nixos-gpu/resources' "$setupScript" | head -1)
|
||||||
|
|
||||||
|
# Extract the GPU environment path
|
||||||
|
envPath=$(grep -oP '/nix/store/[^/]+-non-nixos-gpu' "$resourcesPath/non-nixos-gpu.service" | head -1)
|
||||||
|
|
||||||
|
if [[ -z "$envPath" ]]; then
|
||||||
|
fail "Could not find GPU environment path in service file"
|
||||||
|
fi
|
||||||
|
|
||||||
|
markerFile="$envPath/lib/nvidia-test-marker"
|
||||||
|
assertFileExists "$markerFile"
|
||||||
|
assertFileContains "$markerFile" "MOCK_NVIDIA_DRIVER_FOR_TESTING"
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
{ config, lib, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
targets.genericLinux.gpu = {
|
||||||
|
enable = true;
|
||||||
|
nixStateDirectory = "/custom/state/directory";
|
||||||
|
};
|
||||||
|
|
||||||
|
nmt.script = ''
|
||||||
|
setupScript="$TESTED/home-path/bin/non-nixos-gpu-setup"
|
||||||
|
assertFileExists "$setupScript"
|
||||||
|
assertFileIsExecutable "$setupScript"
|
||||||
|
|
||||||
|
# Find and check the resources directory
|
||||||
|
resourcesPath=$(grep -oP '/nix/store/[^/]+-non-nixos-gpu/resources' "$setupScript" | head -1)
|
||||||
|
assertDirectoryExists "$resourcesPath"
|
||||||
|
|
||||||
|
# Check that gcroots dir was set
|
||||||
|
cat "$setupScript"
|
||||||
|
assertFileRegex "$setupScript" ' "/custom/state/directory"/gcroots'
|
||||||
|
|
||||||
|
serviceFile="$resourcesPath/non-nixos-gpu.service"
|
||||||
|
assertFileExists "$serviceFile"
|
||||||
|
|
||||||
|
# Check that no placeholders remain
|
||||||
|
assertFileNotRegex "$serviceFile" '@@[^@]\+@@'
|
||||||
|
assertFileNotRegex "$setupScript" '@@[^@]\+@@'
|
||||||
|
'';
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue