Sharing swift runtime libraries

I have a Swift 3 application (macOS Sierra) that contains an embedded launch-helper application in its bundle. I wrote the helper in Swift 3 as well and now notice that my 30 line helper is using 8MB of disk, primarily due to it's embedded Swift runtime libraries.


Is there any supported way to have the helper link to the parent application runtime so that the parent and the helper are sharing a single copy of the Swift runtime. I figured I can play tricks with loader paths etc but don't want to go that route if its not supported.


Thanks

Bryan

Replies

It’s completely normal for embedded Swift code to use the Swift runtime from the app it’s embedded in. Indeed, this happens by default if you’re creating an app extension (

.appex
). To make this work you need to:
  1. Set Always Embed Swift Standard Libraries (

    ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES
    ) on the app.
  2. Clear Always Embed Swift Standard Libraries on the helper.

  3. Set Runpath Search Paths (

    LD_RUNPATH_SEARCH_PATHS
    ) on the helper to reference the location of the Swift standard libraries within the app.

    For a sandboxed login item within a Mac app, I think you’ll want

    @executable_path/../../../../Frameworks
    , but I may have counted the double dots wrong (I’m basing this on some recent experience with app extensions).

Share and Enjoy

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

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

I got the @executable_path working OK, but Always Embed Swift Standard Librariesis being ignored. It is defaulted to NO and setting/resetting it on the targets makes no difference - both targets are receiving a copy of the libraries.


In the build log for LaunchHelper (Always Embed is now set to NO) I see:

CopySwiftLibs /Users/bryan/Library/Developer/Xcode/DerivedData/MyApp-ahjuzftwvdgvyrazjorwycvnzxoz/Build/Products/Debug/LaunchHelper.app


Any clues as to what other switch(es) may be causing CopySwiftLibs to be triggered?


I'm running Xcode 8.1 on Sierra 10.12.1 and the application is being built for macOS.


Thanks

Bryan

Bummer. Thinking about this more, I’m pretty sure that Always Embed Swift Standard Libraries is the wrong option here. Sorry about the bum steer.

Any clues as to what other switch(es) may be causing CopySwiftLibs to be triggered?

No. My best guess at this point is that Xcode understands the difference between an app target and an extension target, and thus includes the Swift libraries in one but not the other. That’s pretty much what QA1881 says.

At this point I’m going to admit that I’m out of my depth )-: I recommend you open a DTS tech support incident and one of our Tools Guys™ can look into this.

If you do open a TSI for this please email me the follow-up number so that I can add my comments to the incident. My email address is in my signature.

Share and Enjoy

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

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

TSI submitted and I have emailed the details to you


Thanks

Bryan

Any resolution to this pending? It's not really a show-stopper except my app is 50% bigger than it need be.


Bryan

Any resolution to this pending?

I don’t comment about official DTS business here on DevForums but feel free to drop me a line at my individual email address (in my signature).

Share and Enjoy

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

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

I'm hitting, possibly, a related bug with Xcode 11.3.1: in my case swift libraries are not included. After checking the build log I found that CopySwiftLibs is executed with a bunch of --scan-executable and --scan-dir arguments. But this arguments miss the necessary path, in particular path to XPC services.


I checked release notes for newer versions of Xcode but have not found that issue being listed. Is there a known workaround?

As a workaround I explicitly set ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES to NO in the main app and added the following Run Script phase:


/usr/bin/xcrun swift-stdlib-tool \

--copy \

--verbose \

--sign ${EXPANDED_CODE_SIGN_IDENTITY} \

--scan-folder ${TARGET_BUILD_DIR}/${CONTENTS_FOLDER_PATH} \

--platform macosx \

--toolchain ${DT_TOOLCHAIN_DIR} \

--destination ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH} \

--strip-bitcode \

--strip-bitcode-tool ${DT_TOOLCHAIN_DIR}/usr/bin/bitcode_strip


with a single output file:


${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/libswiftCore.dylib