build CUDA Windows : detection + reparation de l'integration Visual Studio de CUDA manquante (erreur cryptique 'No CUDA toolset found', issue #10) - verif avant cmake via vswhere, copie auto des MSBuildExtensions du toolkit si possible, sinon message clair avec les 2 solutions ; filet dans hintMissingBuildDep

This commit is contained in:
nathaninline committed 2026-07-22 12:24:33 +02:00
1 parent 48c3e807be
commit 4fea700edc
3 files changed
+89

No files matched your search

+20
View File
@@ -120,6 +120,15 @@ func buildLlamacpp(repo string, p buildPlan, clean bool) error {
// on les réinjecte sinon le configure échoue sur « CUDA Toolkit directory '' ».
parts = append(parts, cudaPathEnv(filepath.Dir(cudaBin))...)
env = strings.Join(parts, "\x00")
// Générateur Visual Studio : vérifie (et répare si possible) l'intégration
// MSBuild de CUDA AVANT de configurer — sinon CMake échoue sur le cryptique
// « No CUDA toolset found » (cf. issue #10 : CUDA dans un chemin custom sans
// l'option « Visual Studio Integration », ou VS installé après CUDA).
if strings.HasPrefix(p.gen, "Visual Studio") {
if err := ensureCudaVSIntegration(filepath.Dir(cudaBin)); err != nil {
return err
}
}
}
cfgArgs := []string{"-B", "build", "-S", "."}
@@ -164,6 +173,17 @@ func hintMissingBuildDep(p buildPlan, cfgLog string) {
// Backend Vulkan : les en-têtes SPIR-V (paquet SPIRV-Headers) sont requis par
// la config CMake de ggml-vulkan, mais absents par défaut sur beaucoup de
// distros même quand glslc/libvulkan sont là.
// Windows/CUDA : « No CUDA toolset found » = intégration MSBuild de CUDA
// absente de Visual Studio. Normalement intercepté AVANT le configure par
// ensureCudaVSIntegration ; ce filet sert aux cas où la détection n'a pas pu
// conclure (vswhere absent, install VS non standard).
if p.backend == "cuda" && strings.Contains(log, "No CUDA toolset found") {
fmt.Printf("\n%s l'intégration Visual Studio de CUDA est absente (« No CUDA toolset found »).\n", yellow("[dépendance]"))
fmt.Printf(" Relance l'installeur du CUDA Toolkit (installation personnalisée) en cochant « CUDA → Visual Studio Integration »\n")
fmt.Printf(" (Visual Studio avec le workload C++ doit déjà être installé), ou copie les fichiers de\n")
fmt.Printf(" <toolkit>\\extras\\visual_studio_integration\\MSBuildExtensions vers\n")
fmt.Printf(" <VS>\\MSBuild\\Microsoft\\VC\\<version>\\BuildCustomizations, puis relance %s.\n", bold("jean llamacpp install"))
}
if p.backend == "vulkan" && strings.Contains(log, "SPIRV-Headers") {
fmt.Printf("\n%s dépendance manquante pour le backend %s : les en-têtes SPIR-V (paquet « SPIRV-Headers ») sont introuvables.\n",
yellow("[dépendance]"), green("Vulkan"))
+4
View File
@@ -175,6 +175,10 @@ func ensureCompiler() error {
// nothing extra to inject.
func cudaPathEnv(toolkitDir string) []string { return nil }
// ensureCudaVSIntegration is Windows-specific (MSBuild CUDA integration check);
// no-op on Unix.
func ensureCudaVSIntegration(toolkitDir string) error { return nil }
// ensureAccelerator is a no-op on Unix: CUDA/ROCm toolkits are installed through
// the distro (their layout is already probed by findNvcc / detectBuildPlan), and
// auto-installing multi-GB GPU toolkits across distros is too varied to do safely.
+65
View File
@@ -297,6 +297,71 @@ func ensureAccelerator() {
}
}
// ensureCudaVSIntegration vérifie que l'intégration MSBuild de CUDA (fichiers
// « CUDA x.y.props/targets » dans BuildCustomizations de Visual Studio) est en
// place — sans elle, le générateur Visual Studio échoue sur le cryptique
// « No CUDA toolset found » (CMakeDetermineCompilerId). Cas typiques : CUDA
// installé dans un chemin custom (ex. F:\Cuda) sans cocher « Visual Studio
// Integration », ou VS (ré)installé APRÈS CUDA — l'installeur NVIDIA n'intègre
// que les VS présents au moment où il tourne. On tente d'abord de copier les
// fichiers depuis le toolkit (extras\visual_studio_integration\MSBuildExtensions) ;
// si ça échoue (droits), on explique quoi faire au lieu de laisser l'erreur
// CMake brute. Best-effort : sans vswhere/VS détectable on laisse cmake juger.
func ensureCudaVSIntegration(toolkitDir string) error {
vs := vswherePath()
if _, err := os.Stat(vs); err != nil {
return nil
}
out, err := exec.Command(vs, "-latest", "-products", "*",
"-requires", "Microsoft.VisualStudio.Component.VC.Tools.x86.x64",
"-property", "installationPath").Output()
if err != nil {
return nil
}
installPath := strings.TrimSpace(string(out))
if installPath == "" {
return nil
}
dsts, _ := filepath.Glob(filepath.Join(installPath, "MSBuild", "Microsoft", "VC", "*", "BuildCustomizations"))
for _, d := range dsts {
if m, _ := filepath.Glob(filepath.Join(d, "CUDA *.props")); len(m) > 0 {
return nil // intégration déjà en place
}
}
// Absente : tentative de réparation depuis le toolkit lui-même.
src := filepath.Join(toolkitDir, "extras", "visual_studio_integration", "MSBuildExtensions")
files, _ := filepath.Glob(filepath.Join(src, "*"))
copied := 0
for _, dst := range dsts {
ok := len(files) > 0
for _, f := range files {
b, err := os.ReadFile(f)
if err != nil {
ok = false
break
}
if err := os.WriteFile(filepath.Join(dst, filepath.Base(f)), b, 0o644); err != nil {
ok = false
break
}
}
if ok {
copied++
}
}
if copied > 0 {
fmt.Printf("%s intégration Visual Studio de CUDA absente — réparée (fichiers copiés depuis %s)\n", yellow("[fix]"), src)
return nil
}
return fmt.Errorf(`l'intégration Visual Studio de CUDA est absente : aucun fichier « CUDA x.y.props » sous
%s\MSBuild\Microsoft\VC\<version>\BuildCustomizations
Sans elle, CMake échoue sur « No CUDA toolset found ». Pour corriger, au choix :
1. relance l'installeur du CUDA Toolkit (installation personnalisée) et coche « CUDA → Visual Studio Integration » — Visual Studio doit déjà être installé à ce moment-là ;
2. ou copie (en admin) les fichiers de
%s
vers le dossier BuildCustomizations ci-dessus, puis relance jean llamacpp install`, installPath, src)
}
// cudaPathEnv returns the CUDA toolkit env vars the MSBuild CUDA integration
// needs (CUDA_PATH and the version-specific CUDA_PATH_Vx_y), derived from the
// toolkit root, e.g. "...\CUDA\v13.3" → CUDA_PATH_V13_3. Returns NUL-free