swiftlang / swift-installer-scripts

Apache License 2.0
72 stars 38 forks source link

Windows apps packaging their Swift runtime can make the toolchain unusable #339

Open tristanlabelle opened 1 month ago

tristanlabelle commented 1 month ago

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:

tristanlabelle commented 1 month ago

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>
compnerd commented 1 month ago

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.

tristanlabelle commented 1 month ago

@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 commented 1 month ago

@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.

tristanlabelle commented 1 month ago

(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.