I’ve posted about my initial week with the Surface Pro X not long ago, now a month later I want to address an important topic which I see as crucial for Windows on ARM to get traction: Developer Support. At the moment it is really hard to develop GUI apps for Windows on ARM outside of the “Visual Studio ecosystem”.

As of this writing there is no native Windows on ARM versions of: Python, Ruby, Go, Rust, Pascal/Lazarus, D, Nim, Zig, Racket, Clojure, Java.

Right now, I have Visual Studio 2019 running on my Surface Pro X and I’m trying to use it to port other languages to Windows on ARM.

In this brief post, I’m going to explain why I see this as a problem; what I tried to do to solve this for my own personal usage; what challenges I faced; and some approaches that Microsoft could (and should) do to solve this.

Disclaimer: I am not a senior native developer. I am a curious tinkerer. I can build native, mobile, and web apps, but I’m not experienced with Visual Studio, or with all the plumbing and low level requirements for lots of the things I’ll be talking about here. This is a personal account of how I tried to handle the lack of developer tools familiar to me in this platform. I may be wrong on many occasions and will welcome fixes and pointers to help me solve the challenges explained below.

Why this is a problem? Isn’t 32bit x86 emulation great?

Yes, the x86 win32 emulation is awesome and without it I couldn’t use the machine at all as many of the apps I depend on are not native. But we all know that this emulation is not how we’re supposed to run this machine, this is a stopgap solution until the ecosystem catches up. The problem is that without more languages and libraries, we can’t catch up!

I really think Windows on ARM is missing simple, easy to use, scripting languages that can build both GUI and CLI apps with minimal effort. The kind you can use to create simple apps or small projects. If you have an idea for a small app, your only real solution is to build it using VS. Without a rich and broad development ecosystem, we can’t build the gazillion apps which makes Windows useful.

But you have electron right?

Lets get the elephant out of the room: There is an unofficial build of NodeJS for WoA and official builds for Electron 6 and 7. There is a catch though, node-gyp is not yet ready for prime usage in WoA. If your electron-based app uses native modules, there is a great chance that node-gyp with fail to find a arm64 prebuilt version of it online and then try to build from source and end up either building the x86/amd64 unusable architectures or failing to build for arm64 . I’ve tried with many electron based apps from communities I am a part of and the native modules always failed building. If your app doesn’t depend on native modules, then it is OK and workable, but do you really want to launch a full chrome engine for every little app you want to use? The Surface Pro X is quite powerful, it can run those apps but it feels like wasted computing power to launch multiple web engines to handle trivial apps.

What about WSL? Docker?

I’m talking here most specifically about building GUI Desktop applications. WSL and Docker are great if you’re a web developer doing webby stuff, or if you’re developing terminal apps for Linux. I use WSL every day, but I want to have more Desktop apps. It is almost an ironic that we carry this much computing power in our machines just to let it sit idle while we use everything from remote servers. I’m tired of SaaS. I want tiny apps.

It is not only the languages, it is the ecosystem to build them.

So what is a developer with insomnia to do? Well, lets start trying to port the languages we like to the platform. By port here I basically mean see if the provided instructions to build something on windows can be adapted for cross-compiling arm64 binaries. I don’t feel confident to go poking into source code that needs changing for most of the languages I enjoy working with, so porting might be the wrong term. Still, I noticed that the challenges preventing me from even starting to compile the languages fell into two broad categories:

You need something to make Windows look like UNIX: Lots of languages require mingw64, cygwin or msys2 to build. I believe that this is a side-effect of them being worked by cross-platform teams who are more comfortable with a UNIX-like system. Until those set of tools are available, building those languages is quite hard.

Our build scripts rely on external prebuilts: You know the frustration in Super Mario Bros when Mario arrives at a castle just to be told by Toad that the princess is in yet another castle? Thats how I feel when I download source code for something feeling it is all there just to see it starting to fetch stuff once you tell it to build. Usually that process fail as most build farms used by those languages are not creating Windows on ARM artifacts. Some don’t even offer a fallback to build from source.

What did I try to do then?

At the beginning I decided to try to compile some languages I enjoy using. These days, for my own personal use, I mostly enjoy Lua and Racket.

I started with Racket which thankfully has simple instructions to build on Windows. Still, I couldn’t make the build work because the provided Visual Studio solutions and projects are not configured for arm64 . The build also relies on fetching prebuilt artifacts from the web. I stopped trying to build it once I’ve reached their ffi library which relies on assembly code. On windows, it defaults to x86/amd64 assembly, I managed to tweak the build instructions to use their aarch64 assembly folder and the arm assembler from VS but it failed to build. I believe this is more about configuration than changing source code but I didn’t had time to dive deeper.

Then I proceeded to compile Lua, which is probably the easiest language to compile in the world. The Lua Team deserves a lot of praise in that the language is so easy to build that even a high-level application developer with zero VS experience like me can do it. I ended up compiling and distributing all the four major versions of it for arm64. I also wrote a PR for Luarocks, which is Lua’s most popular package manager, to make sure it could cross-compile arm64 binaries for Windows. This means that Lua can now be used to script simple tools for Windows and as soon as someone work on one of the GUI libraries, we’ll have a simple solution to get started developing small nimble apps for WoA. I managed to get wxWidgets compiled for WoA but couldn’t build the wxLua which is the runtime with bindings.

I couldn’t get chicken scheme or gambit scheme to build.

I couldn’t get vcpkg working, it fails to find the installation of Visual Studio 2019 on my machine.

In the end, I’m mostly using Electron without native modules to build little personal toys 😿, at least until either I can make some GUI library work with Lua or someone ports another language with working GUI bindings.

Why use this machine at all?

I like it, and already own it. I love the form-factor, LTE is great, screen is great. The fact that I am willing to step out of my comfort zone and actually attempt to compile and contribute to many languages is proof enough that I really like this machine, and that I think it is an worthy endeavour to attempt to make its ecosystem better.

You don’t expect Microsoft to port all languages in existence, do you?

Of course not, lets be reasonable. Microsoft is already doing a ton of work. Still, the problem of “we need moar languages!!!” needs to be solved. Here are multiple approaches that I think Microsoft should take to help fix this. This will only work out if Microsoft work to empower the communities building such languages.

Many communities don’t have access to Windows on ARM machines.

There are libraries and languages that are not being ported due to the lack of access to machines. Microsoft should:

☁ Find out which libraries are most commonly used and need porting. Offer access for the maintainers to Azure Virtual Desktop and/or Visual Studio Online (this is better if they offer native arm64 experiences there, I’m not sure they do but even access to cross-compilers there is already a step forward). There need to be a port for Windows on ARM of at least the following libraries: Qt, GTK, wxWidgets. Languages like: Python, Ruby, Rust, and Go are essential.

💻 Give real Surface Pro X to some crucial maintainers out there to get some languages ported. Nothing beats having the real thing. Get in contact with them, check if all they need is a machine? if it is, give them one.

💰 It would be great if Microsoft could offer grants or sponsorships like Mozilla does with MOSS with the objective of getting stuff working on WoA. FOSS has a sustainability problem and many maintainers don’t have the means to devote time to this task. Being able to sponsor work is probably one of the best ways to get the ball rolling towards more developer support for Windows on ARM.

Final remarks