Manually integrating Swift packages?

I apologize if this has been discussed - I've attempted to read through existing threads, but haven't found anything directly addressing Swift package integration on Windows.

With SPM not yet available in the toolchain but a desire to begin testing packages for compatibility, is there a way to "manually" build and link packages for Windows? IE: If you pull the source from Git, can you place it relative to a project and somehow point the build system to that folder?

I'm confident I'm misusing terminology, but I'd imagine many other developers who've used SPM but been shielded from its internals are in a similar spot. If the answer is "just wait for SPM to be available", that's reasonable enough.

Also, fantastic work on all of this. I think there's a much larger user base excited about the addition of the platform than are comfortable posting.

1 Like

While you are waiting for SwiftPM to be completed, you can use one of the strategies in the following threads. The first thread is older and generated CMake instructions from SwiftPM on another supported platform before checking out the package on Windows. The second is newer and cross‐compiles out of WSL.

If your intention is mostly just to add a Windows CI job to an existing package using GitHub Actions, then you can simply run a tool of mine with $ workspace refresh continuous‐integration, and it will generate an action configuration for you that includes not only Windows, but also Android and web (which you can then trim however you want). The tool is updated periodically so that it always generates the action scripts according to the current best practice with the least peripheral scaffolding.

2 Likes

These are fantastic resources. Thank you for blazing the trail!

I've been attempting to recreate your steps from the second link (related to cross-compiling from WSL) but doing so on macOS, as I figure that's a setup that many who want to try Windows support might be interested in. I've successfully brought over the Windows toolchain (everything within C:\Library\Developer), and have been referencing your Github integration script (here).

This is probably a silly question, but I'm continuing to get errors that Library/Developer/Windows/Developer/Platforms/Windows.platform/Developer/SDKs/Windows.sdk/usr/lib/swift/windows/x86_64/Swift.swiftmodule was "compiled module was created by a newer version of the compiler". I've confirmed the version of the swift toolchain on my macOS instance is Apple Swift version 5.3 (swiftlang-1200.0.29.2 clang-1200.0.30.1), which ships with XCode 12.

Did you run into any issues with toolchain version mismatch? Does the fact that XCode rolls out the toolchain less often essentially rule out macOS as a cross-compiling option?

Regarding this error (which isn’t specific to macOS):

The toolchain (macOS in your case) and the SDK (Windows) have to be from the exact same commit (or, if you’re very lucky, very close commits sometimes work too). That link to the script on GitHub pointed at a specific commit in order to zero in on the relevant lines, but that commit is out of date and would have had you installing the 5.2.1 SDK, which doesn’t match the 5.3 you say you have on macOS.

If, from that link, you switch from the particular commit to the master branch, and then scroll back to the same place in the file, you will see an updated version of the script valid for 5.3. (The installer is also directly available from swift.org now, so you can use that instead of the one from compnerd/swift-build. I just haven’t gotten around to switching the link yet.)


An additional puzzle you will have is the Windows SDK. I’m not talking about the Swift SDK for Windows that you can easily download, but rather the Windows platform C headers that come from Visual Studio. These aren’t redistributable due to licensing restrictions, so the only way to get them is from Visual Studio. Since Visual Studio is already present on every GitHub action host, the script I linked didn’t need to install it. The first part of the script asks Visual Studio where the SDK is and records it in some environment variables. Those variables are then used later to know where to copy module maps into the SDK, and then to direct SwiftPM about where to include them from.

WSL can see outside itself into the main Windows file system, and that is why everything works. Since you aren’t building from inside Windows, you will need some other means of accessing a Windows file system that has Visual Studio installed. Then you will have to adjust those steps accordingly so that everything points properly to where the Windows SDK actually lives, and not to some empty or invalid path.

P.S. It does sound as though SwiftPM is now included in the latest toolchain snapshots, so if you don’t care about working with a pinned stable release, you can probably just use SwiftPM directly on Windows.

Sorry, I should have provided more detail here: I'm using the 5.3 version of the Windows SDK from the "Releases" section of the downloads page on swift.org. I've been mostly referencing the "Build" section of your script to understand which flags need to be passed.

This is very good to know. I have access to a machine with Visual Studio (and have Swift working there via cmake), but I wasn't aware of the redistribution restrictions. That could throw a bit of a wrench in this for anyone hoping to cross-compile.

I may end up heading down this direction. My instinct was that the developer experience would likely be better on macOS in the near term, and that a lower barrier to entry might incentivize everyone to test their existing / new libraries against Windows.

That is strange. Maybe some closed‐source Xcode integration hooks interfere with a hash and make the compatibility check fail? I don’t really know.