From 2da635c048fbc41c359b57cb14ebb53d3c5843d3 Mon Sep 17 00:00:00 2001 From: deepend-tildeclub <58404188+deepend-tildeclub@users.noreply.github.com> Date: Sun, 1 Feb 2026 21:29:24 -0700 Subject: [PATCH] Refactor GTK3 bundle extraction and handling --- .github/workflows/windows-build.yml | 212 ++++++++++++---------------- 1 file changed, 94 insertions(+), 118 deletions(-) diff --git a/.github/workflows/windows-build.yml b/.github/workflows/windows-build.yml index efe55fda..c8b88b82 100644 --- a/.github/workflows/windows-build.yml +++ b/.github/workflows/windows-build.yml @@ -66,8 +66,6 @@ jobs: # ------------------------------------------ # GTK: download wingtk/gvsbuild GTK3 bundle and normalize into: # C:\gtk-build\gtk\\release\{bin,include,lib} - # - # IMPORTANT: do NOT assume layout inside the zip. Detect prefix by locating gtk-3*.lib. # ------------------------------------------ $wantArch = if ("${{ matrix.platform }}" -eq "x64") { "x64" } else { "x86" } $wantPlat = "${{ matrix.platform }}" @@ -77,18 +75,17 @@ jobs: New-Item -Path $extractRoot -ItemType Directory -Force | Out-Null function Get-PEMachine([string]$path) { - # Returns 0x8664 (x64), 0x014c (x86), or $null if not PE. try { $fs = [System.IO.File]::Open($path, 'Open', 'Read', 'ReadWrite') try { $br = New-Object System.IO.BinaryReader($fs) $mz = $br.ReadUInt16() - if ($mz -ne 0x5A4D) { return $null } # "MZ" + if ($mz -ne 0x5A4D) { return $null } # MZ $fs.Seek(0x3C, [System.IO.SeekOrigin]::Begin) | Out-Null $peOff = $br.ReadUInt32() $fs.Seek($peOff, [System.IO.SeekOrigin]::Begin) | Out-Null $peSig = $br.ReadUInt32() - if ($peSig -ne 0x00004550) { return $null } # "PE\0\0" + if ($peSig -ne 0x00004550) { return $null } # PE\0\0 $machine = $br.ReadUInt16() return $machine } finally { @@ -99,42 +96,22 @@ jobs: } } - function Pick-GtkPrefix([string]$root, [string]$arch) { - # Find a plausible GTK3 MSVC import lib anywhere in extracted tree. - $libs = Get-ChildItem -Path $root -Recurse -File -Filter "*.lib" -ErrorAction SilentlyContinue - - # Prefer exact well-known names first. - $preferred = @( - '^gtk-3\.0\.lib$', - '^gtk-3-0\.lib$', - '^gtk-3\.lib$' - ) - - foreach ($rx in $preferred) { - $cand = $libs | Where-Object { $_.Name -match $rx } | - Sort-Object -Property FullName | - Select-Object -First 1 - if ($cand) { - # prefix is parent of the lib directory - return (Split-Path -Parent $cand.Directory.FullName) - } - } - - # Fallback: any gtk-3*.lib - $cand2 = $libs | Where-Object { $_.Name -match '^gtk-3.*\.lib$' } | - Sort-Object -Property FullName | - Select-Object -First 1 - if ($cand2) { - return (Split-Path -Parent $cand2.Directory.FullName) - } - - return $null - } - function Ensure-Dir([string]$p) { if (-not (Test-Path $p)) { New-Item -Path $p -ItemType Directory -Force | Out-Null } } + function Pick-GtkPrefix([string]$root) { + $libs = Get-ChildItem -Path $root -Recurse -File -Filter "*.lib" -ErrorAction SilentlyContinue + $preferred = @('^gtk-3\.0\.lib$', '^gtk-3-0\.lib$', '^gtk-3\.lib$') + foreach ($rx in $preferred) { + $cand = $libs | Where-Object { $_.Name -match $rx } | Select-Object -First 1 + if ($cand) { return (Split-Path -Parent $cand.Directory.FullName) } + } + $cand2 = $libs | Where-Object { $_.Name -match '^gtk-3.*\.lib$' } | Select-Object -First 1 + if ($cand2) { return (Split-Path -Parent $cand2.Directory.FullName) } + return $null + } + function Copy-AliasLib([string]$gtkLibDir, [string]$targetName, [string[]]$sourceNameRegexes) { $target = Join-Path $gtkLibDir $targetName if (Test-Path $target) { return } @@ -154,55 +131,90 @@ jobs: } } - function Ensure-GenmarshalWrapper([string]$gtkBinDir, [string]$gtkPrefix, [string]$wantPlat) { + function Ensure-GenmarshalReady([string]$gtkBinDir, [string]$gtkPrefix, [string]$wantPlat) { Ensure-Dir $gtkBinDir - # Search *anywhere* under prefix for glib-genmarshal*.exe (layout varies by bundle) - $cands = Get-ChildItem -Path $gtkPrefix -Recurse -File -Filter "glib-genmarshal*.exe" -ErrorAction SilentlyContinue - - if (-not $cands -or $cands.Count -eq 0) { - # Also try without extension, just in case the bundle ships a script - $cands2 = Get-ChildItem -Path $gtkPrefix -Recurse -File -Filter "glib-genmarshal*" -ErrorAction SilentlyContinue | - Where-Object { $_.Extension -ne ".pdb" -and $_.Extension -ne ".txt" } - if ($cands2 -and $cands2.Count -gt 0) { - Write-Host "Found non-.exe glib-genmarshal candidates:" - $cands2 | Select-Object -First 20 | ForEach-Object { Write-Host " - $($_.FullName)" } - } - throw "GTK3 bundle extracted, but no glib-genmarshal*.exe found anywhere under detected GTK prefix: $gtkPrefix" - } - $wantMachine = if ($wantPlat -eq "x64") { 0x8664 } else { 0x014c } - # Prefer machine-matching candidates. - $picked = $null - foreach ($c in $cands) { - $m = Get-PEMachine $c.FullName - if ($m -eq $wantMachine) { $picked = $c; break } - } - if (-not $picked) { - # Last resort: just take the first one and hope it's not the wrong arch. - $picked = $cands | Select-Object -First 1 - Write-Host "Warning: could not confirm glib-genmarshal arch; using: $($picked.FullName)" - } else { - Write-Host "glib-genmarshal selected: $($picked.FullName)" + $binScript = Join-Path $gtkBinDir "glib-genmarshal" + $binExe = Join-Path $gtkBinDir "glib-genmarshal.exe" + + # 1) If we already have glib-genmarshal (no extension) in bin, prefer it. + if (Test-Path $binScript) { + $m = Get-PEMachine $binScript + if ($m) { + # It's a PE binary without .exe. Make an .exe copy for subprocess callers, and keep python wrapper. + if ($m -ne $wantMachine) { + throw "glib-genmarshal in bin is PE but wrong arch (machine=0x{0:X})." -f $m + } + Copy-Item $binScript $binExe -Force + $wrapperLines = @( + "import os, subprocess, sys", + "tool = os.path.join(os.path.dirname(__file__), 'glib-genmarshal.exe')", + "sys.exit(subprocess.call([tool] + sys.argv[1:]))" + ) + $wrapperLines | Set-Content -Path $binScript -Encoding ASCII + return + } + + # Not PE: likely a script. If it's python-ish, we're done because vcxproj calls python.exe