# completley written by chatgpt btw. dont bother for winslop Set-StrictMode -Version Latest $ErrorActionPreference = "Stop" $BuildDir = Join-Path $env:USERPROFILE "Documents\SubWave\build\Desktop_Qt_6_10_2_MinGW_64_bit-Release" $ZipOutDir = Join-Path $env:USERPROFILE "Documents\SubWave\build" $QtBin = "C:\Qt\6.10.2\mingw_64\bin" $Msys2Bin = "C:\msys64\mingw64\bin" $FFmpegBin = "C:\ffmpeg\bin" $AppExe = Join-Path $BuildDir "SubWave.exe" $StagingDir = Join-Path $env:TEMP "SubWave_staging" $ZipPath = Join-Path $ZipOutDir "SubWave.zip" function Copy-Dll($src, $dst) { if (Test-Path $src) { if (-not (Test-Path $dst)) { Copy-Item $src $dst Write-Host " Copied: $(Split-Path $src -Leaf)" } else { Write-Host " Skip (exists): $(Split-Path $src -Leaf)" } } else { Write-Warning " Not found: $src" } } function Copy-DllFromMsys2OrFallback($name, $fallbackDir) { $msys2Path = "$Msys2Bin\$name" if (Test-Path $msys2Path) { Copy-Dll $msys2Path "$BuildDir\$name" } elseif ($fallbackDir -and (Test-Path "$fallbackDir\$name")) { Copy-Dll "$fallbackDir\$name" "$BuildDir\$name" } else { Write-Warning " Not found anywhere: $name" } } function Copy-PatternFromMsys2OrFallback($pattern, $fallbackDir) { $found = Get-ChildItem "$Msys2Bin\$pattern" -ErrorAction SilentlyContinue if ($found) { $found | ForEach-Object { Copy-Dll $_.FullName "$BuildDir\$($_.Name)" } } elseif ($fallbackDir) { Get-ChildItem "$fallbackDir\$pattern" -ErrorAction SilentlyContinue | ForEach-Object { Copy-Dll $_.FullName "$BuildDir\$($_.Name)" } } else { Write-Warning " No match for: $pattern" } } # Sanity check foreach ($p in $BuildDir, $QtBin, $AppExe) { if (-not (Test-Path $p)) { Write-Error "Missing: $p"; exit 1 } } if (-not (Test-Path $Msys2Bin)) { Write-Warning "MSYS2 not found at $Msys2Bin - will use fallback paths only" } # 1. windeployqt Write-Host "`n=== windeployqt ===" -ForegroundColor Cyan & "$QtBin\windeployqt.exe" --release --no-translations --no-network --compiler-runtime $AppExe if ($LASTEXITCODE -ne 0) { Write-Error "windeployqt failed"; exit 1 } # 2. FFmpeg - only what CMake links (avformat, avcodec, avutil, swresample) Write-Host "`n=== FFmpeg DLLs ===" -ForegroundColor Cyan $ffmpegPatterns = "libavformat-*.dll","libavcodec-*.dll","libavutil-*.dll","libswresample-*.dll", "avformat-*.dll","avcodec-*.dll","avutil-*.dll","swresample-*.dll" foreach ($p in $ffmpegPatterns) { Copy-PatternFromMsys2OrFallback $p $FFmpegBin } # 3. FFTW3 - double precision only (fftw3, not fftw3f or fftw3l) Write-Host "`n=== FFTW3 ===" -ForegroundColor Cyan Copy-DllFromMsys2OrFallback "libfftw3-3.dll" $null # 4. MinGW runtime Write-Host "`n=== MinGW runtime ===" -ForegroundColor Cyan foreach ($dll in "libgcc_s_seh-1.dll","libstdc++-6.dll","libwinpthread-1.dll") { Copy-DllFromMsys2OrFallback $dll $QtBin } # 5. Stage into a clean copy Write-Host "`n=== Staging ===" -ForegroundColor Cyan if (Test-Path $StagingDir) { Remove-Item $StagingDir -Recurse -Force } Copy-Item $BuildDir $StagingDir -Recurse Write-Host " Staged to: $StagingDir" # 6. Strip non-essentials from the staging copy Write-Host "`n=== Stripping ===" -ForegroundColor Cyan # Folders to remove entirely $foldersToRemove = @( "SubWave_autogen", "Testing", "tls", "networkinformation", ".qt", ".qtc", ".qtc_clangd", "CMakeFiles", "sqldrivers", "position", "sensors", "serialport", "scenegraph", "virtualkeyboard", "printsupport", "bearer", "networkauth", "webengine*", "qtwebengine*" ) foreach ($folder in $foldersToRemove) { Get-ChildItem $StagingDir -Recurse -Directory -Filter $folder | ForEach-Object { Remove-Item $_.FullName -Recurse -Force Write-Host " Removed dir: $($_.Name)" } } # File patterns to remove $filesToRemove = @( "*.pdb", "*.ilk", "*.exp", "*.lib", "*.map", "*.qm", "*.ts", "*.cmake", "*.ninja", "build.ninja", "CMakeCache.txt", "CMakeCache.txt.prev", ".ninja_deps", ".ninja_log" ) foreach ($pattern in $filesToRemove) { Get-ChildItem $StagingDir -Recurse -Filter $pattern | ForEach-Object { Remove-Item $_.FullName -Force Write-Host " Removed: $($_.FullName.Replace($StagingDir, ''))" } } # Remove DLLs that windeployqt pulls in but the app doesn't need Write-Host "`n=== Removing unneeded DLLs ===" -ForegroundColor Cyan $dllsToRemove = @( # Qt modules not in CMake "Qt6Svg.dll", # OpenSSL - no network "libssl-3-x64.dll", "libcrypto-3-x64.dll", # FFmpeg libs not linked "avfilter-*.dll", "libavfilter-*.dll", "avdevice-*.dll", "libavdevice-*.dll", "swscale-*.dll", "libswscale-*.dll", "postproc-*.dll", "libpostproc-*.dll", # FFTW variants not linked "libfftw3f-3.dll", "libfftw3l-3.dll" ) foreach ($pattern in $dllsToRemove) { Get-ChildItem $StagingDir -Filter $pattern -ErrorAction SilentlyContinue | ForEach-Object { Remove-Item $_.FullName -Force Write-Host " Removed: $($_.Name)" } } # Remove duplicate/older FFmpeg DLLs — keep only the highest version per library Write-Host "`n=== Deduplicating FFmpeg DLLs ===" -ForegroundColor Cyan $ffmpegBases = @("avcodec","avformat","avutil","swresample", "libavcodec","libavformat","libavutil","libswresample") foreach ($base in $ffmpegBases) { $matches = @(Get-ChildItem $StagingDir -Filter "$base-*.dll" -ErrorAction SilentlyContinue) if ($matches.Count -gt 1) { # Sort by version number extracted from filename, keep the last (highest) $sorted = $matches | Sort-Object { [int]($_.Name -replace ".*-(\d+)\.dll",'$1') } $sorted | Select-Object -SkipLast 1 | ForEach-Object { Remove-Item $_.FullName -Force Write-Host " Removed older: $($_.Name)" } } } # 7. Zip from staging Write-Host "`n=== Zipping ===" -ForegroundColor Cyan if (Test-Path $ZipPath) { Remove-Item $ZipPath -Force } Compress-Archive -Path "$StagingDir\*" -DestinationPath $ZipPath Remove-Item $StagingDir -Recurse -Force Write-Host " Zipped to: $ZipPath" Write-Host "`nDone." -ForegroundColor Green