cmake_cpputest_template/inc/misc/install_xpack_gcc.ps1
2025-12-23 14:33:54 -08:00

190 lines
No EOL
8.5 KiB
PowerShell

using namespace System.IO;
using namespace System.IO.Compression.FileSystem;
[CmdletBinding(DefaultParameterSetName = 'DestPreset')]
param (
# Uses one of the preset locations to install to
[Parameter(ParameterSetName = 'DestPreset', Position = 0)]
[ValidateSet('User', 'System')]
[string]$Destination = 'User',
# If a preset location is not used, then the user must specify a path to install to
[Parameter(ParameterSetName = 'DestPath', Position = 0, Mandatory = $true)]
[string]$Path,
# If enabled, will prevent modification of your PATH environment variable
[switch]$NoPath,
# If enabled, will not install our make
[switch]$NoMake,
# Skips all prompts and just installs, mainly intended for use if we need to re-run as admin.
[switch]$SkipPrompts
);
$ErrorActionPreference = 'Stop';
[string] $XpackVersion = '14.2.0-3';
[string] $XpackEdition = 'riscv-none-elf-gcc';
[string] $XpackArch = 'win32-x64';
[string] $XpackNameEd = "xpack-$XpackEdition";
[string] $XpackNameEdVer = "$XpackNameEd-$XpackVersion";
[string] $XpackNameEdVerArch = "$XpackNameEdVer-$XpackArch"
[string] $XpackDownloadFilename = "$XpackNameEdVerArch.zip";
[string] $XpackDownloadURL = "https://github.com/xpack-dev-tools/$XpackEdition-xpack/releases/download/v$XpackVersion/$XpackDownloadFilename";
[string] $MakeVersion = '4.4.1';
[string] $MakeEdition = 'without-guile';
[string] $MakeArch = 'w32';
[string] $MakeName = "make-$MakeVersion-$MakeEdition"
[string] $MakeNameFull = "$MakeName-$MakeArch";
[string] $MakeDownloadFilename = "$MakeNameFull-bin.zip";
[string] $MakeDownloadURL = "https://sourceforge.net/projects/ezwinports/files/$MakeDownloadFilename/download";
[EnvironmentVariableTarget] $PathScope = [EnvironmentVariableTarget]::User;
[string] $TempFolder = [Path]::GetTempPath();
[bool] $NoClearTemp = $false;
if ($PSCmdlet.ParameterSetName -EQ 'DestPreset')
{
if ($Destination -EQ 'User') { $Path = Join-Path $ENV:LocalAppData $XpackNameEd; }
elseif ($Destination -EQ 'System')
{
$Path = Join-Path $ENV:ProgramFiles $XpackNameEd;
$PathScope = [EnvironmentVariableTarget]::Machine;
}
else { throw 'Unknown Preset Destination'; }
}
if ([string]::IsNullOrEmpty($Path)) { throw 'Destination path must be provided'; }
[string] $TempFolder = Join-Path $TempFolder 'ch32fun';
[string] $XpackDownloadFilePath = Join-Path $TempFolder $XpackDownloadFilename;
[string] $XpackPath = Join-Path $Path $XpackVersion;
[string] $XpackBinPath = Join-Path $XpackPath 'bin';
[string] $MakeDownloadFilePath = Join-Path $TempFolder $MakeDownloadFilename;
Write-Host "${XpackNameEdVer}:";
Write-Host " will be downloaded from " -NoNewline -ForegroundColor 'DarkGray';
Write-Host $XpackDownloadURL -ForegroundColor 'DarkGreen';
Write-Host " to " -NoNewline -ForegroundColor 'DarkGray';
Write-Host $XpackDownloadFilePath -ForegroundColor 'DarkGreen';
Write-Host " then installed to " -NoNewline -ForegroundColor 'DarkGray';
Write-Host $XpackPath -ForegroundColor 'DarkGreen';
Write-Host;
if (-NOT $NoMake)
{
Write-Host "${MakeName}:"
Write-Host " will be downloaded from " -NoNewline -ForegroundColor 'DarkGray';
Write-Host $MakeDownloadURL -ForegroundColor 'DarkGreen';
Write-Host " to " -NoNewline -ForegroundColor 'DarkGray';
Write-Host $MakeDownloadFilePath -ForegroundColor 'DarkGreen';
Write-Host " then installed to " -NoNewline -ForegroundColor 'DarkGray';
Write-Host $XpackBinPath -ForegroundColor 'DarkGreen';
Write-Host;
}
if ($NoPath) { Write-Host "Your environment variables will not be edited.`n"; }
else
{
Write-Host "xpack will be added to your " -NoNewline;
Write-Host $PathScope.ToString().ToLower() -ForegroundColor 'DarkGreen' -NoNewline;
Write-Host " PATH environment variable.`n";
}
if (-NOT $SkipPrompts)
{
[string] $Answer = Read-Host -Prompt "Is this correct? (y/n)";
if ($Answer -NE 'y') { Exit; }
}
try
{ # Check if we need elevation
[bool] $IsAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] 'Administrator');
if ((-NOT $NoPath) -AND ($PathScope -EQ [EnvironmentVariableTarget]::Machine) -AND (-NOT $IsAdmin)) { throw; } # If we want to set the system PATH variable, we need to elevate
if (-NOT (Test-Path $Path)) { New-Item -ItemType Directory -Path $Path -ErrorAction SilentlyContinue -ErrorVariable PermissionError | Out-Null; }
if ($PermissionError) { throw; }
[string] $TestFile = Join-Path $Path 'TestingFile.txt';
Set-Content -Path $TestFile -Value 'Checking permissions.' -ErrorAction SilentlyContinue -ErrorVariable PermissionError;
if ($PermissionError) { throw; }
Remove-Item -Path $TestFile -ErrorAction SilentlyContinue -ErrorVariable PermissionError;
if ($PermissionError) { throw; }
}
catch
{
Write-Host 'Administrator permissions are required, requesting elevation...';
if (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] 'Administrator'))
{
if ([int](Get-CimInstance -Class Win32_OperatingSystem | Select-Object -ExpandProperty BuildNumber) -GE 6000)
{
$CommandLine = "-File `"$($MyInvocation.MyCommand.Path)`" -SkipPrompts";
if ($PSCmdlet.ParameterSetName -EQ 'DestPreset') { $CommandLine += " -Destination `"$Destination`""; }
else { $CommandLine += " -Path `"$Path`""; }
if ($NoPath) { $CommandLine += ' -NoPath'; }
if ($NoMake) { $CommandLine += ' -NoMake'; }
try { Start-Process -FilePath 'PowerShell.exe' -Verb RunAs -ArgumentList $CommandLine; }
catch { Write-Error 'Failed to elevate to administrator.'; Exit; }
}
}
else { Write-Error 'Could not access folder, but am already administrator!'; Exit; }
if (-NOT $NoPath) { Write-Host 'You may need to restart your terminal before changes apply.'; }
Exit;
}
[void](New-Item -Path $TempFolder -ItemType Directory -Force);
[void](New-Item -Path $Path -ItemType Directory -Force);
if ($PSVersionTable.PSVersion.Major -LT 7) { $ProgressPreference = 'SilentlyContinue'; } # Showing progress makes it download very slowly on old PowerShell https://github.com/PowerShell/PowerShell/issues/2138
Write-Host "Downloading $XpackDownloadFilename" -NoNewline;
try { Write-Host $(' ({0:F2} MB)...' -F ([long]::Parse((Invoke-WebRequest -UseBasicParsing -Uri $XpackDownloadURL -Method Head).Headers['Content-Length']) / (1024.0 * 1024.0))); }
catch { Write-Host '...'; }
Invoke-WebRequest -UseBasicParsing -Uri $XpackDownloadURL -OutFile $XpackDownloadFilePath;
if (-NOT $NoMake)
{
Write-Host "Downloading $MakeDownloadFilename...";
Invoke-WebRequest -UseBasicParsing -UserAgent 'Wget' -Uri $MakeDownloadURL -OutFile $MakeDownloadFilePath;
}
Write-Host "Extracting $XpackDownloadFilename...";
[string] $XpackTempPath = Join-Path $TempFolder 'xpath';
if (Test-Path $XpackTempPath) { Remove-Item -Recurse -Force $XpackTempPath; }
Expand-Archive $XpackDownloadFilePath -DestinationPath $XpackTempPath;
if (-NOT (Test-Path $XpackPath)) { [void](New-Item -Path $XpackPath -ItemType Directory -Force); }
Copy-Item -Path $(Join-Path $(Join-Path $XpackTempPath $XpackNameEdVer) '*') -Destination $XpackPath -Recurse -Force;
if (-NOT $NoMake)
{
[string] $MakeTempPath = Join-Path $TempFolder 'make';
Write-Host "Extracting $MakeDownloadFilename...";
Expand-Archive -Force $MakeDownloadFilePath -DestinationPath $MakeTempPath;
Move-Item -Force -Path $(Join-Path $MakeTempPath 'bin/make.exe') -Destination $XpackBinPath;
}
if (-NOT $NoClearTemp)
{
Write-Host "Deleting $TempFolder...";
Remove-Item $TempFolder -Force -Recurse;
}
if (-NOT $NoPath)
{
Write-Host "Adding to $PathScope PATH environment variable...";
$CurrentPATH = [Environment]::GetEnvironmentVariable('PATH', $PathScope);
if ([string]::IsNullOrWhitespace($CurrentPATH)) { Write-Error 'Could not retrieve the current PATH, not editing'; Exit; }
if ($CurrentPATH.Contains($XpackBinPath.TrimEnd(('\', '/')))) # If the install dir is on the path, regardless of trailing slash or not
{
Write-Host ' It looks like this xpack installation is already in your user PATH, so it will not be edited.';
}
else {
$NewPATH = "$CurrentPATH;$XpackBinPath";
[Environment]::SetEnvironmentVariable('PATH', $NewPATH, $PathScope);
Write-Host ' You may need to restart your terminal before you can use xpack gcc.';
}
# Detect GitHub Actions runner and export for future steps
if ($env:GITHUB_ACTIONS -eq 'true') {
Write-Host "Detected GitHub Actions runner. Prepending xPack bin to PATH for workflow steps..."
Add-Content -Path $env:GITHUB_ENV -Value "PATH=$XpackBinPath`:$env:PATH"
}
}
Write-Host 'Finished!';