From ec42c5bba085061b55cbc4d1e8eb21787660d5ee Mon Sep 17 00:00:00 2001 From: Avasam Date: Wed, 17 Jun 2026 11:06:21 -0400 Subject: [PATCH 01/11] Attempt fix Linux UPX compression --- scripts/build.ps1 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/build.ps1 b/scripts/build.ps1 index 6127dfa7..7e2941a8 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -64,7 +64,10 @@ try { $_.Directory -like '*/AppDir/_internal' -or # _internal/PySide6/Qt/*/*.so* causes Segmentation fault # _internal/PySide6/Qt/plugins/*/*.so* breaks style - $_.Directory -like '*/AppDir/_internal/PySide6/Qt/*' + $_.Directory -like '*/AppDir/_internal/PySide6/Qt/*' -or + # numpy bundles OpenBLAS here; UPX breaks ELF load command page-alignment + # (environment-dependent, may not reproduce locally). + $_.Directory -like '*/AppDir/_internal/numpy.libs' ) } try { From 2cab593508b12abb6d1cae4d0de70944fc351968 Mon Sep 17 00:00:00 2001 From: Avasam Date: Wed, 17 Jun 2026 11:12:53 -0400 Subject: [PATCH 02/11] Try 2 --- scripts/build.ps1 | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/scripts/build.ps1 b/scripts/build.ps1 index 7e2941a8..35d2370b 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -65,9 +65,8 @@ try { # _internal/PySide6/Qt/*/*.so* causes Segmentation fault # _internal/PySide6/Qt/plugins/*/*.so* breaks style $_.Directory -like '*/AppDir/_internal/PySide6/Qt/*' -or - # numpy bundles OpenBLAS here; UPX breaks ELF load command page-alignment - # (environment-dependent, may not reproduce locally). - $_.Directory -like '*/AppDir/_internal/numpy.libs' + # numpy-bundled OpenBLAS; UPX breaks ELF load command page-alignment (environment-dependent, may not reproduce locally). + $_.Name -like 'libscipy_openblas64_*' ) } try { From 5a43ea22afdc54d3f8a018a48b0aafab90363b51 Mon Sep 17 00:00:00 2001 From: Avasam Date: Wed, 17 Jun 2026 11:22:56 -0400 Subject: [PATCH 03/11] test without UPX --- scripts/build.ps1 | 48 +++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/scripts/build.ps1 b/scripts/build.ps1 index 35d2370b..efd3bfee 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -53,30 +53,30 @@ try { Move-Item build/AppDir/AutoSplit/_internal build/AppDir/_internal Remove-Item build/AppDir/AutoSplit - if ([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture -eq 'X64') { - # Technically UPX works for Linux executables, but trying to compress .so can still result in Segmentation fault - # https://github.com/orgs/pyinstaller/discussions/8922#discussioncomment-13185670 - # https://github.com/pyinstaller/pyinstaller/blob/4d28a528f8ab8632f7cfa7662fc6fcc45881e741/PyInstaller/building/utils.py#L281-L288 - $soFilesToCompress = Get-ChildItem -Path build/AppDir/_internal -Recurse -File -Filter '*.so*' - | Where-Object { - -not ( - # _internal/*.so* causes Segmentation fault - $_.Directory -like '*/AppDir/_internal' -or - # _internal/PySide6/Qt/*/*.so* causes Segmentation fault - # _internal/PySide6/Qt/plugins/*/*.so* breaks style - $_.Directory -like '*/AppDir/_internal/PySide6/Qt/*' -or - # numpy-bundled OpenBLAS; UPX breaks ELF load command page-alignment (environment-dependent, may not reproduce locally). - $_.Name -like 'libscipy_openblas64_*' - ) - } - try { - & 'scripts/.upx/upx' --lzma --best build/AppDir/AppRun $soFilesToCompress - } - catch { - # UPX exits 1 when a file was skipped (e.g. already compressed) - not fatal - if ($LASTEXITCODE -ne 1) { throw } - } - } + # if ([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture -eq 'X64') { + # # Technically UPX works for Linux executables, but trying to compress .so can still result in Segmentation fault + # # https://github.com/orgs/pyinstaller/discussions/8922#discussioncomment-13185670 + # # https://github.com/pyinstaller/pyinstaller/blob/4d28a528f8ab8632f7cfa7662fc6fcc45881e741/PyInstaller/building/utils.py#L281-L288 + # $soFilesToCompress = Get-ChildItem -Path build/AppDir/_internal -Recurse -File -Filter '*.so*' + # | Where-Object { + # -not ( + # # _internal/*.so* causes Segmentation fault + # $_.Directory -like '*/AppDir/_internal' -or + # # _internal/PySide6/Qt/*/*.so* causes Segmentation fault + # # _internal/PySide6/Qt/plugins/*/*.so* breaks style + # $_.Directory -like '*/AppDir/_internal/PySide6/Qt/*' -or + # # numpy-bundled OpenBLAS; UPX breaks ELF load command page-alignment (environment-dependent, may not reproduce locally). + # $_.Name -like 'libscipy_openblas64_*' + # ) + # } + # try { + # & 'scripts/.upx/upx' --lzma --best build/AppDir/AppRun $soFilesToCompress + # } + # catch { + # # UPX exits 1 when a file was skipped (e.g. already compressed) - not fatal + # if ($LASTEXITCODE -ne 1) { throw } + # } + # } chmod +x build/AppDir/AppRun From ef9b549a731e3384f99f92a28bcbb19a22374218 Mon Sep 17 00:00:00 2001 From: Avasam Date: Wed, 17 Jun 2026 11:33:41 -0400 Subject: [PATCH 04/11] try stack of fixes --- scripts/build.ps1 | 57 +++++++++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 24 deletions(-) diff --git a/scripts/build.ps1 b/scripts/build.ps1 index efd3bfee..7e9b5869 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -39,6 +39,7 @@ try { if (Test-Path build/AppDir) { Remove-Item build/AppDir -Recurse -Force } $arguments += @( '--distpath=build/AppDir' + '--noupx' # Run manually below # Apply a symbol-table strip to the executable and shared libs (not recommended for Windows) '--strip') } @@ -53,30 +54,38 @@ try { Move-Item build/AppDir/AutoSplit/_internal build/AppDir/_internal Remove-Item build/AppDir/AutoSplit - # if ([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture -eq 'X64') { - # # Technically UPX works for Linux executables, but trying to compress .so can still result in Segmentation fault - # # https://github.com/orgs/pyinstaller/discussions/8922#discussioncomment-13185670 - # # https://github.com/pyinstaller/pyinstaller/blob/4d28a528f8ab8632f7cfa7662fc6fcc45881e741/PyInstaller/building/utils.py#L281-L288 - # $soFilesToCompress = Get-ChildItem -Path build/AppDir/_internal -Recurse -File -Filter '*.so*' - # | Where-Object { - # -not ( - # # _internal/*.so* causes Segmentation fault - # $_.Directory -like '*/AppDir/_internal' -or - # # _internal/PySide6/Qt/*/*.so* causes Segmentation fault - # # _internal/PySide6/Qt/plugins/*/*.so* breaks style - # $_.Directory -like '*/AppDir/_internal/PySide6/Qt/*' -or - # # numpy-bundled OpenBLAS; UPX breaks ELF load command page-alignment (environment-dependent, may not reproduce locally). - # $_.Name -like 'libscipy_openblas64_*' - # ) - # } - # try { - # & 'scripts/.upx/upx' --lzma --best build/AppDir/AppRun $soFilesToCompress - # } - # catch { - # # UPX exits 1 when a file was skipped (e.g. already compressed) - not fatal - # if ($LASTEXITCODE -ne 1) { throw } - # } - # } + # PyInstaller's --strip breaks ELF load command alignment in numpy's vendored OpenBLAS. + # Restore the original unstripped library from site-packages. + $numpyLibsSrc = uv run --active python -c "import numpy, pathlib; print(pathlib.Path(numpy.__file__).parent.parent / 'numpy.libs')" + if (Test-Path $numpyLibsSrc) { + Get-ChildItem $numpyLibsSrc -Filter 'libscipy_openblas64_*.so' | + Copy-Item -Destination 'build/AppDir/_internal/numpy.libs/' -Force + } + + if ([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture -eq 'X64') { + # Technically UPX works for Linux executables, but trying to compress .so can still result in Segmentation fault + # https://github.com/orgs/pyinstaller/discussions/8922#discussioncomment-13185670 + # https://github.com/pyinstaller/pyinstaller/blob/4d28a528f8ab8632f7cfa7662fc6fcc45881e741/PyInstaller/building/utils.py#L281-L288 + $soFilesToCompress = Get-ChildItem -Path build/AppDir/_internal -Recurse -File -Filter '*.so*' + | Where-Object { + -not ( + # _internal/*.so* causes Segmentation fault + $_.Directory -like '*/AppDir/_internal' -or + # _internal/PySide6/Qt/*/*.so* causes Segmentation fault + # _internal/PySide6/Qt/plugins/*/*.so* breaks style + $_.Directory -like '*/AppDir/_internal/PySide6/Qt/*' -or + # numpy-bundled OpenBLAS; --strip breaks its ELF load alignment (restored below) — skip UPX to avoid re-breaking it + $_.Name -like 'libscipy_openblas64_*' + ) + } + try { + & 'scripts/.upx/upx' --lzma --best build/AppDir/AppRun $soFilesToCompress + } + catch { + # UPX exits 1 when a file was skipped (e.g. already compressed) - not fatal + if ($LASTEXITCODE -ne 1) { throw } + } + } chmod +x build/AppDir/AppRun From 6510898f49a7b0efd0f0c2fd6ae5867902677153 Mon Sep 17 00:00:00 2001 From: Avasam Date: Wed, 17 Jun 2026 11:35:46 -0400 Subject: [PATCH 05/11] Additional conditional --- scripts/build.ps1 | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/scripts/build.ps1 b/scripts/build.ps1 index 7e9b5869..8e4083f0 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -22,9 +22,13 @@ try { '--additional-hooks-dir=Pyinstaller/hooks', "--add-data=pyproject.toml$([System.IO.Path]::PathSeparator).", '--icon=res/icon.ico') - if (-not $WineCompat) { + # Don't UPX compress if trying to be Wine Compatible, or on Linux (handled manually below) + if (-not $WineCompat -or -not $Windows) { $arguments += '--upx-dir=scripts/.upx' } + else { + $arguments += '--noupx' + } if ($SupportsSplashScreen) { # https://github.com/pyinstaller/pyinstaller/issues/9022 $arguments += @('--splash=res/splash.png') @@ -39,7 +43,6 @@ try { if (Test-Path build/AppDir) { Remove-Item build/AppDir -Recurse -Force } $arguments += @( '--distpath=build/AppDir' - '--noupx' # Run manually below # Apply a symbol-table strip to the executable and shared libs (not recommended for Windows) '--strip') } From 86dc5aa40e983136aac7aab23f36443b030cdd37 Mon Sep 17 00:00:00 2001 From: Avasam Date: Wed, 17 Jun 2026 11:56:32 -0400 Subject: [PATCH 06/11] disable strip + upx entirely --- scripts/build.ps1 | 51 ++++++++++++++++++++++++----------------------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/scripts/build.ps1 b/scripts/build.ps1 index 8e4083f0..37395c5f 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -44,7 +44,8 @@ try { $arguments += @( '--distpath=build/AppDir' # Apply a symbol-table strip to the executable and shared libs (not recommended for Windows) - '--strip') + # '--strip') + ) } Write-Output $arguments @@ -65,30 +66,30 @@ try { Copy-Item -Destination 'build/AppDir/_internal/numpy.libs/' -Force } - if ([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture -eq 'X64') { - # Technically UPX works for Linux executables, but trying to compress .so can still result in Segmentation fault - # https://github.com/orgs/pyinstaller/discussions/8922#discussioncomment-13185670 - # https://github.com/pyinstaller/pyinstaller/blob/4d28a528f8ab8632f7cfa7662fc6fcc45881e741/PyInstaller/building/utils.py#L281-L288 - $soFilesToCompress = Get-ChildItem -Path build/AppDir/_internal -Recurse -File -Filter '*.so*' - | Where-Object { - -not ( - # _internal/*.so* causes Segmentation fault - $_.Directory -like '*/AppDir/_internal' -or - # _internal/PySide6/Qt/*/*.so* causes Segmentation fault - # _internal/PySide6/Qt/plugins/*/*.so* breaks style - $_.Directory -like '*/AppDir/_internal/PySide6/Qt/*' -or - # numpy-bundled OpenBLAS; --strip breaks its ELF load alignment (restored below) — skip UPX to avoid re-breaking it - $_.Name -like 'libscipy_openblas64_*' - ) - } - try { - & 'scripts/.upx/upx' --lzma --best build/AppDir/AppRun $soFilesToCompress - } - catch { - # UPX exits 1 when a file was skipped (e.g. already compressed) - not fatal - if ($LASTEXITCODE -ne 1) { throw } - } - } + # if ([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture -eq 'X64') { + # # Technically UPX works for Linux executables, but trying to compress .so can still result in Segmentation fault + # # https://github.com/orgs/pyinstaller/discussions/8922#discussioncomment-13185670 + # # https://github.com/pyinstaller/pyinstaller/blob/4d28a528f8ab8632f7cfa7662fc6fcc45881e741/PyInstaller/building/utils.py#L281-L288 + # $soFilesToCompress = Get-ChildItem -Path build/AppDir/_internal -Recurse -File -Filter '*.so*' + # | Where-Object { + # -not ( + # # _internal/*.so* causes Segmentation fault + # $_.Directory -like '*/AppDir/_internal' -or + # # _internal/PySide6/Qt/*/*.so* causes Segmentation fault + # # _internal/PySide6/Qt/plugins/*/*.so* breaks style + # $_.Directory -like '*/AppDir/_internal/PySide6/Qt/*' -or + # # numpy-bundled OpenBLAS; --strip breaks its ELF load alignment (restored below) — skip UPX to avoid re-breaking it + # $_.Name -like 'libscipy_openblas64_*' + # ) + # } + # try { + # & 'scripts/.upx/upx' --lzma --best build/AppDir/AppRun $soFilesToCompress + # } + # catch { + # # UPX exits 1 when a file was skipped (e.g. already compressed) - not fatal + # if ($LASTEXITCODE -ne 1) { throw } + # } + # } chmod +x build/AppDir/AppRun From 1a04d817277fb4b441b919f750f3d3a603637b18 Mon Sep 17 00:00:00 2001 From: Avasam Date: Wed, 17 Jun 2026 12:01:08 -0400 Subject: [PATCH 07/11] Is strip by itself the problem ? --- scripts/build.ps1 | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/scripts/build.ps1 b/scripts/build.ps1 index 37395c5f..c74bf1e0 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -44,8 +44,7 @@ try { $arguments += @( '--distpath=build/AppDir' # Apply a symbol-table strip to the executable and shared libs (not recommended for Windows) - # '--strip') - ) + '--strip') } Write-Output $arguments From 3226dfbc21a34a0233105135444241f9e3a911c2 Mon Sep 17 00:00:00 2001 From: Avasam Date: Wed, 17 Jun 2026 12:22:16 -0400 Subject: [PATCH 08/11] Now is `--strip` still broken ? --- scripts/build.ps1 | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/scripts/build.ps1 b/scripts/build.ps1 index c74bf1e0..482f713e 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -23,7 +23,7 @@ try { "--add-data=pyproject.toml$([System.IO.Path]::PathSeparator).", '--icon=res/icon.ico') # Don't UPX compress if trying to be Wine Compatible, or on Linux (handled manually below) - if (-not $WineCompat -or -not $Windows) { + if (-not $WineCompat -and -not $IsLinux) { $arguments += '--upx-dir=scripts/.upx' } else { @@ -57,12 +57,11 @@ try { Move-Item build/AppDir/AutoSplit/_internal build/AppDir/_internal Remove-Item build/AppDir/AutoSplit - # PyInstaller's --strip breaks ELF load command alignment in numpy's vendored OpenBLAS. - # Restore the original unstripped library from site-packages. + # PyInstaller's --strip breaks ELF load command alignment in all of numpy's vendored libs. + # Restore all original unstripped libraries from site-packages. $numpyLibsSrc = uv run --active python -c "import numpy, pathlib; print(pathlib.Path(numpy.__file__).parent.parent / 'numpy.libs')" if (Test-Path $numpyLibsSrc) { - Get-ChildItem $numpyLibsSrc -Filter 'libscipy_openblas64_*.so' | - Copy-Item -Destination 'build/AppDir/_internal/numpy.libs/' -Force + Copy-Item -Path "$numpyLibsSrc/*" -Destination 'build/AppDir/_internal/numpy.libs/' -Force } # if ([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture -eq 'X64') { @@ -77,8 +76,8 @@ try { # # _internal/PySide6/Qt/*/*.so* causes Segmentation fault # # _internal/PySide6/Qt/plugins/*/*.so* breaks style # $_.Directory -like '*/AppDir/_internal/PySide6/Qt/*' -or - # # numpy-bundled OpenBLAS; --strip breaks its ELF load alignment (restored below) — skip UPX to avoid re-breaking it - # $_.Name -like 'libscipy_openblas64_*' + # # numpy.libs: --strip breaks ELF load alignment in all bundled libs (restored below) — skip UPX to avoid re-breaking them + # $_.Directory -like '*/AppDir/_internal/numpy.libs' # ) # } # try { From 859530d91d2e22cd8901e7f44be654d20a54fd56 Mon Sep 17 00:00:00 2001 From: Avasam Date: Wed, 17 Jun 2026 12:26:56 -0400 Subject: [PATCH 09/11] Better print --- scripts/build.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/build.ps1 b/scripts/build.ps1 index 482f713e..7f1cd857 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -47,7 +47,7 @@ try { '--strip') } - Write-Output $arguments + Write-Output pyinstaller ($arguments -join ' ') & uv run --active pyinstaller @arguments if ($IsLinux) { From 93382a9f72717d049ddee06b6b01fb0969d12049 Mon Sep 17 00:00:00 2001 From: Avasam Date: Wed, 17 Jun 2026 12:35:21 -0400 Subject: [PATCH 10/11] Re-enable UPX --- scripts/build.ps1 | 48 +++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/scripts/build.ps1 b/scripts/build.ps1 index 7f1cd857..c312df17 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -64,30 +64,30 @@ try { Copy-Item -Path "$numpyLibsSrc/*" -Destination 'build/AppDir/_internal/numpy.libs/' -Force } - # if ([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture -eq 'X64') { - # # Technically UPX works for Linux executables, but trying to compress .so can still result in Segmentation fault - # # https://github.com/orgs/pyinstaller/discussions/8922#discussioncomment-13185670 - # # https://github.com/pyinstaller/pyinstaller/blob/4d28a528f8ab8632f7cfa7662fc6fcc45881e741/PyInstaller/building/utils.py#L281-L288 - # $soFilesToCompress = Get-ChildItem -Path build/AppDir/_internal -Recurse -File -Filter '*.so*' - # | Where-Object { - # -not ( - # # _internal/*.so* causes Segmentation fault - # $_.Directory -like '*/AppDir/_internal' -or - # # _internal/PySide6/Qt/*/*.so* causes Segmentation fault - # # _internal/PySide6/Qt/plugins/*/*.so* breaks style - # $_.Directory -like '*/AppDir/_internal/PySide6/Qt/*' -or - # # numpy.libs: --strip breaks ELF load alignment in all bundled libs (restored below) — skip UPX to avoid re-breaking them - # $_.Directory -like '*/AppDir/_internal/numpy.libs' - # ) - # } - # try { - # & 'scripts/.upx/upx' --lzma --best build/AppDir/AppRun $soFilesToCompress - # } - # catch { - # # UPX exits 1 when a file was skipped (e.g. already compressed) - not fatal - # if ($LASTEXITCODE -ne 1) { throw } - # } - # } + if ([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture -eq 'X64') { + # Technically UPX works for Linux executables, but trying to compress .so can still result in Segmentation fault + # https://github.com/orgs/pyinstaller/discussions/8922#discussioncomment-13185670 + # https://github.com/pyinstaller/pyinstaller/blob/4d28a528f8ab8632f7cfa7662fc6fcc45881e741/PyInstaller/building/utils.py#L281-L288 + $soFilesToCompress = Get-ChildItem -Path build/AppDir/_internal -Recurse -File -Filter '*.so*' + | Where-Object { + -not ( + # _internal/*.so* causes Segmentation fault + $_.Directory -like '*/AppDir/_internal' -or + # _internal/PySide6/Qt/*/*.so* causes Segmentation fault + # _internal/PySide6/Qt/plugins/*/*.so* breaks style + $_.Directory -like '*/AppDir/_internal/PySide6/Qt/*' -or + # numpy.libs: --strip breaks ELF load alignment in all bundled libs (restored below) — skip UPX to avoid re-breaking them + $_.Directory -like '*/AppDir/_internal/numpy.libs' + ) + } + try { + & 'scripts/.upx/upx' --lzma --best build/AppDir/AppRun $soFilesToCompress + } + catch { + # UPX exits 1 when a file was skipped (e.g. already compressed) - not fatal + if ($LASTEXITCODE -ne 1) { throw } + } + } chmod +x build/AppDir/AppRun From d3662d650dff68b875bb98faf4ec5cea981e1b20 Mon Sep 17 00:00:00 2001 From: Avasam Date: Sun, 21 Jun 2026 14:30:55 -0400 Subject: [PATCH 11/11] fix multiline output --- scripts/build.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/build.ps1 b/scripts/build.ps1 index c312df17..3b00848b 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -47,7 +47,7 @@ try { '--strip') } - Write-Output pyinstaller ($arguments -join ' ') + Write-Output "pyinstaller $($arguments -join ' ')" & uv run --active pyinstaller @arguments if ($IsLinux) {