113 lines
4.9 KiB
PowerShell
113 lines
4.9 KiB
PowerShell
# Build the Switch NRO from Windows using devkitPro's MSYS2 toolchain.
|
|
param(
|
|
[string]$DevkitProPath = '',
|
|
[switch]$KeepBuild
|
|
)
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
|
|
function Quote-Bash([string]$Value) {
|
|
return "'" + $Value.Replace("'", "'\''") + "'"
|
|
}
|
|
|
|
$projectRoot = [IO.Path]::GetFullPath($PSScriptRoot)
|
|
if (-not $DevkitProPath) {
|
|
if ($env:DEVKITPRO -and (Test-Path -LiteralPath $env:DEVKITPRO)) {
|
|
$DevkitProPath = $env:DEVKITPRO
|
|
} else {
|
|
$DevkitProPath = 'C:\devkitPro'
|
|
}
|
|
}
|
|
$devkitRoot = [IO.Path]::GetFullPath($DevkitProPath)
|
|
|
|
$bash = Join-Path $devkitRoot 'msys2\usr\bin\bash.exe'
|
|
$cygpath = Join-Path $devkitRoot 'msys2\usr\bin\cygpath.exe'
|
|
$rules = Join-Path $devkitRoot 'libnx\switch_rules'
|
|
$compiler = Join-Path $devkitRoot 'devkitA64\bin\aarch64-none-elf-g++.exe'
|
|
$pkgConfig = Join-Path $devkitRoot 'portlibs\switch\bin\aarch64-none-elf-pkg-config'
|
|
|
|
foreach ($required in @($bash, $cygpath, $rules, $compiler, $pkgConfig)) {
|
|
if (-not (Test-Path -LiteralPath $required)) {
|
|
throw "Missing Switch build dependency: $required`nInstall devkitPro's Switch toolchain and switch-pkg-config packages; see README.md."
|
|
}
|
|
}
|
|
|
|
if ($devkitRoot -match '\s') {
|
|
throw 'The devkitPro installation path contains spaces; install it at C:\devkitPro or choose a path without spaces.'
|
|
}
|
|
|
|
$tempRoot = [IO.Path]::GetFullPath([IO.Path]::GetTempPath())
|
|
if ($tempRoot -match '\s') {
|
|
throw 'The temporary path contains spaces. Set TEMP to a writable directory without spaces before building.'
|
|
}
|
|
|
|
# The upstream devkitPro Makefile pattern requires a path without spaces, so
|
|
# compile a fresh copy in the temp folder.
|
|
$stage = Join-Path $tempRoot ('switchnote-build-' + [Guid]::NewGuid().ToString('N'))
|
|
$resolvedStage = [IO.Path]::GetFullPath($stage)
|
|
$tempPrefix = $tempRoot.TrimEnd('\', '/') + [IO.Path]::DirectorySeparatorChar
|
|
if (-not $resolvedStage.StartsWith($tempPrefix, [StringComparison]::OrdinalIgnoreCase) -or
|
|
-not ([IO.Path]::GetFileName($resolvedStage) -match '^switchnote-build-[0-9a-f]{32}$')) {
|
|
throw "Unexpected temporary build path: $resolvedStage"
|
|
}
|
|
|
|
New-Item -ItemType Directory -Path $stage | Out-Null
|
|
try {
|
|
foreach ($entry in @('Makefile', 'source', 'include', 'third_party', 'romfs')) {
|
|
$source = Join-Path $projectRoot $entry
|
|
if (-not (Test-Path -LiteralPath $source)) {
|
|
throw "Project file or directory is missing: $source"
|
|
}
|
|
Copy-Item -LiteralPath $source -Destination (Join-Path $stage $entry) -Recurse
|
|
}
|
|
|
|
$rootJpeg = Join-Path $projectRoot 'icon.jpg'
|
|
$rootPng = Join-Path $projectRoot 'icon.png'
|
|
if (Test-Path -LiteralPath $rootPng) {
|
|
try {
|
|
Add-Type -AssemblyName System.Drawing
|
|
$inputImage = [Drawing.Image]::FromFile($rootPng)
|
|
$bitmap = [Drawing.Bitmap]::new(256, 256)
|
|
$graphics = [Drawing.Graphics]::FromImage($bitmap)
|
|
try {
|
|
$graphics.Clear([Drawing.Color]::White)
|
|
$graphics.InterpolationMode = [Drawing.Drawing2D.InterpolationMode]::HighQualityBicubic
|
|
$graphics.DrawImage($inputImage, 0, 0, 256, 256)
|
|
$bitmap.Save((Join-Path $stage 'icon.jpg'), [Drawing.Imaging.ImageFormat]::Jpeg)
|
|
} finally {
|
|
$graphics.Dispose()
|
|
$bitmap.Dispose()
|
|
$inputImage.Dispose()
|
|
}
|
|
} catch {
|
|
Write-Warning "Could not convert icon.png to JPEG; the default libnx icon will be used. $($_.Exception.Message)"
|
|
}
|
|
} elseif (Test-Path -LiteralPath $rootJpeg) {
|
|
Copy-Item -LiteralPath $rootJpeg -Destination (Join-Path $stage 'icon.jpg')
|
|
}
|
|
|
|
$devkitUnix = (& $cygpath -u $devkitRoot).Trim()
|
|
if ($LASTEXITCODE -ne 0 -or -not $devkitUnix) { throw 'cygpath could not translate the devkitPro path.' }
|
|
$stageUnix = (& $cygpath -u $stage).Trim()
|
|
if ($LASTEXITCODE -ne 0 -or -not $stageUnix) { throw 'cygpath could not translate the build path.' }
|
|
|
|
$devkitQuoted = Quote-Bash $devkitUnix
|
|
$stageQuoted = Quote-Bash $stageUnix
|
|
$command = 'export DEVKITPRO={0}; export DEVKITA64="$DEVKITPRO/devkitA64"; export PATH="$DEVKITA64/bin:$DEVKITPRO/tools/bin:$DEVKITPRO/portlibs/switch/bin:$PATH"; cd {1}; make -j2' -f $devkitQuoted, $stageQuoted
|
|
& $bash -lc $command
|
|
if ($LASTEXITCODE -ne 0) { throw "Switch build failed with exit code $LASTEXITCODE." }
|
|
|
|
$builtNro = Join-Path $stage 'switchnote.nro'
|
|
if (-not (Test-Path -LiteralPath $builtNro)) { throw "Build reported success but no NRO exists at $builtNro" }
|
|
$destination = Join-Path $projectRoot 'switchnote.nro'
|
|
Copy-Item -LiteralPath $builtNro -Destination $destination -Force
|
|
Write-Host "Built $destination"
|
|
} finally {
|
|
if ($KeepBuild) {
|
|
Write-Host "Temporary build retained at $stage"
|
|
} elseif (Test-Path -LiteralPath $stage) {
|
|
# This directory was created above and its full path was checked against TEMP.
|
|
Remove-Item -LiteralPath $stage -Recurse -Force
|
|
}
|
|
}
|
