From 78a3a7061f5fe98029015a7aced68ad1ec30bd15 Mon Sep 17 00:00:00 2001 From: deepend-tildeclub <58404188+deepend-tildeclub@users.noreply.github.com> Date: Mon, 12 Jan 2026 19:27:43 -0700 Subject: [PATCH] Enhance MSYS2 workflow with Python and Inno Setup Added Python and CFFI packages to MSYS2 workflow and updated installation commands for Inno Setup. --- .github/workflows/windows-arm64-msys2.yml | 125 ++++++---------------- 1 file changed, 30 insertions(+), 95 deletions(-) diff --git a/.github/workflows/windows-arm64-msys2.yml b/.github/workflows/windows-arm64-msys2.yml index a9b38689..ed1af308 100644 --- a/.github/workflows/windows-arm64-msys2.yml +++ b/.github/workflows/windows-arm64-msys2.yml @@ -26,6 +26,8 @@ jobs: mingw-w64-clang-aarch64-gettext-tools mingw-w64-clang-aarch64-libxml2 mingw-w64-clang-aarch64-winpthreads + mingw-w64-clang-aarch64-python + mingw-w64-clang-aarch64-python-cffi mingw-w64-clang-aarch64-gtk2 mingw-w64-clang-aarch64-gtk-update-icon-cache mingw-w64-clang-aarch64-luajit @@ -38,55 +40,28 @@ jobs: set -euxo pipefail export PATH="/clangarm64/bin:$PATH" - # Make gettext XML ITS rules resolvable (defensive; avoids /usr/bin/msgfmt nonsense) + # Ensure gettext ITS data is available to msgfmt export MSGFMT="/clangarm64/bin/msgfmt" export GETTEXTDATADIR="/clangarm64/share/gettext" rm -rf build dist rel mkdir -p dist + # Clean DESTDIR layout: dist/bin, dist/lib, dist/share... meson setup build \ + --prefix=/ \ + --bindir=bin \ + --libdir=lib \ + --datadir=share \ -Dtext-frontend=true \ -Ddbus=disabled \ -Dwith-upd=false \ -Dwith-perl=false \ - -Dc_link_args=-lwinpthread \ - -Dcpp_link_args=-lwinpthread + -Dc_link_args="-pthread -lwinpthread" \ + -Dcpp_link_args="-pthread -lwinpthread" - # If the project exposes a Meson option to disable python, do it on ARM64. - # (Your python plugin currently dies on missing pthread_* symbols.) - python - <<'PY' - import json, subprocess - - def pick_disable(opt): - t = opt.get("type") - if t == "boolean": - return "false" - if t == "combo": - choices = opt.get("choices") or [] - lowered = [c.lower() for c in choices] - for want in ("disabled", "false", "no", "off"): - if want in lowered: - return choices[lowered.index(want)] - return None - - opts = json.loads(subprocess.check_output(["meson", "introspect", "build", "--buildoptions"], text=True)) - candidates = [o for o in opts if "python" in (o.get("name","").lower())] - if not candidates: - print("No Meson build options containing 'python' found; leaving as-is.") - raise SystemExit(0) - - for o in candidates: - name = o.get("name","") - val = pick_disable(o) - if not val: - continue - print(f"Disabling python-related option: {name} -> {val}") - subprocess.check_call(["meson", "configure", "build", f"-D{name}={val}"]) - break - else: - print("Found python-ish options, but none had a clear disable value; leaving as-is.") - PY + # Sanity check: python can import cffi now + /clangarm64/bin/python.exe -c "import sys, cffi; print('python:', sys.version); print('cffi:', cffi.__version__)" - name: Build shell: msys2 {0} @@ -107,7 +82,6 @@ jobs: run: | set -euxo pipefail export PATH="/clangarm64/bin:$PATH" - DESTDIR="$PWD/dist" ninja -C build install echo "Installed files (debug):" @@ -120,35 +94,25 @@ jobs: export PATH="/clangarm64/bin:$PATH" shopt -s nullglob - # Find installed EXEs and plugin DLLs (anywhere under dist/) mapfile -t targets < <(find dist -type f \( -iname 'zoitechat*.exe' -o -ipath '*/plugins/*.dll' \) 2>/dev/null || true) - if [ "${#targets[@]}" -eq 0 ]; then echo "No installed binaries/plugins found under dist/ (skipping dep harvest)" exit 0 fi - # Prefer directory containing zoitechat.exe as the runtime "bin" directory mainexe="$(printf '%s\n' "${targets[@]}" | grep -iE '/zoitechat\.exe$' | head -n1 || true)" - if [ -n "$mainexe" ]; then - bindir="$(dirname "$mainexe")" - else - # fallback: directory of first exe - firstexe="$(printf '%s\n' "${targets[@]}" | grep -iE '\.exe$' | head -n1 || true)" - bindir="$(dirname "$firstexe")" + if [ -z "$mainexe" ]; then + echo "zoitechat.exe not found under dist/; skipping dep harvest" + exit 0 fi + bindir="$(dirname "$mainexe")" echo "Using bindir: $bindir" - printf '%s\n' "${targets[@]}" for f in "${targets[@]}"; do - # ntldd can return non-zero; do not let it kill the job. deps="$(ntldd -R "$f" 2>/dev/null || true)" - if [ -z "$deps" ]; then - continue - fi + [ -n "$deps" ] || continue - # pull absolute DLL paths (first column) and copy those coming from clangarm64 runtime while IFS= read -r dll; do [ -n "$dll" ] || continue cp -n "$dll" "$bindir/" || true @@ -166,48 +130,29 @@ jobs: run: | set -euxo pipefail export PATH="/clangarm64/bin:$PATH" - shopt -s nullglob rm -rf rel mkdir -p rel - # Locate install root by finding zoitechat.exe, then walking up to its parent directory. app_exe="$(find dist -type f -iname 'zoitechat.exe' | head -n1 || true)" if [ -z "$app_exe" ]; then echo "zoitechat.exe not found under dist/; cannot build installer." - find dist -maxdepth 8 -type f -print || true exit 1 fi bin_dir="$(dirname "$app_exe")" install_root="$(cd "$bin_dir/.." && pwd)" - echo "bin_dir: $bin_dir" - echo "install_root: $install_root" - - # Copy the whole installed prefix into rel/, so your ARM .iss can reference bin/, share/, lib/, etc. cp -a "$install_root/." rel/ echo "rel/ contents (debug):" - find rel -maxdepth 5 -type f \( -iname 'zoitechat*.exe' -o -iname '*.dll' -o -iname '*.xml' -o -iname '*.desktop' \) -print || true + find rel -maxdepth 5 -type f \( -iname 'zoitechat*.exe' -o -iname '*.dll' \) -print || true - name: Install Inno Setup (find real ISCC.exe) shell: pwsh run: | $ErrorActionPreference = "Stop" - # Try winget first (nice when it works) - try { - if (-not (Get-Command winget.exe -ErrorAction SilentlyContinue)) { - Write-Host "winget not found; skipping winget install attempt." - } else { - winget install --id JRSoftware.InnoSetup -e --accept-package-agreements --accept-source-agreements - } - } catch { - Write-Host "winget install failed (continuing): $($_.Exception.Message)" - } - - # Ensure Chocolatey exists (GitHub runners usually have it, but ARM runners are special snowflakes) if (-not (Get-Command choco.exe -ErrorAction SilentlyContinue)) { Write-Host "Chocolatey not found; installing..." Set-ExecutionPolicy Bypass -Scope Process -Force @@ -215,18 +160,26 @@ jobs: iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1')) } - # Install Inno Setup via choco (idempotent) - choco install innosetup -y --no-progress | Out-Host + # Force install to repair broken shims/missing tools + choco install innosetup -y --force --no-progress | Out-Host $candidates = @() - # 1) Common install paths + # Common install paths $pf = ${env:ProgramFiles} $pfx86 = ${env:ProgramFiles(x86)} if ($pf) { $candidates += (Join-Path $pf "Inno Setup 6\ISCC.exe") } if ($pfx86){ $candidates += (Join-Path $pfx86 "Inno Setup 6\ISCC.exe") } - # 2) Registry uninstall keys often have InstallLocation + # Chocolatey tools path (real binary often lives here) + $chocoRoot = ${env:ChocolateyInstall} + if ($chocoRoot -and (Test-Path $chocoRoot)) { + $candidates += (Join-Path $chocoRoot "lib\innosetup\tools\ISCC.exe") + $candidates += (Get-ChildItem -Path (Join-Path $chocoRoot "lib\innosetup") -Recurse -Filter "ISCC.exe" -ErrorAction SilentlyContinue | + Select-Object -ExpandProperty FullName -First 10) + } + + # Registry uninstall keys sometimes provide InstallLocation $regKeys = @( "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Inno Setup 6_is1", "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Inno Setup 6_is1" @@ -238,20 +191,6 @@ jobs: } catch {} } - # 3) Chocolatey tool locations (avoid the shim in choco\bin) - $chocoRoot = ${env:ChocolateyInstall} - if ($chocoRoot -and (Test-Path $chocoRoot)) { - $candidates += (Get-ChildItem -Path (Join-Path $chocoRoot "lib") -Recurse -Filter "ISCC.exe" -ErrorAction SilentlyContinue | - Where-Object { $_.FullName -notmatch '\\chocolatey\\bin\\' } | - Select-Object -ExpandProperty FullName -First 10) - } - - # 4) Last resort: whatever is on PATH (might be a shim, might work) - try { - $cmd = Get-Command iscc.exe -ErrorAction Stop - $candidates += $cmd.Source - } catch {} - $iscc = $candidates | Where-Object { $_ -and (Test-Path $_) } | Select-Object -First 1 if (-not $iscc) { Write-Host "Checked candidates:" @@ -262,7 +201,6 @@ jobs: Write-Host "Using ISCC:" $iscc & $iscc /? | Out-Host - # Export for next step "ISCC_PATH=$iscc" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8 - name: Build ARM64 installer @@ -276,12 +214,9 @@ jobs: } if (-not (Test-Path "installer\zoitechat-arm64.iss")) { - Write-Host "Repo layout:" - Get-ChildItem -Recurse -Depth 3 | Select-Object FullName | Out-Host throw "installer\zoitechat-arm64.iss not found." } - # Compile. Your ARM .iss should point SourceDir to ..\rel (prepared above). & $iscc "installer\zoitechat-arm64.iss" | Out-Host - uses: actions/upload-artifact@v4