Swift 5 Runtime Support for Command Line Tools Package

I have a Swift command line tool embedded in a Swift application that is compiled to run on macOS 10.10 and later.


After upgrading the application and tool to Swift 5, will users on macos 10.14.3 and earlier have to install the Swift 5 Runtime Support?

Is there anyway to link or invoke the tool so that it uses the Runtime Libraries already embedded in the Frameworks directory of the application bundle?

Answered by DTS Engineer in 355000022

Earlier I wrote:

You’ve hit an interesting edge case.

I talked to folks internally and there’s a general consensus that resolving this edge case — as a reminder, we’re specifically referring to the problem where you’re shipping a GUI app with an embedded helper tool — by having the helper tool reference the host app’s Swift runtime is fine.

The one thing to watch out for is the rpath setup in your tool. You have to make sure that the tool’s rpath references

/usr/lib/swift
first and the embedded runtime second. That way, the tool will use the system runtime if it’s available, and then fallback to the embedded runtime.

For example, if you take Xcode 10.2, create a new Swift app, and then build it, the app’s rpath setup looks like this:

$ otool -l ***.app/Contents/MacOS/***
…
Load command 30
          cmd LC_RPATH
      cmdsize 32
         path /usr/lib/swift (offset 12)
Load command 31
          cmd LC_RPATH
      cmdsize 48
         path @executable_path/../Frameworks (offset 12)
…

Your tool will need to ape this, using an appropriate relative path in the second entry.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

>will users...


Depends. Seen this doc dated today? https://support.apple.com/kb/DL1998?locale=en_US

I have a Swift command line tool embedded in a Swift application that is compiled to run on macOS 10.10 and later.

You’ve hit an interesting edge case. I suspect that there will be a nice solution to this problem (based on your tool using the runtime libraries built in to your app) but I’m not 100% sure that’s something we officially support. My recommendation:

  1. Ask over on Swift Forums. Someone over there might know the official story off the top of their head.

  2. If not, open a DTS tech support incident and DTS’s tools specialist can research this properly.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanks Quinn

For now I put up a dialog at application launch explaining to the user that they need to install the run-time library and giving them a button that will open their browser at the download site. Less than ideal solution but it does stop the issue from being a show-stopper.


I'm just checking to see if /usr/lib/swift is populated to determine if the libraries are installed before putting up the dialog. Maybe there is a better way of doing that.


Also - I have hard-coded the url for the download site - that will probably come back to bite me at some time.


Bryan

With help from user @bmodesitt in the Swift Forums I was able to get this working without the user having to manually install the runtime.


1. In the tool build settings, point "Runpath Search Paths" to @executable_path/../Frameworks/ (my tool is installed in the parent bundle at Contents/MacOS/)


2. Add /usr/lib/swift/libswiftSwiftOnoneSupport.dylib to the parent app Frameworks. I did this by opening a Finder window at /usr/lib/swift and dragging the dylib to the Frameworks group in the Xcode project.


3. I tested by building the app on 10.14.4, Xcode 10.2 and then running the built application on a macOS 10.12 (Sierra) virtual machine. No crashes reported.


Hope this helps someone else.

Accepted Answer

Earlier I wrote:

You’ve hit an interesting edge case.

I talked to folks internally and there’s a general consensus that resolving this edge case — as a reminder, we’re specifically referring to the problem where you’re shipping a GUI app with an embedded helper tool — by having the helper tool reference the host app’s Swift runtime is fine.

The one thing to watch out for is the rpath setup in your tool. You have to make sure that the tool’s rpath references

/usr/lib/swift
first and the embedded runtime second. That way, the tool will use the system runtime if it’s available, and then fallback to the embedded runtime.

For example, if you take Xcode 10.2, create a new Swift app, and then build it, the app’s rpath setup looks like this:

$ otool -l ***.app/Contents/MacOS/***
…
Load command 30
          cmd LC_RPATH
      cmdsize 32
         path /usr/lib/swift (offset 12)
Load command 31
          cmd LC_RPATH
      cmdsize 48
         path @executable_path/../Frameworks (offset 12)
…

Your tool will need to ape this, using an appropriate relative path in the second entry.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

>I was able to get this working without the user having to manually install the runtime.


Good info, thanks for the follow up and good luck w/your application.

You mentioned that it would be acceptable for an embedded helper tool to reference its host app's Swift runtime. What about a daemon that's included with an app?


In my case, the daemon is installed to /Library/LaunchDaemons, and its companion app is installed wherever the user chooses (/Applications would be traditional, but nothing prevents the user from putting it somewhere else). The daemon isn't embedded in its companion app, nor does the companion app have a guaranteed location in the filesystem.


The daemon and its companion app must support back to macOS 10.13. Would it be acceptable to include the Swift 5 runtime libraries from Apple's package here: https://support.apple.com/kb/DL1998?locale=en_US, inside the installer package for my own app? Otherwise, for users running versions of macOS prior to 10.14.4, they couldn't run my app and daemon without first installing the separate Swift 5 runtime package from Apple. I'm concerned that the installation experience will be poor, and hard to explain and support (instead of "just working" after they run my installer).


Thank you for any insight!

Swift 5 Runtime Support for Command Line Tools Package
 
 
Q