Windows has definitely come a far way from when it started. However, one feature that still is not available on Windows is static linking. Everything currently requires dynamic linking, which is a bit unfortunate. Although, technically, the Microsoft linker can resolve the imported symbol, it comes at a cost (binary size and runtime overheads, and unnecessary warnings). It would be wonderful to get this issue resolved. Even then, it results in over-exposure of the interfaces, which is another source of issues. However, going the other way has even bigger problems, and given that dynamic linkage is generally preferable, it is what I focused on initially.
Let me summarise the behaviour just to be extremely clear about what is needed even though this is probably known to many people already. The primary issue is that calls need to indicate their DLL storage, that is indicate whether they are local to the module or not. This is normally done via
__declspec(dllexport)indicates that the function participates in global symbol resolution and should be made available to all modules in the address space
__declspec(dllimport)indicates that the function resides in an external module in the address space.
We currently do a pretty good job about identifying module local symbols by identifying the module being built, and anything outside of the module is marked for import. Any public interface is marked as export. This has resolved nearly all of the references to functions across module boundaries.
For static linking, we need to indicate to the driver that the module is meant for static linking. We can easily require that when building a static module that
-static is passed to the frontend via the driver (or swift-package-manager). This would prevent the public interfaces from being marked as
__declspec(dllexport). This would resolve the over-exported API surface issue.
The problem however arises for the functions that live outside the current module. How could we tell that a module is to be linked statically and calls to it should not be marked as
One solution that I can think of, which I really am not sure is the best that we can do, is to serialize to the swiftmodule to indicate whether it is static or dynamic. I'd love to get other opinions and thoughts and see if we can come up with a better solution.