From 5ccc525281c4bf222e4b17dcd2cc88fd1da88920 Mon Sep 17 00:00:00 2001 From: Bruno Lopes Date: Sun, 14 Sep 2025 07:16:05 -0300 Subject: [PATCH] build/windows: Add colored output and .pdb support for Cmake self builds --- .gitlab-ci.yml | 8 ++-- build/windows/1_build-deps-msys2.ps1 | 12 +++-- build/windows/2_build-gimp-msys2.ps1 | 6 +-- build/windows/2_bundle-gimp-uni_sym.py | 63 +++++++++++++------------- 4 files changed, 46 insertions(+), 43 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 39b3ebd128..b77a7da156 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -548,11 +548,11 @@ gimp-snap: # 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 = "$env:GIMP_PREFIX/lib/pkgconfig;$env:MSYS_ROOT/$env:MSYSTEM_PREFIX/lib/pkgconfig;$env:MSYS_ROOT/$env:MSYSTEM_PREFIX/share/pkgconfig" +- $env:XDG_DATA_DIRS = "$env:GIMP_PREFIX/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 = "$env:GIMP_PREFIX/bin;$env:MSYS_ROOT/$env:MSYSTEM_PREFIX/bin;$env:PATH" +- $env:GI_TYPELIB_PATH = "$env:GIMP_PREFIX/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 558c0f15e3..a3fcc8b6fe 100644 --- a/build/windows/1_build-deps-msys2.ps1 +++ b/build/windows/1_build-deps-msys2.ps1 @@ -45,9 +45,9 @@ Write-Output "$([char]27)[0Ksection_end:$(Get-Date -UFormat %s -Millisecond 0):d $GIMP_DIR = $PWD Set-Location ${GIMP_DIR}${PARENT_DIR} -if (-not $GIMP_PREFIX) +if (-not $env:GIMP_PREFIX) { - $GIMP_PREFIX = "$PWD\_install" + $env:GIMP_PREFIX = "$PWD\_install" } Invoke-Expression ((Get-Content $GIMP_DIR\.gitlab-ci.yml | Select-String 'win_environ\[' -Context 0,7) -replace '> ','' -replace '- ','') @@ -90,12 +90,16 @@ function self_build ([string]$repo, [array]$branch, [array]$patches, [array]$opt { if ((Test-Path meson.build -Type Leaf) -and -not (Test-Path CMakeLists.txt -Type Leaf)) { - meson setup _build-$env:MSYSTEM_PREFIX -Dprefix="$GIMP_PREFIX" $PKGCONF_RELOCATABLE_OPTION --buildtype=debugoptimized ` + #Add-Content meson.build "meson.add_install_script(find_program('$("$GIMP_DIR".Replace('\','/'))/build/windows/2_bundle-gimp-uni_sym.py'))" + meson setup _build-$env:MSYSTEM_PREFIX -Dprefix="$env:GIMP_PREFIX" $PKGCONF_RELOCATABLE_OPTION ` + -Dbuildtype=debugoptimized -Dc_args='-fansi-escape-codes -gcodeview' -Dcpp_args='-fansi-escape-codes -gcodeview' -Dc_link_args='-Wl,--pdb=' -Dcpp_link_args='-Wl,--pdb=' ` $(if ($branch -like '-*') { $branch } elseif ($patches -like '-*') { $patches } else { $options }); } elseif (Test-Path CMakeLists.txt -Type Leaf) { - cmake -G Ninja -B _build-$env:MSYSTEM_PREFIX -DCMAKE_INSTALL_PREFIX="$GIMP_PREFIX" -DCMAKE_BUILD_TYPE=RelWithDebInfo ` + Add-Content CMakeLists.txt "install(CODE `"execute_process(COMMAND `${Python3_EXECUTABLE`} $("$GIMP_DIR".Replace('\','/'))/build/windows/2_bundle-gimp-uni_sym.py`)`")" + cmake -G Ninja -B _build-$env:MSYSTEM_PREFIX -DCMAKE_INSTALL_PREFIX="$env:GIMP_PREFIX" ` + -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_COLOR_DIAGNOSTICS=ON -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=' ` $(if ($branch -like '-*') { $branch } elseif ($patches -like '-*') { $patches } else { $options }); } if ("$LASTEXITCODE" -gt '0') { exit 1 } diff --git a/build/windows/2_build-gimp-msys2.ps1 b/build/windows/2_build-gimp-msys2.ps1 index 4925bc8dc8..d783dfb0b3 100644 --- a/build/windows/2_build-gimp-msys2.ps1 +++ b/build/windows/2_build-gimp-msys2.ps1 @@ -30,10 +30,10 @@ if ($GITLAB_CI) # Prepare env -if (-not $GIMP_PREFIX) +if (-not $env:GIMP_PREFIX) { #FIXME:'gimpenv' have buggy code about Windows paths. See: https://gitlab.gnome.org/GNOME/gimp/-/issues/12284 - $GIMP_PREFIX = "$PWD\..\_install".Replace('\', '/') + $env:GIMP_PREFIX = "$PWD\..\_install".Replace('\', '/') } Invoke-Expression ((Get-Content .gitlab-ci.yml | Select-String 'win_environ\[' -Context 0,7) -replace '> ','' -replace '- ','') @@ -43,7 +43,7 @@ Write-Output "$([char]27)[0Ksection_start:$(Get-Date -UFormat %s -Millisecond 0) if (-not (Test-Path _build-$env:MSYSTEM_PREFIX\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:MSYSTEM_PREFIX -Dprefix="$env: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 } diff --git a/build/windows/2_bundle-gimp-uni_sym.py b/build/windows/2_bundle-gimp-uni_sym.py index 3df7da044a..e6e8df4444 100644 --- a/build/windows/2_bundle-gimp-uni_sym.py +++ b/build/windows/2_bundle-gimp-uni_sym.py @@ -1,40 +1,39 @@ #!/usr/bin/env python3 import os import shutil -import fnmatch +import re +import sys +import json -if not os.getenv("MESON_BUILD_ROOT"): - # On Windows, this script is run if meson option 'win-debugging' is set to 'native' - print("\033[31m(ERROR)\033[0m: Script called standalone. Please just build GIMP on Windows and this script will be called if needed.") +if not os.path.isfile("build.ninja"): + print("\033[31m(ERROR)\033[0m: Script called standalone. This script should be only called from build systems.") sys.exit(1) -# This .py script should not even exist -# Ideally meson should take care of it automatically. -# See: https://github.com/mesonbuild/meson/issues/12977 -for build_root, _, build_bins in os.walk(os.getenv("MESON_BUILD_ROOT")): - for file in build_bins: - if fnmatch.fnmatch(file, '*.dll') or fnmatch.fnmatch(file, '*.exe'): - build_bin = os.path.join(build_root, file) - installed_bin = None - for installed_root, _, installed_bins in os.walk(os.getenv("MESON_INSTALL_DESTDIR_PREFIX")): - if os.path.basename(build_bin) in installed_bins: - installed_bin = os.path.join(installed_root, os.path.basename(build_bin)) - break - if installed_bin and not "test-plug-ins" in build_bin: - install_dir = os.path.dirname(installed_bin) - pdb_debug = os.path.splitext(build_bin)[0] + '.pdb' - print(f"Installing {pdb_debug} to {install_dir}") +if os.getenv("MESON_BUILD_ROOT", False): + with open("meson-info/intro-installed.json", "r") as f: + build_installed = json.load(f) + for build_bin, installed_bin in build_installed.items(): + if build_bin.endswith((".dll", ".exe")): + pdb_debug = os.path.splitext(build_bin)[0] + ".pdb" + install_dir = os.path.dirname(installed_bin) + if os.path.isfile(pdb_debug): + if not os.getenv("MESON_INSTALL_DRY_RUN"): + print(f"Installing {pdb_debug} to {install_dir}") + shutil.copy2(pdb_debug, install_dir) - # Clang correctly puts the .pdb along the $installed_bin - if os.path.isfile(pdb_debug): - if not os.getenv("MESON_INSTALL_DRY_RUN"): +else: + for build_root, dirs, files in os.walk(os.getcwd()): + for file in files: + if file.endswith('_install.cmake'): + with open(os.path.join(build_root, file), "r") as f: + content = f.read() + installed_root = re.search(r'set\s*\(\s*CMAKE_INSTALL_PREFIX\s*"([^"]+)"\s*\)', content).group(1) + for build_bin_line in re.findall(r'file\([^\)]*FILES\s+"[^"]+\.(?:dll|exe)"[^\)]*\)', content): + build_bin = re.search(r'FILES\s+"([^"]+\.(?:dll|exe))"', build_bin_line).group(1) + pdb_debug = os.path.splitext(build_bin)[0] + ".pdb" + install_dir = os.path.join(installed_root, re.search(r'DESTINATION\s+"\$\{CMAKE_INSTALL_PREFIX\}(/[^"\s]+)"', build_bin_line).group(1).lstrip('/')) + if os.path.isfile(pdb_debug): + print(f"-- Installing: {install_dir}/{os.path.basename(pdb_debug)}") + if not os.path.exists(install_dir): + os.makedirs(install_dir) shutil.copy2(pdb_debug, install_dir) - - # GCC dumbly puts the .pdb in $MESON_BUILD_ROOT - else: - if not os.getenv("MESON_INSTALL_DRY_RUN"): - for gcc_root, _, gcc_files in os.walk(os.getenv("MESON_BUILD_ROOT")): - for gcc_file in gcc_files: - if fnmatch.fnmatch(gcc_file, os.path.basename(pdb_debug)): - shutil.copy2(os.path.join(gcc_root, gcc_file), install_dir) - break