Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions .github/workflows/buildwheel.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ 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.2
Expand All @@ -22,7 +22,14 @@ jobs:
- uses: msys2/setup-msys2@v2.30.0
with:
msystem: ucrt64
if: ${{ startsWith( matrix.os , 'windows' ) }}
update: true
if: ${{ matrix.os == 'windows-2022' }}

- uses: msys2/setup-msys2@v2.30.0
with:
msystem: clangarm64
update: true
if: ${{ matrix.os == 'windows-11-arm' }}

# Install pkgconfig on Windows from choco rather than from msys and
# avoid using the Strawberry one.
Expand All @@ -41,7 +48,7 @@ jobs:
uses: pypa/cibuildwheel@298ed2fb2c105540f5ed055e8a6ad78d82dd3a7e # v3.3.1
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: ${{ matrix.os == 'windows-11-arm' && 'msys2 -c bin/cibw_before_all_windows_arm64.sh' || 'msys2 -c bin/cibw_before_all_windows_amd64.sh' }}

- uses: actions/upload-artifact@v7
with:
Expand Down Expand Up @@ -81,12 +88,16 @@ jobs:
ubuntu-24.04-arm,
windows-2022,
windows-2025,
windows-11-arm,
macos-15-intel,
macos-14,
macos-15,
]
# This list to be kept in sync with python-requires in pyproject.toml.
python-version: ['3.11', '3.12', '3.13', '3.13t', '3.14', '3.14t', 'pypy3.11']
exclude:
- os: windows-11-arm
python-version: pypy3.11

steps:
- uses: actions/setup-python@v6
Expand Down
42 changes: 41 additions & 1 deletion bin/build_dependencies_unix.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ set -o errexit

SKIP_GMP=no
SKIP_MPFR=no
PATCH_GMP_C23=no
PATCH_LDD=no
PATCH_IMMINTRIN=no
GMP_FAT_ARG="--enable-fat"
GMP_ASSEMBLY_ARG=
HOST_ARG=

USE_GMP=gmp
PATCH_GMP_ARM64=no
Expand All @@ -38,6 +44,9 @@ do
echo " --host <HOST> - set the host (target) for GMP build"
echo " --skip-gmp - skip building GMP"
echo " --skip-mpfr - skip building MPFR"
echo " --disable-assembly - disable GMP assembly routines"
echo " --patch-ldd - patch flint shared linking for mingw on arm64"
echo " --patch-immintrin - patch flint arm64 msvc header to avoid immintrin.h"
echo
echo "Legacy options:"
echo " --gmp gmp - build based on GMP (default)"
Expand Down Expand Up @@ -84,6 +93,12 @@ do
SKIP_MPFR=yes
shift
;;
--disable-assembly)
# GMP does not allow --enable-fat together with --disable-assembly.
GMP_FAT_ARG=
GMP_ASSEMBLY_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
Expand All @@ -95,6 +110,16 @@ do
PATCH_GMP_C23=yes
shift
;;
--patch-ldd)
# Needed only for the FLINT shared build on mingw arm64.
PATCH_LDD=yes
shift
;;
--patch-immintrin)
# Needed only for the FLINT headers consumed by MSVC on Windows arm64.
PATCH_IMMINTRIN=yes
shift
;;
--use-gmp-github-mirror)
USE_GMP_GITHUB_MIRROR=yes
shift
Expand Down Expand Up @@ -191,7 +216,8 @@ if [ "$USE_GMP" = "gmp" ]; then
./configfsf.guess

./configure --prefix=$PREFIX\
--enable-fat\
$GMP_FAT_ARG\
$GMP_ASSEMBLY_ARG\
--enable-shared=yes\
--enable-static=no\
--host=$HOST_ARG
Expand Down Expand Up @@ -310,6 +336,20 @@ 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 -p1 < ../../../bin/patch-flint-windows-arm64-link.diff
fi
if [ "$PATCH_IMMINTRIN" = "yes" ]; then
echo
echo --------------------------------------------
echo " patching FLINT"
echo --------------------------------------------
patch -N -Z -p1 < ../../../bin/patch-flint-windows-arm64-immintrin.diff
fi
./bootstrap.sh
./configure --prefix=$PREFIX\
--host=$HOST_ARG\
Expand Down
50 changes: 12 additions & 38 deletions bin/cibw_before_all_windows.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,52 +2,26 @@

set -o errexit

pacman -S --noconfirm \
mingw-w64-ucrt-x86_64-gcc\
mingw-w64-ucrt-x86_64-tools-git\
m4\
make\
base-devel\
autoconf-wrapper\
automake-wrapper\
libtool\
git\
#

bin/build_dependencies_unix.sh \
--use-gmp-github-mirror\
--patch-C23\
#
if [ $# -lt 2 ]; then
echo "usage: $0 <llvm-machine> <build-dependencies-args>..."
exit 1
fi

# Assumes the standard GitHub Actions Windows 2022 runner layout.
PATH="$PATH:$(find "/c/Program Files/Microsoft Visual Studio/2022/" -name "Hostx86")/x64/"
llvm_machine="$1"
shift

if [ "${RUNNER_ARCH}" = "ARM64" ]
then
msvc_machine=arm64
else
msvc_machine=x64
fi
bin/build_dependencies_unix.sh "$@"

mkdir -p .local/lib
cd .local/bin
for dll_file in libgmp-*.dll libmpfr-*.dll libflint*.dll
do
lib_name=$(basename -s .dll ${dll_file})
exports_file=${lib_name}-exports.txt
lib_name=$(basename -s .dll "${dll_file}")
def_file=${lib_name}.def
lib_file=${lib_name}.lib
name=$(echo ${lib_name}|sed 's/^lib//;s/[-.][0-9].*$//')

dumpbin //exports ${dll_file} > ${exports_file}

echo LIBRARY ${lib_name} > ${def_file}
echo EXPORTS >> ${def_file}
awk 'NR>19 && $4 != "" {print $4 " @"$1}' ${exports_file} >> ${def_file}
sed -i 's/$/\r/' ${def_file}
name=$(echo "${lib_name}" | sed 's/^lib//;s/[-.][0-9].*$//')

lib //def:${def_file} //out:${lib_file} //machine:${msvc_machine}
rm ${exports_file} ${def_file} ${lib_name}.exp
mv ${lib_file} ../lib/${name}.lib
gendef "${dll_file}"
llvm-lib /def:"${def_file}" /out:"../lib/${name}.lib" /machine:${llvm_machine} /nologo
rm "${def_file}"
done
cd ../..
22 changes: 22 additions & 0 deletions bin/cibw_before_all_windows_amd64.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/bin/bash

set -o errexit

pacman -S --noconfirm \
mingw-w64-ucrt-x86_64-gcc \
mingw-w64-ucrt-x86_64-llvm-tools \
mingw-w64-ucrt-x86_64-tools-git \
m4 \
make \
base-devel \
autoconf-wrapper \
automake-wrapper \
libtool \
git \
#

bin/cibw_before_all_windows.sh \
x64 \
--use-gmp-github-mirror \
--patch-C23 \
#
26 changes: 26 additions & 0 deletions bin/cibw_before_all_windows_arm64.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/bin/bash

set -o errexit

pacman -S --noconfirm \
mingw-w64-clang-aarch64-toolchain \
mingw-w64-clang-aarch64-llvm-tools \
mingw-w64-clang-aarch64-tools-git \
m4 \
make \
base-devel \
autoconf-wrapper \
automake-wrapper \
libtool \
git \
#

bin/cibw_before_all_windows.sh \
arm64 \
--use-gmp-github-mirror \
--disable-assembly \
--host aarch64-w64-mingw32 \
--patch-C23 \
--patch-ldd \
--patch-immintrin \
#
12 changes: 12 additions & 0 deletions bin/patch-flint-windows-arm64-immintrin.diff
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
diff --git a/src/longlong_msc_arm64.h b/src/longlong_msc_arm64.h
index 44d96f03f..6ade48289 100644
--- a/src/longlong_msc_arm64.h
+++ b/src/longlong_msc_arm64.h
@@ -14,7 +14,6 @@

#include <stdlib.h>
#include <intrin.h>
-#include <immintrin.h>

/* Trailing and leading zeros */
# define flint_clz _CountLeadingZeros64
27 changes: 27 additions & 0 deletions bin/patch-flint-windows-arm64-link.diff
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
diff --git a/Makefile.in b/Makefile.in
index 0f25aa2b5..f6f46b7d6 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -416,18 +416,12 @@ 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)
35 changes: 22 additions & 13 deletions doc/source/build.rst
Original file line number Diff line number Diff line change
Expand Up @@ -352,21 +352,30 @@ builds on Windows using MSVC.

The `MSYS2 <https://www.msys2.org/>`_ project provides a Unix-like environment
for Windows and a package manager that can be used to install the dependencies.
The git repo for ``python-flint`` has a script `bin/cibw_before_all_windows.sh
<https://github.com/flintlib/python-flint/blob/master/bin/cibw_before_all_windows.sh>`_
that installs the dependencies under MSYS2 and builds ``GMP``, ``MPFR``,
``FLINT``. This script is used for building the Windows binaries for PyPI. We
use the ``UCRT64`` (``mingw-w64-ucrt-x86_64``) toolchain under MSYS2 to build
``GMP``, ``MPFR`` and ``FLINT`` because it makes it possible to have a fat
build of ``GMP``
(``--enable-fat``) which bundles micro-architecture specific optimisations for
``x86_64`` in a redistributable shared library. This is important for
performance on modern ``x86_64`` CPUs and is not possible if building ``GMP``
with MSVC. The Python extension modules themselves are then built with MSVC via
The git repo for ``python-flint`` has scripts
`bin/cibw_before_all_windows_amd64.sh
<https://github.com/flintlib/python-flint/blob/master/bin/cibw_before_all_windows_amd64.sh>`_
and `bin/cibw_before_all_windows_arm64.sh
<https://github.com/flintlib/python-flint/blob/master/bin/cibw_before_all_windows_arm64.sh>`_
that install the dependencies under MSYS2 and build ``GMP``, ``MPFR``,
``FLINT``. These scripts are used for building the Windows binaries for PyPI.

For ``x86_64`` wheels we use the ``UCRT64`` (``mingw-w64-ucrt-x86_64``)
toolchain under MSYS2 to build ``GMP``, ``MPFR`` and ``FLINT`` because it
makes it possible to have a fat build of ``GMP`` (``--enable-fat``) which
bundles micro-architecture specific optimisations for ``x86_64`` in a
redistributable shared library. This is important for performance on modern
``x86_64`` CPUs and is not possible if building ``GMP`` with MSVC.

For Windows ``arm64`` wheels we use the ``CLANGARM64`` MSYS2 toolchain instead.
The ``GMP`` build there does not use ``--enable-fat`` and instead uses the
generic build that works with that toolchain.

The Python extension modules themselves are then built with MSVC via
``meson --vsenv`` while linking against the MSYS2-built ``GMP``, ``MPFR`` and
``FLINT`` libraries through ``pkg-config``. This mixed-toolchain arrangement
keeps the ``GMP`` fat build while using the standard Windows compiler for the
extension modules.
keeps the MSYS2 dependency builds while using the standard Windows compiler for
the extension modules on both ``x86_64`` and ``arm64``.


.. _non_standard_location:
Expand Down
3 changes: 1 addition & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ files = ["src"]
addopts = "--import-mode=importlib"

[tool.cibuildwheel]
skip = "*-win32 *-manylinux_i686 *-manylinux_armv7l *-musllinux_*"
skip = "*-win32 pp*-win_arm64 *-manylinux_i686 *-manylinux_armv7l *-musllinux_*"

enable = [
# Uncomment this to test beta versions of CPython in CI (but comment out
Expand Down Expand Up @@ -154,7 +154,6 @@ repair-wheel-command = [
]

[tool.cibuildwheel.windows]
before-all = "C:\\msys64\\usr\\bin\\bash bin/cibw_before_all_windows.sh"
before-build = "pip install wheel delvewheel"
config-settings = {setup-args = ["--vsenv"], build-dir = "build"}
repair-wheel-command = [
Expand Down
Loading