Building vkdevicechooser, missing vk_layer_dispatch_table.h

Hello,

I’m pretty new to Nix and I’d like to use GitHub - aejsmith/vkdevicechooser: Vulkan layer to force a specific device to be used on my NixOS system.

Building it as described in the README doesn’t seem sound or even possible because it needs to install files in the system.

So I’m trying to make a new package for it, but I’m stuck because it doesn’t find the header vulkan/vk_layer_dispatch_table.h. It does find the other vulkan headers though.

It looks like this header is generated. How can I make it available to the package?

I tried adding vulkan-validation-layers, vulkan-utility-libraries, vulkan-extension-layer and other packages, to no avail.

Here’s my current package source:

{ lib
, stdenv
, fetchFromGitHub
, meson
, vulkan-headers
}:

stdenv.mkDerivation rec {
  pname = "vkdevicechooser";
  version = "1.0";

  src = fetchFromGitHub {
    owner = "aejsmith";
    repo = "vkdevicechooser";
    rev = "1.0";
    hash = "sha256-low5vkuZT4gWta4PeoCaP/jIO1uszACq+LTZopo8BAI=";
  };

  nativeBuildInputs = [
    meson
  ];

  buildInputs = [
    vulkan-headers
  ];

  meta = with lib; {
    description = "Vulkan layer to force a specific device to be used";
    homepage    = "https://github.com/aejsmith/vkdevicechooser";
    platforms   = platforms.unix;
    license     = licenses.mit;
  };
}

And the output when I try to use it:

error: builder for '/nix/store/jyhrh51glbhx4dnh1dkig3q7ymxw4pj6-vkdevicechooser-1.0.drv' failed with exit code 1;
       last 10 log lines:
       > C++ linker for the host machine: g++ ld.bfd 2.40
       > Host machine cpu family: x86_64
       > Host machine cpu: x86_64
       > Has header "vulkan/vulkan.h" : YES
       > Has header "vulkan/vk_layer.h" : YES
       > Has header "vulkan/vk_layer_dispatch_table.h" : NO
       >
       > meson.build:17:4: ERROR: Problem encountered: Vulkan development files not present (vulkan/vk_layer_dispatch_table.h)

I was finally able to make it work.

The generated header is in the vulkan-validation-layers package but it’s not part of its output files. I added the following to its derivation to make the header available:

  installPhase = ''
    mkdir -p $out/include/vulkan
    cp ../layers/vulkan/generated/*.h $out/include/vulkan
    make install
  '';

Then this derivation installs vkdevicechooser:

{ lib
, stdenv
, fetchFromGitHub
, writeText
, meson
, vulkan-headers
, vulkan-validation-layers
, ninja
, jq
}:

stdenv.mkDerivation rec {
  pname = "vkdevicechooser";
  version = "1.0";

  src = fetchFromGitHub {
    owner = "aejsmith";
    repo = "vkdevicechooser";
    rev = "1.0";
    hash = "sha256-low5vkuZT4gWta4PeoCaP/jIO1uszACq+LTZopo8BAI=";
  };

  nativeBuildInputs = [
    meson
    jq
  ];

  buildInputs = [
    vulkan-headers
    vulkan-validation-layers
    ninja
  ];

  # Help vulkan-loader find the validation layers
  setupHook = writeText "setup-hook" ''
    addToSearchPath XDG_DATA_DIRS @out@/share
  '';

  mesonFlags = ["-Dc_args=-I${vulkan-validation-layers}/include"];

  # Include absolute paths to layer libraries in their associated
  # layer definition json files.
  preFixup = ''
    for f in "$out"/share/vulkan/explicit_layer.d/*.json "$out"/share/vulkan/implicit_layer.d/*.json; do
      jq <"$f" >tmp.json ".layer.library_path = \"$out/lib/\" + .layer.library_path"
      mv tmp.json "$f"
    done
  '';

  meta = with lib; {
    description = "Vulkan layer to force a specific device to be used";
    homepage    = "https://github.com/aejsmith/vkdevicechooser";
    platforms   = platforms.unix;
    license     = licenses.mit;
  };
}

Should I suggest the change to vulkan-validation-layers? Is there a better way to do that?

And should I suggest adding this vkdevicechooser package?