From 2b4bc5eb5e24f4271020b6a7893e28e7d76069b7 Mon Sep 17 00:00:00 2001 From: Daniel Han Date: Thu, 16 Apr 2026 08:33:58 +0000 Subject: [PATCH] Prepend cmake, nvcc, Python Scripts; keep venv Scripts appended The previous commit switched Add-ToUserPath to append by default so that installing unsloth would not silently hijack the user's system python / pip. That was correct for the venv Scripts dir (which contains python.exe and pip.exe alongside unsloth.exe), but wrong for the three studio/setup call sites. Those persist cmake, the driver-compatible nvcc, and the Python user Scripts dir for future shells, and in all three cases an older tool already earlier in the user PATH would keep winning after the install finished. The nvcc case is especially load-bearing: setup selects a driver-compatible CUDA toolkit, then llama.cpp builds against whatever wins PATH resolution, so a stale older nvcc produces broken builds. Pass -Position 'Prepend' explicitly at the three setup.ps1 call sites (cmake at line 754, nvcc bin at line 1025, Python user Scripts at line 1191). None of those directories holds python.exe, so prepending them does not re-introduce the original hijack problem. Leave the install.ps1 venv Scripts call on the default Append with a comment explaining why. --- install.ps1 | 5 +++++ studio/setup.ps1 | 21 ++++++++++++++++----- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/install.ps1 b/install.ps1 index 842ce90de9..15795932a1 100644 --- a/install.ps1 +++ b/install.ps1 @@ -1033,6 +1033,11 @@ shell.Run cmd, 0, False New-StudioShortcuts -UnslothExePath $UnslothExe # ── Add venv Scripts dir to User PATH so `unsloth studio` works from any terminal ── + # Use the default Append position here: this venv dir holds python.exe and + # pip.exe alongside unsloth.exe, so prepending would silently hijack the + # user's system python / pip in every future shell. Desktop shortcuts and + # the launch-studio wrapper call unsloth.exe by absolute path, so studio + # itself does not rely on this entry winning resolution races. $ScriptsDir = Join-Path $VenvDir "Scripts" if (Add-ToUserPath -Directory $ScriptsDir) { Refresh-SessionPath diff --git a/studio/setup.ps1 b/studio/setup.ps1 index 173f97b8f0..914830afcc 100644 --- a/studio/setup.ps1 +++ b/studio/setup.ps1 @@ -752,8 +752,11 @@ if (-not $HasCmake) { foreach ($d in $cmakeDefaults) { if (Test-Path (Join-Path $d "cmake.exe")) { $env:Path = "$d;$env:Path" - # Persist to user PATH so Refresh-Environment does not drop it later - Add-ToUserPath -Directory $d | Out-Null + # Persist to user PATH so Refresh-Environment does not drop it later. + # Prepend so the newly-selected cmake wins over any older cmake + # entry already in the user PATH (this dir has only cmake.exe, no + # python.exe, so prepending does not hijack the user's interpreter). + Add-ToUserPath -Directory $d -Position 'Prepend' | Out-Null $HasCmake = $null -ne (Get-Command cmake -ErrorAction SilentlyContinue) if ($HasCmake) { Write-Host " Found cmake at $d (added to PATH)" -ForegroundColor Gray @@ -1019,8 +1022,12 @@ $nvccBinDir = Split-Path $NvccPath -Parent if ($env:PATH -notlike "*$nvccBinDir*") { [Environment]::SetEnvironmentVariable('PATH', "$nvccBinDir;$env:PATH", 'Process') } -# Persist nvcc bin dir to User PATH so it works in new terminals -if (Add-ToUserPath -Directory $nvccBinDir) { +# Persist nvcc bin dir to User PATH so it works in new terminals. +# Prepend so the toolkit we just selected (driver-compatible) wins over any +# older CUDA bin dir already on the user PATH. Critical for llama.cpp builds: +# a later Refresh-Environment could otherwise reorder the selected nvcc behind +# a stale one. No hijack risk since this dir has only CUDA tools, no python. +if (Add-ToUserPath -Directory $nvccBinDir -Position 'Prepend') { substep "Persisted CUDA bin dir to user PATH" } @@ -1181,7 +1188,11 @@ if ($HasPython) { # Ensure Python Scripts dir is on PATH (so 'unsloth' command works in new terminals) $ScriptsDir = python -c "import sysconfig; print(sysconfig.get_path('scripts', 'nt_user') if __import__('os').path.exists(sysconfig.get_path('scripts', 'nt_user')) else sysconfig.get_path('scripts'))" if ($LASTEXITCODE -eq 0 -and $ScriptsDir -and (Test-Path $ScriptsDir)) { - if (Add-ToUserPath -Directory $ScriptsDir) { + # Prepend so the freshly installed `unsloth` console script wins over any + # older pip-installed copy already earlier on the user PATH. This dir holds + # entry points only (python.exe lives one level up), so prepending does not + # hijack the user's python interpreter. + if (Add-ToUserPath -Directory $ScriptsDir -Position 'Prepend') { # Also add to current process so it's available immediately $ProcessPathEntries = $env:PATH.Split(';') if (-not ($ProcessPathEntries | Where-Object { $_.TrimEnd('\') -eq $ScriptsDir })) {