Recently Clang added support for native compilation on Windows on Arm (WoA). This was a great opportunity to try it out and compile natively an open-source application using the new Clang tools.
The application in question is PuTTY, a free SSH, and Telnet client. PuTTY has run natively on WoA for years, so the main goal of this project was to demonstrate that the compilation process was simple. Also to see if Clang could do it without having to jump through the hoops of cross compilation. This was a great way to test the pre-release version of Clang (current release found here).
I started by looking at how PuTTY was built on Windows. Due to my unfamiliarity with the program, and the fact that the build process is not a simple CMake based one, I got in touch with PuTTY’s creator and asked about how to go about the build process. He informed me that there was a Perl script to setup the appropriate platform-specific build files, and then recommended using Make to run a custom Makefile.
Why did I do this? Essentially, I wanted to successfully build for WoA as it currently is, cross compiled from Linux. Since I was trying to mimic the original cross-compilation process, I performed much of it with Windows subsystem for Linux (WSL2). However, I later realized it was a convoluted way to compile for WoA, and that a native compilation on WoA was a much easier route.
First, I ran PuTTY’s Perl script, “mkfiles.pl” to generate the necessary build folder for Windows. I did this in Windows PowerShell, but this could be done in WSL if wanted. I had to specify the target platform to ensure the right files were created, by adding “Platform=arm64” to the Perl command.
Next, I ran Visual Studio 2019’s Developer Command Prompt, which automatically sets up an environment for compilation. In this prompt, I used a tool called msvc-extract, to extract the visual studio headers (later used to set environment variables), for use in WSL2 later. Due to WSL not being case-sensitive, unlike Linux, I had to request a custom version of msvc-extract – which is helpfully made by the same developer as PuTTY – before I could use it in WSL2.
Once we have extracted these files into a sensible location, we use WSL to run a couple of scripts to initialize the build environment. We then point to the now extracted VS headers, before double-checking we have Clang installed correctly. Once everything is setup up, we run the “Makefile.clangcl” and PuTTY should build correctly.
Now, while this works, it is a convoluted way to compile for WoA. Especially since a native compilation is now available through the new LLVM toolchain.
The cross compilation build process
Compiling PuTTY natively turned out to be a much simpler process. It starts the same, by running the Perl script with the platform argument to create the arm64 build folder. To run the Perl script, I needed to find a 32-bit x86 Perl installer to run under emulation, since there was not a native WoA installer available. I used Strawberry Perl for this.
The next step is slightly more complicated. To use the Visual Studio command prompt, we need to modify the target of one of the existing tools prompts. As there were no arm64 tools provided by default in Visual Studio, I modified the x86 prompt (“x86 Native Tools Command Prompt for VS 2019“). By changing the shortcut target from “vcvarsamd64_x86.bat” to “vcvarsamd64_arm64.bat”, we can launch the prompt in arm64 mode, ready for compilation.
From here, I just needed to make sure I had the latest Clang version installed correctly, as well as a suitable Make tool (I used mingw32-make, but I am sure there are other options). After making sure everything was appropriately configured, I ran the make command, and PuTTY compiled. Overall, a much simpler process than cross compilation, be that from Linux or non-Arm Windows.
The native build process
Overall, the compilation process was a success. After familiarizing myself with how PuTTY is built, the process for compiling it natively went very smoothly.
Thanks to the newly available Clang tools, the end build process was simple. However, identifying the build process was more complicated than anticipated. In fact, this took up most of the project. This means it is probably a good idea to read up on the current build process for the software you want to build, since knowing the build process helps if you need to adapt it for WoA. That being said, the new process is far simpler and less time consuming than the previous cross compilation. It just proves the great strides that are being made within the WoA developer ecosystem.
For more information about developing for WoA, visit the WoA portal on developer.arm.com.
Read about the native LLVM toolchain
Learn about Windows on Arm