Windows apps packaging their Swift runtime can make the toolchain unusable
Opened this issue · 5 comments
We recently modified the installer for Nick Lockwood's SwiftFormat project to include the Swift runtime dlls, since the one installed on the machine might not be ABI-compatible. The installer will add its target folder to the system %Path%
, which will then win when resolving swiftCore.dll
and other Swift runtime dlls, breaking the toolchain programs like swift.exe
.
Repro steps:
- Install a Swift toolchain different from SwiftFormat's (not 5.10.1)
- In a new command prompt, run
swift.exe --version
. It should work as expected. - Install SwiftFormat from this release
- In a new command prompt, run
swift.exe --version
. It will now crash because it's picking up the Swift runtime binaries from the SwiftFormat installation.
I was cautiously optimistic for a short-term fix where SwiftFormat could include a swiftformat.exe.config
to add a subdirectory to its dll search path but this mechanism appears only supported for .NET assemblies :(
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<configuration>
<windows>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity name="SwiftFormat" type="win32" processorArchitecture="amd64"/>
<probing privatePath="SwiftRuntime"/>
</assemblyBinding>
</windows>
</configuration>
I think that we want to migrate to a Win32 SxS approach for the runtime. This would allow us to share a global installation of the runtime across applications without worrying about the ABI stability issue. We would need to embed the build number until an ABI stable build is available. Each application would then need to request the explicit revision of the runtime, and would load that specific version even though there may be multiple installed runtimes which are all in Path
.
@compnerd , would this require switching the installer to per-machine installs? ("a global installation of the runtime"), and could we bake in swiftc.exe
the logic needed to make the app request the matching runtime, or would this require every app to know to add an extra build step?
@compnerd , would this require switching the installer to per-machine installs? ("a global installation of the runtime"), and could we bake in
swiftc.exe
the logic needed to make the app request the matching runtime, or would this require every app to know to add an extra build step?
I think that it would be best to switch to per-machine installs, but, it might be possible to retain the per-user install for the runtime.
The request is going to be application specific. There is no reason to assume that the compiler knows the runtime version precisely. ABI stability would mean that you can switch between versions and the handling for this is in the loader, which means that the linker is what needs to change. If you can change link.exe
, we could consider that, but otherwise the application needs to handle their own manifest changes.
(for the record) We considered using the win32 .local
dll loading mechanism (Dynamic-link library redirection - Win32 apps) as a workaround to unblock affected apps but it won't work. It's used to force loading a dll that is next to the exe even if a full path to some other location was specified to LoadLibrary.