so first off, I want to say that this question:
Bundle framework with application in XCode
and this question:
OSX: changing path of .framework
were both extremely helpful getting me up to this point, but I'm still not quite there.
So, like both the Original Posters for the two previous questions, I'm trying to embed a framework inside my app bundle. Or, rather, the issue is that I'm trying to embed MULTIPLE frameworks in my app bundle, some of which depend on eachother. I believe that even though my application can successfully find the frameworks (i've changed the install directory so the frameworks know where they are), the ones that reference each other are still looking for the frameworks to be installed in the normal ~/Library/Frameworks directory.
This is the output I'm getting when trying to run my app:
Dyld Error Message:
Library not loaded: #rpath/SDL.framework/Versions/A/SDL
Referenced from: /Users/Daly/Library/Developer/Xcode/DerivedData/Coin_Checkers_2-cibyiolfgsmcicdrcfxufftxzbsk/Build/Products/Debug/Coin Checkers 2.app/Contents/MacOS/../Frameworks/SDL_image.framework/SDL_image
Reason: image not found
Binary Images:
0x7fff5fc00000 - 0x7fff5fc3be0f dyld 132.1 (???) <29DECB19-0193-2575-D838-CF743F0400B2> /usr/lib/dyld
It seems to me that It's correctly loading SDL_image, but failing when SDL_image references SDL. Is there any similar trick I can use to direct the SDL_image framework to the correct location for my embedded SDL framework?
Thanks a bunch!
Oh, never mind. I hadn't seen this question until it showed up in the related section on the side:
Embedding frameworks in a Mac App Bundle
Apparently all I needed to do was set the runpath searchpath, and that solved all my problems. I had tried setting the Frameworks search path, but that didn't seem to help.
In fact, I redownloaded the frameworks to see if the install_name_tool steps were even necessary, and it seems they are not. they worked without it. Interesting.
Related
I've been banging my head against the wall on this for hours. I've been playing around with CMUSphinx's pocketsphinx library, running on OSX 10.10/XCode 7.2,and want to get my .app bundle to work on computers besides my own. Most importantly, there are three dynamic libraries that have to be embedded in the .app bundle(libpocketsphinx.3.dylib, libsphinxad.3.dylib, and libsphinxbase.3.dylib), and then loaded using Runpath Search Paths settings in XCode.
I've read just about everything I can find on how to get this to work. I should note that the .app bundle compiles/runs as intended on my own machine. I've made sure that the libraries are copied into the .app bundle's /Contents/Frameworks folder. The libraries are not using references, but are copied into my source folder (as per a forum post on this exact issue on CMUSphinx's page). I've tried just about every combination of using install_name_tool for #rpath/libraryname.dylib, as well as #loader_path and #executable_path in both the executable (so changing it in XCode to #whatever_path/../Frameworks), as well as the three library files. I also have tried #loader_path/Frameworks per another post here, but no luck.
Whats weird is the error I'm getting seems like it is loading libsphinxad.3.dylib, as both libsphinxad.3.dylib and libsphinxad.3.dylib rely on libsphinxbase.3.dylib, but I get this error in the crash report:
Dyld Error Message:
Library not loaded: /usr/local/lib/libsphinxbase.3.dylib
Referenced from: /Volumes/SunGate/VoiceCommander.app/Contents/Frameworks/libsphinxad.3.dylib
Reason: image not found
Note, the /Volumes/SunGate/ is just a drive on another machine I'm testing this on.
I would really appreciate help with this! I will do my best to provide any other information that might help solve this!
I found this lib by using the "find" command on my system. Not surprisingly it was here
sphinxbase/src/libsphinxbase/.libs/libsphinxbase.3.dylib
I linked it to /usr/local/lib/
ln -s sphinxbase/src/libsphinxbase/.libs/libsphinxbase.3.dylib /usr/local/lib/libsphinxbase.3.dylib
And all set to go!
So I followed this tutorial:
http://locomoviles.com/ios-tutorials/create-ios-cocoa-touch-framework-using-xcode/
Everything went fine except when I went to run the program I got the following error:
> dyld: Library not loaded:
> #rpath/SwiftFramework.framework/SwiftFramework Referenced from:
> /Users/bluke/Library/Developer/CoreSimulator/Devices/40677D10-F22B-4AE4-B767-06439AB7887A/data/Containers/Bundle/Application/8C6A5F76-C666-4B69-9353-A0ABD7DA085B/UseFramework.app/UseFramework
> Reason: image not found
I was able to solve this problem by adding the framework as an embedded binary, but I don't understand why this was needed to solve the problem.
I thought that the framework would be included in my application bundle as a dynamically linked library (i.e. not embedded in my application's binary directly) and then linked at run time. Is this assumption incorrect?
Just in case my question was unclear, I've added the following pictures.
This is what was producing the error:
If I add the framework to the embedded binaries it works:
I thought that the framework would be included in my application
bundle as a dynamically linked library (i.e. not embedded in my
application's binary directly) and then linked at run time. Is this
assumption incorrect?
Yes, it's incorrect. iOS apps link 3rd party frameworks statically, not dynamically. This prevents apps from downloading and dynamically linking code that hasn't been vetted by the app store review process.
This allows apps coded in Swift to run on devices running a version of iOS pre-dating Swift (earlier than iOS8).
Non-Apple frameworks can be embedded on iOS8 and above only.
It is also nice to add a prefix the the name identifying the developer organization so as to avoid comflicts and confusion. "SwiftFramework" looks so much like an Apple framework.
I have little to no knowledge about linking and referencing files/resources when it comes to compiled languages (I'm a Ruby programmer).
I'm trying my best using general tutorials on "how to add a framework to XCode 4 project", but I'm having a rough time trying to understand how am I supposed to do this, as everything I do fails in the end.
I've simply created a new cocoa application, went to build phases / Link Binary With Libraries and added Gosu.framework there. I didn't do anything else.
Now when I try to run the application, I get this error:
dyld: Library not loaded: #executable_path/../Frameworks/Gosu.framework/Versions/A/Gosu
Referenced from: /Users/ellmo/Library/Developer/Xcode/DerivedData/gosuTest-hkmqdspnwjepredgslldpnmuhlvx/Build/Products/Debug/gosuTest.app/Contents/MacOS/gosuTest
Reason: image not found
What should I do?
I have created a Mac app which uses the RMSharedPreferences framework. When opening the app, it immediately crashes and I get the following error:
Dyld Error Message:
Library not loaded: #rpath/RMSharedPreferences.framework/Versions/A/RMSharedPreferences
Referenced from: /Users/USER/Desktop/MyApp.app/Contents/MacOS/MyApp
Reason: image not found
It seems that it can't find the framework. I have tried adding a copy files phase to the target which should copy the framework and when browsing the contents of the app in Finder, it seems that it is copied correctly.
Does anyone know what might cause this error?
EDIT: Setting the framework to optional does make the application launch without any errors but the application does not fully work. Any RMSharedPreferences related calls will be ignored.
Since you are bundling the framework with your app, you should set the framework's install location. You can set that in your framework target build setting "installation location". Use something like:
#executable_path
You could also use a separate folder for your frameworks, then you would use:
#executable_path/../Frameworks/
In case you can't rebuild the framework (which is not yours, but I am saying in general), you can modify a prebuilt framework installation path like this:
install_name_tool -id #executable_path/../Frameworks/<framework_name> <your_framework>
Here you can find a reference for this.
If you are going to bundle a framework inside another framework, you can use #loader_path instead of #executable_path.
#rpath is a more flexible keyword, and its use is recommended.
The better way to do this is to set the "Runpath Search Paths" build setting in Xcode.
This avoids the need for an additional build phase script to modify the framework.
For instance, in your situation, you could set "Runpath Search Paths" to
#executable_path/../Frameworks
or
#loader_path/../Frameworks
if you're trying to load the framework from within a framework.
I have an Xcode 4 project, a Cocoa application with Spotlight, Core Data and unit tests. The app uses a custom framework named TBPluginManager I wrote to load bundles. I originally wrote the framework in Xcode 3 but when I used it in Xcode 4 GDB kept complaining, so I recreated the framework in Xcode 4. This made GDB happy, until I tried to run the built-in unit-test and got:
[Switching to process 3840 thread 0x0]
dyld: Library not loaded: > Library/Frameworks/TBPluginManager.framework/Versions/A/TBPluginManager
Referenced from: /Users/elise/Library/Developer/Xcode/DerivedData/BookManager-cooglmktssmptpatjuetculukiqd/Build/Products/Release/BookManager.app/Contents/MacOS/BookManager
Reason: image not found
sharedlibrary apply-load-rules all
No memory available to program now: unsafe to call malloc
Now I can understand why the unit test cannot find the framework since it lives not at Library/Frameworks/TBPluginManager.framework but at /Library/Frameworks/TBPluginManager.framework. But how do I tell that to the unit-test bundle? I've tried setting the Framework, Header and Library Search path build setting, but to no avail.
BTW, I've gone back to GHUnit but I'd like to get this working as well.
FOLLOW-UP: Much as it bugs me that Grady Player got an account just to tell me that I'm an idiot, it just may be that he or she is right. My lovely, dependable framework is generating warnings and errors like they're going out of fashion and so I've turned the problem over to Apple Developer Technical Support. If anything interesting comes out of it, I'll post it here. Otherwise, I'll delete the question.
make sure that the framework installed at /Library/Frameworks/TBPluginManager.framework is valid and the same arch as you are trying to link it to. If you are in doubt recompile the framework again, put it in a custom location and set that custom location in your framework search path.