From a0ac7efd2d878411260be11a4a3d2c8fb30b6034 Mon Sep 17 00:00:00 2001 From: Gordon Lam <73506701+yeelam-gordon@users.noreply.github.com> Date: Fri, 29 Aug 2025 01:23:52 -0700 Subject: [PATCH] Improve how to build the project in PowerToys easier (#41459) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This pull request refactors and standardizes the PowerToys build scripts to improve maintainability, reusability, and platform detection. The main changes are the introduction of a shared helper script (`build-common.ps1`), migration of build logic in individual scripts to use these helpers, and enhanced platform auto-detection. This makes the build pipeline more robust and easier to use from any directory within the repository. As the result of our recent changes, use the following guidance when working in the PowerToys repo: 1. Use `build-essentials.ps1` before any development in general - Purpose: restore NuGet packages for the full solution and build a small set of essential native projects (runner, settings). This is a fast way to ensure native artifacts required for local development are available. 2. Use `build.ps1` from any folder - Purpose: lightweight local builder. It auto-discovers the target platform (x64/arm64/x86) and builds projects it finds in the current directory. - Notes: you can pass additional MSBuild arguments positionally (e.g. `./tools/build/build.ps1 '/p:CIBuild=true'`) — the script will forward them to MSBuild. - Use `-RestoreOnly` to only restore packages for local projects. 3. Use `build-installer.ps1` to create a local installer (use with caution) - Purpose: runs the full pipeline that restores, builds the full solution, signs packages, and builds the installer (MSI/bootstrapper). - Caution: this script performs cleaning (git clean) and installer packaging steps that may remove untracked files under `installer/`. Additional notes - Shared helpers live in `build-common.ps1` and are used by the other scripts (`RunMSBuild`, `RestoreThenBuild`, `BuildProjectsInDirectory`, platform auto-detection). **Shared build logic and helper functions:** * Added new `tools/build/build-common.ps1` file containing reusable PowerShell functions for MSBuild invocation, solution/project restore and build, platform detection, and project discovery. All build scripts now dot-source this file for shared functionality. **Refactoring of build scripts to use shared helpers:** * Updated `tools/build/build-essentials.ps1` to use `build-common.ps1` helpers, including auto-detection of repository root and platform, and simplified project build logic. * Created new `tools/build/build.ps1` for quick local builds, using shared helpers and supporting extra MSBuild arguments and platform auto-detection. * Refactored `tools/build/build-installer.ps1` to remove duplicate build logic, use shared helpers, and support platform auto-detection and argument forwarding. [[1]](diffhunk://#diff-21888769485d767c43c0895fe315e6f6d7384da62f60ef917d8a61a610da10b9L55-R74) [[2]](diffhunk://#diff-21888769485d767c43c0895fe315e6f6d7384da62f60ef917d8a61a610da10b9L83-L126) **Improved platform detection and argument handling:** * All scripts now auto-detect the target platform if not specified, using the new `Get-DefaultPlatform` helper. This supports x64, arm64, and x86 hosts. [[1]](diffhunk://#diff-43764921d6c830dbb3a15fe875aebfbc46966ae5ff62f3179adb3ff046b47b9dR1-R166) [[2]](diffhunk://#diff-946ed85e16779fdbcfeb7de80f631eae2da0f7bd478e27e22621121b409dde88L1-R70) [[3]](diffhunk://#diff-7a444242b2a6d9c642341bd2ef45f51ba5698ad7827e5136e85eb483863967a7R1-R88) [[4]](diffhunk://#diff-21888769485d767c43c0895fe315e6f6d7384da62f60ef917d8a61a610da10b9L55-R74) **Consistent MSBuild invocation and logging:** * MSBuild calls now consistently use shared helpers, centralized logging, and support passing extra arguments such as `/p:CIBuild=true` and custom solution/project paths. [[1]](diffhunk://#diff-43764921d6c830dbb3a15fe875aebfbc46966ae5ff62f3179adb3ff046b47b9dR1-R166) [[2]](diffhunk://#diff-21888769485d767c43c0895fe315e6f6d7384da62f60ef917d8a61a610da10b9L137-R110) [[3]](diffhunk://#diff-21888769485d767c43c0895fe315e6f6d7384da62f60ef917d8a61a610da10b9L151-R125) [[4]](diffhunk://#diff-21888769485d767c43c0895fe315e6f6d7384da62f60ef917d8a61a610da10b9L162-R139) **Project and solution build improvements:** * Build scripts now discover and build projects in preferred order (.sln, .csproj, .vcxproj), and support restoring packages only if requested. [[1]](diffhunk://#diff-43764921d6c830dbb3a15fe875aebfbc46966ae5ff62f3179adb3ff046b47b9dR1-R166) [[2]](diffhunk://#diff-7a444242b2a6d9c642341bd2ef45f51ba5698ad7827e5136e85eb483863967a7R1-R88) Let me know if you need a walkthrough of the new helper functions or how to use the updated build scripts! --- tools/build/BUILD-GUIDELINES.md | 21 ++++ tools/build/build-common.ps1 | 166 +++++++++++++++++++++++++++++++ tools/build/build-essentials.cmd | 5 + tools/build/build-essentials.ps1 | 81 ++++++++++++--- tools/build/build-installer.ps1 | 73 +++++--------- tools/build/build.cmd | 5 + tools/build/build.ps1 | 88 ++++++++++++++++ 7 files changed, 376 insertions(+), 63 deletions(-) create mode 100644 tools/build/BUILD-GUIDELINES.md create mode 100644 tools/build/build-common.ps1 create mode 100644 tools/build/build-essentials.cmd create mode 100644 tools/build/build.cmd create mode 100644 tools/build/build.ps1 diff --git a/tools/build/BUILD-GUIDELINES.md b/tools/build/BUILD-GUIDELINES.md new file mode 100644 index 0000000000..3ee54a6bf3 --- /dev/null +++ b/tools/build/BUILD-GUIDELINES.md @@ -0,0 +1,21 @@ +# Build scripts - quick guideline + +As the result of our recent changes, use the following guidance when working in the PowerToys repo: + +1. Use `build-essentials.ps1` before any development in general + - Purpose: restore NuGet packages for the full solution and build a small set of essential native projects (runner, settings). This is a fast way to ensure native artifacts required for local development are available. + +2. Use `build.ps1` from any folder + - Purpose: lightweight local builder. It auto-discovers the target platform (x64/arm64/x86) and builds projects it finds in the current directory. + - Notes: you can pass additional MSBuild arguments (e.g. `./tools/build/build.ps1 '/p:CIBuild=true'`) — the script will forward them to MSBuild. + - Use `-RestoreOnly` to only restore packages for local projects. + +3. Use `build-installer.ps1` to create a local installer (use with caution) + - Purpose: runs the full pipeline that restores, builds the full solution, signs packages, and builds the installer (MSI/bootstrapper). + - Caution: this script performs cleaning (git clean) and installer packaging steps that may remove untracked files under `installer/`. + +Additional notes +- Shared helpers live in `build-common.ps1` and are used by the other scripts (`RunMSBuild`, `RestoreThenBuild`, `BuildProjectsInDirectory`, platform auto-detection). +- If you want a different default platform selection, set the `-Platform` parameter explicitly when invoking the scripts. + +If you want, I can add this guidance to the repository README instead or add a short one-liner comment to the top of `build-common.ps1` so tools can discover it automatically. diff --git a/tools/build/build-common.ps1 b/tools/build/build-common.ps1 new file mode 100644 index 0000000000..ec3586f2f3 --- /dev/null +++ b/tools/build/build-common.ps1 @@ -0,0 +1,166 @@ +<# +.SYNOPSIS +Shared build helper functions for PowerToys build scripts. + +.DESCRIPTION +This file provides reusable helper functions used by the build scripts: +- Get-BuildPaths: returns ScriptDir, OriginalCwd, RepoRoot (repo root detection) +- RunMSBuild: wrapper around msbuild.exe (accepts optional Platform/Configuration) +- RestoreThenBuild: performs restore and optionally builds the solution/project +- BuildProjectsInDirectory: discovers and builds local .sln/.csproj/.vcxproj files + +USAGE +Dot-source this file from a script to load helpers: +. "$PSScriptRoot\build-common.ps1" + +.NOTES +Do not execute this file directly; dot-source it from `build.ps1` or `build-installer.ps1` so helpers are available in your script scope. +#> + +function RunMSBuild { + param ( + [string]$Solution, + [string]$ExtraArgs, + [string]$Platform, + [string]$Configuration + ) + + # Prefer the solution's folder for logs; fall back to current directory + $logRoot = Split-Path -Path $Solution + if (-not $logRoot) { $logRoot = '.' } + + $cfg = $null + if ($Configuration) { $cfg = $Configuration.ToLower() } else { $cfg = 'unknown' } + $plat = $null + if ($Platform) { $plat = $Platform.ToLower() } else { $plat = 'unknown' } + + $allLog = Join-Path $logRoot ("build.{0}.{1}.all.log" -f $cfg, $plat) + $warningLog = Join-Path $logRoot ("build.{0}.{1}.warnings.log" -f $cfg, $plat) + $errorsLog = Join-Path $logRoot ("build.{0}.{1}.errors.log" -f $cfg, $plat) + $binLog = Join-Path $logRoot ("build.{0}.{1}.trace.binlog" -f $cfg, $plat) + + $base = @( + $Solution + "/p:Platform=$Platform" + "/p:Configuration=$Configuration" + "/verbosity:normal" + '/clp:Summary;PerformanceSummary;ErrorsOnly;WarningsOnly' + "/fileLoggerParameters:LogFile=$allLog;Verbosity=detailed" + "/fileLoggerParameters1:LogFile=$warningLog;WarningsOnly" + "/fileLoggerParameters2:LogFile=$errorsLog;ErrorsOnly" + "/bl:$binLog" + '/nologo' + ) + + $cmd = $base + ($ExtraArgs -split ' ') + Write-Host (("[MSBUILD] {0}" -f ($cmd -join ' '))) + + Push-Location $script:RepoRoot + try { + & msbuild.exe @cmd + if ($LASTEXITCODE -ne 0) { + Write-Error (("Build failed: {0} {1}" -f $Solution, $ExtraArgs)) + exit $LASTEXITCODE + } + } finally { + Pop-Location + } +} + +function RestoreThenBuild { + param ( + [string]$Solution, + [string]$ExtraArgs, + [string]$Platform, + [string]$Configuration, + [bool]$RestoreOnly=$false + ) + + $restoreArgs = '/t:restore /p:RestorePackagesConfig=true' + if ($ExtraArgs) { $restoreArgs = "$restoreArgs $ExtraArgs" } + RunMSBuild $Solution $restoreArgs $Platform $Configuration + + if (-not $RestoreOnly) { + $buildArgs = '/m' + if ($ExtraArgs) { $buildArgs = "$buildArgs $ExtraArgs" } + RunMSBuild $Solution $buildArgs $Platform $Configuration + } +} + +function BuildProjectsInDirectory { + param( + [string]$DirectoryPath, + [string]$ExtraArgs, + [string]$Platform, + [string]$Configuration, + [switch]$RestoreOnly + ) + + if (-not (Test-Path $DirectoryPath)) { + return $false + } + + $files = @() + try { + $files = Get-ChildItem -Path (Join-Path $DirectoryPath '*') -Include *.sln,*.csproj,*.vcxproj -File -ErrorAction SilentlyContinue + } catch { + $files = @() + } + + if (-not $files -or $files.Count -eq 0) { + return $false + } + + $names = ($files | ForEach-Object { $_.Name }) -join ', ' + Write-Host ("[LOCAL BUILD] Found {0} project(s) in {1}: {2}" -f $files.Count, $DirectoryPath, $names) + + $preferredOrder = @('.sln', '.csproj', '.vcxproj') + $files = $files | Sort-Object @{Expression = { [array]::IndexOf($preferredOrder, $_.Extension.ToLower()) }} + + foreach ($f in $files) { + Write-Host ("[LOCAL BUILD] Building {0}" -f $f.FullName) + if ($f.Extension -eq '.sln') { + RestoreThenBuild $f.FullName $ExtraArgs $Platform $Configuration $RestoreOnly + } else { + $buildArgs = '/m' + if ($ExtraArgs) { $buildArgs = "$buildArgs $ExtraArgs" } + RunMSBuild $f.FullName $buildArgs $Platform $Configuration + } + } + + return $true +} + +function Get-DefaultPlatform { + <# + Returns a default target platform string based on the host machine (x64, arm64, x86). + #> + try { + $envArch = $env:PROCESSOR_ARCHITECTURE + if ($envArch) { $envArch = $envArch.ToLower() } + if ($envArch -eq 'amd64' -or $envArch -eq 'x86_64') { return 'x64' } + if ($envArch -match 'arm64') { return 'arm64' } + if ($envArch -eq 'x86') { return 'x86' } + + if ($env:PROCESSOR_ARCHITEW6432) { + $envArch2 = $env:PROCESSOR_ARCHITEW6432.ToLower() + if ($envArch2 -eq 'amd64') { return 'x64' } + if ($envArch2 -match 'arm64') { return 'arm64' } + } + + try { + $osArch = [System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture + switch ($osArch.ToString().ToLower()) { + 'x64' { return 'x64' } + 'arm64' { return 'arm64' } + 'x86' { return 'x86' } + } + } catch { + # ignore - RuntimeInformation may not be available + } + } catch { + # ignore any errors and fall back + } + + return 'x64' +} diff --git a/tools/build/build-essentials.cmd b/tools/build/build-essentials.cmd new file mode 100644 index 0000000000..db51faaa9a --- /dev/null +++ b/tools/build/build-essentials.cmd @@ -0,0 +1,5 @@ +@echo off +REM Wrapper to run build-essentials.ps1 from cmd.exe +set SCRIPT_DIR=%~dp0 +powershell.exe -NoProfile -ExecutionPolicy Bypass -File "%SCRIPT_DIR%build-essentials.ps1" %* +exit /b %ERRORLEVEL% diff --git a/tools/build/build-essentials.ps1 b/tools/build/build-essentials.ps1 index 81a3c6733b..21b378d0e3 100644 --- a/tools/build/build-essentials.ps1 +++ b/tools/build/build-essentials.ps1 @@ -1,16 +1,71 @@ -cd $PSScriptRoot -cd ..\.. -$cwd = Get-Location -$SolutionDir = $cwd,"" -join "\" -cd $SolutionDir -$BuildArgs = "/p:Configuration=Release /p:Platform=x64 /p:BuildProjectReferences=false /p:SolutionDir=$SolutionDir" +<# +.SYNOPSIS +Build essential native PowerToys projects (runner and settings), restoring NuGet packages first. -$ProjectsToBuild = - ".\src\runner\runner.vcxproj", - ".\src\modules\shortcut_guide\shortcut_guide.vcxproj", - ".\src\modules\fancyzones\lib\FancyZonesLib.vcxproj", - ".\src\modules\fancyzones\dll\FancyZonesModule.vcxproj" +.DESCRIPTION +Lightweight script to build a small set of essential C++ projects used by PowerToys' runner and native modules. This script first restores NuGet packages for the full solution (`PowerToys.sln`) and then builds the runner and settings projects. Intended for fast local builds during development. -$ProjectsToBuild | % { - Invoke-Expression "msbuild $_ $BuildArgs" +.PARAMETER Platform +Target platform for the build (for example: 'x64', 'arm64'). If omitted the script will attempt to auto-detect the host platform. + +.PARAMETER Configuration +Build configuration (for example: 'Debug' or 'Release'). Default is 'Debug'. + +.EXAMPLE +.\tools\build\build-essentials.ps1 +Restores packages for the solution and builds the default set of native projects using the auto-detected platform and Debug configuration. + +.EXAMPLE +.\tools\build\build-essentials.ps1 -Platform arm64 -Configuration Release +Restores packages and builds the essentials in Release mode for ARM64, even if your machine is running on x64. + +.NOTES +- This script dot-sources `build-common.ps1` and uses the shared helper `RunMSBuild`. +- It will call `RestoreThenBuild 'PowerToys.sln'` before building the essential projects to ensure NuGet packages are restored. +- The script attempts to locate the repository root automatically and can be run from any folder inside the repo. +#> + +param ( + [string]$Platform = '', + [string]$Configuration = 'Debug' +) + +# Find repository root starting from the script location +$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Definition +$repoRoot = $ScriptDir +while ($repoRoot -and -not (Test-Path (Join-Path $repoRoot "PowerToys.sln"))) { + $parent = Split-Path -Parent $repoRoot + if ($parent -eq $repoRoot) { + Write-Error "Could not find PowerToys repository root." + exit 1 + } + $repoRoot = $parent +} + +# Export script-scope variables used by build-common helpers +Set-Variable -Name RepoRoot -Value $repoRoot -Scope Script -Force + +# Load shared helpers +. "$PSScriptRoot\build-common.ps1" + +# If platform not provided, auto-detect from host +if (-not $Platform -or $Platform -eq '') { + try { + $Platform = Get-DefaultPlatform + Write-Host ("[AUTO-PLATFORM] Detected platform: {0}" -f $Platform) + } catch { + Write-Warning "Failed to auto-detect platform; defaulting to 'x64'" + $Platform = 'x64' + } +} + +# Ensure solution packages are restored +RestoreThenBuild 'PowerToys.sln' '' $Platform $Configuration $true + +# Build both runner and settings +$ProjectsToBuild = @(".\src\runner\runner.vcxproj", ".\src\settings-ui\Settings.UI\PowerToys.Settings.csproj") +$ExtraArgs = "/p:SolutionDir=$repoRoot\" +foreach ($proj in $ProjectsToBuild) { + Write-Host ("[BUILD-ESSENTIALS] Building {0}" -f $proj) + RunMSBuild $proj $ExtraArgs $Platform $Configuration } \ No newline at end of file diff --git a/tools/build/build-installer.ps1 b/tools/build/build-installer.ps1 index a1a1f8d5f1..24bcc3a218 100644 --- a/tools/build/build-installer.ps1 +++ b/tools/build/build-installer.ps1 @@ -52,12 +52,26 @@ Runs the pipeline for x64 Release with 'vnext' suffix. #> param ( - [string]$Platform = 'x64', + [string]$Platform = '', [string]$Configuration = 'Release', [string]$PerUser = 'true', [string]$InstallerSuffix = 'wix5' ) +# Ensure helpers are available +. "$PSScriptRoot\build-common.ps1" + +# Auto-detect platform when not provided +if (-not $Platform -or $Platform -eq '') { + try { + $Platform = Get-DefaultPlatform + Write-Host ("[AUTO-PLATFORM] Detected platform: {0}" -f $Platform) + } catch { + Write-Warning "Failed to auto-detect platform; defaulting to x64" + $Platform = 'x64' + } +} + # Find the PowerToys repository root automatically $scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Definition $repoRoot = $scriptDir @@ -80,50 +94,7 @@ if (-not $repoRoot -or -not (Test-Path (Join-Path $repoRoot "PowerToys.sln"))) { } Write-Host "PowerToys repository root detected: $repoRoot" - -function RunMSBuild { - param ( - [string]$Solution, - [string]$ExtraArgs - ) - - $base = @( - $Solution - "/p:Platform=$Platform" - "/p:Configuration=$Configuration" - "/p:CIBuild=true" - '/verbosity:normal' - '/clp:Summary;PerformanceSummary;ErrorsOnly;WarningsOnly' - '/nologo' - ) - - $cmd = $base + ($ExtraArgs -split ' ') - Write-Host ("[MSBUILD] {0} {1}" -f $Solution, ($cmd -join ' ')) - - # Run MSBuild from the repository root directory - Push-Location $repoRoot - try { - & msbuild.exe @cmd - if ($LASTEXITCODE -ne 0) { - Write-Error ("Build failed: {0} {1}" -f $Solution, $ExtraArgs) - exit $LASTEXITCODE - } - } finally { - Pop-Location - } -} - -function RestoreThenBuild { - param ([string]$Solution) - - # 1) restore - RunMSBuild $Solution '/t:restore /p:RestorePackagesConfig=true' - # 2) build ------------------------------------------------- - RunMSBuild $Solution '/m' -} - # WiX v5 projects use WixToolset.Sdk via NuGet/MSBuild; a separate WiX 3 installation is not required here. - Write-Host ("[PIPELINE] Start | Platform={0} Configuration={1} PerUser={2}" -f $Platform, $Configuration, $PerUser) Write-Host '' @@ -134,7 +105,9 @@ if (Test-Path $cmdpalOutputPath) { Remove-Item $cmdpalOutputPath -Recurse -Force -ErrorAction Ignore } -RestoreThenBuild 'PowerToys.sln' +$commonArgs = '/p:CIBuild=true' +# No local projects found (or continuing) - build full solution and tools +RestoreThenBuild 'PowerToys.sln' $commonArgs $Platform $Configuration $msixSearchRoot = Join-Path $repoRoot "$Platform\$Configuration" $msixFiles = Get-ChildItem -Path $msixSearchRoot -Recurse -Filter *.msix | @@ -148,8 +121,8 @@ else { Write-Warning "[SIGN] No .msix files found in $msixSearchRoot" } -RestoreThenBuild 'tools\BugReportTool\BugReportTool.sln' -RestoreThenBuild 'tools\StylesReportTool\StylesReportTool.sln' +RestoreThenBuild 'tools\BugReportTool\BugReportTool.sln' $commonArgs $Platform $Configuration +RestoreThenBuild 'tools\StylesReportTool\StylesReportTool.sln' $commonArgs $Platform $Configuration Write-Host '[CLEAN] installer (keep *.exe)' Push-Location $repoRoot @@ -159,10 +132,10 @@ try { Pop-Location } -RunMSBuild 'installer\PowerToysSetup.sln' '/t:restore /p:RestorePackagesConfig=true' +RunMSBuild 'installer\PowerToysSetup.sln' "$commonArgs /t:restore /p:RestorePackagesConfig=true" $Platform $Configuration -RunMSBuild 'installer\PowerToysSetup.sln' "/m /t:PowerToysInstallerVNext /p:PerUser=$PerUser /p:InstallerSuffix=$InstallerSuffix" +RunMSBuild 'installer\PowerToysSetup.sln' "$commonArgs /m /t:PowerToysInstallerVNext /p:PerUser=$PerUser /p:InstallerSuffix=$InstallerSuffix" $Platform $Configuration -RunMSBuild 'installer\PowerToysSetup.sln' "/m /t:PowerToysBootstrapperVNext /p:PerUser=$PerUser /p:InstallerSuffix=$InstallerSuffix" +RunMSBuild 'installer\PowerToysSetup.sln' "$commonArgs /m /t:PowerToysBootstrapperVNext /p:PerUser=$PerUser /p:InstallerSuffix=$InstallerSuffix" $Platform $Configuration Write-Host '[PIPELINE] Completed' diff --git a/tools/build/build.cmd b/tools/build/build.cmd new file mode 100644 index 0000000000..45b59c42b2 --- /dev/null +++ b/tools/build/build.cmd @@ -0,0 +1,5 @@ +@echo off +REM Wrapper to run the PowerShell build script from cmd.exe +set SCRIPT_DIR=%~dp0 +powershell.exe -NoProfile -ExecutionPolicy Bypass -File "%SCRIPT_DIR%build.ps1" %* +exit /b %ERRORLEVEL% diff --git a/tools/build/build.ps1 b/tools/build/build.ps1 new file mode 100644 index 0000000000..e947541283 --- /dev/null +++ b/tools/build/build.ps1 @@ -0,0 +1,88 @@ +<# +.SYNOPSIS +Light-weight wrapper to build local projects (solutions/projects) in the current working directory using helpers in build-common.ps1. + +.DESCRIPTION +This script is intended for quick local builds. It dot-sources `build-common.ps1` and calls `BuildProjectsInDirectory` against the current directory. Use `-RestoreOnly` to only restore packages for local projects. If `-Platform` is omitted the script attempts to auto-detect the host platform. + +.PARAMETER Platform +Target platform (e.g., 'x64', 'arm64'). If omitted the script will try to detect the host platform automatically. + +.PARAMETER Configuration +Build configuration (e.g., 'Debug', 'Release'). Default: 'Debug'. + +.PARAMETER RestoreOnly +If specified, only perform package restore for local projects and skip the build steps for a solution file (i.e. .sln). + +.PARAMETER ExtraArgs +Any remaining, positional arguments passed to the script are forwarded to MSBuild as additional arguments (e.g., '/p:CIBuild=true'). + +.EXAMPLE +.\tools\build\build.ps1 +Builds any .sln/.csproj/.vcxproj in the current working directory (auto-detects Platform). + +.EXAMPLE +.\tools\build\build.ps1 -Platform x64 -Configuration Release +Builds local projects for x64 Release. + +.EXAMPLE +.\tools\build\build.ps1 '/p:CIBuild=true' '/p:SomeOther=Value' +Pass additional MSBuild arguments; these are forwarded to the underlying msbuild calls. + +.EXAMPLE +.\tools\build\build.ps1 -RestoreOnly '/p:CIBuild=true' +Only restores packages for local projects; ExtraArgs still forwarded to msbuild's restore phase. + +.NOTES +- This file expects `build-common.ps1` to be located in the same folder and dot-sources it to load helper functions. +- ExtraArgs are captured using PowerShell's ValueFromRemainingArguments and joined before being passed to the helpers. +#> + +param ( + [string]$Platform = '', + [string]$Configuration = 'Debug', + [switch]$RestoreOnly, + [Parameter(ValueFromRemainingArguments=$true)] + [string[]]$ExtraArgs +) + +. "$PSScriptRoot\build-common.ps1" + +# If user passed MSBuild-style args (e.g. './build.ps1 /p:CIBuild=true'), +# those will bind to $Platform/$Configuration; detect those and move them to ExtraArgs. +$positionalExtra = @() +if ($Platform -and $Platform -match '^[\/-]') { + $positionalExtra += $Platform + $Platform = '' +} +if ($Configuration -and $Configuration -match '^[\/-]') { + $positionalExtra += $Configuration + $Configuration = 'Debug' +} +if ($positionalExtra.Count -gt 0) { + if (-not $ExtraArgs) { $ExtraArgs = @() } + $ExtraArgs = $positionalExtra + $ExtraArgs +} + +# Auto-detect platform when not provided +if (-not $Platform -or $Platform -eq '') { + try { + $Platform = Get-DefaultPlatform + Write-Host ("[AUTO-PLATFORM] Detected platform: {0}" -f $Platform) + } catch { + Write-Warning "Failed to auto-detect platform; defaulting to x64" + $Platform = 'x64' + } +} + +$cwd = (Get-Location).ProviderPath +$extraArgsString = $null +if ($ExtraArgs -and $ExtraArgs.Count -gt 0) { $extraArgsString = ($ExtraArgs -join ' ') } + +if (BuildProjectsInDirectory -DirectoryPath $cwd -ExtraArgs $extraArgsString -Platform $Platform -Configuration $Configuration -RestoreOnly:$RestoreOnly) { + Write-Host "[BUILD] Local projects built; exiting." + exit 0 +} else { + Write-Host "[BUILD] No local projects found in $cwd" + exit 0 +}