name: Windows Build on: push: branches: - master pull_request: branches: - master jobs: windows_build: runs-on: windows-2019 permissions: contents: read id-token: write attestations: write artifact-metadata: write strategy: matrix: platform: [x64, win32] arch: [x64, x86] exclude: - platform: x64 arch: x86 - platform: win32 arch: x64 fail-fast: false steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: python-version: "3.14.2" architecture: ${{ matrix.arch }} - name: Install Dependencies (GTK3 toolchain + packagers) env: GITHUB_TOKEN: ${{ github.token }} shell: pwsh run: | $ErrorActionPreference = "Stop" New-Item -Name "deps" -ItemType "Directory" -Force | Out-Null # Inno Setup + IDP (kept as-is) Invoke-WebRequest http://files.jrsoftware.org/is/5/innosetup-5.5.9-unicode.exe -OutFile deps\innosetup-unicode.exe & deps\innosetup-unicode.exe /VERYSILENT | Out-Null Invoke-WebRequest https://github.com/zoitechat/gvsbuild/releases/download/zoitechat-2.17.0/idpsetup-1.5.1.exe -OutFile deps\idpsetup.exe & deps\idpsetup.exe /VERYSILENT # WinSparkle / gendef / perl (kept as-is) Invoke-WebRequest https://github.com/zoitechat/gvsbuild/releases/download/zoitechat-2.17.0/gendef-20111031.7z -OutFile deps\gendef.7z & 7z.exe x deps\gendef.7z -oC:\gtk-build | Out-Null Invoke-WebRequest https://github.com/zoitechat/gvsbuild/releases/download/zoitechat-2.17.0/WinSparkle-20151011.7z -OutFile deps\WinSparkle.7z & 7z.exe x deps\WinSparkle.7z -oC:\gtk-build\WinSparkle | Out-Null Invoke-WebRequest https://github.com/zoitechat/gvsbuild/releases/download/zoitechat-2.17.0/perl-5.20.0-${{ matrix.arch }}.7z -OutFile deps\perl-${{ matrix.arch }}.7z & 7z.exe x deps\perl-${{ matrix.arch }}.7z -oC:\gtk-build\perl-5.20\${{ matrix.platform }} | Out-Null # ------------------------------------------ # GTK: download wingtk/gvsbuild GTK3 bundle and normalize into: # C:\gtk-build\gtk\\release\{bin,include,lib} # ------------------------------------------ $wantArch = if ("${{ matrix.platform }}" -eq "x64") { "x64" } else { "x86" } $wantPlat = "${{ matrix.platform }}" $extractRoot = "C:\_gtk_extract" if (Test-Path $extractRoot) { Remove-Item $extractRoot -Recurse -Force } New-Item -Path $extractRoot -ItemType Directory -Force | Out-Null function Get-PEMachine([string]$path) { 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 $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 $machine = $br.ReadUInt16() return $machine } finally { $fs.Close() } } catch { 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 } $allLibs = Get-ChildItem -Path $gtkLibDir -File -Filter "*.lib" -ErrorAction SilentlyContinue $src = $null foreach ($rx in $sourceNameRegexes) { $src = $allLibs | Where-Object { $_.Name -match $rx } | Select-Object -First 1 if ($src) { break } } if ($src) { Copy-Item $src.FullName $target -Force Write-Host "Alias: $targetName <= $($src.Name)" } else { Write-Host "Alias not created: $targetName (no match in $gtkLibDir)" } } function Ensure-GenmarshalReady([string]$gtkBinDir, [string]$gtkPrefix, [string]$wantPlat) { Ensure-Dir $gtkBinDir $wantMachine = if ($wantPlat -eq "x64") { 0x8664 } else { 0x014c } $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