cmake/cmake-builder.ps1 added quotes to arguments that contained spaces, so that arguments printed correctly for progress output. This introduced excess quotes that caused CMake (and likely other MS apps) confusion or argument misinterpretation. Instead of CMake seeing a single "Visual Studio 17 2022", CMake was actually seeing "\"Visual Studio 17 2022\"". This patch only adds the additional quotes when reporting progress or emitting debug output. Otherwise, command line arguments are passed unmolested.
584 lines
19 KiB
PowerShell
584 lines
19 KiB
PowerShell
# Author: B. Scott Michel (scooter.phd@gmail.com)
|
|
# "scooter me fecit"
|
|
|
|
<#
|
|
.SYNOPSIS
|
|
Configure and build SIMH's dependencies and simulators using the Microsoft Visual
|
|
Studio C compiler or MinGW-W64-based gcc compiler.
|
|
|
|
.DESCRIPTION
|
|
This script executes the three (3) phases of building the entire suite of SIMH
|
|
simulators using the CMake meta-build tool. The phases are:
|
|
|
|
1. Configure and generate the build environment selected by '-flavor' option.
|
|
2. Build missing runtime dependencies and the simulator suite with the compiler
|
|
configuration selected by the '-config' option. The "Release" configuration
|
|
generates optimized executables; the "Debug" configuration generates
|
|
development executables with debugger information.
|
|
3. Test the simulators
|
|
|
|
There is an install phase that can be invoked separately as part of the SIMH
|
|
packaging process.
|
|
|
|
The test and install phases can be enabled or disabled by the appropriate command line
|
|
flag (e.g., '-noInstall', '-noTest', '-testOnly', '-installOnly'.)
|
|
|
|
Build environment and artifact locations:
|
|
-----------------------------------------
|
|
cmake/build-vs* MSVC build products and artifacts
|
|
cmake/build-mingw MinGW-W64 products and artifacts
|
|
cmake/build-ninja Ninja builder products and artifacts
|
|
|
|
.EXAMPLE
|
|
PS> cmake-builder.ps1 -flavor vs2022 -config Release
|
|
|
|
Generate/configure, build, test and install the SIMH simulator suite using
|
|
the Visual Studio 2022 toolchain in the Release (optimized) compile
|
|
configuration.
|
|
|
|
.EXAMPLE
|
|
PS> cmake-builder.ps1 vs2022 Release
|
|
|
|
Another way to generate/configure, build, test and install the SIMH simulator
|
|
suite using the Visual Studio 2022 toolchain in the Release (optimized)
|
|
compile configuration.
|
|
|
|
.EXAMPLE
|
|
PS> cmake-builder.ps1 vs2019 Debug -notest -noinstall
|
|
|
|
Generate/configure and build the SIMH simulator suite with the Visual Studio
|
|
2019 toolchain in the Debug compile configuration. Does not execute tests and
|
|
does not install the simulators under the BIN subdirectory in the top of the
|
|
source tree.
|
|
|
|
.EXAMPLE
|
|
|
|
PS> cmake-builder.ps1 -flavor vs2019 -config Release -installonly
|
|
|
|
Install the simulators under the BIN subdirectory in the top of the source
|
|
tree. Does not generate/configure, but will build to ensure that compile
|
|
targets (simulator executables) are up-to-date.
|
|
#>
|
|
|
|
param (
|
|
## String arguments are positional, so if the user invokes this script
|
|
## as "cmake-builder.ps1 vs2022 Debug", it's the same as saying
|
|
## "cmake-builder.ps1 -flavor vs2022 -config Debug"
|
|
|
|
|
|
## The build environment's "flavor" that determines which CMake generator is used
|
|
## to create all of the build machinery to compile the SIMH simulator suite
|
|
## and the target compiler.
|
|
##
|
|
## Supported flavors:
|
|
## ------------------
|
|
## vs2022 Visual Studio 2022 (default)
|
|
## vs2022-xp Visual Studio 2022 XP compat
|
|
## vs2022-x64 Visual Studio 2022 64-bit
|
|
## vs2019 Visual Studio 2019
|
|
## vs2019-xp Visual Studio 2019 XP compat
|
|
## vs2019-x64 Visual Studio 2019 64-bit
|
|
## vs2017 Visual Studio 2017
|
|
## vs2017-xp Visual Studio 2017 XP compat
|
|
## vs2017-x64 Visual Studio 2017 64-bit
|
|
## vs2015 Visual Studio 2015
|
|
## mingw-make MinGW GCC/mingw32-make
|
|
## mingw-ninja MinGW GCC/ninja
|
|
[Parameter(Mandatory=$false)]
|
|
[string] $flavor = "vs2022",
|
|
|
|
## The target build configuration. Valid values: "Release" and "Debug"
|
|
[Parameter(Mandatory=$false)]
|
|
[string] $config = "Release",
|
|
|
|
## Supply a suffix for CPack package names via -DSIMH_PACKAGE_SUFFIX
|
|
[Parameter(Mandatory=$false)]
|
|
[string] $cpack_suffix = "",
|
|
|
|
## (optional) Build a specific simulator or simulators. Separate multiple
|
|
## targets with a comma, ## e.g. "--target pdp8,pdp11,vax750,altairz80,3b2"
|
|
[Parameter(Mandatory=$false)]
|
|
[string[]] $target = "",
|
|
|
|
## The rest are flag arguments
|
|
|
|
## Clean (remove) the CMake build directory before configuring
|
|
[Parameter(Mandatory=$false)]
|
|
[switch] $clean = $false,
|
|
|
|
## Get help.
|
|
[Parameter(Mandatory=$false)]
|
|
[switch] $help = $false,
|
|
|
|
## Compile the SIMH simulator suite without network support.
|
|
[Parameter(Mandatory=$false)]
|
|
[switch] $nonetwork = $false,
|
|
|
|
## Compile the SIMH simulator suite without video support.
|
|
[Parameter(Mandatory=$false)]
|
|
[switch] $novideo = $false,
|
|
|
|
## Compile the SIMH simulator without AIO support.
|
|
[Parameter(Mandatory=$false)]
|
|
[switch] $noaio = $false,
|
|
|
|
## Compile the SIMH simulator without AIO instrinsics ("lock-free" AIO),
|
|
## using lock-based AIO via thread mutexes instead.
|
|
[Parameter(Mandatory=$false)]
|
|
[switch] $noaiointrinsics = $false,
|
|
|
|
## Disable the build's tests.
|
|
[Parameter(Mandatory=$false)]
|
|
[switch] $notest = $false,
|
|
|
|
## Do not install the simulator suite in the source directory's BIN
|
|
## subdirectory.
|
|
[Parameter(Mandatory=$false)]
|
|
[switch] $noinstall = $false,
|
|
|
|
## Enable parallel builds.
|
|
[Parameter(Mandatory=$false)]
|
|
[switch] $parallel = $false,
|
|
|
|
## Configure and generate the build environment. Don't compile, test or install.
|
|
[Parameter(Mandatory=$false)]
|
|
[switch] $generate = $false,
|
|
|
|
## Only run the tests.
|
|
[Parameter(Mandatory=$false)]
|
|
[switch] $testonly = $false,
|
|
|
|
## Only install the SIMH simulator suite in the source directory's BIN
|
|
## subdirectory.
|
|
[Parameter(Mandatory=$false)]
|
|
[switch] $installOnly = $false,
|
|
|
|
## Turn on Windows API deprecation warnings. NOTE: These warnings are OFF by
|
|
## default.
|
|
[Parameter(Mandatory=$false)]
|
|
[switch] $windeprecation = $false,
|
|
|
|
## Enable Link-Time Optimization (LTO).
|
|
[Parameter(Mandatory=$false)]
|
|
[switch] $lto = $false,
|
|
|
|
## Turn on maximal compiler warnings for Debug builds (e.g. "-Wall" or "/W3")
|
|
[Parameter(Mandatory=$false)]
|
|
[switch] $debugWall = $false,
|
|
|
|
## Enable the cppcheck static code analysis rules
|
|
[Parameter(Mandatory=$false)]
|
|
[switch] $cppcheck = $false
|
|
)
|
|
|
|
$scriptName = $(Split-Path -Leaf $PSCommandPath)
|
|
$scriptCmd = ${PSCommandPath}
|
|
|
|
function Show-Help
|
|
{
|
|
Get-Help -full ${scriptCmd}
|
|
exit 0
|
|
}
|
|
|
|
|
|
## CMake generator info:
|
|
class GeneratorInfo
|
|
{
|
|
[string] $Generator
|
|
[bool] $SingleConfig
|
|
[bool] $UCRT
|
|
[string] $UCRTVersion
|
|
[string[]]$ArchArgs
|
|
|
|
GeneratorInfo([string]$gen, $configFlag, $ucrtFlag, $ucrtVer, [string[]]$arch)
|
|
{
|
|
$this.Generator = $gen
|
|
$this.SingleConfig = $configFlag
|
|
$this.UCRT = $ucrtFlag
|
|
$this.UCRTVersion = $ucrtVer
|
|
$this.ArchArgs = $arch
|
|
}
|
|
}
|
|
|
|
## Multiple build configurations selected at compile time
|
|
$multiConfig = $false
|
|
## Single configuration selected at configuration time
|
|
$singleConfig = $true
|
|
|
|
$cmakeGenMap = @{
|
|
"vs2022" = [GeneratorInfo]::new("Visual Studio 17 2022", $multiConfig, $false, "", @("-A", "Win32"));
|
|
"vs2022-xp" = [GeneratorInfo]::new("Visual Studio 17 2022", $multiConfig, $false, "", @("-A", "Win32", "-T", "v141_xp"));
|
|
"vs2022-x64" = [GeneratorInfo]::new("Visual Studio 17 2022", $multiConfig, $false, "", @("-A", "x64", "-T", "host=x64"));
|
|
"vs2019" = [GeneratorInfo]::new("Visual Studio 16 2019", $multiConfig, $false, "", @("-A", "Win32"));
|
|
"vs2019-xp" = [GeneratorInfo]::new("Visual Studio 16 2019", $multiConfig, $false, "", @("-A", "Win32", "-T", "v141_xp"));
|
|
"vs2019-x64" = [GeneratorInfo]::new("Visual Studio 17 2022", $multiConfig, $false, "", @("-A", "x64", "-T", "host=x64"));
|
|
"vs2017" = [GeneratorInfo]::new("Visual Studio 15 2017", $multiConfig, $false, "", @("-A", "Win32"));
|
|
"vs2017-xp" = [GeneratorInfo]::new("Visual Studio 15 2017", $multiConfig, $false, "", @("-A", "Win32", "-T", "v141_xp"));
|
|
"vs2017-x64" = [GeneratorInfo]::new("Visual Studio 17 2022", $multiConfig, $false, "", @("-A", "x64", "-T", "host=x64"));
|
|
"vs2015" = [GeneratorInfo]::new("Visual Studio 14 2015", $multiConfig, $false, "", @());
|
|
"mingw-make" = [GeneratorInfo]::new("MinGW Makefiles", $singleConfig, $false, "", @());
|
|
"mingw-ninja" = [GeneratorInfo]::new("Ninja", $singleConfig, $false, "", @())
|
|
}
|
|
|
|
|
|
function Get-GeneratorInfo([string]$flavor)
|
|
{
|
|
return $cmakeGenMap[$flavor]
|
|
}
|
|
|
|
function Quote-Args([string[]]$arglist)
|
|
{
|
|
return ($arglist | foreach-object { if ($_ -like "* *") { "`"$_`"" } else { $_ } })
|
|
}
|
|
|
|
|
|
## Output help early and exit.
|
|
if ($help)
|
|
{
|
|
Show-Help
|
|
}
|
|
|
|
### CTest params:
|
|
## timeout is 180 seconds
|
|
$ctestTimeout = "300"
|
|
|
|
## Sanity checking: Check that utilities we expect exist...
|
|
## CMake: Save the location of the command because we'll invoke it later. Same
|
|
## with CTest
|
|
$cmakeCmd = $(Get-Command -Name cmake.exe -ErrorAction Ignore).Path
|
|
$ctestCmd = $(Get-Command -Name ctest.exe -ErrorAction Ignore).Path
|
|
if ($cmakeCmd.Length -gt 0)
|
|
{
|
|
Write-Host "** ${scriptName}: cmake is '${cmakeCmd}'"
|
|
Write-Host "** $(& ${cmakeCmd} --version)"
|
|
}
|
|
else {
|
|
@"
|
|
!! ${scriptName} error:
|
|
|
|
The 'cmake' command was not found. Please ensure that you have installed CMake
|
|
and that your PATH environment variable references the directory in which it
|
|
was installed.
|
|
"@
|
|
|
|
exit 1
|
|
}
|
|
|
|
if (!$testonly)
|
|
{
|
|
## Check for GCC and mingw32-make if user wants the mingw flavor build.
|
|
if ($flavor -eq "mingw" -or $flavor -eq "ninja")
|
|
{
|
|
if ($(Get-Command gcc -ErrorAction Ignore).Path.Length -eq 0) {
|
|
@"
|
|
!! ${scriptName} error:
|
|
|
|
Did not find 'gcc', the GNU C/C++ compiler toolchain. Please ensure you have
|
|
installed gcc and that your PATH environment variables references the directory
|
|
in which it was installed.
|
|
"@
|
|
exit 1
|
|
}
|
|
|
|
if ($(Get-Command mingw32-make -ErrorAction Ignore).Path.Length -eq 0) {
|
|
@"
|
|
!! ${scriptName} error:
|
|
|
|
Did not find 'mingw32-make'. Please ensure you have installed mingw32-make and
|
|
that your PATH environment variables references the directory in which it was
|
|
installed.
|
|
|
|
See the .travis/deps.sh functions mingw64() and ucrt64() for the pacman packages
|
|
that should be installed.
|
|
"@
|
|
exit 1
|
|
}
|
|
}
|
|
}
|
|
|
|
## Validate the requested configuration.
|
|
if (!@("Release", "Debug").Contains($config))
|
|
{
|
|
@"
|
|
${scriptName}: Invalid configuration: "${config}".
|
|
|
|
"@
|
|
Show-Help
|
|
}
|
|
|
|
## Look for Git's /usr/bin subdirectory: CMake (and other utilities) have issues
|
|
## with the /bin/sh installed there (Git's version of MinGW.)
|
|
|
|
$tmp_path = $env:PATH
|
|
$git_usrbin = "${env:ProgramFiles}\Git\usr\bin"
|
|
$tmp_path = ($tmp_path.Split(';') | Where-Object { $_ -ne "${git_usrbin}"}) -join ';'
|
|
if ($tmp_path -ne ${env:PATH})
|
|
{
|
|
Write-Host "** ${scriptName}: Removed ${git_usrbin} from PATH (Git MinGW problem)"
|
|
$env:PATH = $tmp_path
|
|
}
|
|
|
|
## Also make sure that none of the other cmake-* directories are in the user's PATH
|
|
## because CMake's find_package does traverse PATH looking for potential candidates
|
|
## for dependency libraries.
|
|
|
|
$origPath = $env:PATH
|
|
$modPath = $origPath
|
|
|
|
if (Test-Path -Path cmake\dependencies) {
|
|
$bdirs = $(Get-ChildItem -Attribute Directory cmake\dependencies\*).ForEach({ $_.FullName + "\bin" })
|
|
$modPath = (${env:Path}.Split(';') | Where-Object { $bdirs -notcontains $_ }) -join ';'
|
|
if ($modPath -ne $origPath) {
|
|
Write-Host "** ${scriptName}: Removed cmake\dependencies 'bin' directories from PATH."
|
|
}
|
|
}
|
|
|
|
## Setup:
|
|
$simhTopDir = $(Split-Path -Parent $(Resolve-Path -Path $PSCommandPath).Path)
|
|
While (!([String]::IsNullOrEmpty($simhTopDir) -or (Test-Path -Path ${simhTopDir}\CMakeLists.txt))) {
|
|
$simhTopDir = $(Split-Path -Parent $simhTopDir)
|
|
}
|
|
if ([String]::IsNullOrEmpty($simhTopDir)) {
|
|
@"
|
|
!! ${scriptName}: Cannot locate SIMH top-level source directory from
|
|
the script's path name. You should really not see this message.
|
|
"@
|
|
|
|
exit 1
|
|
} else {
|
|
Write-Host "** ${scriptName}: SIMH top-level source directory is ${simhTopDir}"
|
|
}
|
|
|
|
$buildDir = "${simhTopDir}\cmake\build-${flavor}"
|
|
$genInfo = $(Get-GeneratorInfo $flavor)
|
|
if ($null -eq $genInfo)
|
|
{
|
|
Write-Host ""
|
|
Write-Host "!! ${scriptName}: Unrecognized build flavor '${flavor}'."
|
|
Write-Host ""
|
|
Show-Help
|
|
}
|
|
|
|
if ($testonly)
|
|
{
|
|
$scriptPhases = @("test")
|
|
}
|
|
elseif ($generate)
|
|
{
|
|
$scriptPhases = @("generate")
|
|
}
|
|
elseif ($installOnly)
|
|
{
|
|
$scriptPhases = @("install")
|
|
}
|
|
else
|
|
{
|
|
$scriptPhases = @( "generate", "build", "test")
|
|
if ($notest)
|
|
{
|
|
$scriptPhases = $scriptPhases | Where-Object { $_ -ne 'test' }
|
|
}
|
|
if ($noinstall -or ![String]::IsNullOrEmpty($target))
|
|
{
|
|
$scriptPhases = $scriptPhases | Where-Object { $_ -ne 'install' }
|
|
}
|
|
}
|
|
|
|
if (($scriptPhases -contains "generate") -or ($scriptPhases -contains "build"))
|
|
{
|
|
## Clean out the build subdirectory
|
|
if ((Test-Path -Path ${buildDir}) -and $clean)
|
|
{
|
|
Write-Host "** ${scriptName}: Removing ${buildDir}"
|
|
Remove-Item -recurse -force -Path ${buildDir} -ErrorAction SilentlyContinue | Out-Null
|
|
}
|
|
|
|
if (!(Test-Path -Path ${buildDir}))
|
|
{
|
|
Write-Host "** ${scriptName}: Creating ${buildDir} subdirectory"
|
|
New-Item -Path ${buildDir} -ItemType Directory | Out-Null
|
|
}
|
|
else
|
|
{
|
|
Write-Host "** ${scriptName}: ${buildDir} exists."
|
|
}
|
|
|
|
## Unconditionally remove the CMake cache.
|
|
Remove-Item -Force -Path ${buildDir}/CMakeCache.txt -ErrorAction SilentlyContinue | Out-Null
|
|
Remove-Item -Recurse -Force -Path ${buildDir}/CMakeFiles -ErrorAction SilentlyContinue | Out-Null
|
|
|
|
## Where we do the heaving lifting:
|
|
$generateArgs = @("-G", $genInfo.Generator)
|
|
if ($genInfo.SingleConfig) {
|
|
## Single configuration set at compile time:
|
|
$generateArgs += @("-DCMAKE_BUILD_TYPE=${config}")
|
|
}
|
|
if ($genInfo.UCRT) {
|
|
## Universal Windows Platform
|
|
$generateArgs += @("-DCMAKE_SYSTEM_NAME=WindowsStore", "-DCMAKE_SYSTEM_VERSION=$($genInfo.UCRTVersion)")
|
|
}
|
|
$generateArgs += $genInfo.ArchArgs + @("-Wno-dev", "--no-warn-unused-cli")
|
|
if ($nonetwork)
|
|
{
|
|
$generateArgs += @("-DWITH_NETWORK:Bool=Off")
|
|
}
|
|
if ($novideo)
|
|
{
|
|
$generateArgs += @("-DWITH_VIDEO:Bool=Off")
|
|
}
|
|
if ($noaio)
|
|
{
|
|
$generateArgs += @("-DWITH_ASYNC:Bool=Off")
|
|
}
|
|
if ($noaiointrinsics)
|
|
{
|
|
$generateArgs += @("-DDONT_USE_AIO_INTRINSICS:Bool=On")
|
|
}
|
|
if ($lto)
|
|
{
|
|
$generateArgs += @("-DRELEASE_LTO:Bool=On")
|
|
}
|
|
if ($debugWall)
|
|
{
|
|
$generateArgs += @("-DDEBUG_WALL:Bool=On")
|
|
}
|
|
if ($cppcheck)
|
|
{
|
|
$generateArgs += @("-DENABLE_CPPCHECK:Bool=On")
|
|
}
|
|
if (![String]::IsNullOrEmpty($cpack_suffix))
|
|
{
|
|
$generateArgs += @("-DSIMH_PACKAGE_SUFFIX:Bool=${cpack_suffix}")
|
|
}
|
|
|
|
$buildArgs = @("--build", "${buildDir}", "--config", "${config}")
|
|
if ($parallel)
|
|
{
|
|
$buildArgs += "--parallel"
|
|
}
|
|
if ($verbose)
|
|
{
|
|
$buildArgs += "--verbose"
|
|
}
|
|
if ($windeprecation)
|
|
{
|
|
$buildArgs += "-DWINAPI_DEPRECATION:Bool=TRUE"
|
|
}
|
|
if (![String]::IsNullOrEmpty($target)) {
|
|
foreach ($targ in $target) {
|
|
$buildArgs += @("--target", "$targ")
|
|
}
|
|
}
|
|
|
|
$buildSpecificArgs = @()
|
|
if ($flavor -eq "mingw" -and $parallel)
|
|
{
|
|
## Limit the number of parallel jobs mingw32-make can spawn. Otherwise
|
|
## it'll overwhelm the machine.
|
|
$buildSpecificArgs += @("-j", "8")
|
|
}
|
|
}
|
|
|
|
$exitval = 0
|
|
|
|
foreach ($phase in $scriptPhases) {
|
|
$savedPATH = $env:PATH
|
|
$argList = @()
|
|
$phaseCommand = "Write-Output"
|
|
|
|
switch -exact ($phase)
|
|
{
|
|
"generate" {
|
|
$generateArgs += @("-S", ${simhTopDir})
|
|
$generateArgs += @("-B", ${buildDir})
|
|
|
|
Write-Host "** ${scriptName}: Configuring and generating"
|
|
|
|
$phaseCommand = ${cmakeCmd}
|
|
$argList = $generateArgs
|
|
}
|
|
|
|
"build" {
|
|
Write-Host "** ${scriptName}: Building simulators."
|
|
|
|
$phaseCommand = ${cmakeCmd}
|
|
$argList = $buildArgs + $buildSpecificArgs
|
|
}
|
|
|
|
"test" {
|
|
Write-Host "** ${scriptName}: Testing simulators."
|
|
|
|
## CTest arguments:
|
|
$testArgs = @("-C", $config, "--timeout", $ctestTimeout, "-T", "test",
|
|
"--output-on-failure")
|
|
|
|
## Output gets confusing (and tests can time out when executing in parallel)
|
|
## if ($parallel)
|
|
## {
|
|
## $testArgs += @("--parallel", $ctestParallel)
|
|
## }
|
|
|
|
if ($verbose)
|
|
{
|
|
$testArgs += @("--verbose")
|
|
}
|
|
|
|
if (![String]::IsNullOrEmpty($target)) {
|
|
$tests = "simh-(" + ($target -join "|") + ")`$"
|
|
$testArgs += @("-R", $tests)
|
|
}
|
|
|
|
$phaseCommand = ${ctestCmd}
|
|
$argList = $testArgs
|
|
|
|
$env:PATH = $modPath
|
|
|
|
$depTopDir = $(& $cmakeCmd -L -N ${buildDir} | Select-String "SIMH_DEP_TOPDIR")
|
|
if ($depTopDir) {
|
|
## RHS of the cached variable's value.
|
|
$depTopDir = $depTopDir.Line.Split('=')[1]
|
|
$env:PATH = "${depTopdir}\bin;${env:PATH}"
|
|
}
|
|
}
|
|
|
|
"install" {
|
|
Write-Host "** ${scriptName}: Installing simulators."
|
|
|
|
$installPrefix = $(& $cmakeCmd -L -N ${buildDir} | Select-String "CMAKE_INSTALL_PREFIX")
|
|
$installPrefix = $installPrefix.Line.Split('=')[1]
|
|
$installPath = $installPrefix
|
|
|
|
Write-Host "** ${scriptName}: Install directory ${installPath}"
|
|
if (!(Test-Path -Path ${installPath}))
|
|
{
|
|
Write-Host "** ${scriptName}: Creating ${installPath}"
|
|
New-Item -${installPath} -ItemType Directory -ErrorAction SilentlyContinue
|
|
}
|
|
|
|
$phaseCommand = ${cmakeCmd}
|
|
$argList = @( "--install", "${buildDir}", "--config", "${config}")
|
|
}
|
|
}
|
|
|
|
try {
|
|
Push-Location ${buildDir}
|
|
Write-Host "** ${phaseCommand} $(Quote-Args ${argList})"
|
|
& $phaseCommand @arglist
|
|
if ($LastExitCode -gt 0) {
|
|
$printPhase = (Get-Culture).TextInfo.ToTitleCase($phase)
|
|
Write-Error $("${printPhase} phase exited with non-zero status: " + $LastExitCode)
|
|
exit 1
|
|
}
|
|
}
|
|
catch {
|
|
Write-Host "Error running '${phaseCommand} ${argList}' command: $($_.Exception.Message)" -ForegroundColor Red
|
|
throw $_
|
|
}
|
|
finally {
|
|
Pop-Location
|
|
}
|
|
|
|
$env:PATH = $savedPATH
|
|
}
|
|
|
|
exit $exitval
|