Introduction
If developers are exploring Windows on Arm and native development, they will be pleased to hear that Python, the most widely-used programming language, now has native support for Arm platforms. Starting with python 3.11, an official installer for Windows on Arm is now available. It’s a great time for developers to start their journey targeting Windows on Arm.
Python has been very successful thanks to its rich ecosystem, and especially pip packages (https://pypi.org/). Some packages use native code (mostly C/C++), which usually involve some efforts to enable a new platform.
In the last months, Linaro has been contributing to several key packages, and provided a CI machine to build and test for Windows on Arm. In this blog we talk about the work involved in making the official installer for Windows on Arm available and how you can get set up.
CPython
CPython is the official implementation for Python and its standard library. It’s written in C and Python.
Starting with version 3.8, experimental support for Windows on Arm was added, and it was possible to download it using Nuget or build it from source directly.
With the release of Python 3.11, Windows on Arm is now listed as a supported platform (Tier 3), and an installer is now available here. Great time for Pythonistas using a WoA machine 🐍🥳🐍! Note: This is still an experimental support, and some bugs can be present.
Python is using buildbot for its CI. Thanks to Linaro’s lab, we could provide a Surface Pro X to run a worker, that is now officially supporting this platform.
User’s perspective
Big picture
Most of the software used in the python community is available through pip.
Projects can be packaged in wheels that can contain compiled code, making it easy and fast to install for users. A wheel can be platform agnostic (if the package is pure python), or platform specific.
When installing a package using pip install mypackage, pip automatically installs the packages and its dependencies for you. In this order, it will try to:
- Find a platform agnostic wheel
- Find a platform specific wheel
- Build from source code
Build environment
To be able to install a package using C/C++ code, you’ll need to install Visual Studio Community (available for free). You just need to select “Desktop development with C++” workflow, and everything should be installed correctly. From there, pip will be able to compile packages that do not offer wheels.
Some python packages require additional tools and libraries for compilation. A few examples are CMake, LLVM, Rust, etc. Having them installed in your environment will help pip to install packages without any additional manual steps. You can refer to Linaro’s wiki page that lists instructions and additional requirements for those.
Maintainer’s perspective
When porting to a new platform, you have to choose between a native and a cross compilation workflow. That’s what we present in this section. More detailed information is available on our wiki.
If your library is a pure python one, you’re good to go. If you depend on C/C++ code, keep on reading.
When porting is needed
If your package is a pure python one, there is nothing to do. Pip can create and use “none” packages that don’t target a specific architecture, and they can be created from any machine. If that’s the case, you can skip this whole section.
However, if you are using native code, through C/C++ for instance, you’ll have to make it work for Windows on Arm. Keep on reading to discover possible solutions.
Going native
The good news is that everything is already handled in Python. It will correctly compile your package, without any further work needed. What’s more, working natively allows you to run tests. However, accessing a Windows on Arm machine might be the tough part. As of today, there is no “free” solution for that, you’ll have to invest in some technology:
Physical machines
- Any Windows on Arm Laptop/Tablet ( for example, the Microsoft Surface Pro X, Lenovo Thinkpad X13s, HP Elite Folio, Samsung Galaxy Book Go)
- Now available: Microsoft Volterra. A great devkit for developers.
- Raspberry Pi 4: Small but cheap and flexible to use. Here is how to install Windows on it.
Apple M1: You can run a Windows on Arm machine for free and easily using UTM. Pricey but might be worth it if you need to support that platform, too.
Cloud
Since April 2022, it’s possible to run Windows on Arm on Azure.
CI/CD
So far, there is no platform supporting Windows on Arm as a runner (in particular, it is lacking on GitHub and Azure DevOps). However, you can still set up your own machine and register it as a self hosted runner for your favourite environment. We tried that for GitHub, Azure DevOps, and Gitlab and it’s working well.
Cross compilation
If you can’t have a dedicated machine, you can still try to cross compile your package. However, you’ll lose the ability to run tests.
To enable cross compilation, some environment variables control:
- How to compile a single C/C++ file (VSCMD_ARG_TGT_ARCH)
- How to package libraries in a wheel file (SETUPTOOLS_EXT_SUFFIX)
Both are now handled by setuptools (>=57.4.0). In short, python distutils is now deprecated (with plans to remove it in python 3.12) and will be replaced by setuptools (details here).
To cross compile you have to set this environment:
# ensure minimal version of setuptools is available
python -m pip install "setuptools>=57.4.0"
# use distutils coming from setuptools (will be default in python 3.12)
set SETUPTOOLS_USE_DISTUTILS=local
# controls how to compile one file
set VSCMD_ARG_TGT_ARCH=arm64
# how to name library file in wheel (set cp3XX for your python version)
set SETUPTOOLS_EXT_SUFFIX=.cp311-win_arm64.pyd
From there, you can create a wheel by using pip wheel, as usual. More tips and build instructions per package are provided on our wiki.
Limitations
As seen above, your project should be using setuptools (with a recent enough version).
Alas some projects are blocked by that: notably numpy. They are now working to move away from old distutils package.
In general, python 3.12 support should be the last step to make sure all packages can be easily cross compiled, as it will be mandatory to use setuptools.
cibuildwheel
This is a convenient tool that allows you to create wheels for different architectures, automatically. This PR adds support for cross compiling to win-arm64, and should be merged soon.
Examples
Some projects who started cross compiling for win-arm64:
Work in Progress
- cibuildwheel: PR to cross compile for win-arm64
- Numpy: moving from distutils to meson, should enable cross compilation
- PyTorch : Linaro is working to enable Windows on Arm platform (status)
- Anaconda and Conda-forge: we have been discussing with Anaconda and conda-forge community to enable Windows on Arm platform. This is now in progress: stay tuned!
That’s all folks!
This concludes our tour of Python for Windows on Arm. Even though the path to support all python packages is still long, there are plenty of packages already available. This effort will be continued, and python 3.12 should be the last step to democratise this, thanks to setuptools usage becoming mandatory. Considering Python is the most used programming language, a lot of developers will have the opportunity to program with Python on Windows on Arm natively.
Microsoft and Linaro will continue to be involved in this enablement, and keep helping communities to enable Python for Windows on Arm.
For more information on Linaro’s Windows on Arm Project and how to get involved, go to our Project page.