Created
December 21, 2025 23:42
-
-
Save ichadhr/5d4c7b9c86558846067986078ac782b3 to your computer and use it in GitHub Desktop.
Windows build ik_llama.cpp (fork of llama.cpp)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <# | |
| install_ik_llama.ps1 | |
| -------------------- | |
| Installs all prerequisites and builds ikawrakow/ik_llama.cpp on Windows. | |
| • Works on Windows PowerShell 5 and PowerShell 7 | |
| • Uses the Ninja generator (fast, no VS-integration dependency) | |
| • Re-usable: just run the script; it installs only what is missing | |
| • Supports CUDA 12.4+ and 13.x | |
| • Pass -CudaArch <SM> to target a different GPU | |
| (auto-detects if not specified; defaults to 86 = RTX-30-series; GTX-1070 = 61, Ada = 89, etc.) | |
| #> | |
| [CmdletBinding()] | |
| param( | |
| [int] $CudaArch, | |
| [switch]$SkipBuild | |
| ) | |
| $ScriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Definition | |
| $RepoDir = Join-Path $ScriptRoot 'vendor\ik_llama.cpp' | |
| # --------------------------------------------------------------------------- | |
| # Helper functions | |
| # --------------------------------------------------------------------------- | |
| function Assert-Admin { | |
| $id = [Security.Principal.WindowsIdentity]::GetCurrent() | |
| $prn = New-Object Security.Principal.WindowsPrincipal($id) | |
| if (-not $prn.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) { | |
| throw "Run this script from an *elevated* PowerShell window." | |
| } | |
| } | |
| function Test-Command ([string]$Name) { | |
| $null -ne (Get-Command $Name -ErrorAction SilentlyContinue) | |
| } | |
| function Test-VSTools { | |
| $vswhere = Join-Path ${Env:ProgramFiles(x86)} 'Microsoft Visual Studio\Installer\vswhere.exe' | |
| if (-not (Test-Path $vswhere)) { return $false } | |
| $path = & $vswhere -latest -products * ` | |
| -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 ` | |
| -property installationPath 2>$null | |
| -not [string]::IsNullOrWhiteSpace($path) | |
| } | |
| function Test-CUDA { | |
| $root = 'C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA' | |
| if (-not (Test-Path $root)) { return $false } | |
| foreach ($d in Get-ChildItem $root -Directory) { | |
| if ($d.Name -match '^v(12|13)\.(\d+)$') { | |
| $major = [int]$Matches[1] | |
| $minor = [int]$Matches[2] | |
| if ($major -gt 12 -or ($major -eq 12 -and $minor -ge 4)) { return $true } | |
| } | |
| } | |
| return $false | |
| } | |
| function Wait-Until ($TestFn, [int]$TimeoutMin, [string]$What) { | |
| Write-Host " waiting for $What ..." | |
| $sw = [Diagnostics.Stopwatch]::StartNew() | |
| while ($sw.Elapsed.TotalMinutes -lt $TimeoutMin) { | |
| if (& $TestFn) { return } | |
| Start-Sleep 30 | |
| } | |
| throw "$What did not finish installing in $TimeoutMin minutes." | |
| } | |
| function Wait-VSToolsReady { | |
| try { | |
| Wait-Until { Test-VSTools } 10 "VS Build Tools" | |
| return $true | |
| } catch { | |
| return $false | |
| } | |
| } | |
| function Wait-CUDAReady { | |
| try { | |
| Wait-Until { Test-CUDA } 10 "CUDA Toolkit" | |
| return $true | |
| } catch { | |
| return $false | |
| } | |
| } | |
| function Install-Winget ([string]$Id, [string]$Override = '') { | |
| Write-Host "-> installing $Id ..." | |
| $wingetArgs = @( | |
| 'install', '--id', $Id, '--silent', '--disable-interactivity', | |
| '--accept-source-agreements', '--accept-package-agreements', '-e', '--wait' | |
| ) | |
| if ($Override) { $wingetArgs += @('--override', "`"$Override`"") } | |
| $p = Start-Process winget -ArgumentList $wingetArgs -NoNewWindow -Wait -PassThru | |
| # -1978335189 (0x8A150005) = "no applicable upgrade found" | |
| if ($p.ExitCode -and $p.ExitCode -ne -1978335189) { | |
| throw "winget failed (exit $($p.ExitCode)) while installing $Id" | |
| } | |
| } | |
| function Install-VSTools { | |
| Write-Host "-> downloading and installing VS 2022 Build Tools ..." | |
| $url = 'https://aka.ms/vs/17/release/vs_BuildTools.exe' | |
| $exe = Join-Path $env:TEMP 'vs_BuildTools.exe' | |
| Invoke-WebRequest -Uri $url -OutFile $exe | |
| $vsArgs = '--add Microsoft.VisualStudio.Workload.VCTools --includeRecommended --quiet --norestart --wait' | |
| $p = Start-Process -FilePath $exe -ArgumentList $vsArgs -Wait -PassThru | |
| if ($p.ExitCode -ne 0 -and $p.ExitCode -ne 3010) { | |
| throw "VS Build Tools installer failed with exit code $($p.ExitCode)." | |
| } | |
| } | |
| # Bring MSVC variables (cl, link, lib paths, etc.) into this PowerShell session | |
| function Import-VSEnv { | |
| $vswhere = Join-Path ${Env:ProgramFiles(x86)} 'Microsoft Visual Studio\Installer\vswhere.exe' | |
| $vsroot = & $vswhere -latest -products * ` | |
| -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 ` | |
| -property installationPath 2>$null | |
| if (-not $vsroot) { throw "VS Build Tools not found." } | |
| $vcvars = Join-Path $vsroot 'VC\Auxiliary\Build\vcvars64.bat' | |
| Write-Host " importing MSVC environment from $vcvars" | |
| $envDump = cmd /s /c "`"$vcvars`" && set" | |
| foreach ($line in $envDump -split "`r?`n") { | |
| if ($line -match '^(.*?)=(.*)$') { | |
| $name, $value = $Matches[1], $Matches[2] | |
| Set-Item -Path "Env:$name" -Value $value | |
| } | |
| } | |
| } | |
| # Select newest CUDA >=12.4, export env, return CMake arg | |
| function Use-LatestCuda { | |
| $root = 'C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA' | |
| $latest = Get-ChildItem $root -Directory | | |
| Where-Object { $_.Name -match '^v(12|13)\.(\d+)$' -and | |
| ($Matches[1] -gt 12 -or ($Matches[1] -eq 12 -and $Matches[2] -ge 4)) } | | |
| Sort-Object { [version]($_.Name -replace '^v') } -Descending | | |
| Select-Object -First 1 | |
| if (-not $latest) { throw 'No CUDA >=12.4 installation found.' } | |
| $env:CUDA_PATH = $latest.FullName | |
| $version = $latest.Name -replace '^v' | |
| $major, $minor = $version -split '\.' | |
| Set-Item -Path ("Env:CUDA_PATH_V${major}_${minor}") -Value $latest.FullName | |
| $env:Path = "$($latest.FullName)\bin;$env:Path" | |
| Write-Host " Using CUDA toolkit at $($env:CUDA_PATH)" | |
| "-DCUDAToolkit_ROOT=$($latest.FullName)" | |
| } | |
| function Get-CudaArch { | |
| try { | |
| $computeCap = nvidia-smi --query-gpu=compute_cap --format=csv,noheader,nounits 2>$null | Select-Object -First 1 | |
| if ($computeCap) { | |
| $major, $minor = $computeCap -split '\.' | |
| $sm = [int]($major + $minor.PadLeft(1, '0')) | |
| Write-Host "Detected CUDA architecture: $sm" | |
| return $sm | |
| } | |
| } catch {} | |
| Write-Host "Could not detect CUDA architecture, using default 86" | |
| return 86 | |
| } | |
| # --------------------------------------------------------------------------- | |
| # Main routine | |
| # --------------------------------------------------------------------------- | |
| Assert-Admin | |
| if (-not $PSBoundParameters.ContainsKey('CudaArch')) { | |
| $CudaArch = Get-CudaArch | |
| } | |
| $reqs = @( | |
| @{Name = 'Git'; Test = { Test-Command git }; Id = 'Git.Git' }, | |
| @{Name = 'CMake'; Test = { Test-Command cmake }; Id = 'Kitware.CMake' }, | |
| @{Name = 'Ninja'; Test = { Test-Command ninja }; Id = 'Kitware.Ninja' }, | |
| @{Name = 'VS Build Tools'; Test = { Test-VSTools }; | |
| Id = 'Microsoft.VisualStudio.2022.BuildTools'; | |
| Override = '--add Microsoft.VisualStudio.Workload.VCTools --includeRecommended --quiet --norestart' | |
| }, | |
| @{Name = 'CUDA Toolkit >=12.4'; Test = { Test-CUDA }; Id = 'Nvidia.CUDA' } | |
| ) | |
| foreach ($r in $reqs) { | |
| if (-not (& $r.Test)) { | |
| if ($r.Name -eq 'VS Build Tools') { | |
| Install-VSTools | |
| if (-not (Wait-VSToolsReady)) { throw 'VS Build Tools install timed out.' } | |
| } | |
| else { | |
| Install-Winget -Id $r.Id -Override $r.Override | |
| if ($r.Name -eq 'CUDA Toolkit >=12.4') { | |
| if (-not (Wait-CUDAReady)) { throw 'CUDA install timed out.' } | |
| } | |
| elseif (-not (& $r.Test)) { | |
| throw "$($r.Name) could not be installed automatically." | |
| } | |
| } | |
| } | |
| Write-Host ("[OK] {0}" -f $r.Name) | |
| } | |
| if (-not $PSBoundParameters.ContainsKey('CudaArch')) { | |
| # Set CUDA environment to make nvidia-smi available | |
| $null = Use-LatestCuda | |
| $CudaArch = Get-CudaArch | |
| } | |
| Import-VSEnv # make cl.exe etc. available in this session | |
| # Clone or update repo | |
| if (-not (Test-Path $RepoDir)) { | |
| Write-Host "-> cloning ik_llama.cpp into $RepoDir" | |
| git clone https://github.com/ikawrakow/ik_llama.cpp $RepoDir | |
| } | |
| else { | |
| Write-Host "-> updating existing ik_llama.cpp in $RepoDir" | |
| git -C $RepoDir pull --ff-only | |
| } | |
| if ($SkipBuild) { Write-Host 'SkipBuild set – done.'; return } | |
| # Configure & build | |
| $cudaRootArg = Use-LatestCuda | |
| $build = Join-Path $RepoDir 'build' | |
| New-Item $build -ItemType Directory -Force | Out-Null | |
| $cmakeArgs = @( | |
| '-G', 'Ninja', | |
| '-DGGML_CUDA=ON', | |
| '-DGGML_CUBLAS=ON', | |
| '-DCMAKE_BUILD_TYPE=Release', | |
| "-DCMAKE_CUDA_ARCHITECTURES=$CudaArch", | |
| $cudaRootArg | |
| ) | |
| Push-Location $build | |
| Write-Host '-> generating solution ...' | |
| cmake .. @cmakeArgs | |
| Write-Host '-> building (Release) ...' | |
| cmake --build . --config Release --target llama-server llama-batched-bench llama-cli llama-bench --parallel | |
| Pop-Location | |
| Write-Host '' | |
| Write-Host ("Done! Binaries are in: ""{0}""." -f (Join-Path $build 'bin')) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment