param( [string]$MsysRoot = 'C:\msys64', [switch]$EnableCableMedia ) $ErrorActionPreference = 'Stop' $repo = (Get-Location).Path $iconGenerator = Join-Path $repo 'tools\make_windows_icon.ps1' $makeIcon = Join-Path $repo 'assets\dat-thang.ico' $iconResourceCompiler = Join-Path $MsysRoot 'ucrt64\bin\windres.exe' $bash = Join-Path $MsysRoot 'usr\bin\bash.exe' $ucrtBin = Join-Path $MsysRoot 'ucrt64\bin' if (!(Test-Path -LiteralPath $bash)) { throw "MSYS2 bash not found at $bash. Install MSYS2 with the UCRT64 environment." } foreach ($tool in @('gcc.exe', 'mingw32-make.exe', 'pkg-config.exe', 'windres.exe')) { if (!(Test-Path -LiteralPath (Join-Path $ucrtBin $tool))) { throw "Required UCRT64 tool missing: $tool" } } if (!(Test-Path -LiteralPath $makeIcon) -or (Get-Item -LiteralPath $iconGenerator).LastWriteTimeUtc -gt (Get-Item -LiteralPath $makeIcon).LastWriteTimeUtc) { & powershell.exe -NoProfile -ExecutionPolicy Bypass -File $iconGenerator if ($LASTEXITCODE -ne 0) { throw "Windows icon generation failed with exit code $LASTEXITCODE" } } $repoUnix = $repo -replace '^([A-Za-z]):', '/$1' -replace '\\', '/' $repoUnix = $repoUnix -replace '^/([A-Za-z])', '/$1' $mediaFlag = if ($EnableCableMedia) { '1' } else { '0' } $mediaCheck = if ($EnableCableMedia) { ' && pkg-config --exists libavformat libavcodec libavutil libswresample libswscale' } else { '' } $command = "export PATH=/ucrt64/bin:`$PATH; cd '$repoUnix' && pkg-config --exists libsodium libcurl sdl2 SDL2_ttf$mediaCheck && mingw32-make -f Makefile.windows all ENABLE_CABLE_MEDIA=$mediaFlag" & $bash -lc $command if ($LASTEXITCODE -ne 0) { throw "Windows build failed with exit code $LASTEXITCODE" } $objdump = Join-Path $ucrtBin 'objdump.exe' $queue = [System.Collections.Generic.Queue[string]]::new() Get-ChildItem -LiteralPath (Join-Path $repo 'build\windows') -Filter '*.exe' | ForEach-Object { $queue.Enqueue($_.FullName) } $seen = [System.Collections.Generic.HashSet[string]]::new([System.StringComparer]::OrdinalIgnoreCase) while ($queue.Count -gt 0) { $binary = $queue.Dequeue() $deps = & $objdump -p $binary 2>$null | Select-String 'DLL Name:' foreach ($depLine in $deps) { $dll = ($depLine.Line -replace '^.*DLL Name:\s*', '').Trim() if (!$dll -or $dll -match '^(api-ms-win-|ext-ms-win-)' -or !$seen.Add($dll)) { continue } $sourceDll = Join-Path $ucrtBin $dll if (Test-Path -LiteralPath $sourceDll) { $targetDll = Join-Path (Split-Path -Parent $binary) $dll Copy-Item -LiteralPath $sourceDll -Destination $targetDll -Force $queue.Enqueue($targetDll) } } } Write-Host "Windows development build: $repo\build\windows" Write-Host "Windows portable package: $repo\dist\windows-x64" Write-Host "Windows distributions: $repo\dist\installers"