Merge pull request #40 from zimbatm/nvidia-version-file

Nvidia version file
This commit is contained in:
Guillaume Bouchard 2020-04-28 17:12:48 +02:00 committed by GitHub
commit 76196e5da3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 83 additions and 46 deletions

18
all.nix
View File

@ -1,4 +1,16 @@
import ./default.nix { let
nvidiaVersion = "440.82"; pkgs = import <nixpkgs> { config = { allowUnfree = true; }; };
nvidiaHash = "edd415acf2f75a659e0f3b4f27c1fab770cf21614e84a18152d94f0d004a758e"; in
{
pure = pkgs.recurseIntoAttrs (pkgs.callPackage ./nixGL.nix {
nvidiaVersion = "440.82";
nvidiaHash = "edd415acf2f75a659e0f3b4f27c1fab770cf21614e84a18152d94f0d004a758e";
});
versionFile = pkgs.recurseIntoAttrs (pkgs.callPackage ./nixGL.nix {
nvidiaVersionFile = pkgs.writeText "nvidia-version-440.82" ''
NVRM version: NVIDIA UNIX x86_64 Kernel Module 440.82 Wed Apr 1 20:04:33 UTC 2020
GCC version: gcc version 9.3.0 (Arch Linux 9.3.0-1)
'';
});
} }

View File

@ -4,6 +4,11 @@
# Hash of the Nvidia driver .run file. null is fine, but fixing a value here # Hash of the Nvidia driver .run file. null is fine, but fixing a value here
# will be more reproducible and more efficient. # will be more reproducible and more efficient.
nvidiaHash ? null, nvidiaHash ? null,
# Alternatively, you can pass a path that points to a nvidia version file
# and let nixGL extract the version from it. That file must be a copy of
# /proc/driver/nvidia/version. Nix doesn't like zero-sized files (see
# https://github.com/NixOS/nix/issues/3539 ).
nvidiaVersionFile ? null,
# Enable 32 bits driver # Enable 32 bits driver
# This is one by default, you can switch it to off if you want to reduce a # This is one by default, you can switch it to off if you want to reduce a
# bit the size of nixGL closure. # bit the size of nixGL closure.
@ -15,5 +20,10 @@
} }
}: }:
pkgs.callPackage ./nixGL.nix { pkgs.callPackage ./nixGL.nix {
inherit nvidiaVersion nvidiaHash enable32bits; inherit
nvidiaVersion
nvidiaVersionFile
nvidiaHash
enable32bits
;
} }

View File

@ -4,6 +4,11 @@
# Hash of the Nvidia driver .run file. null is fine, but fixing a value here # Hash of the Nvidia driver .run file. null is fine, but fixing a value here
# will be more reproducible and more efficient. # will be more reproducible and more efficient.
nvidiaHash ? null, nvidiaHash ? null,
# Alternatively, you can pass a path that points to a nvidia version file
# and let nixGL extract the version from it. That file must be a copy of
# /proc/driver/nvidia/version. Nix doesn't like zero-sized files (see
# https://github.com/NixOS/nix/issues/3539 ).
nvidiaVersionFile ? null,
# Enable 32 bits driver # Enable 32 bits driver
# This is one by default, you can switch it to off if you want to reduce a # This is one by default, you can switch it to off if you want to reduce a
# bit the size of nixGL closure. # bit the size of nixGL closure.
@ -14,50 +19,59 @@
}: }:
let let
_nvidiaVersionFile =
if nvidiaVersionFile != null then
nvidiaVersionFile
else
# HACK: Get the version from /proc. It turns out that /proc is mounted
# inside of the build sandbox and varies from machine to machine.
#
# builtins.readFile is not able to read /proc files. See
# https://github.com/NixOS/nix/issues/3539.
runCommand "impure-nvidia-version-file" {
# To avoid sharing the build result over time or between machine,
# Add an impure parameter to force the rebuild on each access.
time = builtins.currentTime;
}
"cp /proc/driver/nvidia/version $out || touch $out";
# The nvidia version. Either fixed by the `nvidiaVersion` argument, or # The nvidia version. Either fixed by the `nvidiaVersion` argument, or
# auto-detected. # auto-detected. Auto-detection is impure.
_nvidiaVersion = if nvidiaVersion != null _nvidiaVersion =
then nvidiaVersion if nvidiaVersion != null then
else nvidiaVersion
# This is the auto-detection mecanism. This is ugly. else
# We read /proc/driver/nvidia/version which is set by the Nvidia driver kernel module. # Get if from the nvidiaVersionFile
# This fails if the nvidia driver kernel module is not loaded. let
# I'd like to just read the file using `${/proc/driver/nvidia/version}` and data = builtins.readFile _nvidiaVersionFile;
# then let nix invalidate the derivation if the content of this file versionMatch = builtins.match ".*Module +([0-9]+\\.[0-9]+).*" data;
# changes, but that's not possible, see in
# https://github.com/NixOS/nix/issues/3539 if versionMatch != null then
# But /proc is readable at build time! So runCommand works fine. builtins.head versionMatch
import (runCommand "auto-detect-nvidia" { else
time = builtins.currentTime; null;
}
''
# Written this way so if the version file does not exists, the script crashs
VERSION="$(${pcre}/bin/pcregrep -o1 'Module +([0-9]+\.[0-9]+)' /proc/driver/nvidia/version)"
echo "\"$VERSION\"" > $out
'');
addNvidiaVersion = drv: drv.overrideAttrs(oldAttrs: { addNvidiaVersion = drv: drv.overrideAttrs(oldAttrs: {
name = oldAttrs.name + "-${_nvidiaVersion}"; name = oldAttrs.name + "-${_nvidiaVersion}";
}); });
writeExecutable = { name, text } : writeTextFile { writeExecutable = { name, text } : writeTextFile {
inherit name text; inherit name text;
executable = true; executable = true;
destination = "/bin/${name}"; destination = "/bin/${name}";
checkPhase = '' checkPhase = ''
${shellcheck}/bin/shellcheck "$out/bin/${name}" ${shellcheck}/bin/shellcheck "$out/bin/${name}"
# Check that all the files listed in the output binary exists
for i in $(${pcre}/bin/pcregrep -o0 '/nix/store/.*?/[^ ":]+' $out/bin/${name})
do
ls $i > /dev/null || (echo "File $i, referenced in $out/bin/${name} does not exists."; exit -1)
done
'';
};
# Check that all the files listed in the output binary exists
for i in $(${pcre}/bin/pcregrep -o0 '/nix/store/.*?/[^ ":]+' $out/bin/${name})
do
ls $i > /dev/null || (echo "File $i, referenced in $out/bin/${name} does not exists."; exit -1)
done
'';
};
in in
rec { rec {
nvidia = (linuxPackages.nvidia_x11.override { nvidia = (linuxPackages.nvidia_x11.override {
@ -175,8 +189,9 @@ in
# The output derivation contains nixGL which point either to # The output derivation contains nixGL which point either to
# nixGLNvidia or nixGLIntel using an heuristic. # nixGLNvidia or nixGLIntel using an heuristic.
nixGLDefault = nixGLDefault =
if builtins.pathExists "/proc/driver/nvidia/version" if _nvidiaVersion != null then
then nixGLCommon nixGLNvidia nixGLCommon nixGLNvidia
else nixGLCommon nixGLIntel; else
nixGLCommon nixGLIntel
} ;
}