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
8 changes: 8 additions & 0 deletions doc/users/next_whats_new/windows_arm64.rst
Original file line number Diff line number Diff line change
@@ -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.
45 changes: 38 additions & 7 deletions setupext.py
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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")


Expand Down