whisper.cpp unter Arch Linux/CachyOS: CMake-Fehler „Could not find SPIRV-Headers“ beheben

von Stefan Lindecke (Admin)

Beim Kompilieren von whisper.cpp mit Vulkan-Unterstützung unter Arch Linux oder CachyOS kann CMake mit einer zunächst etwas irreführenden Fehlermeldung abbrechen.

Vulkan selbst wird dabei korrekt erkannt:

-- Found Vulkan: /usr/lib/libvulkan.so (found version "1.4.357")
-- Configuring incomplete, errors occurred!

Unmittelbar danach erscheint jedoch:

CMake Error at ggml/src/ggml-vulkan/CMakeLists.txt:14 (find_package):
  Could not find a package configuration file provided by "SPIRV-Headers"
  with any of the following names:

    SPIRV-Headers.cps
    spirv-headers.cps
    SPIRV-HeadersConfig.cmake
    spirv-headers-config.cmake

Die Ursache ist nicht der Vulkan-Treiber. Es fehlt das Development-Paket SPIRV-Headers.

Warum tritt der Fehler auf?

Ein typischer Dependency-Check für Vulkan prüft beispielsweise, ob folgende Komponenten vorhanden sind:

vulkaninfo
libvulkan.so
glslc
glslangValidator

Sind diese vorhanden, könnte ein Installationsskript zu dem Ergebnis kommen:

[Vulkan] Linux dependencies already satisfied; skipping install.

Das reicht für aktuelle Versionen von whisper.cpp bzw. dessen GGML-Vulkan-Backend jedoch nicht unbedingt aus.

Während der CMake-Konfiguration wird zusätzlich nach dem CMake-Paket SPIRV-Headers gesucht.

Fehlt dieses, kann CMake das Vulkan-Backend nicht konfigurieren.

Lösung unter Arch Linux und CachyOS

Unter Arch-basierten Distributionen lässt sich das fehlende Paket einfach über Pacman installieren:

sudo pacman -S spirv-headers

Wer sicherstellen möchte, dass die üblichen Vulkan-Entwicklungswerkzeuge vollständig vorhanden sind, kann stattdessen die relevanten Pakete gemeinsam installieren:

sudo pacman -S \
    vulkan-headers \
    vulkan-icd-loader \
    shaderc \
    glslang \
    spirv-tools \
    spirv-headers

Mit --needed verhindert Pacman, dass bereits vorhandene Pakete unnötig neu installiert werden:

sudo pacman -S --needed \
    vulkan-headers \
    vulkan-icd-loader \
    shaderc \
    glslang \
    spirv-tools \
    spirv-headers

Prüfen, ob SPIRV-Headers korrekt installiert wurde

Nach der Installation kann überprüft werden, ob die von CMake benötigte Konfigurationsdatei vorhanden ist:

pacman -Ql spirv-headers | grep SPIRV-HeadersConfig

Auf einem Arch-System sollte dabei unter anderem eine Datei wie diese auftauchen:

/usr/share/cmake/SPIRV-Headers/SPIRV-HeadersConfig.cmake

Alternativ kann direkt geprüft werden:

test -f /usr/share/cmake/SPIRV-Headers/SPIRV-HeadersConfig.cmake \
    && echo "SPIRV-Headers gefunden" \
    || echo "SPIRV-Headers fehlt"

CMake-Cache anschließend löschen

Nach einer fehlgeschlagenen CMake-Konfiguration empfiehlt es sich, das Build-Verzeichnis zu entfernen.

Beispielsweise:

rm -rf build

Danach kann whisper.cpp erneut mit Vulkan-Unterstützung konfiguriert werden:

cmake -B build \
    -DGGML_VULKAN=ON

Anschließend erfolgt der eigentliche Build:

cmake --build build -j$(nproc)

Automatische Dependency-Prüfung verbessern

Besonders relevant ist das Problem bei eigenen Installations- oder Build-Skripten.

Ein Skript sollte nicht lediglich prüfen, ob vulkaninfo funktioniert oder libvulkan.so vorhanden ist. Für das Kompilieren des Vulkan-Backends werden zusätzliche Development-Pakete benötigt.

Für Arch Linux und CachyOS könnte eine einfache Prüfung beispielsweise so aussehen:

required_packages=(
    cmake
    gcc
    make
    git
    vulkan-headers
    vulkan-icd-loader
    shaderc
    glslang
    spirv-tools
    spirv-headers
)

missing_packages=()

for package in "${required_packages[@]}"; do
    if ! pacman -Q "$package" >/dev/null 2>&1; then
        missing_packages+=("$package")
    fi
done

if ((${#missing_packages[@]})); then
    echo "Fehlende Pakete: ${missing_packages[*]}"
    sudo pacman -S --needed "${missing_packages[@]}"
else
    echo "Alle Build-Abhängigkeiten sind vorhanden."
fi

Damit wird spirv-headers zukünftig ebenfalls berücksichtigt.

Vulkan-Laufzeit und Vulkan-Entwicklungsumgebung sind nicht dasselbe

Der Fehler zeigt einen wichtigen Unterschied.

Ein funktionierendes:

vulkaninfo

bedeutet zunächst nur, dass eine Vulkan-Laufzeitumgebung vorhanden und grundsätzlich verwendbar ist.

Das bedeutet nicht automatisch, dass alle Komponenten installiert sind, die zum Kompilieren einer Vulkan-Anwendung benötigt werden.

So kann CMake problemlos melden:

-- Found Vulkan: /usr/lib/libvulkan.so

und der Build trotzdem wenige Zeilen später wegen eines fehlenden Development-Pakets abbrechen.

Bei Build-Systemen sollte deshalb zwischen Runtime-Abhängigkeiten und Build-Abhängigkeiten unterschieden werden.

Die CMake-Warnung ist nicht die Ursache

Zusätzlich kann beim Build folgende Meldung erscheinen:

CMake Warning (deprecated) at CMakeLists.txt:1 (cmake_minimum_required):
  Compatibility with CMake < 3.10 will be removed from a future version of
  CMake.

Diese Meldung sieht auffällig aus, ist für den beschriebenen Fehler aber irrelevant.

Es handelt sich lediglich um eine Deprecation-Warnung.

Der eigentliche Abbruch erfolgt hier:

Could not find a package configuration file provided by "SPIRV-Headers"

Kurzlösung

Wer lediglich schnell weiterbauen möchte, benötigt unter Arch Linux beziehungsweise CachyOS in der Regel nur:

sudo pacman -S --needed spirv-headers
rm -rf build
cmake -B build -DGGML_VULKAN=ON
cmake --build build -j$(nproc)

Sollte der Build danach weitere Vulkan-Abhängigkeiten vermissen, empfiehlt es sich, die vollständige Development-Umgebung zu installieren:

sudo pacman -S --needed \
    vulkan-headers \
    vulkan-icd-loader \
    shaderc \
    glslang \
    spirv-tools \
    spirv-headers

Fazit

Wenn whisper.cpp unter Arch Linux oder CachyOS Vulkan korrekt erkennt, CMake anschließend aber über fehlende SPIRV-Headers stolpert, liegt das Problem normalerweise nicht am Grafikkartentreiber.

Das Paket

spirv-headers

fehlt in der Build-Umgebung.

Gerade automatisierte Installer sollten deshalb nicht nur die Vulkan-Runtime prüfen, sondern auch die zum Kompilieren benötigten Development-Pakete berücksichtigen. Dadurch lässt sich vermeiden, dass ein Dependency-Check zunächst Erfolg meldet und der anschließende CMake-Lauf trotzdem abbricht.