Alec
Alec

Reputation: 92

Distribute mac application with third-party frameworks (Xcode 4)

I've done a lot of research over the last two days, and I must have read through at least 20 successfully answered questions on this website alone. None of the solutions seem to work for me. I'm using five frameworks in my application, and I have no problem running it on my computer. When I try to run the application on another computer I get an error loading the libraries.

Exception Type:  EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x0000000000000002, 0x0000000000000000

Application Specific Information:
dyld: launch, loading dependent libraries

Dyld Error Message:
  Library not loaded: /Users/USER/*/Allegro-5.0.framework/Versions/5.0.7/Allegro-5.0
  Referenced from: /Volumes/VOLUME/Pong.app/Contents/MacOS/../Frameworks/AllegroMain-5.0.framework/AllegroMain-5.0
  Reason: image not found

I've done these steps:

It looks like dyld successfully loads the first framework (Allegro-5.0) but thinks it hasn't when it tries to load the second framework (AllegroMain-5.0)

Additional information:

What my the contents folder of my application bundle looks like: Contents Screenshot

My link binary with libraries and copy files build phases: Xcode screenshot

I'm not positive that I'm right about the cause of the error. I already appealed for help at allegro.cc but was basically told that they can't help me with a framework specific problem. I'd really appreciate any help with figuring this out!

EDIT

I'm not sure if this matters but I thought about it a bit more and there may be a problem with my header search paths. For the application to run, I have to create a new header search path for each framework. I have these five separate header search paths currently set:

 /Library/Frameworks/Allegro-5.0.framework/Versions/Current/Headers
 /Library/Frameworks/AllegroMain-5.0.framework/Versions/Current/Headers
 /Library/Frameworks/AllegroDialog-5.0.framework/Versions/Current/Headers
 /Library/Frameworks/AllegroFont-5.0.framework/Versions/Current/Headers
 /Library/Frameworks/AllegroTTF-5.0.framework/Versions/Current/Headers

I'm unsure of exactly how runpath search path works; will it allow the code to find my headers? The error message doesn't seem like the problem is related to this, but this was another thought that occurred to me.

UPDATE 4/14

Something I did messed something up, because I started getting strange behavior even on my computer. I reinstalled the frameworks, and I'm getting a new error.

Exception Type:  EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x0000000000000002, 0x0000000000000000

Application Specific Information:
dyld: launch, loading dependent libraries

Dyld Error Message:
  Library not loaded: /opt/local/lib/libfreetype.6.dylib
  Referenced from: /Volumes/VOLUME/Pong.app/Contents/MacOS/../Frameworks/AllegroTTF-5.0.framework/Versions/5.0.10/AllegroTTF-5.0
  Reason: image not found

My question is more general now: If I bundle libfreetype with my application, how can I tell the framework where to find it?

Upvotes: 3

Views: 1264

Answers (2)

Alec
Alec

Reputation: 92

Aha, my application now runs on other computers! Here are the steps I took that solved my problem.

  • Tried changing the install_name for the frameworks, but I didn't have a clear understanding of what I was doing, so I must have messed something up.
  • Reinstalled all frameworks to get a clean start.
  • This time, I very carefully changed the install_name of each framework using

sudo install_name_tool -id [install_name] [path/to/framework]

  • At this point, all the frameworks were successfully loaded, but they still tried to find their dependencies in /opt/local/lib
  • I added the dependencies to the copy files build phase in order to include them in the application bundle
  • Finally, I used install name tool again to change the search path for the dependencies.

sudo install_name_tool -change [/old/path/to/library] [/new/path/to/library] [path/to/dependent/framework]

eg: For the libfreetype.6.dylib dependency that caused the last error in my original question, I used the following terminal command.

sudo install_name_tool -change /opt/local/lib/libfreetype.6.dylib @executable_path/../Frameworks/libfreetype.6.dylib /Library/Frameworks/AllegroTTF-5.0.framework/Versions/5.0.10/AllegroTTF-5.0


From what I understand, most of my problems were cause by me trying to blindly follow the terminal commands given in answer to similar, but slightly different problems.

Actually reading some documentation proved to be the key to figuring this out, and I now know quite a bit more about how frameworks and libraries work than I did before attempting to distribute my application.

Thank you, Stack Overflow.

Upvotes: 1

Shiva
Shiva

Reputation: 176

You need to change the install path in frameworks that cross reference other frameworks.

In this case you need to change install path of "/Users/USER/*/Allegro-5.0.framework/Versions/5.0.7/Allegro-5.0" in AllegroMain-5.0.framework to "@executable_path/../Frameworks/Allegro-5.0.framework/Versions/5.0.7/Allegro-5.0".

I ran into similar issue while packaging a application build with Qt.

example : QtGui.framework references QtCore.framework.

name_tool="/Applications/Xcode.app/Contents/Developer/usr/bin/install_Name_tool"
cd "$APPNAME.app/Contents"

$name_tool -change /Users/USERNAME/QtSDK/Desktop/Qt/474/gcc/lib/QtCore.framework/Versions/4/QtCore @executable_path/../Frameworks/QtCore.framework/Versions/4/QtCore ./Frameworks/QtGui.framework/Versions/4/QtGui

Upvotes: 0

Related Questions