122 lines
3.5 KiB
PowerShell
122 lines
3.5 KiB
PowerShell
[CmdletBinding()]
|
|
param(
|
|
[string]$SourceScript,
|
|
[string]$OutputDir,
|
|
[string]$BuildDir,
|
|
[string]$ExeName = 'PortableCaffeine.exe',
|
|
[switch]$ConsoleTarget,
|
|
[switch]$KeepExtractedSource
|
|
)
|
|
|
|
Set-StrictMode -Version Latest
|
|
$ErrorActionPreference = 'Stop'
|
|
|
|
# In Windows PowerShell 5.1, $PSScriptRoot may be empty during param default evaluation.
|
|
# Resolve script-relative defaults after the param block for compatibility.
|
|
$scriptRoot = if (-not [string]::IsNullOrWhiteSpace($PSScriptRoot)) {
|
|
$PSScriptRoot
|
|
} elseif ($MyInvocation.MyCommand.Path) {
|
|
Split-Path -Parent $MyInvocation.MyCommand.Path
|
|
} else {
|
|
(Get-Location).Path
|
|
}
|
|
|
|
if ([string]::IsNullOrWhiteSpace($SourceScript)) {
|
|
$SourceScript = Join-Path $scriptRoot 'caffeine.ps1'
|
|
}
|
|
if ([string]::IsNullOrWhiteSpace($OutputDir)) {
|
|
$OutputDir = Join-Path $scriptRoot 'dist'
|
|
}
|
|
if ([string]::IsNullOrWhiteSpace($BuildDir)) {
|
|
$BuildDir = Join-Path $scriptRoot 'build'
|
|
}
|
|
|
|
function Get-CSharpFromCaffeineScript {
|
|
param(
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$Path
|
|
)
|
|
|
|
if (-not (Test-Path -LiteralPath $Path)) {
|
|
throw "Source script not found: $Path"
|
|
}
|
|
|
|
$raw = Get-Content -LiteralPath $Path -Raw -Encoding UTF8
|
|
|
|
$pattern = '(?s)\$csharp\s*=\s*@''\r?\n(?<code>.*?)\r?\n''@'
|
|
$match = [regex]::Match($raw, $pattern)
|
|
if (-not $match.Success) {
|
|
throw "Could not locate embedded C# here-string (`$csharp = @' ... '@) in $Path"
|
|
}
|
|
|
|
return $match.Groups['code'].Value
|
|
}
|
|
|
|
function Get-CscPath {
|
|
$candidates = @(
|
|
(Join-Path $env:WINDIR 'Microsoft.NET\Framework64\v4.0.30319\csc.exe'),
|
|
(Join-Path $env:WINDIR 'Microsoft.NET\Framework\v4.0.30319\csc.exe')
|
|
)
|
|
|
|
foreach ($candidate in $candidates) {
|
|
if ($candidate -and (Test-Path -LiteralPath $candidate)) {
|
|
return $candidate
|
|
}
|
|
}
|
|
|
|
$cmd = Get-Command csc.exe -ErrorAction SilentlyContinue
|
|
if ($cmd) {
|
|
return $cmd.Source
|
|
}
|
|
|
|
throw "csc.exe not found. Install .NET Framework build tools (or run on Windows with .NET Framework 4.x)."
|
|
}
|
|
|
|
if ([Environment]::OSVersion.Platform -ne [PlatformID]::Win32NT) {
|
|
throw "This build script is intended for Windows because it compiles WinForms code against .NET Framework (csc.exe)."
|
|
}
|
|
|
|
New-Item -ItemType Directory -Force -Path $OutputDir | Out-Null
|
|
New-Item -ItemType Directory -Force -Path $BuildDir | Out-Null
|
|
|
|
$csharpSource = Get-CSharpFromCaffeineScript -Path $SourceScript
|
|
$generatedCsPath = Join-Path $BuildDir 'PortableCaffeine.generated.cs'
|
|
$outExePath = Join-Path $OutputDir $ExeName
|
|
$targetKind = if ($ConsoleTarget) { 'exe' } else { 'winexe' }
|
|
$cscPath = Get-CscPath
|
|
|
|
[System.IO.File]::WriteAllText($generatedCsPath, $csharpSource, (New-Object System.Text.UTF8Encoding($false)))
|
|
|
|
$arguments = @(
|
|
'/nologo'
|
|
"/target:$targetKind"
|
|
'/optimize+'
|
|
'/platform:anycpu'
|
|
"/out:$outExePath"
|
|
'/r:System.dll'
|
|
'/r:System.Windows.Forms.dll'
|
|
'/r:System.Drawing.dll'
|
|
$generatedCsPath
|
|
)
|
|
|
|
Write-Host "Compiling with: $cscPath"
|
|
Write-Host "Target: $targetKind"
|
|
Write-Host "Output: $outExePath"
|
|
|
|
& $cscPath @arguments
|
|
$exitCode = $LASTEXITCODE
|
|
if ($exitCode -ne 0) {
|
|
throw "csc.exe failed with exit code $exitCode"
|
|
}
|
|
|
|
if (-not $KeepExtractedSource) {
|
|
Remove-Item -LiteralPath $generatedCsPath -Force -ErrorAction SilentlyContinue
|
|
}
|
|
|
|
Write-Host ""
|
|
Write-Host "Build succeeded."
|
|
Write-Host "EXE: $outExePath"
|
|
if ($KeepExtractedSource) {
|
|
Write-Host "Extracted source kept at: $generatedCsPath"
|
|
}
|