I agree with the breakdown above. I'm going to write down my ideas, musings, thoughts, and brain-dumps from conversations I've had with @compnerd offline so that folks can see where some of this comes from.
Windows today-ish doesn't ship the C++ runtime on Windows. Instead, the runtimes are distributed and installed in the application "bundle" (not familiar with Windows terminology, but that should be clear enough). Latest supported Visual C++ Redistributable downloads | Microsoft Learn.
This has some interesting benefits, like not having to worry about ABI differences, and applications that depend on buggy behavior can ensure that they're packaged with the buggy runtime that they depend on.
Meanwhile, unlike statically linking (which ensures the same things noted above), if there is a security vulnerability found in a subset of the DLLs, the individual DLLs can be updated without having to rebuild and distribute the whole program.
The Swift runtime doesn't guarantee ABI stability off of Darwin, so bundling the Swift runtime in the application bundle would make sense, and be consistent with the Windows packaging expected today. The Swift compiler and other programs would have a C++ runtime and Swift runtime distributed in its bundle.
Now where things get a little bit more interesting. Windows seems to be pushing away from this model. Redistributing Components By Using Merge Modules | Microsoft Learn. Having every application bundle the C++ runtime is kind of silly, since largely, they shouldn't need a specific (older) version of the C++ runtime. It also means that any program that doesn't update their runtime in the event of a vulnerability is still compromised. So now systems are only partially secured if some applications update the library while others don't. This comes with some challenges. The few questions I have is, where is the "central" location where libraries are "supposed" to go, and what about ABI? I'm glad you asked.
Microsoft describes three options for distributing the C++ runtimes;
- Central deployment
- Local deployment
- Static linking
Central Deployment
Central deployment is what we do today for the Swift runtime. Programs share the runtime as it is installed. This saves storage space and means that anyone who updates the library can update the runtime for everyone, so it's good for safety. It does require that the library is ABI-stable though, which the Swift runtimes and standard library are not on Windows. This is the model that Microsoft is pushing toward as well, so they do have some answers to this question. Specifically, using version numbers in the DLL name/path.
It's still not without restrictions; users need administrative privileges to install libraries centrally. That makes sense from a system security standpoint, but it is a restriction on who can install the runtimes. We do want to think about folks trying to learn Swift in schools where they might not have admin rights.
Local Deployment
Local deployment is what the Microsoft C++ runtimes are transitioning away from, but has worked for them and ensures no ABI breakage. It also ensures that if you tested your application locally before deployment, then deploy it, that it will "just work". It does mean that we're potentially bundling a lot of things though. We would need to include the C++ runtimes and the Swift runtimes. If you bundle corelibs-Foundation, you would need all of its dependencies bundled as well. It doesn't have the admin privilege restriction, so you could download any Swift application and it would work.
It still gives developers the option to update pieces of their program instead of having to redeploy the entire thing, but they would have to know/remember to do that.
Static Linking
I don't have enough experience on Windows to make any certain statements here on developer experience, but from my understanding link is a bit nicer than the unix-style ld in that order and repetitions aren't important for the linking algorithm. The only thing that I see being different here vs the local distribution is that developers only have one binary to distribute, which is a double-edge sword. There's only one binary to distribute, but in the event that any of the libraries contain a vulnerability, the entire binary has to be replaced. It won't require admin privileges and we don't need to worry about ABI because everything is sealed up. (I guess there's one other face here, I don't believe statically linking Swift runtimes works on Windows at the moment, but I could be wrong.)
Summarizing my feelings
I think the ABI thing concerns me most at the moment. We don't currently version the runtime, so anyone updating it will potentially leave all other programs silently broken, which is bad. The core stdlib and runtimes do benefit from Darwin being ABI stable, but other things like corelibs-Foundation do not.
In that regard, I would be most comfortable with programs bundling the runtime they were built against directly in the application. This will ensure that ABI is not a problem and that they will "just work". Like with Microsoft's C++ runtimes, there would be a package for ARM64, X86, and X64. Folks who want to use Swift would bundle those C++ runtimes and the Swift runtime in their program and then they could deploy that wherever.
Once we have version numbers or have a reasonable story for ABI stability on Windows, then I would feel more comfortable saying that we should/could have a central system Swift runtime. This is a future-looking statement, not criticizing the work that has already been done. I recognize that time is a limited resource. 