Pitch: Standardise Swift CLI across all platforms

SwiftPM and it's associated command line tools (swift test, swift build, swift run etc) currently work across all the platforms that SwiftPM supports. However the behaviour of those tools is different across different platforms - it's the same on all platforms apart from macOS. For example on macOS, swift test uses the Objective-C runtime to discover tests. swift build builds against the Objective-C Foundation runtime instead of using corelibs-foundation. This makes writing cross platform code difficult and prone to errors. For example, when developing on macOS you might use a Foundation API that doesn't work or has bugs on Linux. And even if you have a test for it on Linux, you have to ensure it runs on Linux because you can't check that on macOS.

I propose two initial things:

  1. swift test on macOS should use the same test discovery features as the other platforms. This should ensure that when developing on macOS, you make sure your tests run as they would on other platforms/. To me this seems like a fairly simple win without any major downsides (though I'm sure there are some!).
  2. swift build/swift run should use corelibs-foundation. This one is likely to cause more pain and I'm sure there are plenty of things that could block this. One issue I can immediately see is that when running a binary compiled with swift build on macOS I assume it uses the bundled Swift runtime in the OS as there are no static executables on macOS. Changing this to use corelibs-foundation is likely very hard. But would be interesting to hear if there are approaches that would work.

Overall, I think standardising the development flow of Swift packages across platforms would be beneficial to the language and make it easier to develop for.

28 Likes

To be honest, this is very unlikely to work even with significant effort. The library built by corelibs-foundation on macOS is actually called SwiftFoundation to stop the tests accidentally using the real Foundation, and the cut down CoreFoundation has functionality removed that macOS depends on. eg the toolchain snapshots cant be used for building/testing on corelibs-foundation on macOS.

Another issue would be that any code that runs on macOS and expects to use CoreFoundation would fail as CoreFoundation is being made directly inaccessible in corelibs-foundation.

Perhaps an alternative approach would be having swift test use docker to test on other platforms, maybe something like:

swift test --platforms=macos,ubuntu20,centos7 etc and just have it run the tests on each platform in turn using docker for the non-macOS platforms

5 Likes

+1 on point 1. And definitely +1 on the overall conclusion. It not only makes it easier for cross platform work, but also makes code sample and blog articles relevant across platforms if it behaves the same.

Another data point - running swift test crashes on macOS if you only install the Swift toolchain and don't have Xcode installed (reddit post)

4 Likes

Ran into this (I think) today where I am developing a server-side-Swift (Vapor) app and accidentally used something unavailable in corelibs-foundation and only found out when my Linux server tried to build it.

That there's no way to have the compiler tell you what's available to use in Foundation makes cross-platform development a bit trickier (on Mac) than it ought to be!

7 Likes