I'm writing a framework (called Lighthouse.framework) that, in turn, uses code from another framework (RegexKit.framework, to be precise). I have copied RegexKit.framework into my own framework, so that it has a structure like the following:
Lighthouse.framework/
Versions/
A/
Frameworks/
RegexKit.framework
Lighthouse
However, when I try to run an application that uses Lighthouse.framework (my framework), I get the following error:
dyld: Library not loaded: @executable_path/../Frameworks/RegexKit.framework/Versions/A/RegexKit
Referenced from: /Users/mdippery/Developer/Projects/Current/lighthouse/build/Debug/Lighthouse.framework/Versions/A/Lighthouse
Reason: image not found
Obviously, the loader isn't finding RegexKit.
Here're the paths the loader expects to load, courtesy otool
:
build/Debug/Lighthouse.framework/Versions/A/Lighthouse:
/Users/mdippery/Library/Frameworks/Lighthouse.framework/Versions/A/Lighthouse (compatibility version 1.0.0, current version 1.0.0)
/System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa (compatibility version 1.0.0, current version 12.0.0)
@executable_path/../Frameworks/RegexKit.framework/Versions/A/RegexKit (compatibility version 0.4.0, current version 0.6.0)
/usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 111.1.4)
/usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 227.0.0)
/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 476.19.0)
/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (compatibility version 300.0.0, current version 677.26.0)
Can I include a framework in another framework? Is this the proper way to do it? How can I resolve my error?
I discovered a fix for this problem. I incorporated some ideas from sbooth's answer, but the fix was simpler. I ran this script:
as a Run Build Script phase.
Note that, for the general case, you have to change
@executable_path/../
to@loader_path/
, and all is well.Yes, you can.
However, you need the included framework to "know" what its installed location will be at the time that it is built; otherwise,
dyld
won't be able to find it at run time, as you saw.The relevant settings in XCode, if I recall correctly, are "Installation Directory" and "Framework Install Name". The latter probably won't matter for your usage, but you're going to need the former to be something along the lines of:
@executable_path/../Frameworks/Lighthouse.framework/Versions/A/Frameworks/RegexKit.framework/Versions/A/
The easiest way is to use @rpath. Your configuration should look like:
Finally, any applications linking to Lighthouse.framework should set Runpath Search Paths to @loader_path/../Frameworks