Swift on Windows Guide

Just like the macOS SDK (bundled in Xcode), Windows SDK usually doesn’t require specific host OS version. For example, the newest Windows 11 SDK 10.0.22621 supports the following host systems:

  • Windows 10 version 1507 or higher: Home, Professional, Education, and Enterprise (LTSB and S are not supported for UWP)
  • Windows Server 2022, Windows Server 2019, Windows Server 2016, and Windows Server 2012 R2 (Command line only)
  • Windows 8.1
  • Windows 7 SP1

The different part is, Windows apps usually don’t gate on a minimum OS version, but instead they can declare all compatible major versions, and if run in an unlisted OS, Windows will use compatibility mode to pretend it’s an supported one. As you can see, Windows 10 and 11 share the same major version 10.0, so basically there should be no breaking change between these two.

Windows apps typically rely more heavily on runtime API availability checks, because older OSes may gain newer APIs by feature updates and service packs, and the API sets may vary upon OS edition and enabled features. Currently Swift doesn’t have the ability to handle this for developers, but theoretically it could (just need to provide additional API notes and implement the whole OS and library evolution feature). I think that’s some area awaiting improvement, but it’s too large and currently not having high priority.

I think that we should include the VCRedist MSM in the installer so that the commands can just run, but I'm not sure what dependency is dropped by that. We would still need the VS installation due to licensing (cannot just do VC Build Tools) and the need for the VCRuntime content. If we were able to acquire VCRuntime without VS, we could use the nuget package for the WinSDK or just the WinSDK installer, which would effectively shave off ~6G on the download size.

I mean we can drop the Microsoft.VCRedist.2015+.x64 dependency in WinGet manifest. It’s recommended because after we support Windows on ARM, x64 and ARM64 hosts will gain different VCRedist requirements, but WinGet cannot handle the divergence nicely at the moment.

Ah, the dependency in WinGet, not the actual dependency.

Fortunately, that is something that will be forward looking, so we should be able to get away with it. It is unfortunate that they do not support that in the manifest. In any case, using the MSM is definitely preferable. That should ensure that we do not have to worry about a potential mismatch.

Turns out that this is not so simple. The MSM require that you have elevated privileges as they install to a system location. This requires UAC elevation which we would like to avoid. This is the reason that the MSM is also considered deprecated - they install to a system location, so you might as well as use the executable installer in the chain. There is an alternative approach which is to locally bundle the VCRuntime, which is not ideal, but provides a way forward. I think that we will eventually want to have an option to disable the runtime installation and request that the user take care of the dependency or explicitly opt-in to the installation of the VCRuntime. The idea is that the VCRuntime is a system provided component so that it may be serviced by Microsoft.

Hey there! This repo is meant to be an example about how to build cross-platform macOS/Windows applications.

I hope it can be useful! Let me know if you have any thoughts about it!

6 Likes

Thanks for this. Definitely helps when seeing how to approach a project. For me personally, I am on ARM, and until I can build a Windows app inside a VM (soon I hope), then my Windows / Swift project will have to be on hold.

Still, it is great to see what is possible, and I'm really looking forward to when ARM will be supported.

I understand that. Having full ARM support for projections and for the VScode Swift extension would be great. Hopefully we will get there soon!