Swift binary with embedded runtime and standard library?

Hi,
Before swift became ABI stable on Apple platforms, swift programs when compiled would embed the swift standard library and when they would run they would use the objc runtime in that eco system. Now that swift has a staable ABI there is a separate swift runtime. Is a similar centralized runtime needed in Linux or Windows?

  • Is it possible to build a swift binary for linux that does not require anything to be installed on the target OS before the binary can run?
  • Is there a way I can embed the the swift runtime and standard library with in the binary?

https://www.quora.com/Can-applications-written-in-Swift-on-Linux-run-on-Linux/answer/Indrajit-Ghosh-33 The above quora entry says that all is needed is libswiftcore.so but this is from 2016.

Thank you,
Chéyo

Hi!

On Windows, unfortunately, the only option is something similar to macOS - you need to have the runtime installed. Going into the details of why that is required could get long and would be best to do as a long winded post on its own (basically, static linking on Windows doesn't work with Swift - somewhat intentionally).

For Linux and Android, it is possible to statically link the runtime and its dependencies.

In both of these cases, were you to prefer the dynamic linking (which I highly recommend), you would need the swift standard library (and runtime which is part of the standard library) and its dependencies (which is pretty much ICU IIRC).

For non-Windows, non-macOS targets, yes, it is possible. You will need to generate a statically linked binary which will link everything (including the C library, math library, Swift library, and ICU).

IIRC, you would do -static-stdlib -emit-executable to get that working.

@drexin and @spevans may have additional context on this which may have slipped my mind.

Saleem

In case of a -Onone (default) build, you would also need libswiftSwiftOnoneSupport.so. If you are using other modules like Foundation, GLibc etc. you need to include those as well.

-static-stdlib only statically links the libraries that are part of the Swift distribution. If you want a fully self contained binary, including libc etc., that can be achieved with -static-executable. It is rarely advisable to do that, because the system you deploy on may not be compatible with the library versions on your build host and it may also be a security concern.

I concur with @compnerd, that dynamic linking is the recommended option. If you want to know what libraries specifically your binary depends on, the can be checked with readelf -d $BINARY | grep NEEDED.

1 Like

The minor caveat is that if you do -static-stdlib then IMO -static-executable should really be strongly recommended IMO. The law of Highlander - there can be only one (in the address space) - applies to the standard library.

If you have a library written in Swift and an executable written in Swift, you must statically link together everything to ensure that everything is properly resolved. That is, mixing dynamic linking binaries with static linking of the standard library can cause more problems like missing class registration.

1 Like

Yeah, I think that's fair.

There is no fundamental reason static linking shouldn't eventually be supportable on Windows.

Oh, absolutely, and would be something really nice even to support (its largely a matter of plumbing through a few flags honestly). I was merely trying to convey going into the details of why currently it is the way it is is long and has a lot of justifications for why it is as it is.

2 Likes
Terms of Service

Privacy Policy

Cookie Policy