简体   繁体   中英

Problem with Frameworks in Command Line Tool

Before everyone starts throwing other stack-overflow and forum posts at me: I looked at them all. None of them are helping.

I have a simple cmd tool called swizzler and want to embed the SwizzleSrc framework in it. I have followed all the tutorials and stack overflows with no luck. Here is what I am getting.

Build

2019-02-07 19:22:46.785680-0500 Terminal[67444:11837029] flock failed to lock maps file: errno = 35
2019-02-07 19:22:46.786939-0500 Terminal[67444:11837029] flock failed to lock maps file: errno = 35

Run

Last login: Thu Feb  7 19:21:08 on ttys018
NAME-iMac:~ NAME$ /Users/NAME/Library/Developer/Xcode/DerivedData/swizzler-aslysekmorknabdslxbxfaeuiztk/Build/Products/Debug/swizzler ; exit;
dyld: Library not loaded: @rpath/SwizzleSrc.framework/Versions/A/SwizzleSrc
  Referenced from: /Users/NAME/Library/Developer/Xcode/DerivedData/swizzler-aslysekmorknabdslxbxfaeuiztk/Build/Products/Debug/swizzler
  Reason: image not found
Abort trap: 6
logout
Saving session...
...copying shared history...
...saving history...truncating history files...
...completed.

[Process completed]

Can someone please help? I have been trying for days with no avail.

To fix your issue we need to change how Xcode handles Swift Command Line Tool targets by default, specifically the linking convention against the Swift standard libraries.

We need to:

  • embed the Swift standard libraries in your SwizzleSrc framework
  • force your swizzler command line executable to dynamically link all Swift libraries
  • finally, make sure your swizzler executable is then able to find all needed Swift libraries (now placed in the framework target)

Let's get started (assumes you are using Xcode 10.1 or above):

Embedding the Swift Libraries in the Framework

This is pretty straightforward. Change the following Build Settings for the SwizzleSrc framework target:

  • Always Embed Swift Standard Libraries to Yes

Dynamically Linking all Swift Libraries in the Command Line Tool

This is the somewhat tricky part. Add the following User-Defined settings for the swizzler tool target (in the Build Settings ):

  • SWIFT_FORCE_DYNAMIC_LINK_STDLIB set to YES
  • SWIFT_FORCE_STATIC_LINK_STDLIB set to NO

(To add a new User-Defined setting just click the + button just below the Build Settings tab title.)

This will ensure your command line executable will dynamically link all Swift libraries instead (ie, by default they are statically linked). By the way, these exact same settings are used by the Swift Package Manager to fix a related issue.

Update the Runpath for the Command Line Tool

Add the following Runpath Search Path entries for the swizzler tool target (in the Build Settings ):

  • @executable_path
  • @executable_path/SwizzleSrc.framework/Versions/Current/Frameworks

Now clean your build folder, rebuild again both targets, and check if this fixed your issue for good ;)

References

For further information, be sure to check the following links as well:

I also created a (very!) simple Xcode project demonstrating the steps above:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM