From a5d1f4195cda9fdc45c730c628d4ee49c825f210 Mon Sep 17 00:00:00 2001 From: Oscar Benjamin Date: Sun, 25 Jan 2026 17:53:55 +0000 Subject: [PATCH 01/25] maint: add Windows on ARM64 support --- .github/workflows/buildwheel.yml | 13 ++++++++++-- ...ws.sh => cibw_before_all_windows_amd64.sh} | 0 bin/cibw_before_all_windows_arm64.sh | 20 +++++++++++++++++++ 3 files changed, 31 insertions(+), 2 deletions(-) rename bin/{cibw_before_all_windows.sh => cibw_before_all_windows_amd64.sh} (100%) create mode 100755 bin/cibw_before_all_windows_arm64.sh diff --git a/.github/workflows/buildwheel.yml b/.github/workflows/buildwheel.yml index 9b48d669..3c87f6dc 100644 --- a/.github/workflows/buildwheel.yml +++ b/.github/workflows/buildwheel.yml @@ -10,7 +10,14 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-22.04, ubuntu-22.04-arm, windows-2022, macos-15-intel, macos-14] + os: [ + ubuntu-22.04, + ubuntu-22.04-arm, + windows-2022, + windows-11-arm, + macos-15-intel, + macos-14, + ] steps: - uses: actions/checkout@v6.0.1 @@ -38,7 +45,8 @@ jobs: uses: pypa/cibuildwheel@63fd63b352a9a8bdcc24791c9dbee952ee9a8abc # v3.3.0 env: # override setting in pyproject.toml to use msys2 instead of msys64 bash - CIBW_BEFORE_ALL_WINDOWS: msys2 -c bin/cibw_before_all_windows.sh + CIBW_BEFORE_ALL_WINDOWS_AMD64: msys2 -c bin/cibw_before_all_windows_amd64.sh + CIBW_BEFORE_ALL_WINDOWS_ARM64: msys2 -c bin/cibw_before_all_windows_arm64.sh - uses: actions/upload-artifact@v5 with: @@ -78,6 +86,7 @@ jobs: ubuntu-24.04-arm, windows-2022, windows-2025, + windows-11-arm, macos-15-intel, macos-14, macos-15, diff --git a/bin/cibw_before_all_windows.sh b/bin/cibw_before_all_windows_amd64.sh similarity index 100% rename from bin/cibw_before_all_windows.sh rename to bin/cibw_before_all_windows_amd64.sh diff --git a/bin/cibw_before_all_windows_arm64.sh b/bin/cibw_before_all_windows_arm64.sh new file mode 100755 index 00000000..5db3dfb1 --- /dev/null +++ b/bin/cibw_before_all_windows_arm64.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +set -o errexit + +pacman -S --noconfirm \ + mingw-w64-clang-aarch64-toolchain\ + mingw-w64-clang-aarch64-tools-git\ + m4\ + make\ + base-devel\ + autoconf-wrapper\ + automake-wrapper\ + libtool\ + git\ + # + +bin/build_dependencies_unix.sh \ + --use-gmp-github-mirror\ + --patch-C23\ + # From 0606e709bbb8bb4c6ae744bbd517377adb309fd6 Mon Sep 17 00:00:00 2001 From: Oscar Benjamin Date: Sun, 25 Jan 2026 18:17:26 +0000 Subject: [PATCH 02/25] Fix env var names in buildwheel.yml --- .github/workflows/buildwheel.yml | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/.github/workflows/buildwheel.yml b/.github/workflows/buildwheel.yml index 3c87f6dc..212d6164 100644 --- a/.github/workflows/buildwheel.yml +++ b/.github/workflows/buildwheel.yml @@ -41,12 +41,29 @@ jobs: - run: echo "PKG_CONFIG_PATH=${{ github.workspace }}/.local/lib/pkgconfig" >> $env:GITHUB_ENV if: ${{ startsWith( matrix.os , 'windows' ) }} - - name: Build wheels + # We need to set these environment variables here rather than + # pyproject.toml so we can use differnt values for different + # architectures. For non-Windows this is just done with $(uname -m) + # don't know what that would do in msys2 on Windows when cibuildwheel + # parses it. + + - name: Build wheels for windows-2022 + uses: pypa/cibuildwheel@63fd63b352a9a8bdcc24791c9dbee952ee9a8abc # v3.3.0 + if: ${{ matrix.os == 'windows-2022' }} + env: + CIBW_BEFORE_ALL_WINDOWS: msys2 -c bin/cibw_before_all_windows_amd64.sh + + - name: Build wheels for windows-11-arm uses: pypa/cibuildwheel@63fd63b352a9a8bdcc24791c9dbee952ee9a8abc # v3.3.0 + if: ${{ matrix.os == 'windows-11-arm' }} env: - # override setting in pyproject.toml to use msys2 instead of msys64 bash - CIBW_BEFORE_ALL_WINDOWS_AMD64: msys2 -c bin/cibw_before_all_windows_amd64.sh - CIBW_BEFORE_ALL_WINDOWS_ARM64: msys2 -c bin/cibw_before_all_windows_arm64.sh + CIBW_BEFORE_ALL_WINDOWS: msys2 -c bin/cibw_before_all_windows_arm64.sh + + # After all the Windows-specific steps above this is what actually + # #builds the wheels for every other OS: + + - name: Build wheels for any other OS + uses: pypa/cibuildwheel@63fd63b352a9a8bdcc24791c9dbee952ee9a8abc # v3.3.0 - uses: actions/upload-artifact@v5 with: From c157dc1c684651e63a47e55bea3aba94e7ecb34c Mon Sep 17 00:00:00 2001 From: Oscar Benjamin Date: Sun, 25 Jan 2026 18:25:01 +0000 Subject: [PATCH 03/25] Set --host to arm64 for Windows on arm64 --- bin/cibw_before_all_windows_arm64.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/bin/cibw_before_all_windows_arm64.sh b/bin/cibw_before_all_windows_arm64.sh index 5db3dfb1..399c0ba3 100755 --- a/bin/cibw_before_all_windows_arm64.sh +++ b/bin/cibw_before_all_windows_arm64.sh @@ -16,5 +16,6 @@ pacman -S --noconfirm \ bin/build_dependencies_unix.sh \ --use-gmp-github-mirror\ + --host arm64-w64-mingw32\ --patch-C23\ # From 4861f0185d6d8680c543bfbae02ba48b86b5253e Mon Sep 17 00:00:00 2001 From: Oscar Benjamin Date: Sun, 25 Jan 2026 18:40:18 +0000 Subject: [PATCH 04/25] Fix --host --- bin/cibw_before_all_windows_arm64.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/cibw_before_all_windows_arm64.sh b/bin/cibw_before_all_windows_arm64.sh index 399c0ba3..d0f3348d 100755 --- a/bin/cibw_before_all_windows_arm64.sh +++ b/bin/cibw_before_all_windows_arm64.sh @@ -16,6 +16,6 @@ pacman -S --noconfirm \ bin/build_dependencies_unix.sh \ --use-gmp-github-mirror\ - --host arm64-w64-mingw32\ + --host aarch64-pc-windows-gnullvm\ --patch-C23\ # From d2e8d0413bf3d91510fd0c58b5fbe6ece0442819 Mon Sep 17 00:00:00 2001 From: Oscar Benjamin Date: Sun, 25 Jan 2026 18:50:53 +0000 Subject: [PATCH 05/25] Use msystem = clangarm64 for windows arm64 --- .github/workflows/buildwheel.yml | 7 ++++++- bin/cibw_before_all_windows_arm64.sh | 1 - 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/buildwheel.yml b/.github/workflows/buildwheel.yml index 212d6164..f251c663 100644 --- a/.github/workflows/buildwheel.yml +++ b/.github/workflows/buildwheel.yml @@ -29,7 +29,12 @@ jobs: - uses: msys2/setup-msys2@v2.29.0 with: msystem: mingw64 - if: ${{ startsWith( matrix.os , 'windows' ) }} + if: ${{ matrix.os == 'windows-2022' }} + + - uses: msys2/setup-msys2@v2.29.0 + with: + msystem: clangarm64 + if: ${{ matrix.os == 'windows-11-arm' }} # Install pkgconfig on Windows from choco rather than from msys and # avoid using the Strawberry one. diff --git a/bin/cibw_before_all_windows_arm64.sh b/bin/cibw_before_all_windows_arm64.sh index d0f3348d..5db3dfb1 100755 --- a/bin/cibw_before_all_windows_arm64.sh +++ b/bin/cibw_before_all_windows_arm64.sh @@ -16,6 +16,5 @@ pacman -S --noconfirm \ bin/build_dependencies_unix.sh \ --use-gmp-github-mirror\ - --host aarch64-pc-windows-gnullvm\ --patch-C23\ # From 49291df89435c0f1799427fd359ec586731b7ee4 Mon Sep 17 00:00:00 2001 From: Oscar Benjamin Date: Sun, 25 Jan 2026 19:04:32 +0000 Subject: [PATCH 06/25] Don't run cibuildwheel twice on Windows --- .github/workflows/buildwheel.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/buildwheel.yml b/.github/workflows/buildwheel.yml index f251c663..edb3d42b 100644 --- a/.github/workflows/buildwheel.yml +++ b/.github/workflows/buildwheel.yml @@ -65,10 +65,11 @@ jobs: CIBW_BEFORE_ALL_WINDOWS: msys2 -c bin/cibw_before_all_windows_arm64.sh # After all the Windows-specific steps above this is what actually - # #builds the wheels for every other OS: + # builds the wheels for every other OS: - name: Build wheels for any other OS uses: pypa/cibuildwheel@63fd63b352a9a8bdcc24791c9dbee952ee9a8abc # v3.3.0 + if: ${{ !startsWith( matrix.os , 'windows' ) }} - uses: actions/upload-artifact@v5 with: From a7be3bf0fc73fe0ca889c827b2b14a612f6c5a7d Mon Sep 17 00:00:00 2001 From: Oscar Benjamin Date: Sun, 25 Jan 2026 19:43:56 +0000 Subject: [PATCH 07/25] Don't use fat build for Windows on ARM64 --- bin/build_dependencies_unix.sh | 9 ++++++++- bin/cibw_before_all_windows_arm64.sh | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/bin/build_dependencies_unix.sh b/bin/build_dependencies_unix.sh index 6dfdeb12..184da108 100755 --- a/bin/build_dependencies_unix.sh +++ b/bin/build_dependencies_unix.sh @@ -18,6 +18,7 @@ set -o errexit SKIP_GMP=no SKIP_MPFR=no +FAT_GMP_ARG="--enable-fat" USE_GMP=gmp PATCH_GMP_ARM64=no @@ -37,6 +38,7 @@ do echo " --host - set the host (target) for GMP build" echo " --skip-gmp - skip building GMP" echo " --skip-mpfr - skip building MPFR" + echo " --disable-fat - disable building fat binaries" echo echo "Legacy options:" echo " --gmp gmp - build based on GMP (default)" @@ -83,6 +85,11 @@ do SKIP_MPFR=yes shift ;; + --disable-fat) + # Disable building fat binaries + FAT_GMP_ARG="--disable-assembly" + shift + ;; --patch-gmp-arm64) # Needed only for GMP 6.2.1 on OSX arm64 (Apple M1) hardware # As of GMP 6.3.0 this patch is no longer needed @@ -190,7 +197,7 @@ if [ $USE_GMP = "gmp" ]; then ./configfsf.guess ./configure --prefix=$PREFIX\ - --enable-fat\ + $FAT_GMP_ARG\ --enable-shared=yes\ --enable-static=no\ --host=$HOST_ARG diff --git a/bin/cibw_before_all_windows_arm64.sh b/bin/cibw_before_all_windows_arm64.sh index 5db3dfb1..3aae38b5 100755 --- a/bin/cibw_before_all_windows_arm64.sh +++ b/bin/cibw_before_all_windows_arm64.sh @@ -15,6 +15,7 @@ pacman -S --noconfirm \ # bin/build_dependencies_unix.sh \ + --disable-fat\ --use-gmp-github-mirror\ --patch-C23\ # From fcb49d2e2f0f300842811c14e24bbccb4f4b536d Mon Sep 17 00:00:00 2001 From: Oscar Benjamin Date: Sun, 25 Jan 2026 20:56:13 +0000 Subject: [PATCH 08/25] Patch FLINT for mingw on arm64 --- bin/build_dependencies_unix.sh | 16 ++++++++ bin/cibw_before_all_windows_arm64.sh | 1 + bin/patch-ldd.diff | 59 ++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+) create mode 100644 bin/patch-ldd.diff diff --git a/bin/build_dependencies_unix.sh b/bin/build_dependencies_unix.sh index 184da108..d203e2d5 100755 --- a/bin/build_dependencies_unix.sh +++ b/bin/build_dependencies_unix.sh @@ -19,6 +19,7 @@ set -o errexit SKIP_GMP=no SKIP_MPFR=no FAT_GMP_ARG="--enable-fat" +PATCH_LDD=no USE_GMP=gmp PATCH_GMP_ARM64=no @@ -39,6 +40,7 @@ do echo " --skip-gmp - skip building GMP" echo " --skip-mpfr - skip building MPFR" echo " --disable-fat - disable building fat binaries" + echo " --patch-ldd - patch flint to work with ldd (for mingw on arm64)" echo echo "Legacy options:" echo " --gmp gmp - build based on GMP (default)" @@ -101,6 +103,11 @@ do PATCH_GMP_C23=yes shift ;; + --patch-ldd) + # Needed only for GMP 6.3.0 on OSX arm64 (Apple M1) hardware + PATCH_LDD=yes + shift + ;; --use-gmp-github-mirror) USE_GMP_GITHUB_MIRROR=yes shift @@ -316,6 +323,15 @@ echo curl -O -L https://github.com/flintlib/flint/releases/download/v$FLINTVER/flint-$FLINTVER.tar.gz tar xf flint-$FLINTVER.tar.gz cd flint-$FLINTVER + + if [ $PATCH_LDD = "yes" ]; then + echo + echo -------------------------------------------- + echo " patching FLINT" + echo -------------------------------------------- + patch -N -Z -p0 < ../../../bin/patch-ldd.diff + fi + ./bootstrap.sh ./configure --prefix=$PREFIX\ --host=$HOST_ARG\ diff --git a/bin/cibw_before_all_windows_arm64.sh b/bin/cibw_before_all_windows_arm64.sh index 3aae38b5..01c38ced 100755 --- a/bin/cibw_before_all_windows_arm64.sh +++ b/bin/cibw_before_all_windows_arm64.sh @@ -18,4 +18,5 @@ bin/build_dependencies_unix.sh \ --disable-fat\ --use-gmp-github-mirror\ --patch-C23\ + --patch-ldd\ # diff --git a/bin/patch-ldd.diff b/bin/patch-ldd.diff new file mode 100644 index 00000000..df2fb955 --- /dev/null +++ b/bin/patch-ldd.diff @@ -0,0 +1,59 @@ +diff --git a/Makefile.in b/Makefile.in +index 0f25aa2b5..cc0e44708 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -416,6 +416,10 @@ endif + ifneq ($(SHARED), 0) + shared: $(FLINT_DIR)/$(FLINT_LIB_FULL) + ++ifneq ($(strip $(filter gnu% linux-gnu%,@FLINT_BUILD_OS@)),) ++# No command line length limitations under build_os=gnu*|linux-gnu* ++MERGED_OBJS := $(foreach dir,$(DIRS),$($(dir)_OBJS)) ++else + # The following is to avoid reaching the maximum length of command line + # arguments, mainly present on MinGW. + define xxx_merged_lobj_rule +@@ -424,6 +428,7 @@ $(BUILD_DIR)/$(1)_merged.lo: $($(1)_LOBJS) | $(BUILD_DIR) + endef + $(foreach dir, $(DIRS), $(eval $(call xxx_merged_lobj_rule,$(dir)))) + MERGED_LOBJS:=$(foreach dir, $(DIRS),$(BUILD_DIR)/$(dir)_merged.lo) ++endif + + $(FLINT_DIR)/$(FLINT_LIB_FULL): $(MERGED_LOBJS) + @echo "Building $(FLINT_LIB_FULL)" +@@ -437,6 +442,10 @@ endif + ifneq ($(STATIC), 0) + static: $(FLINT_DIR)/$(FLINT_LIB_STATIC) + ++ifneq ($(strip $(filter gnu% linux-gnu%,@FLINT_BUILD_OS@)),) ++# No command line length limitations under build_os=gnu*|linux-gnu* ++MERGED_OBJS := $(foreach dir,$(DIRS),$($(dir)_OBJS)) ++else + # The following is to avoid reaching the maximum length of command line + # arguments, mainly present on MinGW. + define xxx_merged_obj_rule +@@ -445,6 +454,7 @@ $(BUILD_DIR)/$(1)_merged.o: $($(1)_OBJS) | $(BUILD_DIR) + endef + $(foreach dir, $(DIRS), $(eval $(call xxx_merged_obj_rule,$(dir)))) + MERGED_OBJS:=$(foreach dir, $(DIRS),$(BUILD_DIR)/$(dir)_merged.o) ++endif + + $(FLINT_DIR)/$(FLINT_LIB_STATIC): $(MERGED_OBJS) + @echo "Building $(FLINT_LIB_STATIC)" +diff --git a/configure.ac b/configure.ac +index 511d0be9a..9f161e490 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -164,8 +164,12 @@ fi + + dnl Get system triplet + dnl NOTE: This is already invoked from LT_INIT ++dnl AC_CANONICAL_BUILD + dnl AC_CANONICAL_HOST + ++FLINT_BUILD_OS="${build_os}" ++AC_SUBST(FLINT_BUILD_OS) ++ + ################################################################################ + # configure headers + ################################################################################ From eca229b1b4b3bdf8a0dce9d24fba65881aa41974 Mon Sep 17 00:00:00 2001 From: Oscar Benjamin Date: Sun, 25 Jan 2026 21:28:37 +0000 Subject: [PATCH 09/25] Fix patch command --- bin/build_dependencies_unix.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/build_dependencies_unix.sh b/bin/build_dependencies_unix.sh index d203e2d5..aaec4531 100755 --- a/bin/build_dependencies_unix.sh +++ b/bin/build_dependencies_unix.sh @@ -329,7 +329,7 @@ cd flint-$FLINTVER echo -------------------------------------------- echo " patching FLINT" echo -------------------------------------------- - patch -N -Z -p0 < ../../../bin/patch-ldd.diff + patch -N -Z -p1 < ../../../bin/patch-ldd.diff fi ./bootstrap.sh From ad01e8374e37dc0e0dd49aff84bf396aa1b15618 Mon Sep 17 00:00:00 2001 From: Oscar Benjamin Date: Sun, 25 Jan 2026 22:38:55 +0000 Subject: [PATCH 10/25] Fix the ldd patch so that it works on Windows --- bin/patch-ldd.diff | 63 +++++++++++++++------------------------------- 1 file changed, 20 insertions(+), 43 deletions(-) diff --git a/bin/patch-ldd.diff b/bin/patch-ldd.diff index df2fb955..718a7ac7 100644 --- a/bin/patch-ldd.diff +++ b/bin/patch-ldd.diff @@ -1,59 +1,36 @@ diff --git a/Makefile.in b/Makefile.in -index 0f25aa2b5..cc0e44708 100644 +index 0f25aa2b5..0c2f9dad9 100644 --- a/Makefile.in +++ b/Makefile.in -@@ -416,6 +416,10 @@ endif +@@ -416,14 +416,7 @@ endif ifneq ($(SHARED), 0) shared: $(FLINT_DIR)/$(FLINT_LIB_FULL) -+ifneq ($(strip $(filter gnu% linux-gnu%,@FLINT_BUILD_OS@)),) -+# No command line length limitations under build_os=gnu*|linux-gnu* -+MERGED_OBJS := $(foreach dir,$(DIRS),$($(dir)_OBJS)) -+else - # The following is to avoid reaching the maximum length of command line - # arguments, mainly present on MinGW. - define xxx_merged_lobj_rule -@@ -424,6 +428,7 @@ $(BUILD_DIR)/$(1)_merged.lo: $($(1)_LOBJS) | $(BUILD_DIR) - endef - $(foreach dir, $(DIRS), $(eval $(call xxx_merged_lobj_rule,$(dir)))) - MERGED_LOBJS:=$(foreach dir, $(DIRS),$(BUILD_DIR)/$(dir)_merged.lo) -+endif +-# The following is to avoid reaching the maximum length of command line +-# arguments, mainly present on MinGW. +-define xxx_merged_lobj_rule +-$(BUILD_DIR)/$(1)_merged.lo: $($(1)_LOBJS) | $(BUILD_DIR) +- @$(LD) -r $($(1)_LOBJS) -o $(BUILD_DIR)/$(1)_merged.lo +-endef +-$(foreach dir, $(DIRS), $(eval $(call xxx_merged_lobj_rule,$(dir)))) +-MERGED_LOBJS:=$(foreach dir, $(DIRS),$(BUILD_DIR)/$(dir)_merged.lo) ++MERGED_LOBJS := $(foreach dir,$(DIRS),$($(dir)_OBJS)) $(FLINT_DIR)/$(FLINT_LIB_FULL): $(MERGED_LOBJS) @echo "Building $(FLINT_LIB_FULL)" -@@ -437,6 +442,10 @@ endif +@@ -437,14 +430,7 @@ endif ifneq ($(STATIC), 0) static: $(FLINT_DIR)/$(FLINT_LIB_STATIC) -+ifneq ($(strip $(filter gnu% linux-gnu%,@FLINT_BUILD_OS@)),) -+# No command line length limitations under build_os=gnu*|linux-gnu* +-# The following is to avoid reaching the maximum length of command line +-# arguments, mainly present on MinGW. +-define xxx_merged_obj_rule +-$(BUILD_DIR)/$(1)_merged.o: $($(1)_OBJS) | $(BUILD_DIR) +- @$(LD) -r $($(1)_OBJS) -o $(BUILD_DIR)/$(1)_merged.o +-endef +-$(foreach dir, $(DIRS), $(eval $(call xxx_merged_obj_rule,$(dir)))) +-MERGED_OBJS:=$(foreach dir, $(DIRS),$(BUILD_DIR)/$(dir)_merged.o) +MERGED_OBJS := $(foreach dir,$(DIRS),$($(dir)_OBJS)) -+else - # The following is to avoid reaching the maximum length of command line - # arguments, mainly present on MinGW. - define xxx_merged_obj_rule -@@ -445,6 +454,7 @@ $(BUILD_DIR)/$(1)_merged.o: $($(1)_OBJS) | $(BUILD_DIR) - endef - $(foreach dir, $(DIRS), $(eval $(call xxx_merged_obj_rule,$(dir)))) - MERGED_OBJS:=$(foreach dir, $(DIRS),$(BUILD_DIR)/$(dir)_merged.o) -+endif $(FLINT_DIR)/$(FLINT_LIB_STATIC): $(MERGED_OBJS) @echo "Building $(FLINT_LIB_STATIC)" -diff --git a/configure.ac b/configure.ac -index 511d0be9a..9f161e490 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -164,8 +164,12 @@ fi - - dnl Get system triplet - dnl NOTE: This is already invoked from LT_INIT -+dnl AC_CANONICAL_BUILD - dnl AC_CANONICAL_HOST - -+FLINT_BUILD_OS="${build_os}" -+AC_SUBST(FLINT_BUILD_OS) -+ - ################################################################################ - # configure headers - ################################################################################ From 91f985a679a8dfd770a2b79c663fd267c924c853 Mon Sep 17 00:00:00 2001 From: Oscar Benjamin Date: Sun, 25 Jan 2026 23:46:50 +0000 Subject: [PATCH 11/25] Fix patch --- bin/patch-ldd.diff | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bin/patch-ldd.diff b/bin/patch-ldd.diff index 718a7ac7..81b06b92 100644 --- a/bin/patch-ldd.diff +++ b/bin/patch-ldd.diff @@ -1,5 +1,5 @@ diff --git a/Makefile.in b/Makefile.in -index 0f25aa2b5..0c2f9dad9 100644 +index 0f25aa2b5..937fffa10 100644 --- a/Makefile.in +++ b/Makefile.in @@ -416,14 +416,7 @@ endif @@ -14,7 +14,7 @@ index 0f25aa2b5..0c2f9dad9 100644 -endef -$(foreach dir, $(DIRS), $(eval $(call xxx_merged_lobj_rule,$(dir)))) -MERGED_LOBJS:=$(foreach dir, $(DIRS),$(BUILD_DIR)/$(dir)_merged.lo) -+MERGED_LOBJS := $(foreach dir,$(DIRS),$($(dir)_OBJS)) ++MERGED_LOBJS:=$(foreach dir,$(DIRS),$($(dir)_LOBJS)) $(FLINT_DIR)/$(FLINT_LIB_FULL): $(MERGED_LOBJS) @echo "Building $(FLINT_LIB_FULL)" @@ -30,7 +30,7 @@ index 0f25aa2b5..0c2f9dad9 100644 -endef -$(foreach dir, $(DIRS), $(eval $(call xxx_merged_obj_rule,$(dir)))) -MERGED_OBJS:=$(foreach dir, $(DIRS),$(BUILD_DIR)/$(dir)_merged.o) -+MERGED_OBJS := $(foreach dir,$(DIRS),$($(dir)_OBJS)) ++MERGED_OBJS:=$(foreach dir,$(DIRS),$($(dir)_OBJS)) $(FLINT_DIR)/$(FLINT_LIB_STATIC): $(MERGED_OBJS) @echo "Building $(FLINT_LIB_STATIC)" From 5ba5d339a1994ba5cb59ed10fd0ce80a1ae00b03 Mon Sep 17 00:00:00 2001 From: Oscar Benjamin Date: Sat, 21 Mar 2026 19:06:15 +0000 Subject: [PATCH 12/25] Patch FLINT's Makefile for Windows on ARM --- bin/build_dependencies_unix.sh | 8 +++--- bin/patch-flint-windows-arm64-link.diff | 27 +++++++++++++++++++ bin/patch-ldd.diff | 36 ------------------------- 3 files changed, 31 insertions(+), 40 deletions(-) create mode 100644 bin/patch-flint-windows-arm64-link.diff delete mode 100644 bin/patch-ldd.diff diff --git a/bin/build_dependencies_unix.sh b/bin/build_dependencies_unix.sh index aaec4531..33e63184 100755 --- a/bin/build_dependencies_unix.sh +++ b/bin/build_dependencies_unix.sh @@ -40,7 +40,7 @@ do echo " --skip-gmp - skip building GMP" echo " --skip-mpfr - skip building MPFR" echo " --disable-fat - disable building fat binaries" - echo " --patch-ldd - patch flint to work with ldd (for mingw on arm64)" + echo " --patch-ldd - patch flint shared linking for mingw on arm64" echo echo "Legacy options:" echo " --gmp gmp - build based on GMP (default)" @@ -104,7 +104,7 @@ do shift ;; --patch-ldd) - # Needed only for GMP 6.3.0 on OSX arm64 (Apple M1) hardware + # Needed only for the FLINT shared build on mingw arm64. PATCH_LDD=yes shift ;; @@ -329,7 +329,7 @@ cd flint-$FLINTVER echo -------------------------------------------- echo " patching FLINT" echo -------------------------------------------- - patch -N -Z -p1 < ../../../bin/patch-ldd.diff + patch -N -Z -p1 < ../../../bin/patch-flint-windows-arm64-link.diff fi ./bootstrap.sh @@ -339,7 +339,7 @@ cd flint-$FLINTVER --with-mpfr=$PREFIX\ --disable-static\ --disable-debug - make -j6 + make -j4 make install cd .. diff --git a/bin/patch-flint-windows-arm64-link.diff b/bin/patch-flint-windows-arm64-link.diff new file mode 100644 index 00000000..fd77a37a --- /dev/null +++ b/bin/patch-flint-windows-arm64-link.diff @@ -0,0 +1,27 @@ +diff --git a/Makefile.in b/Makefile.in +index 0f25aa2b5..f6f46b7d6 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -416,14 +416,10 @@ endif + ifneq ($(SHARED), 0) + shared: $(FLINT_DIR)/$(FLINT_LIB_FULL) + +-# The following is to avoid reaching the maximum length of command line +-# arguments, mainly present on MinGW. +-define xxx_merged_lobj_rule +-$(BUILD_DIR)/$(1)_merged.lo: $($(1)_LOBJS) | $(BUILD_DIR) +- @$(LD) -r $($(1)_LOBJS) -o $(BUILD_DIR)/$(1)_merged.lo +-endef +-$(foreach dir, $(DIRS), $(eval $(call xxx_merged_lobj_rule,$(dir)))) +-MERGED_LOBJS:=$(foreach dir, $(DIRS),$(BUILD_DIR)/$(dir)_merged.lo) ++SHARED_LINK_RSP := $(BUILD_DIR)/libflint-shared.rsp + +-$(FLINT_DIR)/$(FLINT_LIB_FULL): $(MERGED_LOBJS) ++$(FLINT_DIR)/$(FLINT_LIB_FULL): $(LOBJS) | $(BUILD_DIR) + @echo "Building $(FLINT_LIB_FULL)" +- @$(CC) $(CFLAGS) -shared $(EXTRA_SHARED_FLAGS) $(MERGED_LOBJS) -o $(FLINT_LIB_FULL) $(LDFLAGS) $(LIBS) ++ @: $(file >$(SHARED_LINK_RSP))$(foreach obj,$(LOBJS),$(file >>$(SHARED_LINK_RSP),$(obj))) ++ @$(CC) $(CFLAGS) -shared $(EXTRA_SHARED_FLAGS) @$(SHARED_LINK_RSP) -o $(FLINT_LIB_FULL) $(LDFLAGS) $(LIBS) + @$(RM_F) $(FLINT_LIB) + @$(RM_F) $(FLINT_LIB_MAJOR) + @$(LN_S) $(FLINT_LIB_FULL) $(FLINT_LIB) diff --git a/bin/patch-ldd.diff b/bin/patch-ldd.diff deleted file mode 100644 index 81b06b92..00000000 --- a/bin/patch-ldd.diff +++ /dev/null @@ -1,36 +0,0 @@ -diff --git a/Makefile.in b/Makefile.in -index 0f25aa2b5..937fffa10 100644 ---- a/Makefile.in -+++ b/Makefile.in -@@ -416,14 +416,7 @@ endif - ifneq ($(SHARED), 0) - shared: $(FLINT_DIR)/$(FLINT_LIB_FULL) - --# The following is to avoid reaching the maximum length of command line --# arguments, mainly present on MinGW. --define xxx_merged_lobj_rule --$(BUILD_DIR)/$(1)_merged.lo: $($(1)_LOBJS) | $(BUILD_DIR) -- @$(LD) -r $($(1)_LOBJS) -o $(BUILD_DIR)/$(1)_merged.lo --endef --$(foreach dir, $(DIRS), $(eval $(call xxx_merged_lobj_rule,$(dir)))) --MERGED_LOBJS:=$(foreach dir, $(DIRS),$(BUILD_DIR)/$(dir)_merged.lo) -+MERGED_LOBJS:=$(foreach dir,$(DIRS),$($(dir)_LOBJS)) - - $(FLINT_DIR)/$(FLINT_LIB_FULL): $(MERGED_LOBJS) - @echo "Building $(FLINT_LIB_FULL)" -@@ -437,14 +430,7 @@ endif - ifneq ($(STATIC), 0) - static: $(FLINT_DIR)/$(FLINT_LIB_STATIC) - --# The following is to avoid reaching the maximum length of command line --# arguments, mainly present on MinGW. --define xxx_merged_obj_rule --$(BUILD_DIR)/$(1)_merged.o: $($(1)_OBJS) | $(BUILD_DIR) -- @$(LD) -r $($(1)_OBJS) -o $(BUILD_DIR)/$(1)_merged.o --endef --$(foreach dir, $(DIRS), $(eval $(call xxx_merged_obj_rule,$(dir)))) --MERGED_OBJS:=$(foreach dir, $(DIRS),$(BUILD_DIR)/$(dir)_merged.o) -+MERGED_OBJS:=$(foreach dir,$(DIRS),$($(dir)_OBJS)) - - $(FLINT_DIR)/$(FLINT_LIB_STATIC): $(MERGED_OBJS) - @echo "Building $(FLINT_LIB_STATIC)" From 86b668974706217a71c78411b69b87eb25bf381f Mon Sep 17 00:00:00 2001 From: Oscar Benjamin Date: Sat, 21 Mar 2026 19:57:58 +0000 Subject: [PATCH 13/25] Fix the malformed patch --- bin/patch-flint-windows-arm64-link.diff | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/patch-flint-windows-arm64-link.diff b/bin/patch-flint-windows-arm64-link.diff index fd77a37a..1b67c584 100644 --- a/bin/patch-flint-windows-arm64-link.diff +++ b/bin/patch-flint-windows-arm64-link.diff @@ -2,7 +2,7 @@ diff --git a/Makefile.in b/Makefile.in index 0f25aa2b5..f6f46b7d6 100644 --- a/Makefile.in +++ b/Makefile.in -@@ -416,14 +416,10 @@ endif +@@ -416,18 +416,12 @@ endif ifneq ($(SHARED), 0) shared: $(FLINT_DIR)/$(FLINT_LIB_FULL) From f46aeddc3b8677179e82408da918031763cfeeb1 Mon Sep 17 00:00:00 2001 From: Oscar Benjamin Date: Sat, 21 Mar 2026 20:55:06 +0000 Subject: [PATCH 14/25] Don't try to link Pythonxxx.dll to extension modules --- meson.build | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/meson.build b/meson.build index 16860da3..592b605e 100644 --- a/meson.build +++ b/meson.build @@ -18,7 +18,6 @@ cython_lower = '>=3.0.11' cython_upper = '<3.3' py = import('python').find_installation(pure: false) -dep_py = py.dependency() cc = meson.get_compiler('c') cy = meson.get_compiler('cython') @@ -76,7 +75,7 @@ else have_acb_theta = true endif -pyflint_deps = [dep_py, gmp_dep, mpfr_dep, flint_dep] +pyflint_deps = [gmp_dep, mpfr_dep, flint_dep] add_project_arguments( '-X', 'embedsignature=True', From 42780841a45ebc0490b2b68a2356d5e088d163c5 Mon Sep 17 00:00:00 2001 From: Oscar Benjamin Date: Sat, 21 Mar 2026 22:37:45 +0000 Subject: [PATCH 15/25] Try generating the .dll.a file for clangarm64 --- bin/cibw_before_build_windows_arm64.sh | 91 ++++++++++++++++++++++++++ meson.build | 8 +++ pyproject.toml | 4 ++ 3 files changed, 103 insertions(+) create mode 100755 bin/cibw_before_build_windows_arm64.sh diff --git a/bin/cibw_before_build_windows_arm64.sh b/bin/cibw_before_build_windows_arm64.sh new file mode 100755 index 00000000..128698f5 --- /dev/null +++ b/bin/cibw_before_build_windows_arm64.sh @@ -0,0 +1,91 @@ +#!/bin/bash + +set -o errexit + +repo_root=$(python -c 'from pathlib import Path; print(Path.cwd().resolve().as_posix())') +lib_dir="$repo_root/.local/lib" +pkgconfig_dir="$lib_dir/pkgconfig" +mkdir -p "$pkgconfig_dir" + +dll_name=$(python -c 'import sysconfig; print(sysconfig.get_config_var("LDLIBRARY") or "")') +pkg_version=$(python -c 'import sysconfig; print(sysconfig.get_config_var("LDVERSION") or sysconfig.get_python_version())') +include_dir=$(python -c 'import sysconfig; print(sysconfig.get_config_var("INCLUDEPY") or "")') +base_prefix=$(python -c 'import sys; print(getattr(sys, "base_prefix", sys.prefix))') +python_bin=$(python -c 'import os, sys; print(os.path.dirname(sys.executable))') + +include_dir=${include_dir//\\//} +base_prefix=${base_prefix//\\//} +python_bin=${python_bin//\\//} + +if [ -z "$dll_name" ] || [ -z "$include_dir" ]; then + echo "Could not determine Python DLL or include dir" >&2 + exit 1 +fi + +dll_path="" +for candidate in \ + "$python_bin/$dll_name" \ + "$base_prefix/$dll_name" \ + "$base_prefix/DLLs/$dll_name" \ + "$base_prefix/libs/$dll_name" +do + if [ -f "$candidate" ]; then + dll_path="$candidate" + break + fi +done + +if [ -z "$dll_path" ]; then + echo "Could not find $dll_name" >&2 + exit 1 +fi + +if ! command -v gendef >/dev/null 2>&1; then + echo "Could not find gendef on PATH" >&2 + exit 1 +fi + +if command -v cc >/dev/null 2>&1; then + dlltool=$(cc -print-prog-name=dlltool) +fi +if [ -n "${dlltool:-}" ] && [ -x "$dlltool" ]; then + : +elif [ -n "${dlltool:-}" ] && command -v "$dlltool" >/dev/null 2>&1; then + dlltool=$(command -v "$dlltool") +elif command -v dlltool >/dev/null 2>&1; then + dlltool=$(command -v dlltool) +elif command -v llvm-dlltool >/dev/null 2>&1; then + dlltool=$(command -v llvm-dlltool) +else + echo "Could not find dlltool or llvm-dlltool on PATH" >&2 + exit 1 +fi + +dll_stem=${dll_name%.dll} +def_path="$lib_dir/$dll_stem.def" +import_lib="$lib_dir/lib$dll_stem.dll.a" +pc_path="$pkgconfig_dir/python-$pkg_version.pc" + +rm -f "$def_path" "$import_lib" +( + cd "$lib_dir" + gendef "$dll_path" +) +"$dlltool" -d "$def_path" -D "$dll_name" -l "$import_lib" + +printf 'prefix=%s\n' "$repo_root" > "$pc_path" +printf 'exec_prefix=${prefix}\n' >> "$pc_path" +printf 'libdir=%s\n' "$lib_dir" >> "$pc_path" +printf 'includedir=%s\n\n' "$include_dir" >> "$pc_path" +printf 'Name: Python\n' >> "$pc_path" +printf 'Description: CPython import library for MinGW wheel builds\n' >> "$pc_path" +printf 'Version: %s\n' "$pkg_version" >> "$pc_path" +printf 'Libs: -L${libdir} -l%s\n' "$dll_stem" >> "$pc_path" +printf 'Cflags: -I${includedir}\n' >> "$pc_path" + +if command -v pkg-config >/dev/null 2>&1; then + pkg-config --exists "python-$pkg_version" +fi + +echo "Generated $import_lib" +echo "Generated $pc_path" diff --git a/meson.build b/meson.build index 592b605e..6c61af96 100644 --- a/meson.build +++ b/meson.build @@ -77,6 +77,14 @@ endif pyflint_deps = [gmp_dep, mpfr_dep, flint_dep] +# Meson's Windows sysconfig dependency path can hand the clangarm64 +# toolchain the python DLL itself. Use pkg-config on Windows ARM64 so we can +# provide a MinGW import library instead. +if host_machine.system() == 'windows' and host_machine.cpu_family() in ['aarch64', 'arm64'] and cc.get_id() in ['gcc', 'clang'] + dep_py = py.dependency(method: 'pkg-config') + pyflint_deps = [dep_py] + pyflint_deps +endif + add_project_arguments( '-X', 'embedsignature=True', '-X', 'emit_code_comments=True', diff --git a/pyproject.toml b/pyproject.toml index efa88bef..6ec2b9f3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -176,3 +176,7 @@ repair-wheel-command = [ """, "delvewheel repair -w {dest_dir} {wheel} --add-path .local/bin", ] + +[[tool.cibuildwheel.overrides]] +select = ["*-win_arm64"] +before-build = "C:\\msys64\\usr\\bin\\bash bin/cibw_before_build_windows_arm64.sh && pip install wheel delvewheel" From f089e09bd82333aa87ec92eb53c61e0c2cb9d592 Mon Sep 17 00:00:00 2001 From: Oscar Benjamin Date: Sat, 21 Mar 2026 23:25:19 +0000 Subject: [PATCH 16/25] Add .exe to commands --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 6ec2b9f3..ef1d9246 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -154,7 +154,7 @@ repair-wheel-command = [ ] [tool.cibuildwheel.windows] -before-all = "C:\\msys64\\usr\\bin\\bash bin/cibw_before_all_windows.sh" +before-all = "C:\\msys64\\usr\\bin\\bash.exe bin/cibw_before_all_windows.sh" before-build = "pip install wheel delvewheel" repair-wheel-command = [ """python bin/cibw_repair_wheel_licenses.py {wheel} \ @@ -179,4 +179,4 @@ repair-wheel-command = [ [[tool.cibuildwheel.overrides]] select = ["*-win_arm64"] -before-build = "C:\\msys64\\usr\\bin\\bash bin/cibw_before_build_windows_arm64.sh && pip install wheel delvewheel" +before-build = "C:\\msys64\\usr\\bin\\bash.exe bin/cibw_before_build_windows_arm64.sh && pip install wheel delvewheel" From 484e620a334b7d455dd453afa36d0f3d0a34a0c7 Mon Sep 17 00:00:00 2001 From: Oscar Benjamin Date: Sun, 22 Mar 2026 00:19:21 +0000 Subject: [PATCH 17/25] Move the Windows before_build command to GA yaml file --- .github/workflows/buildwheel.yml | 1 + pyproject.toml | 4 ---- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/buildwheel.yml b/.github/workflows/buildwheel.yml index 84332547..8dd81a7d 100644 --- a/.github/workflows/buildwheel.yml +++ b/.github/workflows/buildwheel.yml @@ -63,6 +63,7 @@ jobs: if: ${{ matrix.os == 'windows-11-arm' }} env: CIBW_BEFORE_ALL_WINDOWS: msys2 -c bin/cibw_before_all_windows_arm64.sh + CIBW_BEFORE_BUILD_WINDOWS: msys2 -c bin/cibw_before_build_windows_arm64.sh && pip install wheel delvewheel # After all the Windows-specific steps above this is what actually # builds the wheels for every other OS: diff --git a/pyproject.toml b/pyproject.toml index ef1d9246..197084f8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -176,7 +176,3 @@ repair-wheel-command = [ """, "delvewheel repair -w {dest_dir} {wheel} --add-path .local/bin", ] - -[[tool.cibuildwheel.overrides]] -select = ["*-win_arm64"] -before-build = "C:\\msys64\\usr\\bin\\bash.exe bin/cibw_before_build_windows_arm64.sh && pip install wheel delvewheel" From 4da6ab6f43e993da18b3379bd9137ee49b5feb2f Mon Sep 17 00:00:00 2001 From: Oscar Benjamin Date: Sun, 22 Mar 2026 01:06:39 +0000 Subject: [PATCH 18/25] Simplify befre_build script for Windows on ARM --- .github/workflows/buildwheel.yml | 2 +- bin/cibw_before_build_windows_arm64.sh | 89 +++++++++++--------------- 2 files changed, 38 insertions(+), 53 deletions(-) diff --git a/.github/workflows/buildwheel.yml b/.github/workflows/buildwheel.yml index 8dd81a7d..6373cb28 100644 --- a/.github/workflows/buildwheel.yml +++ b/.github/workflows/buildwheel.yml @@ -63,7 +63,7 @@ jobs: if: ${{ matrix.os == 'windows-11-arm' }} env: CIBW_BEFORE_ALL_WINDOWS: msys2 -c bin/cibw_before_all_windows_arm64.sh - CIBW_BEFORE_BUILD_WINDOWS: msys2 -c bin/cibw_before_build_windows_arm64.sh && pip install wheel delvewheel + CIBW_BEFORE_BUILD_WINDOWS: python bin/cibw_before_build_windows_arm64.py && msys2 -c bin/cibw_before_build_windows_arm64.sh && pip install wheel delvewheel # After all the Windows-specific steps above this is what actually # builds the wheels for every other OS: diff --git a/bin/cibw_before_build_windows_arm64.sh b/bin/cibw_before_build_windows_arm64.sh index 128698f5..e07e529c 100755 --- a/bin/cibw_before_build_windows_arm64.sh +++ b/bin/cibw_before_build_windows_arm64.sh @@ -2,49 +2,31 @@ set -o errexit -repo_root=$(python -c 'from pathlib import Path; print(Path.cwd().resolve().as_posix())') -lib_dir="$repo_root/.local/lib" -pkgconfig_dir="$lib_dir/pkgconfig" -mkdir -p "$pkgconfig_dir" - -dll_name=$(python -c 'import sysconfig; print(sysconfig.get_config_var("LDLIBRARY") or "")') -pkg_version=$(python -c 'import sysconfig; print(sysconfig.get_config_var("LDVERSION") or sysconfig.get_python_version())') -include_dir=$(python -c 'import sysconfig; print(sysconfig.get_config_var("INCLUDEPY") or "")') -base_prefix=$(python -c 'import sys; print(getattr(sys, "base_prefix", sys.prefix))') -python_bin=$(python -c 'import os, sys; print(os.path.dirname(sys.executable))') - -include_dir=${include_dir//\\//} -base_prefix=${base_prefix//\\//} -python_bin=${python_bin//\\//} - -if [ -z "$dll_name" ] || [ -z "$include_dir" ]; then - echo "Could not determine Python DLL or include dir" >&2 +env_file=.local/cibw_before_build_windows_arm64.env +if [ ! -f "$env_file" ]; then + echo "Could not find $env_file" >&2 exit 1 fi -dll_path="" -for candidate in \ - "$python_bin/$dll_name" \ - "$base_prefix/$dll_name" \ - "$base_prefix/DLLs/$dll_name" \ - "$base_prefix/libs/$dll_name" -do - if [ -f "$candidate" ]; then - dll_path="$candidate" - break - fi -done +# shellcheck disable=SC1090 +. "$env_file" -if [ -z "$dll_path" ]; then - echo "Could not find $dll_name" >&2 - exit 1 +lib_dir_msys="$LIB_DIR" +pkgconfig_dir_msys="$PKGCONFIG_DIR" +dll_path_msys="$DLL_PATH" +if command -v cygpath >/dev/null 2>&1; then + lib_dir_msys=$(cygpath -u "$LIB_DIR") + pkgconfig_dir_msys=$(cygpath -u "$PKGCONFIG_DIR") + dll_path_msys=$(cygpath -u "$DLL_PATH") fi +mkdir -p "$pkgconfig_dir_msys" if ! command -v gendef >/dev/null 2>&1; then echo "Could not find gendef on PATH" >&2 exit 1 fi +dlltool= if command -v cc >/dev/null 2>&1; then dlltool=$(cc -print-prog-name=dlltool) fi @@ -61,31 +43,34 @@ else exit 1 fi -dll_stem=${dll_name%.dll} -def_path="$lib_dir/$dll_stem.def" -import_lib="$lib_dir/lib$dll_stem.dll.a" -pc_path="$pkgconfig_dir/python-$pkg_version.pc" +dll_stem=${DLL_NAME%.dll} +def_path_msys="$lib_dir_msys/$dll_stem.def" +import_lib_msys="$lib_dir_msys/lib$dll_stem.dll.a" +pc_path_msys="$pkgconfig_dir_msys/python-$PKG_VERSION.pc" -rm -f "$def_path" "$import_lib" +rm -f "$def_path_msys" "$import_lib_msys" ( - cd "$lib_dir" - gendef "$dll_path" + cd "$lib_dir_msys" + gendef "$dll_path_msys" ) -"$dlltool" -d "$def_path" -D "$dll_name" -l "$import_lib" +"$dlltool" -d "$def_path_msys" -D "$DLL_NAME" -l "$import_lib_msys" + +cat > "$pc_path_msys" < "$pc_path" -printf 'exec_prefix=${prefix}\n' >> "$pc_path" -printf 'libdir=%s\n' "$lib_dir" >> "$pc_path" -printf 'includedir=%s\n\n' "$include_dir" >> "$pc_path" -printf 'Name: Python\n' >> "$pc_path" -printf 'Description: CPython import library for MinGW wheel builds\n' >> "$pc_path" -printf 'Version: %s\n' "$pkg_version" >> "$pc_path" -printf 'Libs: -L${libdir} -l%s\n' "$dll_stem" >> "$pc_path" -printf 'Cflags: -I${includedir}\n' >> "$pc_path" +Name: Python +Description: CPython import library for MinGW wheel builds +Version: $PKG_VERSION +Libs: -L\${libdir} -l$dll_stem +Cflags: -I\${includedir} +EOF if command -v pkg-config >/dev/null 2>&1; then - pkg-config --exists "python-$pkg_version" + pkg-config --exists "python-$PKG_VERSION" fi -echo "Generated $import_lib" -echo "Generated $pc_path" +echo "Generated $import_lib_msys" +echo "Generated $pc_path_msys" From 41bab7a6656f8cc7357fdcdfb915479ed4cb04e2 Mon Sep 17 00:00:00 2001 From: Oscar Benjamin Date: Sun, 22 Mar 2026 01:42:41 +0000 Subject: [PATCH 19/25] Add the before_build script --- bin/cibw_before_build_windows_arm64.py | 77 ++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100755 bin/cibw_before_build_windows_arm64.py diff --git a/bin/cibw_before_build_windows_arm64.py b/bin/cibw_before_build_windows_arm64.py new file mode 100755 index 00000000..440200e9 --- /dev/null +++ b/bin/cibw_before_build_windows_arm64.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python3 + +from __future__ import annotations + +import shlex +import sys +import sysconfig +from pathlib import Path + + +def _normalize_path(path: Path | str) -> str: + return str(path).replace('\\', '/') + + +def _normalize_dll_name(name: str) -> str: + if name.endswith('.dll'): + return name + if name.startswith('lib') and name.endswith('.dll.a'): + return name[3:-2] + raise SystemExit(f'Unexpected Python library name: {name}') + + +def _find_dll(dll_name: str) -> Path: + candidates: list[Path] = [] + libdir = sysconfig.get_config_var('LIBDIR') + if libdir: + candidates.append(Path(libdir) / dll_name) + exe_dir = Path(sys.executable).resolve().parent + candidates.append(exe_dir / dll_name) + base_prefix = Path(getattr(sys, 'base_prefix', sys.prefix)) + candidates.append(base_prefix / dll_name) + candidates.append(base_prefix / 'DLLs' / dll_name) + candidates.append(base_prefix / 'libs' / dll_name) + + for candidate in candidates: + if candidate.exists(): + return candidate.resolve() + + paths = '\n'.join(_normalize_path(path) for path in candidates) + raise SystemExit(f'Could not find {dll_name} in:\n{paths}') + + +def main() -> None: + repo_root = Path.cwd().resolve() + lib_dir = repo_root / '.local' / 'lib' + pkgconfig_dir = lib_dir / 'pkgconfig' + lib_dir.mkdir(parents=True, exist_ok=True) + pkgconfig_dir.mkdir(parents=True, exist_ok=True) + + raw_name = sysconfig.get_config_var('DLLLIBRARY') or sysconfig.get_config_var('LDLIBRARY') + if not raw_name: + raise SystemExit('Could not determine Python DLL name') + dll_name = _normalize_dll_name(raw_name) + include_dir = sysconfig.get_config_var('INCLUDEPY') + if not include_dir: + raise SystemExit('Could not determine Python include dir') + pkg_version = sysconfig.get_config_var('LDVERSION') or sysconfig.get_python_version() + dll_path = _find_dll(dll_name) + + values = { + 'REPO_ROOT': _normalize_path(repo_root), + 'LIB_DIR': _normalize_path(lib_dir), + 'PKGCONFIG_DIR': _normalize_path(pkgconfig_dir), + 'DLL_NAME': dll_name, + 'DLL_PATH': _normalize_path(dll_path), + 'PKG_VERSION': pkg_version, + 'INCLUDE_DIR': _normalize_path(include_dir), + } + + env_path = repo_root / '.local' / 'cibw_before_build_windows_arm64.env' + env_text = ''.join(f'{key}={shlex.quote(value)}\n' for key, value in values.items()) + env_path.write_text(env_text, encoding='utf-8') + print(f'Generated {env_path}') + + +if __name__ == '__main__': + main() From 9f961de60328555b77b79a20a61371063eaffd87 Mon Sep 17 00:00:00 2001 From: Oscar Benjamin Date: Sun, 22 Mar 2026 02:18:24 +0000 Subject: [PATCH 20/25] Fix dll detection --- bin/cibw_before_build_windows_arm64.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/bin/cibw_before_build_windows_arm64.py b/bin/cibw_before_build_windows_arm64.py index 440200e9..05c0f250 100755 --- a/bin/cibw_before_build_windows_arm64.py +++ b/bin/cibw_before_build_windows_arm64.py @@ -12,12 +12,24 @@ def _normalize_path(path: Path | str) -> str: return str(path).replace('\\', '/') +def _default_dll_name() -> str: + vernum = sysconfig.get_config_var('py_version_nodot') + if not vernum: + vernum = f"{sys.version_info.major}{sys.version_info.minor}" + is_freethreaded = bool(sysconfig.get_config_var('Py_GIL_DISABLED')) + if not is_freethreaded: + abiflags = sysconfig.get_config_var('ABIFLAGS') or getattr(sys, 'abiflags', '') or '' + is_freethreaded = 't' in abiflags + suffix = 't' if is_freethreaded else '' + return f'python{vernum}{suffix}.dll' + + def _normalize_dll_name(name: str) -> str: if name.endswith('.dll'): return name if name.startswith('lib') and name.endswith('.dll.a'): - return name[3:-2] - raise SystemExit(f'Unexpected Python library name: {name}') + return _default_dll_name() + return _default_dll_name() def _find_dll(dll_name: str) -> Path: @@ -47,9 +59,7 @@ def main() -> None: lib_dir.mkdir(parents=True, exist_ok=True) pkgconfig_dir.mkdir(parents=True, exist_ok=True) - raw_name = sysconfig.get_config_var('DLLLIBRARY') or sysconfig.get_config_var('LDLIBRARY') - if not raw_name: - raise SystemExit('Could not determine Python DLL name') + raw_name = sysconfig.get_config_var('DLLLIBRARY') or sysconfig.get_config_var('LDLIBRARY') or '' dll_name = _normalize_dll_name(raw_name) include_dir = sysconfig.get_config_var('INCLUDEPY') if not include_dir: From 4de4cc3e33a202fb2c146bfed973de4e89b4596f Mon Sep 17 00:00:00 2001 From: Oscar Benjamin Date: Sun, 22 Mar 2026 03:02:22 +0000 Subject: [PATCH 21/25] Remove pkgconfig check --- bin/cibw_before_build_windows_arm64.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/bin/cibw_before_build_windows_arm64.sh b/bin/cibw_before_build_windows_arm64.sh index e07e529c..797f3785 100755 --- a/bin/cibw_before_build_windows_arm64.sh +++ b/bin/cibw_before_build_windows_arm64.sh @@ -53,7 +53,12 @@ rm -f "$def_path_msys" "$import_lib_msys" cd "$lib_dir_msys" gendef "$dll_path_msys" ) +echo "Generating $import_lib_msys with $dlltool" "$dlltool" -d "$def_path_msys" -D "$DLL_NAME" -l "$import_lib_msys" +if [ ! -f "$import_lib_msys" ]; then + echo "Failed to create $import_lib_msys" >&2 + exit 1 +fi cat > "$pc_path_msys" </dev/null 2>&1; then - pkg-config --exists "python-$PKG_VERSION" -fi - echo "Generated $import_lib_msys" echo "Generated $pc_path_msys" From 88ffa03da1a51cb13ae53ebaf966e0f541e13cfe Mon Sep 17 00:00:00 2001 From: Oscar Benjamin Date: Sun, 22 Mar 2026 03:54:17 +0000 Subject: [PATCH 22/25] Try this ... --- .github/workflows/buildwheel.yml | 1 + bin/cibw_before_build_windows_arm64.py | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/.github/workflows/buildwheel.yml b/.github/workflows/buildwheel.yml index 6373cb28..265d7762 100644 --- a/.github/workflows/buildwheel.yml +++ b/.github/workflows/buildwheel.yml @@ -64,6 +64,7 @@ jobs: env: CIBW_BEFORE_ALL_WINDOWS: msys2 -c bin/cibw_before_all_windows_arm64.sh CIBW_BEFORE_BUILD_WINDOWS: python bin/cibw_before_build_windows_arm64.py && msys2 -c bin/cibw_before_build_windows_arm64.sh && pip install wheel delvewheel + PYTHONPATH: ${{ github.workspace }}\.local\python-site # After all the Windows-specific steps above this is what actually # builds the wheels for every other OS: diff --git a/bin/cibw_before_build_windows_arm64.py b/bin/cibw_before_build_windows_arm64.py index 05c0f250..5cc800bd 100755 --- a/bin/cibw_before_build_windows_arm64.py +++ b/bin/cibw_before_build_windows_arm64.py @@ -80,7 +80,18 @@ def main() -> None: env_path = repo_root / '.local' / 'cibw_before_build_windows_arm64.env' env_text = ''.join(f'{key}={shlex.quote(value)}\n' for key, value in values.items()) env_path.write_text(env_text, encoding='utf-8') + + python_site = repo_root / '.local' / 'python-site' + python_site.mkdir(parents=True, exist_ok=True) + sitecustomize = python_site / 'sitecustomize.py' + sitecustomize.write_text( + 'import sysconfig\n' + f"sysconfig.get_config_vars()['LIBPC'] = {values['PKGCONFIG_DIR']!r}\n", + encoding='utf-8', + ) + print(f'Generated {env_path}') + print(f'Generated {sitecustomize}') if __name__ == '__main__': From d2b3303e0535b9a0041a2354784b668a3a5f2c4e Mon Sep 17 00:00:00 2001 From: Oscar Benjamin Date: Sun, 22 Mar 2026 14:06:12 +0000 Subject: [PATCH 23/25] Add MS_WIN64 define --- bin/cibw_before_build_windows_arm64.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/cibw_before_build_windows_arm64.sh b/bin/cibw_before_build_windows_arm64.sh index 797f3785..a318b24d 100755 --- a/bin/cibw_before_build_windows_arm64.sh +++ b/bin/cibw_before_build_windows_arm64.sh @@ -70,7 +70,7 @@ Name: Python Description: CPython import library for MinGW wheel builds Version: $PKG_VERSION Libs: -L\${libdir} -l$dll_stem -Cflags: -I\${includedir} +Cflags: -DMS_WIN64 -I\${includedir} EOF echo "Generated $import_lib_msys" From 0b9b982d8cb9677c3bdfcc963ee5f05fa0c2c2b5 Mon Sep 17 00:00:00 2001 From: Oscar Benjamin Date: Sun, 22 Mar 2026 14:55:32 +0000 Subject: [PATCH 24/25] Try to force using msys2 clangarm64 for Windows on ARM --- .github/workflows/buildwheel.yml | 11 +++++++++++ bin/cibw_before_build_windows_arm64.sh | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/.github/workflows/buildwheel.yml b/.github/workflows/buildwheel.yml index 265d7762..3ddfedb4 100644 --- a/.github/workflows/buildwheel.yml +++ b/.github/workflows/buildwheel.yml @@ -36,6 +36,17 @@ jobs: msystem: clangarm64 if: ${{ matrix.os == 'windows-11-arm' }} + - run: | + "C:\\msys64\\clangarm64\\bin" >> $env:GITHUB_PATH + "C:\\msys64\\usr\\bin" >> $env:GITHUB_PATH + "MSYSTEM=CLANGARM64" >> $env:GITHUB_ENV + "CC=clang" >> $env:GITHUB_ENV + "CXX=clang++" >> $env:GITHUB_ENV + "AR=llvm-ar" >> $env:GITHUB_ENV + "RANLIB=llvm-ranlib" >> $env:GITHUB_ENV + "STRIP=llvm-strip" >> $env:GITHUB_ENV + if: ${{ matrix.os == 'windows-11-arm' }} + # Install pkgconfig on Windows from choco rather than from msys and # avoid using the Strawberry one. - run: choco install -y --stoponfirstfailure --checksum 6004DF17818F5A6DBF19CB335CC92702 pkgconfiglite diff --git a/bin/cibw_before_build_windows_arm64.sh b/bin/cibw_before_build_windows_arm64.sh index a318b24d..066a4818 100755 --- a/bin/cibw_before_build_windows_arm64.sh +++ b/bin/cibw_before_build_windows_arm64.sh @@ -69,7 +69,7 @@ includedir=$INCLUDE_DIR Name: Python Description: CPython import library for MinGW wheel builds Version: $PKG_VERSION -Libs: -L\${libdir} -l$dll_stem +Libs: $LIB_DIR/lib$dll_stem.dll.a Cflags: -DMS_WIN64 -I\${includedir} EOF From 37b2f295ef49d5721a02cb47a73b398abb9a83ed Mon Sep 17 00:00:00 2001 From: Oscar Benjamin Date: Sun, 22 Mar 2026 15:27:57 +0000 Subject: [PATCH 25/25] Add --host again --- bin/cibw_before_all_windows_arm64.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/bin/cibw_before_all_windows_arm64.sh b/bin/cibw_before_all_windows_arm64.sh index 01c38ced..af8f037c 100755 --- a/bin/cibw_before_all_windows_arm64.sh +++ b/bin/cibw_before_all_windows_arm64.sh @@ -17,6 +17,7 @@ pacman -S --noconfirm \ bin/build_dependencies_unix.sh \ --disable-fat\ --use-gmp-github-mirror\ + --host aarch64-pc-windows-gnullvm\ --patch-C23\ --patch-ldd\ #