Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 18 additions & 4 deletions apps/arstack_studio/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,15 +81,29 @@ cmake --build build-arstack-studio --target arstack_studio --parallel
```

On the Windows development workstation used for this phase, Qt is installed at
`D:\Qt\6.8.3\msvc2022_64`. Build and launch with one command:
`D:\Qt\6.8.3\msvc2022_64`. The `msvc2022_64` directory is the Qt binary-kit
name; the launcher does **not** require the Visual Studio 2022 IDE. It discovers
the newest installed Visual Studio x64 C++ toolchain with `vswhere`, including
Visual Studio 2026 / MSVC v145.

Build and launch with one command:

```powershell
.\apps\arstack_studio\run.cmd
```

Or call the PowerShell launcher directly:

```powershell
.\apps\arstack_studio\run-windows.ps1
```

Use `-NoLaunch` for a build-only verification. The launcher discovers the
installed Visual Studio C++ toolchain with `vswhere`, reuses its bundled Ninja,
and does not modify the user's global `PATH`.
Use `-NoLaunch` for a build-only verification. Use `-VisualStudioRoot` only when
you intentionally want to override automatic Visual Studio discovery. Use
`-QtRoot` when the Qt kit is installed somewhere other than the default path.
The launcher imports the selected Visual Studio developer environment, verifies
`cl.exe`, and reuses Visual Studio's bundled Ninja without modifying the user's
global `PATH`.

## P2 fast-workflow ribbon

Expand Down
78 changes: 62 additions & 16 deletions apps/arstack_studio/run-windows.ps1
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
param(
[string]$QtRoot = 'D:\Qt\6.8.3\msvc2022_64',
[string]$VisualStudioRoot = '',
[ValidateSet('Debug', 'Release', 'RelWithDebInfo')]
[string]$Configuration = 'Release',
[switch]$NoLaunch
Expand All @@ -8,15 +9,26 @@ param(
$ErrorActionPreference = 'Stop'

if (-not (Test-Path -LiteralPath (Join-Path $QtRoot 'bin\Qt6Core.dll'))) {
throw "Qt runtime was not found at '$QtRoot'. Install Qt 6.8.3 MSVC 2022 with Qt SerialPort first."
throw "Qt runtime was not found at '$QtRoot'. Install a Qt 6.x MSVC x64 kit with Qt SerialPort, or pass -QtRoot explicitly."
}

$vswhere = Join-Path ${env:ProgramFiles(x86)} 'Microsoft Visual Studio\Installer\vswhere.exe'
if (-not (Test-Path -LiteralPath $vswhere)) {
throw 'Visual Studio Installer (vswhere.exe) was not found.'
}

$visualStudio = & $vswhere -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath
if ($VisualStudioRoot) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Skip vswhere validation when an explicit root is supplied

When -VisualStudioRoot points to a valid installation but vswhere.exe is absent or unavailable, the launcher still throws at the unconditional validation on lines 15–18 before reaching this override branch. This defeats the new manual override precisely in environments where automatic discovery cannot be used; only require and invoke vswhere in the else branch.

Useful? React with 👍 / 👎.

$visualStudio = (Resolve-Path -LiteralPath $VisualStudioRoot).Path
} else {
# Do not pin the launcher to a Visual Studio marketing release. vswhere
# selects the newest installation that actually carries the x64 C++ tools,
# including Visual Studio 2026 / v145 and prerelease channels.
$visualStudio = & $vswhere -latest -prerelease -products * `
-requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 `
-property installationPath
$visualStudio = $visualStudio | Select-Object -First 1
}

if (-not $visualStudio) {
throw 'A Visual Studio installation with the C++ x64 toolchain was not found.'
}
Expand All @@ -26,39 +38,73 @@ if (-not (Test-Path -LiteralPath $developerCommand)) {
throw "Visual Studio developer command was not found at '$developerCommand'."
}

$environmentLines = & $env:ComSpec /s /c "`"$developerCommand`" -no_logo -arch=x64 -host_arch=x64 && set"
$developerPath = $null
# Import the complete Developer Command Prompt environment. Environment names
# on Windows are case-insensitive; treating PATH and Path differently can drop
# cl.exe from the process environment and make CMake report an unknown compiler.
$environmentLines = & $env:ComSpec /d /s /c "call `"$developerCommand`" -no_logo -arch=x64 -host_arch=x64 >nul && set"
if ($LASTEXITCODE -ne 0) {
throw "Visual Studio developer environment failed with exit code $LASTEXITCODE."
}

foreach ($line in $environmentLines) {
$separator = $line.IndexOf('=')
if ($separator -gt 0) {
$name = $line.Substring(0, $separator)
$value = $line.Substring($separator + 1)
if ($name -ceq 'PATH') {
$developerPath = $value
} elseif ($name -ine 'Path') {
[Environment]::SetEnvironmentVariable($name, $value, 'Process')
}
[Environment]::SetEnvironmentVariable($name, $value, 'Process')
}
}
if ($developerPath) {
$env:Path = $developerPath

$compiler = Get-Command cl.exe -ErrorAction SilentlyContinue
if (-not $compiler) {
throw "MSVC cl.exe was not exposed by '$developerCommand'. Verify that Desktop development with C++ / MSVC x64 tools are installed in Visual Studio."
}

$ninja = Join-Path $visualStudio 'Common7\IDE\CommonExtensions\Microsoft\CMake\Ninja\ninja.exe'
if (-not (Test-Path -LiteralPath $ninja)) {
throw "The Visual Studio Ninja executable was not found at '$ninja'."
$ninjaCandidates = @(
(Join-Path $visualStudio 'Common7\IDE\CommonExtensions\Microsoft\CMake\Ninja\ninja.exe'),
((Get-Command ninja.exe -ErrorAction SilentlyContinue).Source)
) | Where-Object { $_ -and (Test-Path -LiteralPath $_) }
$ninja = $ninjaCandidates | Select-Object -First 1
if (-not $ninja) {
throw 'Ninja was not found. Install the Visual Studio CMake tools component or make ninja.exe available in PATH.'
}

$cmakeCandidates = @(
((Get-Command cmake.exe -ErrorAction SilentlyContinue).Source),
(Join-Path $visualStudio 'Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe')
) | Where-Object { $_ -and (Test-Path -LiteralPath $_) }
$cmake = $cmakeCandidates | Select-Object -First 1
if (-not $cmake) {
throw 'CMake was not found. Install the Visual Studio CMake tools component or make cmake.exe available in PATH.'
}

$repoRoot = (Resolve-Path (Join-Path $PSScriptRoot '..\..')).Path
$buildDirectory = Join-Path $repoRoot 'build-arstack-studio-qt'

& cmake -S $PSScriptRoot -B $buildDirectory -G Ninja `
# A failed compiler probe can leave CMAKE_CXX_COMPILER-NOTFOUND cached. Clean
# only that broken configure state; successful incremental build caches remain.
$cacheFile = Join-Path $buildDirectory 'CMakeCache.txt'
if ((Test-Path -LiteralPath $cacheFile) -and
(Select-String -LiteralPath $cacheFile -Pattern 'CMAKE_CXX_COMPILER.*NOTFOUND' -Quiet)) {
Remove-Item -LiteralPath $cacheFile -Force
$cmakeFiles = Join-Path $buildDirectory 'CMakeFiles'
if (Test-Path -LiteralPath $cmakeFiles) {
Remove-Item -LiteralPath $cmakeFiles -Recurse -Force
}
}

Write-Host "Visual Studio: $visualStudio"
Write-Host "MSVC compiler: $($compiler.Source)"
Write-Host "Qt: $QtRoot"

& $cmake -S $PSScriptRoot -B $buildDirectory -G Ninja `
"-DCMAKE_MAKE_PROGRAM=$ninja" `
"-DCMAKE_CXX_COMPILER=$($compiler.Source)" `
"-DCMAKE_PREFIX_PATH=$QtRoot" `
"-DCMAKE_BUILD_TYPE=$Configuration"
if ($LASTEXITCODE -ne 0) { throw "Qt configure failed with exit code $LASTEXITCODE." }

& cmake --build $buildDirectory --target arstack_studio --parallel
& $cmake --build $buildDirectory --target arstack_studio --parallel
if ($LASTEXITCODE -ne 0) { throw "Qt build failed with exit code $LASTEXITCODE." }

$executable = Join-Path $buildDirectory 'arstack_studio.exe'
Expand Down
Loading