From aaa5cd5d619ff8288e0b75a45f4a3dc7eb96d8fe Mon Sep 17 00:00:00 2001
From: Johnny <johnnync13@gmail.com>
Date: Wed, 19 Feb 2025 19:58:18 +0100
Subject: [PATCH] gitlab-ci: add wheel jobs for Linux aarch64

Note that aarch64 wheels are built on manylinux_2_28 due to the
unavailability of `git-lfs` in CentOS 7 for aarch64 (the manylinux2014
base distribution).
---
 .gitlab-ci.yml                                | 524 ++++++++++++++++++
 .gitlab/ci/cdash-groups.json                  |  36 ++
 .../ci/configure_wheel_linux310_aarch64.cmake |   1 +
 ...configure_wheel_linux310_aarch64_egl.cmake |   1 +
 ...figure_wheel_linux310_aarch64_osmesa.cmake |   1 +
 .../ci/configure_wheel_linux311_aarch64.cmake |   1 +
 ...configure_wheel_linux311_aarch64_egl.cmake |   1 +
 ...figure_wheel_linux311_aarch64_osmesa.cmake |   1 +
 .../ci/configure_wheel_linux312_aarch64.cmake |   1 +
 ...configure_wheel_linux312_aarch64_egl.cmake |   1 +
 ...figure_wheel_linux312_aarch64_osmesa.cmake |   1 +
 .../ci/configure_wheel_linux313_aarch64.cmake |   1 +
 ...configure_wheel_linux313_aarch64_egl.cmake |   1 +
 ...figure_wheel_linux313_aarch64_osmesa.cmake |   1 +
 .../ci/configure_wheel_linux38_aarch64.cmake  |   1 +
 .../configure_wheel_linux38_aarch64_egl.cmake |   1 +
 ...nfigure_wheel_linux38_aarch64_osmesa.cmake |   1 +
 .../ci/configure_wheel_linux39_aarch64.cmake  |   1 +
 .../configure_wheel_linux39_aarch64_egl.cmake |   1 +
 ...nfigure_wheel_linux39_aarch64_osmesa.cmake |   1 +
 .gitlab/os-linux.yml                          | 173 +++++-
 .../release/dev/wheels-linux-aarch64.md       |   3 +
 22 files changed, 751 insertions(+), 3 deletions(-)
 create mode 100644 .gitlab/ci/configure_wheel_linux310_aarch64.cmake
 create mode 100644 .gitlab/ci/configure_wheel_linux310_aarch64_egl.cmake
 create mode 100644 .gitlab/ci/configure_wheel_linux310_aarch64_osmesa.cmake
 create mode 100644 .gitlab/ci/configure_wheel_linux311_aarch64.cmake
 create mode 100644 .gitlab/ci/configure_wheel_linux311_aarch64_egl.cmake
 create mode 100644 .gitlab/ci/configure_wheel_linux311_aarch64_osmesa.cmake
 create mode 100644 .gitlab/ci/configure_wheel_linux312_aarch64.cmake
 create mode 100644 .gitlab/ci/configure_wheel_linux312_aarch64_egl.cmake
 create mode 100644 .gitlab/ci/configure_wheel_linux312_aarch64_osmesa.cmake
 create mode 100644 .gitlab/ci/configure_wheel_linux313_aarch64.cmake
 create mode 100644 .gitlab/ci/configure_wheel_linux313_aarch64_egl.cmake
 create mode 100644 .gitlab/ci/configure_wheel_linux313_aarch64_osmesa.cmake
 create mode 100644 .gitlab/ci/configure_wheel_linux38_aarch64.cmake
 create mode 100644 .gitlab/ci/configure_wheel_linux38_aarch64_egl.cmake
 create mode 100644 .gitlab/ci/configure_wheel_linux38_aarch64_osmesa.cmake
 create mode 100644 .gitlab/ci/configure_wheel_linux39_aarch64.cmake
 create mode 100644 .gitlab/ci/configure_wheel_linux39_aarch64_egl.cmake
 create mode 100644 .gitlab/ci/configure_wheel_linux39_aarch64_osmesa.cmake
 create mode 100644 Documentation/release/dev/wheels-linux-aarch64.md

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index dd86f5b26d4..b5c28e5e510 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -869,6 +869,422 @@ wheel-linux-python313-x86_64-egl:test-x11:
     needs:
         - wheel-linux-python313-x86_64:build
 
+## Python aarch64 wheel builds
+
+wheel-linux-python38-aarch64:build:
+    extends:
+        - .wheel_linux38_aarch64
+        - .cmake_build_wheel_linux
+        - .linux_aarch64_builder_tags
+        - .cmake_wheel_artifacts
+        - .scheduled_only
+    needs: []
+
+wheel-linux-python38-aarch64:test:
+    extends:
+        - .wheel_linux38_aarch64
+        - .cmake_test_wheel_linux
+        - .linux_aarch64_builder_tags
+        - .scheduled_only
+        - .cdash_annotations_artifacts
+    needs:
+        - wheel-linux-python38-aarch64:build
+
+wheel-linux-python38-aarch64:test-x11:
+    extends:
+        - .wheel_linux38_aarch64
+        - .cmake_test_wheel_linux_x11_aarch64
+        - .linux_aarch64_tester_tags
+        - .scheduled_only
+        - .cdash_annotations_artifacts
+    needs:
+        - wheel-linux-python38-aarch64:build
+
+wheel-linux-python38-aarch64-osmesa:test:
+    extends:
+        - .wheel_linux38_aarch64_osmesa
+        - .cmake_test_wheel_linux
+        - .linux_aarch64_builder_tags
+        - .scheduled_only
+        - .cdash_annotations_artifacts
+    needs:
+        - wheel-linux-python38-aarch64:build
+
+wheel-linux-python38-aarch64-osmesa:test-x11:
+    extends:
+        - .wheel_linux38_aarch64_osmesa
+        - .cmake_test_wheel_linux_x11_aarch64
+        - .linux_aarch64_builder_tags
+        - .scheduled_only
+        - .cdash_annotations_artifacts
+    needs:
+        - wheel-linux-python38-aarch64:build
+
+wheel-linux-python38-aarch64-egl:test:
+    extends:
+        - .wheel_linux38_aarch64_egl
+        - .cmake_test_wheel_linux
+        - .linux_aarch64_builder_tags
+        - .scheduled_only
+        - .cdash_annotations_artifacts
+    needs:
+        - wheel-linux-python38-aarch64:build
+
+wheel-linux-python38-aarch64-egl:test-x11:
+    extends:
+        - .wheel_linux38_aarch64_egl
+        - .cmake_test_wheel_linux_x11_aarch64
+        - .linux_aarch64_tester_tags
+        - .scheduled_only
+        - .cdash_annotations_artifacts
+    needs:
+        - wheel-linux-python38-aarch64:build
+
+wheel-linux-python39-aarch64:build:
+    extends:
+        - .wheel_linux39_aarch64
+        - .cmake_build_wheel_linux
+        - .linux_aarch64_builder_tags
+        - .cmake_wheel_artifacts
+        - .scheduled_only
+    needs: []
+
+wheel-linux-python39-aarch64:test:
+    extends:
+        - .wheel_linux39_aarch64
+        - .cmake_test_wheel_linux
+        - .linux_aarch64_builder_tags
+        - .scheduled_only
+        - .cdash_annotations_artifacts
+    needs:
+        - wheel-linux-python39-aarch64:build
+
+wheel-linux-python39-aarch64:test-x11:
+    extends:
+        - .wheel_linux39_aarch64
+        - .cmake_test_wheel_linux_x11_aarch64
+        - .linux_aarch64_tester_tags
+        - .scheduled_only
+        - .cdash_annotations_artifacts
+    needs:
+        - wheel-linux-python39-aarch64:build
+
+wheel-linux-python39-aarch64-osmesa:test:
+    extends:
+        - .wheel_linux39_aarch64_osmesa
+        - .cmake_test_wheel_linux
+        - .linux_aarch64_builder_tags
+        - .scheduled_only
+        - .cdash_annotations_artifacts
+    needs:
+        - wheel-linux-python39-aarch64:build
+
+wheel-linux-python39-aarch64-osmesa:test-x11:
+    extends:
+        - .wheel_linux39_aarch64_osmesa
+        - .cmake_test_wheel_linux_x11_aarch64
+        - .linux_aarch64_builder_tags
+        - .scheduled_only
+        - .cdash_annotations_artifacts
+    needs:
+        - wheel-linux-python39-aarch64:build
+
+wheel-linux-python39-aarch64-egl:test:
+    extends:
+        - .wheel_linux39_aarch64_egl
+        - .cmake_test_wheel_linux
+        - .linux_aarch64_builder_tags
+        - .scheduled_only
+        - .cdash_annotations_artifacts
+    needs:
+        - wheel-linux-python39-aarch64:build
+
+wheel-linux-python39-aarch64-egl:test-x11:
+    extends:
+        - .wheel_linux39_aarch64_egl
+        - .cmake_test_wheel_linux_x11_aarch64
+        - .linux_aarch64_tester_tags
+        - .scheduled_only
+        - .cdash_annotations_artifacts
+    needs:
+        - wheel-linux-python39-aarch64:build
+
+wheel-linux-python310-aarch64:build:
+    extends:
+        - .wheel_linux310_aarch64
+        - .cmake_build_wheel_linux
+        - .linux_aarch64_builder_tags
+        - .cmake_wheel_artifacts
+        - .scheduled_only
+    needs: []
+
+wheel-linux-python310-aarch64:test:
+    extends:
+        - .wheel_linux310_aarch64
+        - .cmake_test_wheel_linux
+        - .linux_aarch64_builder_tags
+        - .scheduled_only
+        - .cdash_annotations_artifacts
+    needs:
+        - wheel-linux-python310-aarch64:build
+
+wheel-linux-python310-aarch64:test-x11:
+    extends:
+        - .wheel_linux310_aarch64
+        - .cmake_test_wheel_linux_x11_aarch64
+        - .linux_aarch64_tester_tags
+        - .scheduled_only
+        - .cdash_annotations_artifacts
+    needs:
+        - wheel-linux-python310-aarch64:build
+
+wheel-linux-python310-aarch64-osmesa:test:
+    extends:
+        - .wheel_linux310_aarch64_osmesa
+        - .cmake_test_wheel_linux
+        - .linux_aarch64_builder_tags
+        - .scheduled_only
+        - .cdash_annotations_artifacts
+    needs:
+        - wheel-linux-python310-aarch64:build
+
+wheel-linux-python310-aarch64-osmesa:test-x11:
+    extends:
+        - .wheel_linux310_aarch64_osmesa
+        - .cmake_test_wheel_linux_x11_aarch64
+        - .linux_aarch64_builder_tags
+        - .scheduled_only
+        - .cdash_annotations_artifacts
+    needs:
+        - wheel-linux-python310-aarch64:build
+
+wheel-linux-python310-aarch64-egl:test:
+    extends:
+        - .wheel_linux310_aarch64_egl
+        - .cmake_test_wheel_linux
+        - .linux_aarch64_builder_tags
+        - .scheduled_only
+        - .cdash_annotations_artifacts
+    needs:
+        - wheel-linux-python310-aarch64:build
+
+wheel-linux-python310-aarch64-egl:test-x11:
+    extends:
+        - .wheel_linux310_aarch64_egl
+        - .cmake_test_wheel_linux_x11_aarch64
+        - .linux_aarch64_tester_tags
+        - .scheduled_only
+        - .cdash_annotations_artifacts
+    needs:
+        - wheel-linux-python310-aarch64:build
+
+wheel-linux-python311-aarch64:build:
+    extends:
+        - .wheel_linux311_aarch64
+        - .cmake_build_wheel_linux
+        - .linux_aarch64_builder_tags
+        - .cmake_wheel_artifacts
+        - .scheduled_only
+    needs: []
+
+wheel-linux-python311-aarch64:test:
+    extends:
+        - .wheel_linux311_aarch64
+        - .cmake_test_wheel_linux
+        - .linux_aarch64_builder_tags
+        - .scheduled_only
+        - .cdash_annotations_artifacts
+    needs:
+        - wheel-linux-python311-aarch64:build
+
+wheel-linux-python311-aarch64:test-x11:
+    extends:
+        - .wheel_linux311_aarch64
+        - .cmake_test_wheel_linux_x11_aarch64
+        - .linux_aarch64_tester_tags
+        - .scheduled_only
+        - .cdash_annotations_artifacts
+    needs:
+        - wheel-linux-python311-aarch64:build
+
+wheel-linux-python311-aarch64-osmesa:test:
+    extends:
+        - .wheel_linux311_aarch64_osmesa
+        - .cmake_test_wheel_linux
+        - .linux_aarch64_builder_tags
+        - .scheduled_only
+        - .cdash_annotations_artifacts
+    needs:
+        - wheel-linux-python311-aarch64:build
+
+wheel-linux-python311-aarch64-osmesa:test-x11:
+    extends:
+        - .wheel_linux311_aarch64_osmesa
+        - .cmake_test_wheel_linux_x11_aarch64
+        - .linux_aarch64_builder_tags
+        - .scheduled_only
+        - .cdash_annotations_artifacts
+    needs:
+        - wheel-linux-python311-aarch64:build
+
+wheel-linux-python311-aarch64-egl:test:
+    extends:
+        - .wheel_linux311_aarch64_egl
+        - .cmake_test_wheel_linux
+        - .linux_aarch64_builder_tags
+        - .scheduled_only
+        - .cdash_annotations_artifacts
+    needs:
+        - wheel-linux-python311-aarch64:build
+
+wheel-linux-python311-aarch64-egl:test-x11:
+    extends:
+        - .wheel_linux311_aarch64_egl
+        - .cmake_test_wheel_linux_x11_aarch64
+        - .linux_aarch64_tester_tags
+        - .scheduled_only
+        - .cdash_annotations_artifacts
+    needs:
+        - wheel-linux-python311-aarch64:build
+
+wheel-linux-python312-aarch64:build:
+    extends:
+        - .wheel_linux312_aarch64
+        - .cmake_build_wheel_linux
+        - .linux_aarch64_builder_tags
+        - .cmake_wheel_artifacts
+        - .merged_only
+    needs: []
+
+wheel-linux-python312-aarch64:test:
+    extends:
+        - .wheel_linux312_aarch64
+        - .cmake_test_wheel_linux
+        - .linux_aarch64_builder_tags
+        - .merged_only
+        - .cdash_annotations_artifacts
+    needs:
+        - wheel-linux-python312-aarch64:build
+
+wheel-linux-python312-aarch64:test-x11:
+    extends:
+        - .wheel_linux312_aarch64
+        - .cmake_test_wheel_linux_x11_aarch64
+        - .linux_aarch64_tester_tags
+        - .merged_only
+        - .cdash_annotations_artifacts
+    needs:
+        - wheel-linux-python312-aarch64:build
+
+wheel-linux-python312-aarch64-osmesa:test:
+    extends:
+        - .wheel_linux312_aarch64_osmesa
+        - .cmake_test_wheel_linux
+        - .linux_aarch64_builder_tags
+        - .merged_only
+        - .cdash_annotations_artifacts
+    needs:
+        - wheel-linux-python312-aarch64:build
+
+wheel-linux-python312-aarch64-osmesa:test-x11:
+    extends:
+        - .wheel_linux312_aarch64_osmesa
+        - .cmake_test_wheel_linux_x11_aarch64
+        - .linux_aarch64_builder_tags
+        - .merged_only
+        - .cdash_annotations_artifacts
+    needs:
+        - wheel-linux-python312-aarch64:build
+
+wheel-linux-python312-aarch64-egl:test:
+    extends:
+        - .wheel_linux312_aarch64_egl
+        - .cmake_test_wheel_linux
+        - .linux_aarch64_builder_tags
+        - .merged_only
+        - .cdash_annotations_artifacts
+    needs:
+        - wheel-linux-python312-aarch64:build
+
+wheel-linux-python312-aarch64-egl:test-x11:
+    extends:
+        - .wheel_linux312_aarch64_egl
+        - .cmake_test_wheel_linux_x11_aarch64
+        - .linux_aarch64_tester_tags
+        - .merged_only
+        - .cdash_annotations_artifacts
+    needs:
+        - wheel-linux-python312-aarch64:build
+
+wheel-linux-python313-aarch64:build:
+    extends:
+        - .wheel_linux313_aarch64
+        - .cmake_build_wheel_linux
+        - .linux_aarch64_builder_tags
+        - .cmake_wheel_artifacts
+        - .run_manually
+    needs: []
+
+wheel-linux-python313-aarch64:test:
+    extends:
+        - .wheel_linux313_aarch64
+        - .cmake_test_wheel_linux
+        - .linux_aarch64_builder_tags
+        - .run_automatically
+        - .cdash_annotations_artifacts
+    needs:
+        - wheel-linux-python313-aarch64:build
+
+wheel-linux-python313-aarch64:test-x11:
+    extends:
+        - .wheel_linux313_aarch64
+        - .cmake_test_wheel_linux_x11_aarch64
+        - .linux_aarch64_tester_tags
+        - .run_automatically
+        - .cdash_annotations_artifacts
+    needs:
+        - wheel-linux-python313-aarch64:build
+
+wheel-linux-python313-aarch64-osmesa:test:
+    extends:
+        - .wheel_linux313_aarch64_osmesa
+        - .cmake_test_wheel_linux
+        - .linux_aarch64_builder_tags
+        - .run_automatically
+        - .cdash_annotations_artifacts
+    needs:
+        - wheel-linux-python313-aarch64:build
+
+wheel-linux-python313-aarch64-osmesa:test-x11:
+    extends:
+        - .wheel_linux313_aarch64_osmesa
+        - .cmake_test_wheel_linux_x11_aarch64
+        - .linux_aarch64_builder_tags
+        - .run_automatically
+        - .cdash_annotations_artifacts
+    needs:
+        - wheel-linux-python313-aarch64:build
+
+wheel-linux-python313-aarch64-egl:test:
+    extends:
+        - .wheel_linux313_aarch64_egl
+        - .cmake_test_wheel_linux
+        - .linux_aarch64_builder_tags
+        - .run_automatically
+        - .cdash_annotations_artifacts
+    needs:
+        - wheel-linux-python313-aarch64:build
+
+wheel-linux-python313-aarch64-egl:test-x11:
+    extends:
+        - .wheel_linux313_aarch64_egl
+        - .cmake_test_wheel_linux_x11_aarch64
+        - .linux_aarch64_tester_tags
+        - .run_automatically
+        - .cdash_annotations_artifacts
+    needs:
+        - wheel-linux-python313-aarch64:build
+
 wheel:pypi:upload:
     extends:
         - .pypi_upload
@@ -904,6 +1320,36 @@ wheel:pypi:upload:
           artifacts: false
         - job: wheel-linux-python313-x86_64:test-x11
           artifacts: false
+        - wheel-linux-python38-aarch64:build
+        - job: wheel-linux-python38-aarch64:test
+          artifacts: false
+        - job: wheel-linux-python38-aarch64:test-x11
+          artifacts: false
+        - wheel-linux-python39-aarch64:build
+        - job: wheel-linux-python39-aarch64:test
+          artifacts: false
+        - job: wheel-linux-python39-aarch64:test-x11
+          artifacts: false
+        - wheel-linux-python310-aarch64:build
+        - job: wheel-linux-python310-aarch64:test
+          artifacts: false
+        - job: wheel-linux-python310-aarch64:test-x11
+          artifacts: false
+        - wheel-linux-python311-aarch64:build
+        - job: wheel-linux-python311-aarch64:test
+          artifacts: false
+        - job: wheel-linux-python311-aarch64:test-x11
+          artifacts: false
+        - wheel-linux-python312-aarch64:build
+        - job: wheel-linux-python312-aarch64:test
+          artifacts: false
+        - job: wheel-linux-python312-aarch64:test-x11
+          artifacts: false
+        - wheel-linux-python313-aarch64:build
+        - job: wheel-linux-python313-aarch64:test
+          artifacts: false
+        - job: wheel-linux-python313-aarch64:test-x11
+          artifacts: false
         - wheel-macos-python38-x86_64:build
         - job: wheel-macos-python38-x86_64:test
           artifacts: false
@@ -1452,6 +1898,84 @@ release-artifacts:upload:
           artifacts: false
         - job: wheel-linux-python313-x86_64-egl:test-x11
           artifacts: false
+        - wheel-linux-python38-aarch64:build
+        - job: wheel-linux-python38-aarch64:test
+          artifacts: false
+        - job: wheel-linux-python38-aarch64:test-x11
+          artifacts: false
+        - job: wheel-linux-python38-aarch64-osmesa:test
+          artifacts: false
+        - job: wheel-linux-python38-aarch64-osmesa:test-x11
+          artifacts: false
+        - job: wheel-linux-python38-aarch64-egl:test
+          artifacts: false
+        - job: wheel-linux-python38-aarch64-egl:test-x11
+          artifacts: false
+        - wheel-linux-python39-aarch64:build
+        - job: wheel-linux-python39-aarch64:test
+          artifacts: false
+        - job: wheel-linux-python39-aarch64:test-x11
+          artifacts: false
+        - job: wheel-linux-python39-aarch64-osmesa:test
+          artifacts: false
+        - job: wheel-linux-python39-aarch64-osmesa:test-x11
+          artifacts: false
+        - job: wheel-linux-python39-aarch64-egl:test
+          artifacts: false
+        - job: wheel-linux-python39-aarch64-egl:test-x11
+          artifacts: false
+        - wheel-linux-python310-aarch64:build
+        - job: wheel-linux-python310-aarch64:test
+          artifacts: false
+        - job: wheel-linux-python310-aarch64:test-x11
+          artifacts: false
+        - job: wheel-linux-python310-aarch64-osmesa:test
+          artifacts: false
+        - job: wheel-linux-python310-aarch64-osmesa:test-x11
+          artifacts: false
+        - job: wheel-linux-python310-aarch64-egl:test
+          artifacts: false
+        - job: wheel-linux-python310-aarch64-egl:test-x11
+          artifacts: false
+        - wheel-linux-python311-aarch64:build
+        - job: wheel-linux-python311-aarch64:test
+          artifacts: false
+        - job: wheel-linux-python311-aarch64:test-x11
+          artifacts: false
+        - job: wheel-linux-python311-aarch64-osmesa:test
+          artifacts: false
+        - job: wheel-linux-python311-aarch64-osmesa:test-x11
+          artifacts: false
+        - job: wheel-linux-python311-aarch64-egl:test
+          artifacts: false
+        - job: wheel-linux-python311-aarch64-egl:test-x11
+          artifacts: false
+        - wheel-linux-python312-aarch64:build
+        - job: wheel-linux-python312-aarch64:test
+          artifacts: false
+        - job: wheel-linux-python312-aarch64:test-x11
+          artifacts: false
+        - job: wheel-linux-python312-aarch64-osmesa:test
+          artifacts: false
+        - job: wheel-linux-python312-aarch64-osmesa:test-x11
+          artifacts: false
+        - job: wheel-linux-python312-aarch64-egl:test
+          artifacts: false
+        - job: wheel-linux-python312-aarch64-egl:test-x11
+          artifacts: false
+        - wheel-linux-python313-aarch64:build
+        - job: wheel-linux-python313-aarch64:test
+          artifacts: false
+        - job: wheel-linux-python313-aarch64:test-x11
+          artifacts: false
+        - job: wheel-linux-python313-aarch64-osmesa:test
+          artifacts: false
+        - job: wheel-linux-python313-aarch64-osmesa:test-x11
+          artifacts: false
+        - job: wheel-linux-python313-aarch64-egl:test
+          artifacts: false
+        - job: wheel-linux-python313-aarch64-egl:test-x11
+          artifacts: false
         - wheel-macos-python38-x86_64:build
         - job: wheel-macos-python38-x86_64:test
           artifacts: false
diff --git a/.gitlab/ci/cdash-groups.json b/.gitlab/ci/cdash-groups.json
index 0ba7e004ecc..2acbd85d300 100644
--- a/.gitlab/ci/cdash-groups.json
+++ b/.gitlab/ci/cdash-groups.json
@@ -61,6 +61,42 @@
         { "group": "master", "site": "gitlab-ci", "buildname": "vtk-branch-master-[wheel_linux313_x86_64_ext_vtk]" },
         { "group": "master", "site": "gitlab-ci", "buildname": "vtk-branch-master-[wheel_linux313_x86_64_osmesa]" },
         { "group": "master", "site": "gitlab-ci", "buildname": "vtk-branch-master-[wheel_linux313_x86_64_osmesa_ext_vtk]" },
+        { "group": "master", "site": "gitlab-ci", "buildname": "vtk-branch-master-[wheel_linux38_aarch64]" },
+        { "group": "master", "site": "gitlab-ci", "buildname": "vtk-branch-master-[wheel_linux38_aarch64_egl]" },
+        { "group": "master", "site": "gitlab-ci", "buildname": "vtk-branch-master-[wheel_linux38_aarch64_egl_ext_vtk]" },
+        { "group": "master", "site": "gitlab-ci", "buildname": "vtk-branch-master-[wheel_linux38_aarch64_ext_vtk]" },
+        { "group": "master", "site": "gitlab-ci", "buildname": "vtk-branch-master-[wheel_linux38_aarch64_osmesa]" },
+        { "group": "master", "site": "gitlab-ci", "buildname": "vtk-branch-master-[wheel_linux38_aarch64_osmesa_ext_vtk]" },
+        { "group": "master", "site": "gitlab-ci", "buildname": "vtk-branch-master-[wheel_linux39_aarch64]" },
+        { "group": "master", "site": "gitlab-ci", "buildname": "vtk-branch-master-[wheel_linux39_aarch64_egl]" },
+        { "group": "master", "site": "gitlab-ci", "buildname": "vtk-branch-master-[wheel_linux39_aarch64_egl_ext_vtk]" },
+        { "group": "master", "site": "gitlab-ci", "buildname": "vtk-branch-master-[wheel_linux39_aarch64_ext_vtk]" },
+        { "group": "master", "site": "gitlab-ci", "buildname": "vtk-branch-master-[wheel_linux39_aarch64_osmesa]" },
+        { "group": "master", "site": "gitlab-ci", "buildname": "vtk-branch-master-[wheel_linux39_aarch64_osmesa_ext_vtk]" },
+        { "group": "master", "site": "gitlab-ci", "buildname": "vtk-branch-master-[wheel_linux310_aarch64]" },
+        { "group": "master", "site": "gitlab-ci", "buildname": "vtk-branch-master-[wheel_linux310_aarch64_egl]" },
+        { "group": "master", "site": "gitlab-ci", "buildname": "vtk-branch-master-[wheel_linux310_aarch64_egl_ext_vtk]" },
+        { "group": "master", "site": "gitlab-ci", "buildname": "vtk-branch-master-[wheel_linux310_aarch64_ext_vtk]" },
+        { "group": "master", "site": "gitlab-ci", "buildname": "vtk-branch-master-[wheel_linux310_aarch64_osmesa]" },
+        { "group": "master", "site": "gitlab-ci", "buildname": "vtk-branch-master-[wheel_linux310_aarch64_osmesa_ext_vtk]" },
+        { "group": "master", "site": "gitlab-ci", "buildname": "vtk-branch-master-[wheel_linux311_aarch64]" },
+        { "group": "master", "site": "gitlab-ci", "buildname": "vtk-branch-master-[wheel_linux311_aarch64_egl]" },
+        { "group": "master", "site": "gitlab-ci", "buildname": "vtk-branch-master-[wheel_linux311_aarch64_egl_ext_vtk]" },
+        { "group": "master", "site": "gitlab-ci", "buildname": "vtk-branch-master-[wheel_linux311_aarch64_ext_vtk]" },
+        { "group": "master", "site": "gitlab-ci", "buildname": "vtk-branch-master-[wheel_linux311_aarch64_osmesa]" },
+        { "group": "master", "site": "gitlab-ci", "buildname": "vtk-branch-master-[wheel_linux311_aarch64_osmesa_ext_vtk]" },
+        { "group": "master", "site": "gitlab-ci", "buildname": "vtk-branch-master-[wheel_linux312_aarch64]" },
+        { "group": "master", "site": "gitlab-ci", "buildname": "vtk-branch-master-[wheel_linux312_aarch64_egl]" },
+        { "group": "master", "site": "gitlab-ci", "buildname": "vtk-branch-master-[wheel_linux312_aarch64_egl_ext_vtk]" },
+        { "group": "master", "site": "gitlab-ci", "buildname": "vtk-branch-master-[wheel_linux312_aarch64_ext_vtk]" },
+        { "group": "master", "site": "gitlab-ci", "buildname": "vtk-branch-master-[wheel_linux312_aarch64_osmesa]" },
+        { "group": "master", "site": "gitlab-ci", "buildname": "vtk-branch-master-[wheel_linux312_aarch64_osmesa_ext_vtk]" },
+        { "group": "master", "site": "gitlab-ci", "buildname": "vtk-branch-master-[wheel_linux313_aarch64]" },
+        { "group": "master", "site": "gitlab-ci", "buildname": "vtk-branch-master-[wheel_linux313_aarch64_egl]" },
+        { "group": "master", "site": "gitlab-ci", "buildname": "vtk-branch-master-[wheel_linux313_aarch64_egl_ext_vtk]" },
+        { "group": "master", "site": "gitlab-ci", "buildname": "vtk-branch-master-[wheel_linux313_aarch64_ext_vtk]" },
+        { "group": "master", "site": "gitlab-ci", "buildname": "vtk-branch-master-[wheel_linux313_aarch64_osmesa]" },
+        { "group": "master", "site": "gitlab-ci", "buildname": "vtk-branch-master-[wheel_linux313_aarch64_osmesa_ext_vtk]" },
         { "group": "master", "site": "gitlab-ci", "buildname": "vtk-branch-master-[wheel_macos38_x86_64]" },
         { "group": "master", "site": "gitlab-ci", "buildname": "vtk-branch-master-[wheel_macos38_x86_64_ext_vtk]" },
         { "group": "master", "site": "gitlab-ci", "buildname": "vtk-branch-master-[wheel_macos39_arm64]" },
diff --git a/.gitlab/ci/configure_wheel_linux310_aarch64.cmake b/.gitlab/ci/configure_wheel_linux310_aarch64.cmake
new file mode 100644
index 00000000000..a1b99c8d4b6
--- /dev/null
+++ b/.gitlab/ci/configure_wheel_linux310_aarch64.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_LIST_DIR}/configure_wheel.cmake")
diff --git a/.gitlab/ci/configure_wheel_linux310_aarch64_egl.cmake b/.gitlab/ci/configure_wheel_linux310_aarch64_egl.cmake
new file mode 100644
index 00000000000..a1b99c8d4b6
--- /dev/null
+++ b/.gitlab/ci/configure_wheel_linux310_aarch64_egl.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_LIST_DIR}/configure_wheel.cmake")
diff --git a/.gitlab/ci/configure_wheel_linux310_aarch64_osmesa.cmake b/.gitlab/ci/configure_wheel_linux310_aarch64_osmesa.cmake
new file mode 100644
index 00000000000..a1b99c8d4b6
--- /dev/null
+++ b/.gitlab/ci/configure_wheel_linux310_aarch64_osmesa.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_LIST_DIR}/configure_wheel.cmake")
diff --git a/.gitlab/ci/configure_wheel_linux311_aarch64.cmake b/.gitlab/ci/configure_wheel_linux311_aarch64.cmake
new file mode 100644
index 00000000000..a1b99c8d4b6
--- /dev/null
+++ b/.gitlab/ci/configure_wheel_linux311_aarch64.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_LIST_DIR}/configure_wheel.cmake")
diff --git a/.gitlab/ci/configure_wheel_linux311_aarch64_egl.cmake b/.gitlab/ci/configure_wheel_linux311_aarch64_egl.cmake
new file mode 100644
index 00000000000..a1b99c8d4b6
--- /dev/null
+++ b/.gitlab/ci/configure_wheel_linux311_aarch64_egl.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_LIST_DIR}/configure_wheel.cmake")
diff --git a/.gitlab/ci/configure_wheel_linux311_aarch64_osmesa.cmake b/.gitlab/ci/configure_wheel_linux311_aarch64_osmesa.cmake
new file mode 100644
index 00000000000..a1b99c8d4b6
--- /dev/null
+++ b/.gitlab/ci/configure_wheel_linux311_aarch64_osmesa.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_LIST_DIR}/configure_wheel.cmake")
diff --git a/.gitlab/ci/configure_wheel_linux312_aarch64.cmake b/.gitlab/ci/configure_wheel_linux312_aarch64.cmake
new file mode 100644
index 00000000000..a1b99c8d4b6
--- /dev/null
+++ b/.gitlab/ci/configure_wheel_linux312_aarch64.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_LIST_DIR}/configure_wheel.cmake")
diff --git a/.gitlab/ci/configure_wheel_linux312_aarch64_egl.cmake b/.gitlab/ci/configure_wheel_linux312_aarch64_egl.cmake
new file mode 100644
index 00000000000..a1b99c8d4b6
--- /dev/null
+++ b/.gitlab/ci/configure_wheel_linux312_aarch64_egl.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_LIST_DIR}/configure_wheel.cmake")
diff --git a/.gitlab/ci/configure_wheel_linux312_aarch64_osmesa.cmake b/.gitlab/ci/configure_wheel_linux312_aarch64_osmesa.cmake
new file mode 100644
index 00000000000..a1b99c8d4b6
--- /dev/null
+++ b/.gitlab/ci/configure_wheel_linux312_aarch64_osmesa.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_LIST_DIR}/configure_wheel.cmake")
diff --git a/.gitlab/ci/configure_wheel_linux313_aarch64.cmake b/.gitlab/ci/configure_wheel_linux313_aarch64.cmake
new file mode 100644
index 00000000000..a1b99c8d4b6
--- /dev/null
+++ b/.gitlab/ci/configure_wheel_linux313_aarch64.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_LIST_DIR}/configure_wheel.cmake")
diff --git a/.gitlab/ci/configure_wheel_linux313_aarch64_egl.cmake b/.gitlab/ci/configure_wheel_linux313_aarch64_egl.cmake
new file mode 100644
index 00000000000..a1b99c8d4b6
--- /dev/null
+++ b/.gitlab/ci/configure_wheel_linux313_aarch64_egl.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_LIST_DIR}/configure_wheel.cmake")
diff --git a/.gitlab/ci/configure_wheel_linux313_aarch64_osmesa.cmake b/.gitlab/ci/configure_wheel_linux313_aarch64_osmesa.cmake
new file mode 100644
index 00000000000..a1b99c8d4b6
--- /dev/null
+++ b/.gitlab/ci/configure_wheel_linux313_aarch64_osmesa.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_LIST_DIR}/configure_wheel.cmake")
diff --git a/.gitlab/ci/configure_wheel_linux38_aarch64.cmake b/.gitlab/ci/configure_wheel_linux38_aarch64.cmake
new file mode 100644
index 00000000000..a1b99c8d4b6
--- /dev/null
+++ b/.gitlab/ci/configure_wheel_linux38_aarch64.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_LIST_DIR}/configure_wheel.cmake")
diff --git a/.gitlab/ci/configure_wheel_linux38_aarch64_egl.cmake b/.gitlab/ci/configure_wheel_linux38_aarch64_egl.cmake
new file mode 100644
index 00000000000..a1b99c8d4b6
--- /dev/null
+++ b/.gitlab/ci/configure_wheel_linux38_aarch64_egl.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_LIST_DIR}/configure_wheel.cmake")
diff --git a/.gitlab/ci/configure_wheel_linux38_aarch64_osmesa.cmake b/.gitlab/ci/configure_wheel_linux38_aarch64_osmesa.cmake
new file mode 100644
index 00000000000..a1b99c8d4b6
--- /dev/null
+++ b/.gitlab/ci/configure_wheel_linux38_aarch64_osmesa.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_LIST_DIR}/configure_wheel.cmake")
diff --git a/.gitlab/ci/configure_wheel_linux39_aarch64.cmake b/.gitlab/ci/configure_wheel_linux39_aarch64.cmake
new file mode 100644
index 00000000000..a1b99c8d4b6
--- /dev/null
+++ b/.gitlab/ci/configure_wheel_linux39_aarch64.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_LIST_DIR}/configure_wheel.cmake")
diff --git a/.gitlab/ci/configure_wheel_linux39_aarch64_egl.cmake b/.gitlab/ci/configure_wheel_linux39_aarch64_egl.cmake
new file mode 100644
index 00000000000..a1b99c8d4b6
--- /dev/null
+++ b/.gitlab/ci/configure_wheel_linux39_aarch64_egl.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_LIST_DIR}/configure_wheel.cmake")
diff --git a/.gitlab/ci/configure_wheel_linux39_aarch64_osmesa.cmake b/.gitlab/ci/configure_wheel_linux39_aarch64_osmesa.cmake
new file mode 100644
index 00000000000..a1b99c8d4b6
--- /dev/null
+++ b/.gitlab/ci/configure_wheel_linux39_aarch64_osmesa.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_LIST_DIR}/configure_wheel.cmake")
diff --git a/.gitlab/os-linux.yml b/.gitlab/os-linux.yml
index e5767073105..75d14d52318 100644
--- a/.gitlab/os-linux.yml
+++ b/.gitlab/os-linux.yml
@@ -21,6 +21,13 @@
         GIT_CLONE_PATH: $CI_BUILDS_DIR/gitlab-kitware-sciviz-ci
         VTK_INSTALL: 1
 
+.manylinux_2_28_aarch64:
+    image: "quay.io/pypa/manylinux_2_28_aarch64"
+
+    variables:
+        GIT_CLONE_PATH: $CI_BUILDS_DIR/gitlab-kitware-sciviz-ci
+        VTK_INSTALL: 1
+
 .manylinux_2_28_x86_64:
     extends: .manylinux2014_x86_64
     image: "quay.io/pypa/manylinux_2_28_x86_64"
@@ -177,6 +184,144 @@
     variables:
         CMAKE_CONFIGURATION: wheel_linux313_x86_64_egl
 
+.wheel_linux38_aarch64:
+    extends: .manylinux_2_28_aarch64
+
+    variables:
+        CMAKE_CONFIGURATION: wheel_linux38_aarch64
+        PYTHON_PREFIX: /opt/python/cp38-cp38
+
+.wheel_linux38_aarch64_osmesa:
+    extends:
+        - .wheel_linux38_aarch64
+        - .wheel_linux_osmesa_addon
+
+    variables:
+        CMAKE_CONFIGURATION: wheel_linux38_aarch64_osmesa
+
+.wheel_linux38_aarch64_egl:
+    extends:
+        - .wheel_linux38_aarch64
+        - .wheel_linux_egl_addon
+
+    variables:
+        CMAKE_CONFIGURATION: wheel_linux38_aarch64_egl
+
+.wheel_linux39_aarch64:
+    extends: .manylinux_2_28_aarch64
+
+    variables:
+        CMAKE_CONFIGURATION: wheel_linux39_aarch64
+        PYTHON_PREFIX: /opt/python/cp39-cp39
+
+.wheel_linux39_aarch64_osmesa:
+    extends:
+        - .wheel_linux39_aarch64
+        - .wheel_linux_osmesa_addon
+
+    variables:
+        CMAKE_CONFIGURATION: wheel_linux39_aarch64_osmesa
+
+.wheel_linux39_aarch64_egl:
+    extends:
+        - .wheel_linux39_aarch64
+        - .wheel_linux_egl_addon
+
+    variables:
+        CMAKE_CONFIGURATION: wheel_linux39_aarch64_egl
+
+.wheel_linux310_aarch64:
+    extends: .manylinux_2_28_aarch64
+
+    variables:
+        CMAKE_CONFIGURATION: wheel_linux310_aarch64
+        PYTHON_PREFIX: /opt/python/cp310-cp310
+
+.wheel_linux310_aarch64_osmesa:
+    extends:
+        - .wheel_linux310_aarch64
+        - .wheel_linux_osmesa_addon
+
+    variables:
+        CMAKE_CONFIGURATION: wheel_linux310_aarch64_osmesa
+
+.wheel_linux310_aarch64_egl:
+    extends:
+        - .wheel_linux310_aarch64
+        - .wheel_linux_egl_addon
+
+    variables:
+        CMAKE_CONFIGURATION: wheel_linux310_aarch64_egl
+
+.wheel_linux311_aarch64:
+    extends: .manylinux_2_28_aarch64
+
+    variables:
+        CMAKE_CONFIGURATION: wheel_linux311_aarch64
+        PYTHON_PREFIX: /opt/python/cp311-cp311
+
+.wheel_linux311_aarch64_osmesa:
+    extends:
+        - .wheel_linux311_aarch64
+        - .wheel_linux_osmesa_addon
+
+    variables:
+        CMAKE_CONFIGURATION: wheel_linux311_aarch64_osmesa
+
+.wheel_linux311_aarch64_egl:
+    extends:
+        - .wheel_linux311_aarch64
+        - .wheel_linux_egl_addon
+
+    variables:
+        CMAKE_CONFIGURATION: wheel_linux311_aarch64_egl
+
+.wheel_linux312_aarch64:
+    extends: .manylinux_2_28_aarch64
+
+    variables:
+        CMAKE_CONFIGURATION: wheel_linux312_aarch64
+        PYTHON_PREFIX: /opt/python/cp312-cp312
+
+.wheel_linux312_aarch64_osmesa:
+    extends:
+        - .wheel_linux312_aarch64
+        - .wheel_linux_osmesa_addon
+
+    variables:
+        CMAKE_CONFIGURATION: wheel_linux312_aarch64_osmesa
+
+.wheel_linux312_aarch64_egl:
+    extends:
+        - .wheel_linux312_aarch64
+        - .wheel_linux_egl_addon
+
+    variables:
+        CMAKE_CONFIGURATION: wheel_linux312_aarch64_egl
+
+.wheel_linux313_aarch64:
+    extends: .manylinux_2_28_aarch64
+
+    variables:
+        CMAKE_CONFIGURATION: wheel_linux313_aarch64
+        PYTHON_PREFIX: /opt/python/cp313-cp313
+
+.wheel_linux313_aarch64_osmesa:
+    extends:
+        - .wheel_linux313_aarch64
+        - .wheel_linux_osmesa_addon
+
+    variables:
+        CMAKE_CONFIGURATION: wheel_linux313_aarch64_osmesa
+
+.wheel_linux313_aarch64_egl:
+    extends:
+        - .wheel_linux313_aarch64
+        - .wheel_linux_egl_addon
+
+    variables:
+        CMAKE_CONFIGURATION: wheel_linux313_aarch64_egl
+
 .fedora39:
     extends: .linux
     image: "kitware/vtk:ci-fedora39-20240828"
@@ -517,6 +662,22 @@
         - linux-x86_64
         - vtk
 
+# Linux aarch64 tags
+
+.linux_aarch64_builder_tags:
+    tags:
+        - build
+        - docker
+        - linux-aarch64
+        - vtk
+
+.linux_aarch64_tester_tags:
+    tags:
+        - docker
+        - linux-aarch64
+        - x11
+        - vtk
+
 ## Linux-specific scripts
 
 .before_script_linux: &before_script_linux
@@ -638,10 +799,8 @@
         # Pull from `.cmake_test_wheel_linux_x11` when merging happens.
     interruptible: true
 
-.cmake_test_wheel_linux_x11:
+.common_test_wheel_linux_x11: &common_test_wheel_linux_x11
     stage: test
-    image: "quay.io/pypa/manylinux_2_28_x86_64"
-
     script:
         # Set `LD_LIBRARY_PATH` for osmesa wheels.
         - cmake -P .gitlab/ci/download_osmesa.cmake
@@ -667,6 +826,14 @@
         - exec .gitlab/ci/check_warnings.sh ./Testing/ExternalWheel
     interruptible: true
 
+.cmake_test_wheel_linux_x11:
+    extends: .common_test_wheel_linux_x11
+    image: "quay.io/pypa/manylinux_2_28_x86_64"
+
+.cmake_test_wheel_linux_x11_aarch64:
+    extends: .common_test_wheel_linux_x11
+    image: "quay.io/pypa/manylinux_2_28_aarch64"
+
 .cmake_build_java_linux:
     stage: build
     extends: .cmake_build_linux
diff --git a/Documentation/release/dev/wheels-linux-aarch64.md b/Documentation/release/dev/wheels-linux-aarch64.md
new file mode 100644
index 00000000000..dc55774fba5
--- /dev/null
+++ b/Documentation/release/dev/wheels-linux-aarch64.md
@@ -0,0 +1,3 @@
+## wheels-linux-aarch64
+
+VTK now provides wheels for Linux aarch64
-- 
GitLab