From 8e6a99d0e0188c8dd810a2c7ec2b44fb06126ba2 Mon Sep 17 00:00:00 2001 From: Bruno Lopes Date: Wed, 1 Oct 2025 14:07:13 -0300 Subject: [PATCH] build/windows: Make possible to build (babl only) with MSVC --- .gitlab-ci.yml | 18 ++++--- build/windows/1_build-deps-msys2.ps1 | 49 +++++++++++++++----- build/windows/2_build-gimp-msys2.ps1 | 10 ++-- build/windows/all-deps-vcpkg.txt | 8 ++++ build/windows/installer/3_dist-gimp-inno.ps1 | 2 +- 5 files changed, 64 insertions(+), 23 deletions(-) create mode 100644 build/windows/all-deps-vcpkg.txt diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7ed2517b93..fdc42c7dcc 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -14,6 +14,7 @@ spec: description: 'Pipelines used only for testing' options: - GIMP_CI_MESON_CLANG #trigger the Debian Clang build (rare usefulness) + - GIMP_CI_MESON_MSVC #trigger the Windows MSVC build (rare usefulness) - GIMP_CI_RASTER_ICONS #trigger the Debian Clang build without vector icons (rare usefulness) - GIMP_CI_CPPCHECK #trigger cppcheck (static code analysis) - none @@ -528,6 +529,10 @@ gimp-snap: - if: '($GIMP_CI_MS_STORE != null || "$[[ inputs.distribution_pipeline ]]" =~ /.*GIMP_CI_MS_STORE.*/) && $CI_JOB_NAME !~ /.*eol.*/ && $CI_JOB_NAME !~ /.*installer.*/' variables: STORE_OPTION: '-Dms-store=true' + - if: '($GIMP_CI_MESON_MSVC != null || "$[[ inputs.test_pipeline ]]" =~ /.*GIMP_CI_MESON_MSVC.*/) && $CI_JOB_NAME =~ /.*deps.*/ && $CI_JOB_NAME !~ /.*eol.*/ && $CI_JOB_NAME !~ /.*aarch64.*/' + variables: + VCPKG_ROOT: "$CI_PROJECT_DIR/vcpkg" + VARIANT: "-msvc" - <<: *CI_RELEASE variables: INSTALLER_OPTION: '-Dwindows-installer=true' @@ -542,19 +547,20 @@ gimp-snap: #meson.build forces non-relocatable .pc. See: https://github.com/mesonbuild/meson/issues/14346 PKGCONF_RELOCATABLE_OPTION: '-Dpkgconfig.relocatable=true' before_script: - - if (-not $env:MSYSTEM_PREFIX) { $env:MSYSTEM_PREFIX = if ((Get-WmiObject Win32_ComputerSystem).SystemType -like 'ARM64*') { 'clangarm64' } else { 'clang64' }} - - $GIMP_PREFIX = "$PWD\_install-$env:MSYSTEM_PREFIX" + - $GIMP_PREFIX = "$PWD\_install-$(if (-not $env:MSYSTEM_PREFIX) { $(((Get-WmiObject Win32_ComputerSystem).SystemType).Split('-')[0].Trim().ToLower()) } else { $env:MSYSTEM_PREFIX })" + - if ("$VARIANT" -eq '-msvc') { if (-not (Test-Path $env:VCPKG_ROOT)) { git clone --depth 1 https://github.com/microsoft/vcpkg; .\vcpkg\bootstrap-vcpkg.bat }; pip install meson } + - if ("$VARIANT" -eq '-msvc') { $VSINSTALLDIR = $(vswhere -products * -latest -property installationPath); Import-Module "$VSINSTALLDIR\Common7\Tools\Microsoft.VisualStudio.DevShell.dll"; Enter-VsDevShell -VsInstallPath "$VSINSTALLDIR" -SkipAutomaticLocation -DevCmdArguments "-arch=$(((Get-WmiObject Win32_ComputerSystem).SystemType).Split('-')[0].Trim().ToLower())" } timeout: 30m .win_environ: &WIN_ENVIRON # See: https://testing.developer.gimp.org/core/setup/build/windows/#prepare-for-building - Write-Output "$([char]27)[0Ksection_start:$(Get-Date -UFormat %s -Millisecond 0):win_environ[collapsed=true]$([char]13)$([char]27)[0KPreparing build environment" ## Build-time vars -- $env:PKG_CONFIG_PATH = "$GIMP_PREFIX/lib/pkgconfig;$env:MSYS_ROOT/$env:MSYSTEM_PREFIX/lib/pkgconfig;$env:MSYS_ROOT/$env:MSYSTEM_PREFIX/share/pkgconfig" -- $env:XDG_DATA_DIRS = "$GIMP_PREFIX/share;$env:MSYS_ROOT/$env:MSYSTEM_PREFIX/share" +- $env:PKG_CONFIG_PATH = "$GIMP_PREFIX/lib/pkgconfig;$env:VCPKG_ROOT/installed/$env:VCPKG_DEFAULT_TRIPLET/lib/pkgconfig;$env:VCPKG_ROOT/installed/$env:VCPKG_DEFAULT_TRIPLET/share/pkgconfig;$env:MSYS_ROOT/$env:MSYSTEM_PREFIX/lib/pkgconfig;$env:MSYS_ROOT/$env:MSYSTEM_PREFIX/share/pkgconfig" +- $env:XDG_DATA_DIRS = "$GIMP_PREFIX/share;$env:VCPKG_ROOT/installed/$env:VCPKG_DEFAULT_TRIPLET/share;$env:MSYS_ROOT/$env:MSYSTEM_PREFIX/share" ## Runtime vars -- $env:PATH = "$GIMP_PREFIX/bin;$env:MSYS_ROOT/$env:MSYSTEM_PREFIX/bin;$env:PATH" -- $env:GI_TYPELIB_PATH = "$GIMP_PREFIX/lib/girepository-1.0;$env:MSYS_ROOT/$env:MSYSTEM_PREFIX/lib/girepository-1.0" +- $env:PATH = "$GIMP_PREFIX/bin;$env:VCPKG_ROOT/installed/$env:VCPKG_DEFAULT_TRIPLET/bin;$env:MSYS_ROOT/$env:MSYSTEM_PREFIX/bin;$env:PATH" +- $env:GI_TYPELIB_PATH = "$GIMP_PREFIX/lib/girepository-1.0;$env:VCPKG_ROOT/installed/$env:VCPKG_DEFAULT_TRIPLET/lib/girepository-1.0;$env:MSYS_ROOT/$env:MSYSTEM_PREFIX/lib/girepository-1.0" - Write-Output "$([char]27)[0Ksection_end:$(Get-Date -UFormat %s -Millisecond 0):win_environ$([char]13)$([char]27)[0K" deps-win: diff --git a/build/windows/1_build-deps-msys2.ps1 b/build/windows/1_build-deps-msys2.ps1 index d105e459a7..40bf60d5a6 100644 --- a/build/windows/1_build-deps-msys2.ps1 +++ b/build/windows/1_build-deps-msys2.ps1 @@ -21,7 +21,21 @@ if (-not $GITLAB_CI) # Install the required (pre-built) packages for babl, GEGL and GIMP -if (-not $env:MSYS_ROOT) +if (-not $env:VCPKG_ROOT -or (Test-Path "$env:VCPKG_ROOT\vcpkg.exe" -Type Leaf)) + { + $env:VCPKG_ROOT = $(@($(Resolve-Path "${PWD}\..\vcpkg" -ErrorAction SilentlyContinue),$env:VCPKG_ROOT) | ?{$_} | select -First 1) + if ((Test-Path "$env:VCPKG_ROOT\vcpkg.exe" -Type Leaf) -and -not "$env:VSINSTALLDIR") + { + Write-Host '(ERROR): MSVC installation not found. Please, install it then run this script from Developer PowerShell.' -ForegroundColor Red; Remove-Item env:VCPKG_ROOT + exit 1 + } + } +if (-not $env:VCPKG_DEFAULT_TRIPLET -and $env:VCPKG_ROOT) + { + $env:VCPKG_DEFAULT_TRIPLET = if ((Get-WmiObject Win32_ComputerSystem).SystemType -like 'ARM64*') { 'arm64-windows' } else { 'x64-windows' } + } + +if (-not $env:MSYS_ROOT -and -not (Test-Path "$env:VCPKG_ROOT\vcpkg.exe" -Type Leaf)) { $env:MSYS_ROOT = $(Get-ChildItem HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall -Recurse | ForEach-Object { Get-ItemProperty $_.PSPath -ErrorAction SilentlyContinue } | Where-Object { $_.PSObject.Properties.Value -like "*The MSYS2 Developers*" } | ForEach-Object { return "$($_.InstallLocation)" }) -replace '\\','/' if ("$env:MSYS_ROOT" -eq '') @@ -30,14 +44,23 @@ if (-not $env:MSYS_ROOT) exit 1 } } -if (-not $env:MSYSTEM_PREFIX) +if (-not $env:MSYSTEM_PREFIX -and $env:MSYS_ROOT) { $env:MSYSTEM_PREFIX = if ((Get-WmiObject Win32_ComputerSystem).SystemType -like 'ARM64*') { 'clangarm64' } else { 'clang64' } } -Write-Output "$([char]27)[0Ksection_start:$(Get-Date -UFormat %s -Millisecond 0):deps_install[collapsed=true]$([char]13)$([char]27)[0KInstalling dependencies provided by MSYS2" -powershell -Command { $ProgressPreference = 'SilentlyContinue'; $env:PATH="$env:MSYS_ROOT\usr\bin;$env:PATH"; pacman --noconfirm -Suy }; if ("$LASTEXITCODE" -gt '0') { exit 1 } -powershell -Command { $ProgressPreference = 'SilentlyContinue'; $env:PATH="$env:MSYS_ROOT\usr\bin;$env:PATH"; pacman --noconfirm -S --needed $(if ($env:MSYSTEM_PREFIX -ne 'mingw32') { "$(if ($env:MSYSTEM_PREFIX -eq 'clangarm64') { 'mingw-w64-clang-aarch64' } else { 'mingw-w64-clang-x86_64' })-perl" }) (Get-Content build/windows/all-deps-uni.txt | Where-Object { $_.Trim() -ne '' -and -not $_.Trim().StartsWith('#') }).Replace('${MINGW_PACKAGE_PREFIX}',$(if ($env:MINGW_PACKAGE_PREFIX) { "$env:MINGW_PACKAGE_PREFIX" } elseif ($env:MSYSTEM_PREFIX -eq 'clangarm64') { 'mingw-w64-clang-aarch64' } else { 'mingw-w64-clang-x86_64' })).Replace(' \','') }; if ("$LASTEXITCODE" -gt '0') { exit 1 } +Write-Output "$([char]27)[0Ksection_start:$(Get-Date -UFormat %s -Millisecond 0):deps_install[collapsed=true]$([char]13)$([char]27)[0KInstalling dependencies provided by $(if ("$env:VCPKG_ROOT") {'vcpkg'} else {'MSYS2'})" +if (Test-Path "$env:VCPKG_ROOT\vcpkg.exe" -Type Leaf) + { + & "$env:VCPKG_ROOT\vcpkg.exe" upgrade --no-dry-run + & "$env:VCPKG_ROOT\vcpkg.exe" install (Get-Content build/windows/all-deps-vcpkg.txt | Where-Object { $_.Trim() -ne '' -and -not $_.Trim().StartsWith('#') }).Replace(' \','') + $env:PKG_CONFIG="$env:VCPKG_ROOT\installed\$env:VCPKG_DEFAULT_TRIPLET\tools\pkgconf\pkgconf.exe"; $env:CC='clang-cl' + } +else + { + powershell -Command { $ProgressPreference = 'SilentlyContinue'; $env:PATH="$env:MSYS_ROOT\usr\bin;$env:PATH"; pacman --noconfirm -Suy }; if ("$LASTEXITCODE" -gt '0') { exit 1 } + powershell -Command { $ProgressPreference = 'SilentlyContinue'; $env:PATH="$env:MSYS_ROOT\usr\bin;$env:PATH"; pacman --noconfirm -S --needed $(if ($env:MSYSTEM_PREFIX -ne 'mingw32') { "$(if ($env:MSYSTEM_PREFIX -eq 'clangarm64') { 'mingw-w64-clang-aarch64' } else { 'mingw-w64-clang-x86_64' })-perl" }) (Get-Content build/windows/all-deps-uni.txt | Where-Object { $_.Trim() -ne '' -and -not $_.Trim().StartsWith('#') }).Replace('${MINGW_PACKAGE_PREFIX}',$(if ($env:MINGW_PACKAGE_PREFIX) { "$env:MINGW_PACKAGE_PREFIX" } elseif ($env:MSYSTEM_PREFIX -eq 'clangarm64') { 'mingw-w64-clang-aarch64' } else { 'mingw-w64-clang-x86_64' })).Replace(' \','') }; if ("$LASTEXITCODE" -gt '0') { exit 1 } + } Write-Output "$([char]27)[0Ksection_end:$(Get-Date -UFormat %s -Millisecond 0):deps_install$([char]13)$([char]27)[0K" @@ -100,12 +123,12 @@ function self_build ([string]$repo, [array]$branch, [array]$patches, [array]$opt } ## Configure and/or build - if (-not (Test-Path _build-$env:MSYSTEM_PREFIX\build.ninja -Type Leaf)) + if (-not (Test-Path _build-$(@($env:VCPKG_DEFAULT_TRIPLET,$env:MSYSTEM_PREFIX) | ?{$_} | select -First 1)\build.ninja -Type Leaf)) { if ((Test-Path meson.build -Type Leaf) -and -not (Test-Path CMakeLists.txt -Type Leaf)) { #babl and GEGL already auto install .pdb but we don't know about other eventual deps - if ("$env:MSYSTEM_PREFIX" -ne 'MINGW32') + if (-not "$env:VCPKG_ROOT" -and "$env:MSYSTEM_PREFIX" -ne 'MINGW32') { if ("$dep" -ne 'babl' -and "$dep" -ne 'gegl') { @@ -113,24 +136,24 @@ function self_build ([string]$repo, [array]$branch, [array]$patches, [array]$opt } $clang_opts_meson=@('-Dc_args=-"fansi-escape-codes -gcodeview"', '-Dcpp_args=-"fansi-escape-codes -gcodeview"', '-Dc_link_args="-Wl,--pdb="', '-Dcpp_link_args="-Wl,--pdb="') } - meson setup _build-$env:MSYSTEM_PREFIX -Dprefix="$GIMP_PREFIX" $PKGCONF_RELOCATABLE_OPTION ` + meson setup _build-$(@($env:VCPKG_DEFAULT_TRIPLET,$env:MSYSTEM_PREFIX) | ?{$_} | select -First 1) -Dprefix="$GIMP_PREFIX" $PKGCONF_RELOCATABLE_OPTION ` -Dbuildtype=debugoptimized $clang_opts_meson ` $(if ($branch -like '-*') { $branch } elseif ($patches -like '-*') { $patches } else { $options }); } elseif (Test-Path CMakeLists.txt -Type Leaf) { - if ("$env:MSYSTEM_PREFIX" -ne 'MINGW32') + if (-not "$env:VCPKG_ROOT" -and "$env:MSYSTEM_PREFIX" -ne 'MINGW32') { Add-Content CMakeLists.txt "install(CODE `"execute_process(COMMAND `${Python3_EXECUTABLE`} $("$GIMP_DIR".Replace('\','/'))/build/windows/2_bundle-gimp-uni_sym.py`)`")" $clang_opts_cmake=@('-DCMAKE_C_FLAGS="-gcodeview"', '-DCMAKE_CXX_FLAGS="-gcodeview"', '-DCMAKE_EXE_LINKER_FLAGS="-Wl,--pdb="', '-DCMAKE_SHARED_LINKER_FLAGS="-Wl,--pdb="', '-DCMAKE_MODULE_LINKER_FLAGS="-Wl,--pdb="') } - cmake -G Ninja -B _build-$env:MSYSTEM_PREFIX -DCMAKE_INSTALL_PREFIX="$GIMP_PREFIX" ` + cmake -G Ninja -B _build-$(@($env:VCPKG_DEFAULT_TRIPLET,$env:MSYSTEM_PREFIX) | ?{$_} | select -First 1) -DCMAKE_INSTALL_PREFIX="$GIMP_PREFIX" ` -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_COLOR_DIAGNOSTICS=ON $clang_opts_cmake ` $(if ($branch -like '-*') { $branch } elseif ($patches -like '-*') { $patches } else { $options }); } if ("$LASTEXITCODE" -gt '0') { exit 1 } } - Set-Location _build-$env:MSYSTEM_PREFIX + Set-Location _build-$(@($env:VCPKG_DEFAULT_TRIPLET,$env:MSYSTEM_PREFIX) | ?{$_} | select -First 1) ninja; if ("$LASTEXITCODE" -gt '0') { exit 1 } ninja install; if ("$LASTEXITCODE" -gt '0') { exit 1 } Set-Location ../.. @@ -138,6 +161,10 @@ function self_build ([string]$repo, [array]$branch, [array]$patches, [array]$opt } self_build babl +if ($env:VCPKG_ROOT) + { + exit 0 + } self_build gegl @('-Dworkshop=true') if ("$env:MSYSTEM_PREFIX" -ne 'MINGW32') { diff --git a/build/windows/2_build-gimp-msys2.ps1 b/build/windows/2_build-gimp-msys2.ps1 index 8d69b3b973..166c540a1e 100644 --- a/build/windows/2_build-gimp-msys2.ps1 +++ b/build/windows/2_build-gimp-msys2.ps1 @@ -21,11 +21,11 @@ if (-not $GITLAB_CI) # Install the required (pre-built) packages for babl, GEGL and GIMP (again) -Invoke-Expression ((Get-Content build\windows\1_build-deps-msys2.ps1 | Select-String 'MSYS_ROOT\)' -Context 0,12) -replace '> ','') +Invoke-Expression ((($((Get-Content build\windows\1_build-deps-msys2.ps1 | Select-String '-not \$env:VCPKG_ROOT' -Context 0,26).ToString().Split("`n") | Where-Object { $_.Trim() -ne '' } | ForEach-Object { $_ -replace '> ', '' })) -join "`n")) if ($GITLAB_CI) { - Invoke-Expression ((Get-Content build\windows\1_build-deps-msys2.ps1 | Select-String 'deps_install\[' -Context 0,6) -replace '> ','') + Invoke-Expression ((Get-Content build\windows\1_build-deps-msys2.ps1 | Select-String 'deps_install\[' -Context 0,12) -replace '> ','') } @@ -39,15 +39,15 @@ Invoke-Expression ((Get-Content .gitlab-ci.yml | Select-String 'win_environ\[' - # Build GIMP Write-Output "$([char]27)[0Ksection_start:$(Get-Date -UFormat %s -Millisecond 0):gimp_build[collapsed=true]$([char]13)$([char]27)[0KBuilding GIMP" -if (-not (Test-Path _build-$env:MSYSTEM_PREFIX\build.ninja -Type Leaf)) +if (-not (Test-Path _build-$(@($env:VCPKG_DEFAULT_TRIPLET,$env:MSYSTEM_PREFIX) | ?{$_} | select -First 1)\build.ninja -Type Leaf)) { #FIXME: There is no GJS for Windows. See: https://gitlab.gnome.org/GNOME/gimp/-/issues/5891 - meson setup _build-$env:MSYSTEM_PREFIX -Dprefix="$GIMP_PREFIX" $NON_RELOCATABLE_OPTION ` + meson setup _build-$(@($env:VCPKG_DEFAULT_TRIPLET,$env:MSYSTEM_PREFIX) | ?{$_} | select -First 1) -Dprefix="$GIMP_PREFIX" $NON_RELOCATABLE_OPTION ` $INSTALLER_OPTION $STORE_OPTION $PKGCONF_RELOCATABLE_OPTION ` -Denable-default-bin=enabled -Dbuild-id='org.gimp.GIMP_official'; if ("$LASTEXITCODE" -gt '0') { exit 1 } } -Set-Location _build-$env:MSYSTEM_PREFIX +Set-Location _build-$(@($env:VCPKG_DEFAULT_TRIPLET,$env:MSYSTEM_PREFIX) | ?{$_} | select -First 1) ninja; if ("$LASTEXITCODE" -gt '0') { exit 1 } Write-Output "$([char]27)[0Ksection_end:$(Get-Date -UFormat %s -Millisecond 0):gimp_build$([char]13)$([char]27)[0K" diff --git a/build/windows/all-deps-vcpkg.txt b/build/windows/all-deps-vcpkg.txt new file mode 100644 index 0000000000..99fa6a1e67 --- /dev/null +++ b/build/windows/all-deps-vcpkg.txt @@ -0,0 +1,8 @@ +# DEPS AT BUILD-TIME ONLY +pkgconf \ + +# DEPS AT RUNTIME +#glib \ +#json-glib \ +#libjpeg-turbo \ +#libpng diff --git a/build/windows/installer/3_dist-gimp-inno.ps1 b/build/windows/installer/3_dist-gimp-inno.ps1 index f5b58f3e73..aaf1b785aa 100644 --- a/build/windows/installer/3_dist-gimp-inno.ps1 +++ b/build/windows/installer/3_dist-gimp-inno.ps1 @@ -57,7 +57,7 @@ Set-Alias iscc "$INNO_PATH\iscc.exe" #FIXME: Restore the condition when TWAIN 32-bit support is dropped #if (-not (Get-Command "python" -ErrorAction SilentlyContinue) -or "$(Get-Command "python" -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Source)" -like '*WindowsApps*') # { - Invoke-Expression ((Get-Content build\windows\1_build-deps-msys2.ps1 | Select-String 'MSYS_ROOT\)' -Context 0,12) -replace '> ','') + Invoke-Expression ((Get-Content build\windows\1_build-deps-msys2.ps1 | Select-String '-not \$env:MSYS_ROOT' -Context 0,12) -replace '> ','') $env:PATH = "$env:MSYS_ROOT/$env:MSYSTEM_PREFIX/bin;$env:PATH" # } Write-Output "(INFO): Installed Inno: $inno_version_downloaded | Installed Python: $((python --version) -replace '[^0-9.]', '')"