FoundationEssentials on Darwin?

If your Linux or Windows app imports the Foundation library from the Swift toolchain today, you get all of these improvements for free. And if your app is particularly sensitive to binary size, you can now import the FoundationEssentials library, which provides a more targeted subset of Foundation's features that omits internationalization and localization data.

I'm developing a package for both macOS and Windows that is sensitive to binary size, so it sounds like import FoundationEssentials is exatly what I want.

As FoundationEssentials isn't available on macOS, should I explicitly import the swift-foundation package into my project, or should I always check what platform I'm using when importing Foundation?

#if canImport(Darwin)
import Foundation
#else
import FoundationEssentials
import FoundationInternationalization
#endif

It would be rather nice if import FoundationEssentials just worked on Darwin too, the way it does on Windows/Linux.

7 Likes

TL;DR: don’t worry, the Foundation shouldn’t impact your binary size on macOS.

The #if canImport(Darwin) is the solution I’d go with. Yeah, it is cumbersome :dotted_line_face:

On Apple platforms the foundation library is shipped with the OS and is dynamically linked on launch. Unless you are shipping your own version of stdlib, by default, Foundation is not included into your binary.

FoundationEssentials is more tailored for when you are targeting linux, with usually statically linked binary.

If you do want to statically link stdlib on Darwin, then yes, swift-foundation is there. You might have good reasons to. For e.g. if you are targeting an older OS release, but are relying on newer foundation additions.

P.S. you can’t even really make static binaries for Darwin. If you are to make system calls, you are required to dynamically link libSystem.

4 Likes

Thanks. Yeah – I'm not worried about binary size on macOS, but I am worried about binary size on other platforms (Linux, Windows) – that's why it seems like FoundationEssentials is the way to go.

It seems confusing that FoundationEssentials isn't included in macOS to support coding cross platform packages in Xcode. Right now I have to switch to Linux/Windows to confirm that the code I'm writing compiles correctly (because certain symbols are available in Foundation on macOS, but not in FoundationEssentials).

Including FoundationEssentials on Darwin too would make this workflow much more elegant.

2 Likes

I had a discussion with some folks at the conference about this - there are good technical reasons why it is the way it currently is but I agree it's confusing for people trying to write cross-platform code.

There is a quick fix which would allow you to write import FoundationEssentials on Darwin platforms without the need for the #if canImport(Darwin) dance but that would give you the whole of the Foundation API when importing. Great to start with, but problematic when you pull in an API that's not available on Linux and it compiles on macOS but fails when you build it. I do not think this is the right solution.

Marking which APIs are available in FoundationEssentials is a harder task without affecting a lot of other stuff but I'd love to see this eventually solved properly.

cc @Tony_Parker

1 Like

this is pretty closely related to the cross-platform Foundation story, i’ll also cross-link GRDB 7 beta - #4 by taylorswift . the fix also requires a lot of #if canImport(Darwin) conditionals, so it would be great if this stuff just worked by default.

The pattern that I use is:

#if canImport(FoundationEssentials)
import FoundationEssentials
#else
import Foundation
#endif

This makes this less about Darwin and more about Foundation on the different platforms.

7 Likes

Yeah this still presents the problem that you can end up using an API that's not available on FoundatoinEssentials and not see until it hits Linux (as well as the whole perception thing of "it's not the same on all platforms" blah blah blah). Long term I'd love to see import FoundationEssentials work on Darwin and expose the correct APIs

8 Likes

If this happens we need a new way to detect when we're being built against the open source Foundation. Alamofire uses FoundationNetworking to detect this case because URLSession is still hugely incomplete on those platforms. I don't know what the plan is to bring it into the open, but we need a way to detect when that happens and to differentiate it from older versions.

1 Like