How to build 64-bit apps for Windows on ARM

Updates to Visual Studio finally add native ARM64 support to Microsoft’s ARM-based always-connected PCs

How to build 64-bit apps for Windows on ARM
Qualcomm

For much of its, life the Windows ecosystem has been associated with one processor family: Intel’s x86 and compatible devices such as AMD’s. Windows NT’s brief flirtation with other processor families didn’t last long, with MIPs and DEC’s Alpha cast aside after a few releases. Even Intel’s Itanium didn’t last long, with Windows Server 2008 R2 the last release to support it.

But the Intel domination of the Windows platform began to change in earnest with the release of Windows 8. A new edition, Windows RT, brought it to a new processor architecture, with support for ARM’s growing family of hardware. The functionally limited Windows RT was short-lived, and so it got very little hardware support beyond Microsoft’s original Surface RT. But Windows’s ARM support lived on, in the IoT Core release of Windows 10 and in the NT kernel-based Windows 10 Mobile.

Introducing Windows on ARM

In late 2017, Microsoft announced Windows on ARM, a full version of Windows 10 that would run on the latest generation of ARM processors. Developed with Qualcomm, it included an emulation layer that would run 32-bit x86 code alongside UWP apps compiled for ARM32. The emulator worked well, and where code failed to run Microsoft quickly shipped modified configurations that let those apps run.

Always-on, always-connected hardware using Qualcomm’s LTE Snapdragonsystem-on-a-chip (SoC) hardware is attractive. It can support mobile business scenarios more effectively than a smartphone, and with 18 hours or more of battery life, it ensures that mobile PCs will still be online even at the end of a 12-hour shift. Like all PCs, these machines need software, software that performs to the best possible extent.

Unfortunately, Windows on ARM’s reliance on 32-bit code was a limitation, because modern code tends to be compiled for 64-bit systems, supporting the default installation of Windows on Intel systems. So, while you might have an app you want to install on an ARM-based Windows PC, without a 32-bit version it might not be supported.

That 64-bit support was very much an issue with the first tranche of devices, which ran a high-end smartphone-class Snapdragon 845 processor, where performance was limited. But the roadmap for Qualcomm’s ARM processors suggests that performance will improve significantly over the next few years, and current devices are already using the much more capable Snapdragon 850. Code for new machines needs to get the best performance possible, avoiding the emulation overhead.

Today, running native ARM64 code on modern devices removes any penalties associated with running emulated x86 code, at the same time as simplifying the porting of your code from one processor type to another.

Visual Studio now supports ARM64

Beta releases of Visual Studio 15 updates have had ARM 64-bit support for a while now. However, it wasn’t production-ready, and although you could sideload builds of 64-bit ARM apps onto test devices, you couldn’t distribute the apps through the public or private Windows Stores. That’s all changed with the release of Visual Studio 15.9, which makes ARM64 support official, along with the option of distributing your code via through the Windows Store.

Microsoft encourages developers to build ARM64 versions of UWP apps, but Visual Studio 15.9 also supports ARM64 C++ code. That’s an important change, because you can use it to deliver native versions of complex applications simply by installing a new set of Visual C++ compilers and libraries. All you need to do is set up a new build target and compile your code. Existing Win32 code should compile with little change, and your code can now be delivered directly to the Windows Store using Microsoft’s Desktop Bridge to make Windows Store-compatible packages.

Alternatively, Visual Studio’s installer tools will build an ARM-compatible installation package, so code can be installed from existing on-premises deployment tools. Desktop Bridge-wrapped code will also install from Intune’s corporate store, giving you another option for controlling access to any ARM64 business-critical code.

Updating existing projects to target ARM64

Adding ARM64 support to Visual Studio projects is easy enough:

  • For C++ UWP, all you need to do is add the C++ Universal Windows Platform tools. Once they’re installed, you can use the project configuration tools to add a new solution platform for ARM64. If your dependencies support the platform, save the code and use ARM64 as a build target.
  • .Net-based UWP apps need to target a supported build of Windows 10, with a new property group for ARM64 in the project file. Just like C++, create a new solution platform for ARM64 and build and test your code.

Microsoft has provided guidelines for porting existing UWP apps to ARM and ARM64. One of the most important things to keep in mind is that although Windows on ARM devices have built-in cellular modems, they’re not smartphones. The HP Envy X2on my desk is a Surface-sized device, with a big screen and without any of the buttons you’ll find on a smartphone. Code that’s been written for Windows 10 Mobile will port to Windows on ARM, but it’s going to need a completely new UI to handle the lack of device buttons and larger screen real estate found in mobile PCs versus smartphones.

UWP isn’t yet a full replacement for the .Net Framework, so you need to tread carefully when porting existing .Net code to UWP for ARM. Some .Net components haven’t been ported to ARM yet, so you may need to negotiate with vendors to get versions that have been compiled for the new platform.

Also, to debug ARM64 code you need a Windows on ARM device. As part of the build process, sideload your code onto test hardware and then use Visual Studio’s remote debugging tools to set breakpoints and access the stack on the test device.

Building native ARM drivers

One important aspect of Visual Studio 15.9 is support for building ARM64-based drivers. Using Windows Driver Kit with the ARM and ARM64 C++ compilers, either you build new drivers based on Microsoft’s sample code or you modify existing Windows driver code. Because Windows on ARM is the familiar Windows kernel, a recompile should work.

However, architectural differences between the two platforms could cause problems. The lower level the driver, the more work that’s likely to be necessary, though that should only be the province of device manufacturers. Custom USB-connected hardware shouldn’t have much of a dependency on ARM or x86, keeping risks to a minimum.

Copyright © 2018 IDG Communications, Inc.