What is needed for consumers to use my Swift-written DLL I put on NuGet?

What is needed for consumers to use my Swift-written DLL I put on NuGet?

If someone downloads my Swift-written DLL (SwiftXState 0.9.8) from NuGet and puts it in their app, what is needed for that app to launch and use the DLL? Do they need to have any particular distributables installed? Or should it "just work"?

I ask because, well, I put up a PR to an open source Windows app that uses my DLL and the testers are reporting it doesn't launch. Well, it works on my local machine, why doesn't it launch for them? Is there something extra they have to install like updated .NET?

Thanks.

Swift on Windows does not create self-contained .dll and .exe files, unlike some other compilers do. Your .dll is dependent on some other .dll files, which are part of the Swift toolchain.

This is because you have the Swift toolchain installed, and your .dll can find its runtime dependencies there.

How to find runtime dependencies of your .dll file:

Method 1: Write a command-line (not GUI) test .exe which uses your .dll and run it on a clean machine (with no Swift toolchain installed). Tying to run it you can see error messages in the console/terminal telling you which required .dll is absent.

Method 2: Find a utility (e.g. on GitHub) which can list runtime dependencies of a Windows .exe or .dll file;

Method 3: Use Plain Swift for building your .dll and use the Product | Archive for Distribution menu command. This will create a .zip file containing your .dll and all its runtime dependencies[1].

Update: I just realized that you put your .dll on NuGet, which is .NET related. The above recommendations are for classic unmanaged .dll files, cannot say anything about managed .NET specific .dll files.


  1. This method is not free. Sorry for promoting a paid product. â†Šī¸Ž

Thanks Dima,

You got me on the right track.

I was able to figure out the DLLs that should be bundled with our NuGet package for our new Swift state machine library GitHub - gistya/SwiftXState: Swift Adaptation of Stately's XState Actor-based State Management & Orchestration Library ¡ GitHub.

I'm trying to push the "cross platform" thing as far as possible, so we added a C# compatibility wrapper to SwiftXState allowing it to be used on venerable .NET 8 WPF C# Windows apps, etc.

But our Github workflow action to post the built artifacts to NuGet wasn't bundling the Swift-specific dlls with the NuGet package so it required updating the build with:

        run: |
          $out = "$env:NATIVE_DIR/win-x64/native"
          New-Item -ItemType Directory -Force $out | Out-Null

          # Direct Swift runtime dependencies of the bridge — must be present or it won't load.
          $required = @(
            'swift_Concurrency.dll', 'swiftDispatch.dll', 'BlocksRuntime.dll', 'swift_Core.dll',
            'Foundation.dll', 'FoundationEssentials.dll', 'swiftWinSDK.dll', 'swiftCRT.dll'
          )
          # Foundation pulls these in transitively on Windows (i18n + ICU). Best-effort: copy if found.
          $optional = @('FoundationInternationalization.dll', '_FoundationICU.dll')

          # The toolchain puts its runtime DLLs on PATH (so built binaries run); also check the standard
          # installer layout as a fallback.
          $dirs = @()
          $swiftExe = (Get-Command swift -ErrorAction SilentlyContinue).Source
          if ($swiftExe) { $dirs += Split-Path $swiftExe }   # runtime DLLs sit beside swiftc on Windows
          $dirs += ($env:PATH -split ';' | Where-Object { $_ -and (Test-Path $_) })
          $dirs += Get-ChildItem -ErrorAction SilentlyContinue -Directory `
                     "$env:LOCALAPPDATA\Programs\Swift\Runtimes\*\usr\bin" |
                     Select-Object -ExpandProperty FullName

          function Find-Dll($name) {
            foreach ($d in $dirs) { $p = Join-Path $d $name; if (Test-Path $p) { return $p } }
            return $null
          }

          $missing = @()
          foreach ($dll in $required) {
            $src = Find-Dll $dll
            if ($src) { Copy-Item $src $out -Force; Write-Host "bundled  $dll  <- $src" }
            else { $missing += $dll }
          }
          foreach ($dll in $optional) {
            $src = Find-Dll $dll
            if ($src) { Copy-Item $src $out -Force; Write-Host "bundled  $dll  (optional)" }
          }
          # ICU data DLLs sit beside Foundation; their exact names vary by toolchain version.
          $fdll = Find-Dll 'Foundation.dll'
          if ($fdll) {
            Get-ChildItem -Path (Split-Path $fdll) -Filter 'icu*.dll' -ErrorAction SilentlyContinue |
              ForEach-Object { Copy-Item $_.FullName $out -Force; Write-Host "bundled  $($_.Name)  (icu)" }
          }
          if ($missing.Count) {
            Write-Error "Missing required Swift runtime DLLs: $($missing -join ', '). Searched PATH + the Swift install."
            exit 1
          }
          Write-Host "`nStaged for win-x64:"; Get-ChildItem $out | Select-Object Name, Length

      # Upload the whole native folder (Windows carries the Swift runtime DLLs too; macOS/Linux is one file).
1 Like