From d3240555d945e19692f62e48c7b9ca2313f35f22 Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Mon, 14 Mar 2022 12:19:37 -0400 Subject: [PATCH] Backport PR #22429: Enable windows/arm64 platform --- doc/users/next_whats_new/windows_arm64.rst | 8 ++++ setupext.py | 45 ++++++++++++++++++---- 2 files changed, 46 insertions(+), 7 deletions(-) create mode 100644 doc/users/next_whats_new/windows_arm64.rst diff --git a/doc/users/next_whats_new/windows_arm64.rst b/doc/users/next_whats_new/windows_arm64.rst new file mode 100644 index 000000000000..dcaf0e3b618a --- /dev/null +++ b/doc/users/next_whats_new/windows_arm64.rst @@ -0,0 +1,8 @@ +Windows on Arm Support +---------------------- + +Preliminary support for windows on arm64 target added. + +Matplotlib for windows/arm64 requires FreeType 2.11 or above. + +No binary wheels are available yet but can be built from source. \ No newline at end of file diff --git a/setupext.py b/setupext.py index e41ab98fe1c0..90bc304531b5 100644 --- a/setupext.py +++ b/setupext.py @@ -167,12 +167,21 @@ def get_and_extract_tarball(urls, sha, dirname): '955e17244e9b38adb0c98df66abb50467312e6bb70eac07e49ce6bd1a20e809a', '2.10.1': '3a60d391fd579440561bf0e7f31af2222bc610ad6ce4d9d7bd2165bca8669110', + '2.11.1': + 'f8db94d307e9c54961b39a1cc799a67d46681480696ed72ecf78d4473770f09b' } # This is the version of FreeType to use when building a local version. It # must match the value in lib/matplotlib.__init__.py and also needs to be # changed below in the embedded windows build script (grep for "REMINDER" in # this file). Also update the cache path in `.circleci/config.yml`. -LOCAL_FREETYPE_VERSION = '2.6.1' +TESTING_VERSION_OF_FREETYPE = '2.6.1' +if sys.platform.startswith('win') and platform.machine() == 'ARM64': + # older versions of freetype are not supported for win/arm64 + # Matplotlib tests will not pass + LOCAL_FREETYPE_VERSION = '2.11.1' +else: + LOCAL_FREETYPE_VERSION = TESTING_VERSION_OF_FREETYPE + LOCAL_FREETYPE_HASH = _freetype_hashes.get(LOCAL_FREETYPE_VERSION, 'unknown') # Also update the cache path in `.circleci/config.yml`. @@ -646,9 +655,16 @@ def do_custom_build(self, env): subprocess.check_call([make], env=env, cwd=src_path) else: # compilation on windows shutil.rmtree(src_path / "objs", ignore_errors=True) - msbuild_platform = ( - 'x64' if platform.architecture()[0] == '64bit' else 'Win32') - base_path = Path("build/freetype-2.6.1/builds/windows") + is_x64 = platform.architecture()[0] == '64bit' + if platform.machine() == 'ARM64': + msbuild_platform = 'ARM64' + elif is_x64: + msbuild_platform = 'x64' + else: + msbuild_platform = 'Win32' + base_path = Path( + f"build/freetype-{LOCAL_FREETYPE_VERSION}/builds/windows" + ) vc = 'vc2010' sln_path = ( base_path / vc / "freetype.sln" @@ -678,14 +694,29 @@ def do_custom_build(self, env): cc = get_ccompiler() cc.initialize() # Get msbuild in the %PATH% of cc.spawn. + # Freetype 2.10.0+ support static builds. + msbuild_config = ( + "Release Static" + if [*map(int, LOCAL_FREETYPE_VERSION.split("."))] >= [2, 10] + else "Release" + ) + cc.spawn(["msbuild", str(sln_path), "/t:Clean;Build", - f"/p:Configuration=Release;Platform={msbuild_platform}"]) + f"/p:Configuration={msbuild_config};" + f"Platform={msbuild_platform}"]) # Move to the corresponding Unix build path. (src_path / "objs" / ".libs").mkdir() # Be robust against change of FreeType version. - lib_path, = (src_path / "objs" / vc / msbuild_platform).glob( - "freetype*.lib") + lib_paths = Path(src_path / "objs").rglob('freetype*.lib') + # Select FreeType library for required platform + lib_path, = [ + p for p in lib_paths + if msbuild_platform in p.resolve().as_uri() + ] + print( + f"Copying {lib_path} to {src_path}/objs/.libs/libfreetype.lib" + ) shutil.copy2(lib_path, src_path / "objs/.libs/libfreetype.lib")