diff --git a/.github/workflows/windows-build.yml b/.github/workflows/windows-build.yml index e2d6fb5d..21e6ba0d 100644 --- a/.github/workflows/windows-build.yml +++ b/.github/workflows/windows-build.yml @@ -32,7 +32,8 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Setup MSYS2 (only used if we must build GTK via gvsbuild) + # MSYS2 is required for the gvsbuild-from-source fallback path. + - name: Setup MSYS2 (for GTK build fallback) uses: msys2/setup-msys2@v2 with: msys2-location: C:\tools\msys64 @@ -84,7 +85,7 @@ jobs: Where-Object { $_.FullName -match '\\include\\gtk-3\.0\\gtk\\gtk\.h$' } | Select-Object -First 1 if (-not $gtkH) { return $null } - return $gtkH.Directory.Parent.Parent.Parent.FullName + return $gtkH.Directory.Parent.Parent.Parent.FullName # ...\include\gtk-3.0\gtk\gtk.h -> prefix } function Ensure-Junction([string]$linkPath, [string]$targetPath) { @@ -116,16 +117,19 @@ jobs: $wrapperPath = Join-Path $gtkBin "glib-genmarshal" $exePath = Join-Path $gtkBin "glib-genmarshal.exe" + # If a non-exe tool exists, move it aside so our wrapper name is stable. $realPath = Join-Path $gtkBin "glib-genmarshal.real" if (Test-Path $realPath) { Remove-Item $realPath -Force } if (Test-Path $wrapperPath) { + # If it's already our wrapper, keep it. Otherwise move to .real. $first = (Get-Content -Path $wrapperPath -TotalCount 1 -ErrorAction SilentlyContinue) if ($first -notmatch 'import os') { Move-Item $wrapperPath $realPath -Force } } + # If no exe and no real tool, search for any glib-genmarshal* in bin and use that. if (-not (Test-Path $exePath) -and -not (Test-Path $realPath)) { $cand = Get-ChildItem -Path $gtkBin -File -Filter "glib-genmarshal*" | Select-Object -First 1 if ($cand) { @@ -137,6 +141,9 @@ jobs: throw "GTK3 prefix present, but no glib-genmarshal tool found under $gtkBin" } + # Write a python wrapper that dispatches to: + # - glib-genmarshal.exe if present + # - otherwise glib-genmarshal.real (perl or python script) $wrapper = @( "import os, subprocess, sys", "base = os.path.dirname(__file__)", @@ -161,43 +168,38 @@ jobs: } function Ensure-LuaHeaders([string]$gtkInc) { - # Headers only here. We build lua51.lib later under a VS environment. - $luaDir = Join-Path $gtkInc "lua" - New-Item -Path $luaDir -ItemType Directory -Force | Out-Null + # Provide et al for the lua plugin build. + $zip = "deps\luajit-v2.1.zip" + $dst = "deps\luajit-src" + if (-not (Test-Path $dst)) { New-Item -Path $dst -ItemType Directory -Force | Out-Null } - $zip = "deps\lua-5.1.5.tar.gz" - $dst = "deps\lua-5.1.5-src" - if (Test-Path $dst) { Remove-Item $dst -Recurse -Force } - New-Item -Path $dst -ItemType Directory -Force | Out-Null + Invoke-WebRequest https://github.com/LuaJIT/LuaJIT/archive/refs/heads/v2.1.zip -OutFile $zip + Expand-Archive -Force $zip -DestinationPath $dst - Invoke-WebRequest https://www.lua.org/ftp/lua-5.1.5.tar.gz -OutFile $zip - & 7z.exe x $zip -o$dst | Out-Null - & 7z.exe x (Join-Path $dst "lua-5.1.5.tar") -o$dst | Out-Null - - $src = Join-Path $dst "lua-5.1.5\src" - if (-not (Test-Path $src)) { throw "Lua 5.1.5 source layout unexpected (missing $src)" } + $srcDir = Get-ChildItem -Path $dst -Directory | Select-Object -First 1 + if (-not $srcDir) { throw "LuaJIT source zip extracted, but no top directory found." } + $hdrRoot = Join-Path $srcDir.FullName "src" foreach ($h in @("lua.h", "lualib.h", "lauxlib.h", "luaconf.h")) { - $p = Join-Path $src $h - if (-not (Test-Path $p)) { throw "Lua header missing: $p" } - + $p = Join-Path $hdrRoot $h + if (-not (Test-Path $p)) { throw "LuaJIT header missing: $p" } Copy-Item $p (Join-Path $gtkInc $h) -Force - Copy-Item $p (Join-Path $luaDir $h) -Force } } # ------------------------------------------ # GTK: Prefer prebuilt wingtk/gvsbuild GTK3 bundles. - # If missing for x86 (win32), build GTK3 via gvsbuild. + # If missing for x86 (win32), build GTK3 via gvsbuild from source. # ------------------------------------------ - $wantArch = if ("${{ matrix.platform }}" -eq "x64") { "x64" } else { "x86" } - $wantPlat = "${{ matrix.platform }}" + $wantArch = if ("${{ matrix.platform }}" -eq "x64") { "x64" } else { "x86" } # gvsbuild uses x64/x86 + $wantPlat = "${{ matrix.platform }}" # solution uses x64/win32 $extractRoot = "C:\_gtk_extract" if (Test-Path $extractRoot) { Remove-Item $extractRoot -Recurse -Force } New-Item -Path $extractRoot -ItemType Directory -Force | Out-Null $gtkPrefix = $null + $headers = @{ "User-Agent" = "zoitechat-ci" "Authorization" = "Bearer $env:GITHUB_TOKEN" @@ -206,6 +208,8 @@ jobs: try { $release = Invoke-RestMethod -Headers $headers -Uri "https://api.github.com/repos/wingtk/gvsbuild/releases/latest" + + # Try a couple of patterns in case naming shifts slightly. $asset = $release.assets | Where-Object { ($_.name -match '^GTK3_Gvsbuild_.*_(x64|x86)\.zip$' -or $_.name -match '(?i)gtk3.*(x64|x86)\.zip$') -and @@ -220,6 +224,7 @@ jobs: $gtkPrefix = Find-GtkPrefix $extractRoot if (-not $gtkPrefix) { throw "GTK3 bundle extracted, but gtk.h not found. Layout unexpected." } + Write-Host "Detected GTK prefix: $gtkPrefix" } else { Write-Host "No prebuilt GTK3 bundle found for $wantArch. Will build GTK3 from source via gvsbuild." @@ -230,6 +235,7 @@ jobs: } if (-not $gtkPrefix) { + # Build GTK3 via gvsbuild (VS2019) as a fallback. $gvsDir = "C:\gtk-build\github\gvsbuild" if (-not (Test-Path $gvsDir)) { New-Item -Path "C:\gtk-build\github" -ItemType Directory -Force | Out-Null @@ -240,6 +246,7 @@ jobs: python -m pip install --upgrade pip python -m pip install -r requirements.txt + # Build GTK3 (3.24) for VS2019 (16), using MSYS2. python .\build.py build -p=$wantArch --vs-ver=16 --msys-dir=C:\tools\msys64 --gtk3-ver=3.24 -c=release gtk3 Pop-Location @@ -250,6 +257,7 @@ jobs: } # Normalize GTK location to the path your solution expects: + # C:\gtk-build\gtk\\release\... $normBase = "C:\gtk-build\gtk\$wantPlat" New-Item -Path $normBase -ItemType Directory -Force | Out-Null $normRel = Join-Path $normBase "release" @@ -263,16 +271,34 @@ jobs: if (-not (Test-Path $gtkLib)) { throw "GTK lib dir missing at $gtkLib" } if (-not (Test-Path $gtkInc)) { throw "GTK include dir missing at $gtkInc" } + # glib-genmarshal: vcxproj calls python.exe \glib-genmarshal (no extension). + # Ensure we always have a python wrapper named glib-genmarshal in GTK\bin. Ensure-GlibGenmarshalWrapper $gtkBin + + # Provide Lua headers for the lua plugin (lua.c includes ). Ensure-LuaHeaders $gtkInc - # Import-lib name normalization (only helps if the lib exists under a different name) - Copy-AliasLib $gtkLib "gtk-3.0.lib" @('^gtk-3-0\.lib$', '^gtk-3\.lib$', '^gtk-3.*\.lib$', '^gtk-win32-2\.0\.lib$') - Copy-AliasLib $gtkLib "gdk-3.0.lib" @('^gdk-3-0\.lib$', '^gdk-3\.lib$', '^gdk-3.*\.lib$') - Copy-AliasLib $gtkLib "gdk-win32-3.0.lib" @('^gdk-win32-3-0\.lib$', '^gdk-win32-3\.lib$', '^gdk-win32-3.*\.lib$') + # Compatibility aliases for differing .lib names across bundles. + Copy-AliasLib $gtkLib "gtk-3.0.lib" @( + '^gtk-3-0\.lib$', + '^gtk-3\.lib$', + '^gtk-3.*\.lib$', + '^gtk-win32-2\.0\.lib$' + ) - # zlib legacy name (alias if a zlib lib exists) - Copy-AliasLib $gtkLib "zlib.lib" @('^zlib1\.lib$', '^zlibstatic\.lib$', '^zlib.*\.lib$') + Copy-AliasLib $gtkLib "gtk-win32-2.0.lib" @( + '^gtk-3\.0\.lib$', + '^gtk-3-0\.lib$', + '^gtk-3\.lib$', + '^gtk-3.*\.lib$' + ) + + # OpenSSL legacy names (keep older projects happy if they still reference these) + Copy-AliasLib $gtkLib "ssleay32.lib" @('^libssl\.lib$', '^ssl\.lib$') + Copy-AliasLib $gtkLib "libeay32.lib" @('^libcrypto\.lib$', '^crypto\.lib$') + + # libxml2 legacy name + Copy-AliasLib $gtkLib "libxml2.lib" @('^libxml2.*\.lib$') # Persist GTK root for later steps. "GTK_ROOT=$normRel" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8 @@ -304,80 +330,9 @@ jobs: exit /b 1 ) - rem ------------------------------------------------------------ - rem Ensure lua51.lib (build Lua 5.1.5 static library with MSVC) - rem ------------------------------------------------------------ - if not exist "%GTKROOT%\lib\lua51.lib" ( - echo Building lua51.lib (Lua 5.1.5)... - if not exist "deps" mkdir deps - - powershell -NoProfile -ExecutionPolicy Bypass -Command ^ - "$ErrorActionPreference='Stop';" ^ - "if (-not (Test-Path 'deps\lua-5.1.5.tar.gz')) { Invoke-WebRequest https://www.lua.org/ftp/lua-5.1.5.tar.gz -OutFile 'deps\lua-5.1.5.tar.gz' }" - - if exist "deps\lua-5.1.5-src" rmdir /s /q "deps\lua-5.1.5-src" - mkdir "deps\lua-5.1.5-src" - - 7z.exe x "deps\lua-5.1.5.tar.gz" -o"deps\lua-5.1.5-src" >NUL - 7z.exe x "deps\lua-5.1.5-src\lua-5.1.5.tar" -o"deps\lua-5.1.5-src" >NUL - - pushd "deps\lua-5.1.5-src\lua-5.1.5\src" - del /q *.obj >NUL 2>&1 - - for %%f in (*.c) do ( - if /I not "%%f"=="lua.c" if /I not "%%f"=="luac.c" ( - cl /nologo /O2 /MD /c %%f - if errorlevel 1 exit /b 1 - ) - ) - - lib /nologo /out:"%GTKROOT%\lib\lua51.lib" *.obj - if errorlevel 1 exit /b 1 - popd - ) - - rem ------------------------------------------------------------ - rem Ensure libxml2.lib (vcpkg, MSVC-compatible) - rem ------------------------------------------------------------ - if not exist "%GTKROOT%\lib\libxml2.lib" ( - echo Installing libxml2 via vcpkg... - if exist "C:\vcpkg\vcpkg.exe" ( - set "VCPKG_ROOT=C:\vcpkg" - ) else ( - if exist "C:\vcpkg" rmdir /s /q "C:\vcpkg" - git clone --depth 1 https://github.com/microsoft/vcpkg.git C:\vcpkg - call C:\vcpkg\bootstrap-vcpkg.bat - set "VCPKG_ROOT=C:\vcpkg" - ) - - if "${{ matrix.platform }}"=="x64" ( - set "VCPKG_TRIPLET=x64-windows" - ) else ( - set "VCPKG_TRIPLET=x86-windows" - ) - - "%VCPKG_ROOT%\vcpkg.exe" install libxml2:%VCPKG_TRIPLET% zlib:%VCPKG_TRIPLET% - if errorlevel 1 exit /b 1 - - rem Copy MSVC import libs where your vcxproj expects them (GTKROOT\lib) - if exist "%VCPKG_ROOT%\installed\%VCPKG_TRIPLET%\lib\libxml2.lib" ( - copy /Y "%VCPKG_ROOT%\installed\%VCPKG_TRIPLET%\lib\libxml2.lib" "%GTKROOT%\lib\libxml2.lib" >NUL - ) - if exist "%VCPKG_ROOT%\installed\%VCPKG_TRIPLET%\lib\zlib.lib" ( - copy /Y "%VCPKG_ROOT%\installed\%VCPKG_TRIPLET%\lib\zlib.lib" "%GTKROOT%\lib\zlib.lib" >NUL - ) - - rem Copy required DLLs into GTKROOT\bin so packaging has them available later - if exist "%VCPKG_ROOT%\installed\%VCPKG_TRIPLET%\bin" ( - copy /Y "%VCPKG_ROOT%\installed\%VCPKG_TRIPLET%\bin\*.dll" "%GTKROOT%\bin\" >NUL - ) - ) - - rem Make sure the linker can see GTK + Lua + libxml2 set "PATH=%PERL_BIN%;%GTKROOT%\bin;%PATH%" set "LIB=%GTKROOT%\lib;%LIB%" - set "INCLUDE=%GTKROOT%\include\lua;%GTKROOT%\include;%GTKROOT%\include\libxml2;%INCLUDE%" - set "CL=/I""%GTKROOT%\include"" /I""%GTKROOT%\include\lua"" /I""%GTKROOT%\include\libxml2"" %CL%" + set "INCLUDE=%GTKROOT%\include;%INCLUDE%" set "PYTHON_DIR=C:\gtk-build\python-3.14.2\${{ matrix.platform }}" if not exist "%PYTHON_DIR%\libs\python314.lib" (