SDL: Add build-release.py updates from satellite libraries

From 19cc04a162532423eb6384b123ced6fdb8886f8d Mon Sep 17 00:00:00 2001
From: Anonymous Maarten <[EMAIL REDACTED]>
Date: Sat, 7 Dec 2024 10:20:42 +0100
Subject: [PATCH] Add build-release.py updates from satellite libraries

[ci skip]
---
 .github/workflows/release.yml                 |  1 -
 build-scripts/build-release.py                | 64 +++++++++++++++----
 .../android/cmake/SDL3Config.cmake            |  2 +-
 .../msvc/cmake/SDL3Config.cmake.in            |  2 +-
 cmake/android/FindSdlAndroid.cmake            |  2 +-
 cmake/android/FindSdlAndroidBuildTools.cmake  |  2 +-
 cmake/android/FindSdlAndroidPlatform.cmake    |  2 +-
 cmake/android/SdlAndroidFunctions.cmake       |  2 +-
 cmake/android/SdlAndroidScript.cmake          |  2 +-
 9 files changed, 58 insertions(+), 21 deletions(-)

diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 17870cba569fb..35e83195388b5 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -600,7 +600,6 @@ jobs:
               -DCMAKE_PREFIX_PATH="${{ steps.sdk.outputs.prefix }}" \
               -DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK_HOME}/build/cmake/android.toolchain.cmake \
               -DANDROID_ABI=${android_abi} \
-              -Werror=dev \
               -DCMAKE_BUILD_TYPE=Release \
               -B "${android_abi}"
             echo "Building ${android_abi}..."
diff --git a/build-scripts/build-release.py b/build-scripts/build-release.py
index 3295c1f8dd4de..2002039e6aeab 100755
--- a/build-scripts/build-release.py
+++ b/build-scripts/build-release.py
@@ -328,6 +328,10 @@ def configure_text(text: str, context: dict[str, str]) -> str:
     return text
 
 
+def configure_text_list(text_list: list[str], context: dict[str, str]) -> list[str]:
+    return [configure_text(text=e, context=context) for e in text_list]
+
+
 class ArchiveFileTree:
     def __init__(self):
         self._tree: dict[str, NodeInArchive] = {}
@@ -343,7 +347,7 @@ def add_to_archiver(self, archive_base: str, archiver: Archiver):
         added_files = dict()
 
         def calculate_symlink_target(s: NodeInArchive) -> str:
-            dest_dir = os.path.dirname(s.path)
+            dest_dir = os.path.dirname(s.arcpath)
             if dest_dir:
                 dest_dir += "/"
             target = dest_dir + s.symtarget
@@ -357,12 +361,15 @@ def calculate_symlink_target(s: NodeInArchive) -> str:
 
         # Add files in first pass
         for arcpath, node in self._tree.items():
+            assert node is not None, f"{arcpath} -> node"
             if node.data is not None:
                 archiver.add_file_data(arcpath=arc_join(archive_base, arcpath), data=node.data, time=node.time, mode=node.mode)
-                added_files[node.path] = node
+                assert node.arcpath is not None, f"{node=}"
+                added_files[node.arcpath] = node
             elif node.path is not None:
                 archiver.add_file_path(arcpath=arc_join(archive_base, arcpath), path=node.path)
-                added_files[node.path] = node
+                assert node.arcpath is not None, f"{node=}"
+                added_files[node.arcpath] = node
             elif node.symtarget is not None:
                 remaining_symlinks.add(node)
             elif node.directory:
@@ -370,6 +377,8 @@ def calculate_symlink_target(s: NodeInArchive) -> str:
             else:
                 raise ValueError(f"Invalid Archive Node: {repr(node)}")
 
+        assert None not in added_files
+
         # Resolve symlinks in second pass: zipfile does not support symlinks, so add files to zip archive
         while True:
             if not remaining_symlinks:
@@ -380,18 +389,18 @@ def calculate_symlink_target(s: NodeInArchive) -> str:
                 symlink_files_for_zip = {}
                 symlink_target_path = calculate_symlink_target(symlink)
                 if symlink_target_path in added_files:
-                    symlink_files_for_zip[symlink.path] = added_files[symlink_target_path]
+                    symlink_files_for_zip[symlink.arcpath] = added_files[symlink_target_path]
                 else:
                     symlink_target_path_slash = symlink_target_path + "/"
                     for added_file in added_files:
                         if added_file.startswith(symlink_target_path_slash):
-                            path_in_symlink = symlink.path + "/" + added_file.removeprefix(symlink_target_path_slash)
+                            path_in_symlink = symlink.arcpath + "/" + added_file.removeprefix(symlink_target_path_slash)
                             symlink_files_for_zip[path_in_symlink] = added_files[added_file]
                 if symlink_files_for_zip:
                     symlinks_this_time.add(symlink)
                     extra_added_files.update(symlink_files_for_zip)
                     files_for_zip = [{"arcpath": f"{archive_base}/{sym_path}", "data": sym_info.data, "mode": sym_info.mode} for sym_path, sym_info in symlink_files_for_zip.items()]
-                    archiver.add_symlink(arcpath=f"{archive_base}/{symlink.path}", target=symlink.symtarget, time=symlink.time, files_for_zip=files_for_zip)
+                    archiver.add_symlink(arcpath=f"{archive_base}/{symlink.arcpath}", target=symlink.symtarget, time=symlink.time, files_for_zip=files_for_zip)
             # if not symlinks_this_time:
             #     logger.info("files added: %r", set(path for path in added_files.keys()))
             assert symlinks_this_time, f"No targets found for symlinks: {remaining_symlinks}"
@@ -545,6 +554,7 @@ def get_context(self, extra_context: typing.Optional[dict[str, str]]=None) -> di
             "PROJECT_VERSION": self.version,
             "PROJECT_COMMIT": self.commit,
             "PROJECT_REVISION": self.revision,
+            "PROJECT_ROOT": str(self.root),
         }
         if extra_context:
             ctx.update(extra_context)
@@ -741,15 +751,20 @@ def extract_filter(member: tarfile.TarInfo, path: str, /):
                 install_path = build_parent_dir / f"install-{triplet}"
                 shutil.rmtree(install_path, ignore_errors=True)
                 build_path.mkdir(parents=True, exist_ok=True)
+                context = self.get_context({
+                    "ARCH": arch,
+                    "DEP_PREFIX": str(mingw_deps_path / triplet),
+                })
+                extra_args = configure_text_list(text_list=self.release_info["mingw"]["autotools"]["args"], context=context)
+
                 with self.section_printer.group(f"Configuring MinGW {triplet} (autotools)"):
-                    extra_args = [arg.replace("@DEP_PREFIX@", str(mingw_deps_path / triplet)) for arg in self.release_info["mingw"]["autotools"]["args"]]
                     assert "@" not in " ".join(extra_args), f"@ should not be present in extra arguments ({extra_args})"
                     self.executer.run([
                         self.root / "configure",
                         f"--prefix={install_path}",
-                        f"--includedir={install_path}/include",
-                        f"--libdir={install_path}/lib",
-                        f"--bindir={install_path}/bin",
+                        f"--includedir=${{prefix}}/include",
+                        f"--libdir=${{prefix}}/lib",
+                        f"--bindir=${{prefix}}/bin",
                         f"--host={triplet}",
                         f"--build=x86_64-none-linux-gnu",
                     ] + extra_args, cwd=build_path, env=new_env)
@@ -757,7 +772,13 @@ def extract_filter(member: tarfile.TarInfo, path: str, /):
                     self.executer.run(["make", f"-j{self.cpu_count}"], cwd=build_path, env=new_env)
                 with self.section_printer.group(f"Install MinGW {triplet} (autotools)"):
                     self.executer.run(["make", "install"], cwd=build_path, env=new_env)
-                archive_file_tree.add_directory_tree(arc_dir=arc_join(arc_root, triplet), path=install_path)
+                archive_file_tree.add_directory_tree(arc_dir=arc_join(arc_root, triplet), path=install_path, time=self.arc_time)
+
+                print("Recording arch-dependent extra files for MinGW development archive ...")
+                extra_context = {
+                    "TRIPLET": ARCH_TO_TRIPLET[arch],
+                }
+                archive_file_tree.add_file_mapping(arc_dir=arc_root, file_mapping=self.release_info["mingw"]["autotools"].get("files", {}), file_mapping_root=self.root, context=self.get_context(extra_context=extra_context), time=self.arc_time)
 
         if "cmake" in self.release_info["mingw"]:
             assert self.release_info["mingw"]["cmake"]["shared-static"] in ("args", "both")
@@ -770,6 +791,12 @@ def extract_filter(member: tarfile.TarInfo, path: str, /):
                 assert arch not in mingw_archs
                 mingw_archs.add(arch)
 
+                context = self.get_context({
+                    "ARCH": arch,
+                    "DEP_PREFIX": str(mingw_deps_path / triplet),
+                })
+                extra_args = configure_text_list(text_list=self.release_info["mingw"]["cmake"]["args"], context=context)
+
                 build_path = build_parent_dir / f"build-{triplet}"
                 install_path = build_parent_dir / f"install-{triplet}"
                 shutil.rmtree(install_path, ignore_errors=True)
@@ -780,7 +807,6 @@ def extract_filter(member: tarfile.TarInfo, path: str, /):
                     args_for_shared_static = (["-DBUILD_SHARED_LIBS=ON"], ["-DBUILD_SHARED_LIBS=OFF"])
                 for arg_for_shared_static in args_for_shared_static:
                     with self.section_printer.group(f"Configuring MinGW {triplet} (CMake)"):
-                        extra_args = [arg.replace("@DEP_PREFIX@", str(mingw_deps_path / triplet)) for arg in self.release_info["mingw"]["cmake"]["args"]]
                         assert "@" not in " ".join(extra_args), f"@ should not be present in extra arguments ({extra_args})"
                         self.executer.run([
                             f"cmake",
@@ -803,6 +829,13 @@ def extract_filter(member: tarfile.TarInfo, path: str, /):
                         self.executer.run(["cmake", "--install", str(build_path)], cwd=build_path, env=new_env)
                 archive_file_tree.add_directory_tree(arc_dir=arc_join(arc_root, triplet), path=install_path, time=self.arc_time)
 
+                print("Recording arch-dependent extra files for MinGW development archive ...")
+                extra_context = {
+                    "TRIPLET": ARCH_TO_TRIPLET[arch],
+                }
+                archive_file_tree.add_file_mapping(arc_dir=arc_root, file_mapping=self.release_info["mingw"]["cmake"].get("files", {}), file_mapping_root=self.root, context=self.get_context(extra_context=extra_context), time=self.arc_time)
+                print("... done")
+
         print("Recording extra files for MinGW development archive ...")
         archive_file_tree.add_file_mapping(arc_dir=arc_root, file_mapping=self.release_info["mingw"].get("files", {}), file_mapping_root=self.root, context=self.get_context(), time=self.arc_time)
         print("... done")
@@ -1231,6 +1264,10 @@ def _build_msvc_devel(self) -> None:
         zip_path = self.dist_path / f"{self.project}-devel-{self.version}-VC.zip"
         arc_root = f"{self.project}-{self.version}"
 
+        def copy_files_devel(ctx):
+            archive_file_tree.add_file_mapping(arc_dir=arc_root, file_mapping=self.release_info["msvc"]["files-devel"], file_mapping_root=self.root, context=ctx, time=self.arc_time)
+
+
         logger.info("Collecting files...")
         archive_file_tree = ArchiveFileTree()
         if "msbuild" in self.release_info["msvc"]:
@@ -1238,12 +1275,13 @@ def _build_msvc_devel(self) -> None:
                 arch_platform = self._arch_to_vs_platform(arch=arch)
                 platform_context = self.get_context(arch_platform.extra_context())
                 archive_file_tree.add_file_mapping(arc_dir=arc_root, file_mapping=self.release_info["msvc"]["msbuild"]["files-devel"], file_mapping_root=self.root, context=platform_context, time=self.arc_time)
+                copy_files_devel(ctx=platform_context)
         if "cmake" in self.release_info["msvc"]:
             for arch in self.release_info["msvc"]["cmake"]["archs"]:
                 arch_platform = self._arch_to_vs_platform(arch=arch)
                 platform_context = self.get_context(arch_platform.extra_context())
                 archive_file_tree.add_file_mapping(arc_dir=arc_root, file_mapping=self.release_info["msvc"]["cmake"]["files-devel"], file_mapping_root=self._arch_platform_to_install_path(arch_platform), context=platform_context, time=self.arc_time)
-        archive_file_tree.add_file_mapping(arc_dir=arc_root, file_mapping=self.release_info["msvc"]["files-devel"], file_mapping_root=self.root, context=self.get_context(), time=self.arc_time)
+                copy_files_devel(ctx=platform_context)
 
         with Archiver(zip_path=zip_path) as archiver:
             archive_file_tree.add_to_archiver(archive_base="", archiver=archiver)
diff --git a/build-scripts/pkg-support/android/cmake/SDL3Config.cmake b/build-scripts/pkg-support/android/cmake/SDL3Config.cmake
index a41275dc480c5..5b92a456ed3f6 100644
--- a/build-scripts/pkg-support/android/cmake/SDL3Config.cmake
+++ b/build-scripts/pkg-support/android/cmake/SDL3Config.cmake
@@ -1,7 +1,7 @@
 # SDL CMake configuration file:
 # This file is meant to be placed in lib/cmake/SDL3 subfolder of a reconstructed Android SDL3 SDK
 
-cmake_minimum_required(VERSION 3.0...3.5)
+cmake_minimum_required(VERSION 3.0...3.28)
 
 include(FeatureSummary)
 set_package_properties(SDL3 PROPERTIES
diff --git a/build-scripts/pkg-support/msvc/cmake/SDL3Config.cmake.in b/build-scripts/pkg-support/msvc/cmake/SDL3Config.cmake.in
index 5463b498f141f..6387376e8f8a1 100644
--- a/build-scripts/pkg-support/msvc/cmake/SDL3Config.cmake.in
+++ b/build-scripts/pkg-support/msvc/cmake/SDL3Config.cmake.in
@@ -1,7 +1,7 @@
 # @<@PROJECT_NAME@>@ CMake configuration file:
 # This file is meant to be placed in a cmake subfolder of @<@PROJECT_NAME@>@-devel-@<@PROJECT_VERSION@>@-VC.zip
 
-cmake_minimum_required(VERSION 3.0...3.5)
+cmake_minimum_required(VERSION 3.0...3.28)
 
 include(FeatureSummary)
 set_package_properties(SDL3 PROPERTIES
diff --git a/cmake/android/FindSdlAndroid.cmake b/cmake/android/FindSdlAndroid.cmake
index 38a2d7a136c00..851848f783876 100644
--- a/cmake/android/FindSdlAndroid.cmake
+++ b/cmake/android/FindSdlAndroid.cmake
@@ -61,7 +61,7 @@ This module will set the following variables in your project:
 
 #]=======================================================================]
 
-cmake_minimum_required(VERSION 3.7)
+cmake_minimum_required(VERSION 3.7...3.28)
 
 if(NOT PROJECT_NAME MATCHES "^SDL.*")
   message(WARNING "This module is internal to SDL and is currently not supported.")
diff --git a/cmake/android/FindSdlAndroidBuildTools.cmake b/cmake/android/FindSdlAndroidBuildTools.cmake
index b8825d92b572c..999a268edba3b 100644
--- a/cmake/android/FindSdlAndroidBuildTools.cmake
+++ b/cmake/android/FindSdlAndroidBuildTools.cmake
@@ -52,7 +52,7 @@ This module responds to the flags:
 
 #]=======================================================================]
 
-cmake_minimum_required(VERSION 3.7)
+cmake_minimum_required(VERSION 3.7...3.28)
 
 if(NOT PROJECT_NAME MATCHES "^SDL.*")
   message(WARNING "This module is internal to SDL and is currently not supported.")
diff --git a/cmake/android/FindSdlAndroidPlatform.cmake b/cmake/android/FindSdlAndroidPlatform.cmake
index 7b569e3e1b5a1..fbe53c3094ad8 100644
--- a/cmake/android/FindSdlAndroidPlatform.cmake
+++ b/cmake/android/FindSdlAndroidPlatform.cmake
@@ -55,7 +55,7 @@ This module responds to the flags:
 
 #]=======================================================================]
 
-cmake_minimum_required(VERSION 3.7)
+cmake_minimum_required(VERSION 3.7...3.28)
 
 if(NOT PROJECT_NAME MATCHES "^SDL.*")
     message(WARNING "This module is internal to SDL and is currently not supported.")
diff --git a/cmake/android/SdlAndroidFunctions.cmake b/cmake/android/SdlAndroidFunctions.cmake
index b7b3aa84962fe..4acce4700593c 100644
--- a/cmake/android/SdlAndroidFunctions.cmake
+++ b/cmake/android/SdlAndroidFunctions.cmake
@@ -5,7 +5,7 @@ It is (currently) limited to packaging binaries for a single architecture.
 
 #]=======================================================================]
 
-cmake_minimum_required(VERSION 3.7)
+cmake_minimum_required(VERSION 3.7...3.28)
 
 if(NOT PROJECT_NAME MATCHES "^SDL.*")
   message(WARNING "This module is internal to SDL and is currently not supported.")
diff --git a/cmake/android/SdlAndroidScript.cmake b/cmake/android/SdlAndroidScript.cmake
index dd98f9b4bde6f..15dea2d13af3e 100644
--- a/cmake/android/SdlAndroidScript.cmake
+++ b/cmake/android/SdlAndroidScript.cmake
@@ -6,7 +6,7 @@ Because
 
 #]=======================================================================]
 
-cmake_minimum_required(VERSION 3.16)
+cmake_minimum_required(VERSION 3.16...3.28)
 
 if(NOT CMAKE_SCRIPT_MODE_FILE)
   message(FATAL_ERROR "This file can only be used in CMake script mode")