Skip to content

Instantly share code, notes, and snippets.

@CypherpunkSamurai
Created May 19, 2026 06:29
Show Gist options
  • Select an option

  • Save CypherpunkSamurai/10482a5fac89cdf1b8b0bf847f118de5 to your computer and use it in GitHub Desktop.

Select an option

Save CypherpunkSamurai/10482a5fac89cdf1b8b0bf847f118de5 to your computer and use it in GitHub Desktop.
Rust Installer - Portable
<#
.SYNOPSIS
Creates a portable Rust installation with virtualenv-style activation scripts.
.DESCRIPTION
This script creates a self-contained, portable Rust installation that can be
moved between systems or run from external drives. Supports both GNU and MSVC toolchains.
Creates Python virtualenv-style activate/deactivate scripts for shell integration.
.PARAMETER InstallDir
Directory where portable Rust will be installed. Default: .PortableRust
.PARAMETER ToolchainVersion
Rust toolchain version to install. Default: stable (Options: stable, beta, nightly, or specific version)
.PARAMETER ToolchainType
Type of toolchain to install. Default: gnu (Options: gnu, msvc)
.EXAMPLE
.\Install-PortableRust.ps1
Creates a portable Rust installation with GNU toolchain in .PortableRust
.EXAMPLE
.\Install-PortableRust.ps1 -ToolchainType msvc
Creates a portable Rust installation with MSVC toolchain
.EXAMPLE
.\Install-PortableRust.ps1 -InstallDir "D:\Rust" -ToolchainVersion "nightly" -ToolchainType "gnu"
Creates a portable nightly Rust installation with GNU toolchain in D:\Rust
.EXAMPLE
iwr -useb https://raw.githubusercontent.com/yourusername/Install-PortableRust.ps1/main/Install-PortableRust.ps1 | iex
Downloads and runs the script directly
.NOTES
Author: CypherpunkSamurai
Version: 1.4 (Architecture Fix)
Date: 2026-05-19
#>
param (
[string]$InstallDir = ".PortableRust",
[string]$ToolchainVersion = "stable",
[ValidateSet("gnu", "msvc")]
[string]$ToolchainType = "gnu"
)
function Show-Banner {
$bannerColor = "Cyan"
$version = "v1.4 (Architecture Fix)"
Write-Host "`n=======================================================" -ForegroundColor $bannerColor
Write-Host " PORTABLE RUST INSTALLER $version" -ForegroundColor $bannerColor
Write-Host "=======================================================" -ForegroundColor $bannerColor
Write-Host " A tool to create portable Rust development environments" -ForegroundColor $bannerColor
Write-Host "=======================================================" -ForegroundColor $bannerColor
Write-Host ""
}
function Write-ColorMessage {
param(
[Parameter(Mandatory=$true)]
[string]$Message,
[Parameter(Mandatory=$false)]
[string]$ForegroundColor = "White",
[switch]$NoNewline
)
$params = @{
Object = $Message
ForegroundColor = $ForegroundColor
}
if ($NoNewline) {
$params.Add("NoNewline", $true)
}
Write-Host @params
}
function Initialize-InstallationDirectory {
param (
[Parameter(Mandatory=$true)]
[string]$Path
)
Write-ColorMessage "Setting up installation directory..." "Cyan"
if (-not (Test-Path -Path $Path)) {
New-Item -Path $Path -ItemType Directory | Out-Null
Write-ColorMessage "Created directory: $Path" "Green"
}
$absolutePath = (Resolve-Path $Path).Path
Write-ColorMessage "Installation directory: $absolutePath" "Yellow"
return $absolutePath
}
# ✅ FIXED: Proper PowerShell comment-based help (not Python docstrings)
function Get-SystemArchitecture {
<#
.SYNOPSIS
Detects the appropriate Rust host architecture triplet for Windows.
.DESCRIPTION
Returns architecture string like x86_64-pc-windows-gnu
#>
$arch = $env:PROCESSOR_ARCHITECTURE
switch ($arch) {
"ARM64" { return "aarch64-pc-windows-$ToolchainType" }
"AMD64" { return "x86_64-pc-windows-$ToolchainType" }
"x86" { return "i686-pc-windows-$ToolchainType" }
default {
if ([Environment]::Is64BitOperatingSystem) {
return "x86_64-pc-windows-$ToolchainType"
}
return "i686-pc-windows-$ToolchainType"
}
}
}
function Get-RustupInitializer {
param (
[Parameter(Mandatory=$true)]
[string]$InstallDirectory,
[Parameter(Mandatory=$true)]
[string]$HostArch
)
$rustupBaseUrl = "https://static.rust-lang.org/rustup/dist"
$rustupInitUrl = "$rustupBaseUrl/$HostArch/rustup-init.exe"
$rustupInitPath = Join-Path $InstallDirectory "rustup-init.exe"
try {
Write-ColorMessage "Downloading rustup-init.exe... " "Cyan" -NoNewline
$oldProgress = $ProgressPreference
$ProgressPreference = "SilentlyContinue"
try {
Invoke-WebRequest -Uri $rustupInitUrl -OutFile $rustupInitPath
}
finally {
$ProgressPreference = $oldProgress
}
Write-ColorMessage "DONE!" "Green"
return $rustupInitPath
}
catch {
Write-ColorMessage "FAILED!" "Red"
Write-ColorMessage "Error: $_" "Red"
exit 1
}
}
function Install-Rust {
param (
[Parameter(Mandatory=$true)]
[string]$InitializerPath,
[Parameter(Mandatory=$true)]
[string]$ToolchainVersion,
[Parameter(Mandatory=$true)]
[string]$HostArch
)
try {
Write-ColorMessage "Installing Rust ($ToolchainVersion) with $HostArch toolchain..." "Cyan"
& $InitializerPath --no-modify-path -y --default-toolchain $ToolchainVersion --default-host $HostArch
if ($LASTEXITCODE -ne 0) {
throw "rustup-init.exe failed with exit code $LASTEXITCODE"
}
Write-ColorMessage "Rust installation completed successfully!" "Green"
Remove-Item -Path $InitializerPath -Force
Write-ColorMessage "Removed rustup-init.exe" "Green"
return $true
}
catch {
Write-ColorMessage "Failed to install Rust: $_" "Red"
exit 1
}
}
function Create-ActivationScripts {
param (
[Parameter(Mandatory=$true)]
[string]$InstallDirectory,
[Parameter(Mandatory=$true)]
[string]$RustupDir,
[Parameter(Mandatory=$true)]
[string]$CargoDir,
[Parameter(Mandatory=$true)]
[string]$HostArch
)
Write-ColorMessage "Creating activation scripts..." "Cyan"
$scriptsDir = Join-Path $InstallDirectory "Scripts"
if (-not (Test-Path -Path $scriptsDir)) {
New-Item -Path $scriptsDir -ItemType Directory | Out-Null
}
# FIXED: Correct path separators with backslashes
$activateBatContent = @"
@echo off
REM Rust Virtual Environment Activation Script (CMD)
set "RUSTUP_HOME=%~dp0..\.rustup"
set "CARGO_HOME=%~dp0..\.cargo"
set "PATH=%~dp0..\.cargo\bin;%PATH%"
if "%~1"=="" goto :show_info
%*
goto :end
:show_info
if not defined _RUST_OLD_PATH ( set "_RUST_OLD_PATH=%PATH%" )
if not defined _RUST_OLD_RUSTUP_HOME ( if defined RUSTUP_HOME ( set "_RUST_OLD_RUSTUP_HOME=%RUSTUP_HOME%" ) )
if not defined _RUST_OLD_CARGO_HOME ( if defined CARGO_HOME ( set "_RUST_OLD_CARGO_HOME=%CARGO_HOME%" ) )
if not defined _RUST_OLD_PROMPT ( set "_RUST_OLD_PROMPT=%PROMPT%" )
set "PROMPT=(rust-env) %PROMPT%"
echo Rust environment activated (CMD)
echo Toolchain: $HostArch
echo.
echo Available commands: rustc, cargo, rustup
echo To deactivate, run: deactivate
echo.
echo Quick start: cargo new my_project
:end
"@
$deactivateBatContent = @"
@echo off
if defined _RUST_OLD_PATH ( set "PATH=%_RUST_OLD_PATH%" & set "_RUST_OLD_PATH=" )
if defined _RUST_OLD_RUSTUP_HOME ( set "RUSTUP_HOME=%_RUST_OLD_RUSTUP_HOME%" & set "_RUST_OLD_RUSTUP_HOME=" ) else ( set "RUSTUP_HOME=" )
if defined _RUST_OLD_CARGO_HOME ( set "CARGO_HOME=%_RUST_OLD_CARGO_HOME%" & set "_RUST_OLD_CARGO_HOME=" ) else ( set "CARGO_HOME=" )
if defined _RUST_OLD_PROMPT ( set "PROMPT=%_RUST_OLD_PROMPT%" & set "_RUST_OLD_PROMPT=" )
echo Rust environment deactivated
"@
# FIXED: Correct PowerShell path construction and secure command execution
$activatePs1Content = @"
# Rust Virtual Environment Activation Script (PowerShell)
param(
[Parameter(ValueFromRemainingArguments=`$true)]
[string[]]`$Command
)
function global:deactivate {
if (`$env:_RUST_OLD_PATH) { `$env:PATH = `$env:_RUST_OLD_PATH; Remove-Item -Path Env:_RUST_OLD_PATH }
if (`$env:_RUST_OLD_RUSTUP_HOME) { `$env:RUSTUP_HOME = `$env:_RUST_OLD_RUSTUP_HOME; Remove-Item -Path Env:_RUST_OLD_RUSTUP_HOME } elseif (`$env:RUSTUP_HOME) { Remove-Item -Path Env:RUSTUP_HOME }
if (`$env:_RUST_OLD_CARGO_HOME) { `$env:CARGO_HOME = `$env:_RUST_OLD_CARGO_HOME; Remove-Item -Path Env:_RUST_OLD_CARGO_HOME } elseif (`$env:CARGO_HOME) { Remove-Item -Path Env:CARGO_HOME }
if (Get-Command _OLD_RUST_PROMPT -ErrorAction SilentlyContinue) { Copy-Item -Path Function:_OLD_RUST_PROMPT -Destination Function:prompt; Remove-Item -Path Function:_OLD_RUST_PROMPT }
Remove-Item -Path Function:deactivate
Write-Host "Rust environment deactivated" -ForegroundColor Green
}
`$scriptDir = Split-Path -Parent `$MyInvocation.MyCommand.Path
`$installDir = Split-Path -Parent `$scriptDir
`$rustupDir = Join-Path `$installDir ".rustup"
`$cargoDir = Join-Path `$installDir ".cargo"
`$env:RUSTUP_HOME = `$rustupDir
`$env:CARGO_HOME = `$cargoDir
# FIXED: Correct path separator
`$env:PATH = "`$cargoDir\bin;" + `$env:PATH
if (`$Command) {
if (`$Command.Count -gt 0) {
`$exe = `$Command[0]
`$args = if (`$Command.Count -gt 1) { `$Command[1..(`$Command.Count-1)] } else { @() }
# FIXED: Secure execution with & operator
& `$exe @args
}
} else {
if (-not `$env:_RUST_OLD_PATH) { `$env:_RUST_OLD_PATH = `$env:PATH }
if (`$env:RUSTUP_HOME -and -not `$env:_RUST_OLD_RUSTUP_HOME) { `$env:_RUST_OLD_RUSTUP_HOME = `$env:RUSTUP_HOME }
if (`$env:CARGO_HOME -and -not `$env:_RUST_OLD_CARGO_HOME) { `$env:_RUST_OLD_CARGO_HOME = `$env:CARGO_HOME }
if (Get-Command prompt -ErrorAction SilentlyContinue) { Copy-Item -Path Function:prompt -Destination Function:_OLD_RUST_PROMPT }
function global:prompt {
Write-Host "(rust-env) " -NoNewline -ForegroundColor Yellow
if (Get-Command _OLD_RUST_PROMPT -ErrorAction SilentlyContinue) { & _OLD_RUST_PROMPT } else { "PS " + (Get-Location) + "> " }
}
Write-Host "Rust environment activated (PowerShell)" -ForegroundColor Green
Write-Host "Toolchain: $HostArch" -ForegroundColor Cyan
Write-Host ""
Write-Host "Available commands: " -NoNewline; Write-Host "rustc, cargo, rustup" -ForegroundColor White
Write-Host "To deactivate, run: " -NoNewline; Write-Host "deactivate" -ForegroundColor Yellow
Write-Host ""
Write-Host "Quick start: " -NoNewline; Write-Host "cargo new my_project" -ForegroundColor Cyan
Write-Host ""
Write-Host "Command runner usage: " -NoNewline; Write-Host ".\Scripts\Activate.ps1 -- cargo --version" -ForegroundColor Gray
}
"@
$readmePath = Join-Path $InstallDirectory "README.txt"
$currentDate = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$readmeContent = @"
╔═════════════════════════════════════════════════════════════════════╗
║ PORTABLE RUST INSTALLER v1.4 (Architecture Fix) ║
║ Created: $currentDate ║
║ Toolchain: $HostArch ║
╚═════════════════════════════════════════════════════════════════════╝
USAGE:
CMD: Scripts\activate.bat [command...]
PowerShell: .\Scripts\Activate.ps1 [-- command args...]
EXAMPLES:
.\Scripts\Activate.ps1 -- cargo --version
.\Scripts\Activate.ps1 -- cargo new my_project
Scripts\activate.bat cargo build
DEACTIVATE:
Run 'deactivate' from an activated interactive shell
FEATURES:
✅ Portable, movable installation
✅ Auto-detects x86_64/ARM64/x86 architecture
✅ Virtualenv-style activation
✅ No system PATH modification
✅ Pre-configured Cargo settings
"@
try {
$activateBatContent | Out-File -FilePath (Join-Path $scriptsDir "activate.bat") -Encoding ASCII
$deactivateBatContent | Out-File -FilePath (Join-Path $scriptsDir "deactivate.bat") -Encoding ASCII
$activatePs1Content | Out-File -FilePath (Join-Path $scriptsDir "Activate.ps1") -Encoding UTF8
$readmeContent | Out-File -FilePath $readmePath -Encoding UTF8
Write-ColorMessage "Created activation scripts in: $scriptsDir" "Green"
return $true
}
catch {
Write-ColorMessage "Failed to create activation scripts: $_" "Red"
exit 1
}
}
function Test-RustInstallation {
param (
[Parameter(Mandatory=$true)]
[string]$CargoDir,
[Parameter(Mandatory=$true)]
[string]$RustupDir
)
Write-ColorMessage "Verifying Rust installation..." "Cyan"
$cargoBinPath = Join-Path $CargoDir "bin\cargo.exe"
$rustcBinPath = Join-Path $CargoDir "bin\rustc.exe"
$rustupBinPath = Join-Path $CargoDir "bin\rustup.exe"
$allTestsPassed = $true
foreach ($binPath in @($cargoBinPath, $rustcBinPath, $rustupBinPath)) {
$binName = Split-Path $binPath -Leaf
if (Test-Path -Path $binPath) {
try {
$output = & $binPath --version 2>&1
if ($LASTEXITCODE -eq 0) {
Write-ColorMessage "✅ $binName`: $output" "Green"
} else {
Write-ColorMessage "❌ $binName test failed: exit code $LASTEXITCODE" "Red"
$allTestsPassed = $false
}
}
catch {
Write-ColorMessage "❌ $binName test failed: $_" "Red"
$allTestsPassed = $false
}
} else {
Write-ColorMessage "❌ $binName not found at: $binPath" "Red"
$allTestsPassed = $false
}
}
return $allTestsPassed
}
function Initialize-CargoConfig {
param (
[Parameter(Mandatory=$true)]
[string]$CargoDir
)
Write-ColorMessage "Setting up Cargo configuration..." "Cyan"
$cargoConfigPath = Join-Path $CargoDir "config.toml"
$cargoConfigContent = @"
# Portable Rust Cargo Configuration
[build]
# jobs = 0 # Auto-detect cores
[cargo-new]
name = "Your Name"
email = "[email protected]"
[net]
retry = 3
[term]
progress.when = "auto"
progress.width = 80
"@
try {
$cargoConfigContent | Out-File -FilePath $cargoConfigPath -Encoding UTF8
Write-ColorMessage "Created Cargo config: $cargoConfigPath" "Green"
return $true
}
catch {
Write-ColorMessage "Warning: Could not create Cargo config: $_" "Yellow"
return $false
}
}
function Test-CargoFunctionality {
param (
[Parameter(Mandatory=$true)]
[string]$CargoDir,
[Parameter(Mandatory=$true)]
[string]$InstallDir
)
Write-ColorMessage "Testing Cargo functionality..." "Cyan"
$cargoBinPath = Join-Path $CargoDir "bin\cargo.exe"
$testProjectDir = Join-Path $InstallDir "test_project"
try {
if (Test-Path -Path $testProjectDir) {
Remove-Item -Path $testProjectDir -Recurse -Force
}
$createResult = & $cargoBinPath "new" $testProjectDir --name "test_project" 2>&1
if ($LASTEXITCODE -ne 0) {
Write-ColorMessage "⚠️ Cargo new failed: $createResult" "Yellow"
return $false
}
Push-Location $testProjectDir
try {
$buildResult = & $cargoBinPath "check" 2>&1
if ($LASTEXITCODE -eq 0) {
Write-ColorMessage "✅ Cargo functionality test passed" "Green"
return $true
} else {
Write-ColorMessage "⚠️ Cargo check failed: $buildResult" "Yellow"
return $false
}
}
finally {
Pop-Location
}
}
catch {
Write-ColorMessage "⚠️ Cargo functionality test failed: $_" "Yellow"
return $false
}
finally {
if (Test-Path -Path $testProjectDir) {
Remove-Item -Path $testProjectDir -Recurse -Force -ErrorAction SilentlyContinue
}
}
}
function Show-Usage {
Write-ColorMessage "`n🦀 USAGE (Enhanced Dual-Mode):" "Magenta"
Write-ColorMessage "`nInteractive Mode:" "Cyan"
Write-ColorMessage " .\Scripts\Activate.ps1 # Activate" "Gray"
Write-ColorMessage " Scripts\activate.bat # Activate (CMD)" "Gray"
Write-ColorMessage " deactivate # Exit" "Gray"
Write-ColorMessage "`nCommand Mode:" "Cyan"
Write-ColorMessage " .\Scripts\Activate.ps1 -- cargo --version" "Gray"
Write-ColorMessage " Scripts\activate.bat cargo new my_project" "Gray"
Write-ColorMessage "`n📦 Examples:" "Magenta"
Write-ColorMessage " .\Scripts\Activate.ps1 -- cargo new hello" "Gray"
Write-ColorMessage " cd hello" "Gray"
Write-ColorMessage " ..\Scripts\Activate.ps1 -- cargo run" "Gray"
Write-Host ""
}
function Install-PortableRust {
param (
[string]$InstallDir = ".PortableRust",
[string]$ToolchainVersion = "stable",
[ValidateSet("gnu", "msvc")]
[string]$ToolchainType = "gnu"
)
$ErrorActionPreference = "Stop"
$Host.UI.RawUI.WindowTitle = "Portable Rust Installer"
# ✅ FIXED: Now returns clean string, not docstring
$HostArch = Get-SystemArchitecture
Show-Banner
Write-ColorMessage "Starting Portable Rust Installation" "White"
Write-ColorMessage " Toolchain: $HostArch" "Yellow"
Write-ColorMessage " Version: $ToolchainVersion" "Yellow"
Write-ColorMessage " Target: $InstallDir" "Yellow"
Write-ColorMessage "`n"
$InstallDir = Initialize-InstallationDirectory -Path $InstallDir
$RustupDir = Join-Path $InstallDir ".rustup"
$CargoDir = Join-Path $InstallDir ".cargo"
$env:RUSTUP_HOME = $RustupDir
$env:CARGO_HOME = $CargoDir
$env:PATH = "$CargoDir\bin;$env:PATH"
$rustupInitPath = Get-RustupInitializer -InstallDirectory $InstallDir -HostArch $HostArch
Install-Rust -InitializerPath $rustupInitPath -ToolchainVersion $ToolchainVersion -HostArch $HostArch
$installationValid = Test-RustInstallation -CargoDir $CargoDir -RustupDir $RustupDir
if (-not $installationValid) {
Write-ColorMessage "⚠️ Some components failed verification" "Yellow"
}
Initialize-CargoConfig -CargoDir $CargoDir
Test-CargoFunctionality -CargoDir $CargoDir -InstallDir $InstallDir | Out-Null
Create-ActivationScripts -InstallDirectory $InstallDir -RustupDir $RustupDir -CargoDir $CargoDir -HostArch $HostArch
Write-ColorMessage "`n✅ Portable Rust installation is ready!" "Green"
Show-Usage
}
# Main execution
if ($MyInvocation.InvocationName -ne '.') {
$scriptParams = @{}
if ($PSBoundParameters.ContainsKey('InstallDir')) { $scriptParams['InstallDir'] = $InstallDir }
if ($PSBoundParameters.ContainsKey('ToolchainVersion')) { $scriptParams['ToolchainVersion'] = $ToolchainVersion }
if ($PSBoundParameters.ContainsKey('ToolchainType')) { $scriptParams['ToolchainType'] = $ToolchainType }
Install-PortableRust @scriptParams
}
if ($PSScriptRoot -and (Test-Path -Path "$PSScriptRoot\*.psm1")) {
Export-ModuleMember -Function Install-PortableRust
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment