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.

1 Like

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.

3 Likes

As of Swift 5.3, static linking is it’s easier with Linux and standard library. Issues · apple/swift · GitHub

Foundation support with some manual work with the following:

FoundationXML and FoundationNetworking will work when linking with -static-stdlib, when linking with -static-executable, you need to provide the transitive dependencies manually.
https://mobile.twitter.com/evonox/status/1304454877653868544

1 Like

I've had good experiences using -static-stdlib on Linux. I've been able to create executables on one machine then run them on a different machine without needing to install Swift or other dependencies. How realistic would it be to hope that this would be someday come to Windows?

It'd be stellar to someday have the kind of experience that people using Go, Rust, or Dart have in creating standalone executables, but wasn't sure if it was realistic for me to expect that of the Swift toolchain on Windows anytime soon.

I think that it is reasonable to expect this to occur at some point. In fact https://forums.swift.org/t/enabling-static-linking-on-windows was specifically about this.

There is a path that would enable this that I brought up on the thread, and it seems like others agree that it is a reasonable approach. Right now, its a matter of getting everything implemented. There are a ton of things that can be done to add new functionality or improve the development experience on Windows.

I am trying to reduce some of the complexity in getting started, so as much as I would like to get this done, I think that it is pretty low on my priority queue. However, since there is at least an idea of how to approach the problem, others should be able to implement the functionality.

3 Likes