I'm trying to use an external framework with my Swift application for Mac OS X. The external framework also uses Swift, and so depends on the Swift shared libraries (for example, libswiftCore.dylib
). This is verified by the command
$ otool -L PromiseKit.framework/PromiseKit
PromiseKit.framework/PromiseKit:
...
@rpath/libswiftCore.dylib (compatibility version 0.0.0, current version 0.0.0)
Looking up @rpath
I see
$ otool -l PromiseKit.framework/PromiseKit
...
cmd LC_RPATH
cmdsize 40
path @executable_path/Frameworks (offset 12)
So at runtime I expect @rpath
to resolve to @executable_path/Frameworks
The problem
I get a runtime error
dyld: Library not loaded: @rpath/libswiftCore.dylib
Referenced from: .../PromiseKit.framework/Versions/A/PromiseKit
Reason: image not found
Looking in the folder containing my built executable, I don't see a Frameworks
folder.
Failed attempts to fix it
I tried setting EMBEDDED_CONTENT_CONTAINS_SWIFT
to YES
for my app, but this still doesn't create the Frameworks
folder.
I tried manually creating the Frameworks
folder and copying in the Swift shared libraries (from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx
. This fixes the original error, but now I see duplicate symbol warmings like this one:
objc[64445]: Class _TtC10Foundation15NSSimpleCString is implemented in both
.../Frameworks/libswiftFoundation.dylib and
.../myApp.
One of the two will be used. Which one is undefined.
Question
Is it possible that the Swift libraries are being statically linked into my application? If so how do I turn that off and have XCode create the Frameworks
folder version instead?
I think the important point is that it's a command-line app. I tried creating a regular app and adding the framework and I get the expected
Frameworks
folder within my.app
package and it contains the Swift shared libraries
I can get a swift command-line tool with or without an external framework working, as long as:
To get a Framework to copy the swift libraries, set:
To avoid a build failure when a tool tries to copy the swift libraries into its non-existent Bundle Frameworks directory, set:
To configure a tool's runpath, add one of the following to LD_RUNPATH_SEARCH_PATHS:
A. The swift libraries in the external framework:
Note that Xcode doesn't symlink Versions/A/Frameworks to Frameworks by default, like it does with Resources, Headers, and Modules.
B. The swift libraries in the Xcode app:
This only works with a sufficiently similar Xcode installed on each machine the executable needs to run on. But it doesn't require an external framework to get the tool to work.
C. The swift libraries redistributed in the same directory as the executable:
Or, if the executable is in a bin/ directory and the libraries are in a lib/ directory:
This can be redistributed, and doesn't require an external framework to get the tool to work. But it would require a manual copy files phase in Xcode to get the directory structure set up this way.
Note that if the tool is configured with:
Xcode throws the following build error: