[swift-users] How to build a CLI tool which links a Swift framework? (OSX)
razielim at gmail.com
Thu Aug 25 05:28:46 CDT 2016
I’ve got a cross-platform Swift framework which is used in a project, and I want to make a CLI tool which also uses it. I’m having a problem getting the framework and CLI tool to work together, because of the Swift standard libraries:
 If I just create a new CLI app and link it to my framework (setting rpath for the CLI app to “@executable_path” so it can find MyFramework sitting adjacent to it), the first error I receive is:
dyld: Library not loaded: @rpath/libswiftAppKit.dylib
Referenced from: /blah/<MyFramework>.framework/Versions/A/<MyFramework>
Reason: image not found
OK, that’s fair enough - the rpath is set to ../Frameworks (because <MyFramework> is assuming it will be embedded), but the CLI tool isn’t a package and can’t embed anything. So let’s help it by going to Xcode and selecting “Always Embed Swift Standard Libraries” for the framework.
 Now it can find the libraries, but the dynamic linker complains about duplicate definitions. The application doesn’t actually work because it trips up an assertion:
objc: Class _SwiftNativeNSDataBase is implemented in both /blah/<MyFramework>.framework/Versions/A/Frameworks/libswiftCore.dylib (0x109d7e488) and /blah/MyApp (0x109444350). One of the two will be used. Which one is undefined.
objc: Class _SwiftNativeNSCharacterSetBase is implemented in both /blah/<MyFramework>.framework/Versions/A/Frameworks/libswiftCore.dylib (0x109d7e4d8) and /blah/MyApp (0x1094443a0). One of the two will be used. Which one is undefined.
objc: Class _SwiftNativeNSIndexSetBase is implemented in both /blah/<MyFramework>.framework/Versions/A/Frameworks/libswiftCore.dylib (0x109d7e528) and /blah/MyApp (0x1094443f0). One of the two will be used. Which one is undefined.
Assertion failed: (registered == c && "objc_readClassPair failed to instantiate the class in-place"), function swift_instantiateObjCClass, file /Spring/Projects/3rdParty/OpenSource/Apple/swift/stdlib/public/runtime/SwiftObject.mm, line 1273.
So what I’d like to know is — is there a way for this to work?
The CLI app itself embeds the standard libraries, and the framework wants to dynamically link them. I can’t tell the framework not to dynamically load the libraries, and I also can’t make the framework in to a static library, because that’s not supported with Swift (yet?).
The only workaround I can think of is compiling the framework source files directly in to the CLI app. The downside is that it’s more work to manage and isn’t easily scalable to more CLI tools. Do we have anything better?
More information about the swift-users