www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

nixGL.nix (6831B)


      1 { ## Nvidia informations.
      2   # Version of the system kernel module. Let it to null to enable auto-detection.
      3   nvidiaVersion ? null,
      4   # Hash of the Nvidia driver .run file. null is fine, but fixing a value here
      5   # will be more reproducible and more efficient.
      6   nvidiaHash ? null,
      7   # Alternatively, you can pass a path that points to a nvidia version file
      8   # and let nixGL extract the version from it. That file must be a copy of
      9   # /proc/driver/nvidia/version. Nix doesn't like zero-sized files (see
     10   # https://github.com/NixOS/nix/issues/3539 ).
     11   nvidiaVersionFile ? null,
     12   # Enable 32 bits driver
     13   # This is one by default, you can switch it to off if you want to reduce a
     14   # bit the size of nixGL closure.
     15   enable32bits ? true,
     16   writeTextFile, shellcheck, pcre, runCommand, linuxPackages, fetchurl, lib,
     17   runtimeShell, bumblebee, libglvnd, vulkan-validation-layers, mesa_drivers,
     18   pkgsi686Linux,zlib, libdrm, xorg, wayland, gcc
     19 }:
     20 
     21 let
     22   _nvidiaVersionFile =
     23     if nvidiaVersionFile != null then
     24       nvidiaVersionFile
     25     else
     26       # HACK: Get the version from /proc. It turns out that /proc is mounted
     27       # inside of the build sandbox and varies from machine to machine.
     28       #
     29       # builtins.readFile is not able to read /proc files. See
     30       # https://github.com/NixOS/nix/issues/3539.
     31       runCommand "impure-nvidia-version-file" {
     32         # To avoid sharing the build result over time or between machine,
     33         # Add an impure parameter to force the rebuild on each access.
     34         time = builtins.currentTime;
     35         preferLocalBuild = true;
     36         allowSubstitutes = false;
     37       }
     38       "cp /proc/driver/nvidia/version $out || touch $out";
     39 
     40   # The nvidia version. Either fixed by the `nvidiaVersion` argument, or
     41   # auto-detected. Auto-detection is impure.
     42   _nvidiaVersion =
     43     if nvidiaVersion != null then
     44       nvidiaVersion
     45     else
     46       # Get if from the nvidiaVersionFile
     47       let
     48         data = builtins.readFile _nvidiaVersionFile;
     49         versionMatch = builtins.match ".*Module +([0-9]+\\.[0-9]+).*" data;
     50       in
     51       if versionMatch != null then
     52         builtins.head versionMatch
     53       else
     54         null;
     55 
     56   addNvidiaVersion = drv: drv.overrideAttrs(oldAttrs: {
     57     name = oldAttrs.name + "-${_nvidiaVersion}";
     58   });
     59 
     60   writeExecutable = { name, text } : writeTextFile {
     61     inherit name text;
     62 
     63     executable = true;
     64     destination = "/bin/${name}";
     65 
     66 
     67     checkPhase = ''
     68      ${shellcheck}/bin/shellcheck "$out/bin/${name}"
     69 
     70      # Check that all the files listed in the output binary exists
     71      for i in $(${pcre}/bin/pcregrep  -o0 '/nix/store/.*?/[^ ":]+' $out/bin/${name})
     72      do
     73        ls $i > /dev/null || (echo "File $i, referenced in $out/bin/${name} does not exists."; exit -1)
     74      done
     75     '';
     76   };
     77 in
     78   rec {
     79     nvidia = (linuxPackages.nvidia_x11.override {
     80     }).overrideAttrs(oldAttrs: rec {
     81       name = "nvidia-${_nvidiaVersion}";
     82       src = let url ="http://download.nvidia.com/XFree86/Linux-x86_64/${_nvidiaVersion}/NVIDIA-Linux-x86_64-${_nvidiaVersion}.run";
     83       in if nvidiaHash != null
     84       then fetchurl {
     85         inherit url;
     86         sha256 = nvidiaHash;
     87       } else
     88       builtins.fetchurl url;
     89       useGLVND = true;
     90     });
     91 
     92     nvidiaLibsOnly = nvidia.override {
     93       libsOnly = true;
     94       kernel = null;
     95     };
     96 
     97   nixGLNvidiaBumblebee = addNvidiaVersion (writeExecutable {
     98     name = "nixGLNvidiaBumblebee";
     99     text = ''
    100       #!${runtimeShell}
    101       export LD_LIBRARY_PATH=${lib.makeLibraryPath [nvidia]}:$LD_LIBRARY_PATH
    102       ${bumblebee.override {nvidia_x11 = nvidia; nvidia_x11_i686 = nvidia.lib32;}}/bin/optirun --ldpath ${lib.makeLibraryPath ([libglvnd nvidia] ++ lib.optionals enable32bits [nvidia.lib32 pkgsi686Linux.libglvnd])} "$@"
    103     '';
    104   });
    105 
    106   # TODO: 32bit version? Not tested.
    107   nixNvidiaWrapper = api: addNvidiaVersion (writeExecutable {
    108     name = "nix${api}Nvidia";
    109     text = ''
    110       #!${runtimeShell}
    111       ${lib.optionalString (api == "Vulkan") ''export VK_LAYER_PATH=${vulkan-validation-layers}/share/vulkan/explicit_layer.d''}
    112 
    113         ${lib.optionalString (api == "Vulkan") ''export VK_ICD_FILENAMES=${nvidiaLibsOnly}/share/vulkan/icd.d/nvidia.json${lib.optionalString enable32bits ":${nvidiaLibsOnly.lib32}/share/vulkan/icd.d/nvidia.json"}:$VK_ICD_FILENAMES''}
    114         export LD_LIBRARY_PATH=${lib.makeLibraryPath ([
    115           libglvnd
    116           nvidiaLibsOnly
    117         ] ++ lib.optional (api == "Vulkan") vulkan-validation-layers
    118         ++ lib.optionals enable32bits [nvidiaLibsOnly.lib32 pkgsi686Linux.libglvnd])
    119       }:''${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}
    120         "$@"
    121       '';
    122     });
    123 
    124   # TODO: 32bit version? Not tested.
    125   nixGLNvidia = nixNvidiaWrapper "GL";
    126 
    127   # TODO: 32bit version? Not tested.
    128   nixVulkanNvidia = nixNvidiaWrapper "Vulkan";
    129 
    130   nixGLIntel = writeExecutable {
    131     name = "nixGLIntel";
    132     # add the 32 bits drivers if needed
    133     text = let
    134       drivers = [mesa_drivers] ++ lib.optional enable32bits pkgsi686Linux.mesa_drivers;
    135     in ''
    136       #!${runtimeShell}
    137       export LIBGL_DRIVERS_PATH=${lib.makeSearchPathOutput "lib" "lib/dri" drivers}
    138       export LD_LIBRARY_PATH=${
    139         lib.makeLibraryPath drivers
    140       }:$LD_LIBRARY_PATH
    141       "$@"
    142     '';
    143   };
    144 
    145   nixVulkanIntel = writeExecutable {
    146     name = "nixVulkanIntel";
    147     text = let
    148       # generate a file with the listing of all the icd files
    149       icd = runCommand "mesa_icd" {}
    150         (
    151           # 64 bits icd
    152           ''ls ${mesa_drivers}/share/vulkan/icd.d/*.json > f
    153           ''
    154           #  32 bits ones
    155           + lib.optionalString enable32bits ''ls ${pkgsi686Linux.mesa_drivers}/share/vulkan/icd.d/*.json >> f
    156           ''
    157           # concat everything as a one line string with ":" as seperator
    158           + ''cat f | xargs | sed "s/ /:/g" > $out''
    159           );
    160       in ''
    161      #!${runtimeShell}
    162      if [ -n "$LD_LIBRARY_PATH" ]; then
    163        echo "Warning, nixVulkanIntel overwriting existing LD_LIBRARY_PATH" 1>&2
    164      fi
    165      export VK_LAYER_PATH=${vulkan-validation-layers}/share/vulkan/explicit_layer.d
    166      ICDS=$(cat ${icd})
    167      export VK_ICD_FILENAMES=$ICDS:$VK_ICD_FILENAMES
    168      export LD_LIBRARY_PATH=${lib.makeLibraryPath [
    169        zlib
    170        libdrm
    171        xorg.libX11
    172        xorg.libxcb
    173        xorg.libxshmfence
    174        wayland
    175        gcc.cc
    176      ]}:$LD_LIBRARY_PATH
    177      exec "$@"
    178     '';
    179   };
    180 
    181   nixGLCommon = nixGL:
    182     runCommand "nixGLCommon" {
    183       buildInuts = [nixGL];
    184     }
    185       ''
    186       mkdir -p "$out/bin"
    187       # star because nixGLNvidia... have version prefixed name
    188       cp ${nixGL}/bin/* "$out/bin/nixGL";
    189       '';
    190 
    191   # The output derivation contains nixGL which point either to
    192   # nixGLNvidia or nixGLIntel using an heuristic.
    193   nixGLDefault =
    194     if _nvidiaVersion != null then
    195       nixGLCommon nixGLNvidia
    196     else
    197       nixGLCommon nixGLIntel
    198     ;
    199 }