Sparkle framework fails to load inside iPhoto plugin

Asked by Pegolon

When I try to start my iPhoto plugin it crashes with the following trace:
2008-06-23 13:19:18.902 iPhoto[29168:813]
  Error loading /Applications/iPhoto.app/Contents/PlugIns/iPhotoExporter/Contents/MacOS/Exporter:
    dlopen(/Applications/iPhoto.app/Contents/PlugIns/Exporter.iPhotoExporter/Contents/MacOS/Exporter, 265):
    Library not loaded: @executable_path/../Frameworks/Sparkle.framework/Versions/A/Sparkle
  Referenced from: /Applications/iPhoto.app/Contents/PlugIns/iPhotoExporter/Contents/MacOS/Exporter
  Reason: image not found
2008-06-23 13:19:18.903 iPhoto[29168:813] Not a valid plugin: /Applications/iPhoto.app/Contents/PlugIns/iPhotoExporter

The referenced framework is the bundle subdirectory Frameworks/Sparkle.framework/Versions/A, so the "Copy File" task works ok.

Environment: Mac OS X 10.5.3, XCode 3.1, Sparkle 1.5b1 without GC, 10.4 compliant universal target.

Question information

Language:
English Edit question
Status:
Answered
For:
Sparkle Edit question
Assignee:
No assignee Edit question
Last query:
Last reply:
Revision history for this message
Andy Matuschak (andymatuschak) said :
#1

This is a really weird problem with embedded frameworks on OS X. When you build the framework, you have to tell it where it's going to be relative to the executable using the installation path. Normally, one uses something like @executable_path/../Frameworks, but for a plugin, that's obviously going to be incorrect.

Update the Sparkle framework target's installation path to be appropriate to your app, then it should work just fine.

Revision history for this message
iKenndac (danielkennett) said :
#2

I'd not sure I'd go as far as saying it's a problem - much less weird. @executable_path is a macro that returns the app that the bundle is running under.

To make Sparkle work in bundles, set the installation path to: @loader_path/../Frameworks

This will make it work in applications, bundles, frameworks, etc.

Revision history for this message
Peter Speck (speck) said :
#3

A fix is to add a "Run Script" build phase with:

install_name_tool -change \
 "@executable_path/../Frameworks/Sparkle.framework/Versions/A/Sparkle" \
 "@loader_path/../Frameworks/Sparkle.framework/Versions/A/Sparkle" \
 "$INSTALL_PATH/$EXECUTABLE_PATH"

I'm using this for a System Preferences Panel which technically is a plugin to the System Preferences application.

Revision history for this message
tornado (joe-flexgames) said :
#4

Thanks for the heads up on this. I have Sparkle.framework in my Copy Bundle Resources phase for my System Preference (per the other thread you commented on). When I create this run script you pasted above, I get the following error when running the System Preference:

7/27/08 1:28:24 AM System Preferences[10613] Error loading /Users/tornado/Library/PreferencePanes/FlexCal.prefPane/Contents/MacOS/FlexCal: dlopen(/Users/tornado/Library/PreferencePanes/FlexCal.prefPane/Contents/MacOS/FlexCal, 265): Library not loaded: @executable_path/../Frameworks/Sparkle.framework/Versions/A/Sparkle
  Referenced from: /Users/tornado/Library/PreferencePanes/FlexCal.prefPane/Contents/MacOS/FlexCal
  Reason: image not found

When I open my Sys pref Package, my executable is of course in the MacOS folder. Shouldn't the @executable_path you set above instead be

 "@executable_path/../Resources/Sparkle.framework/Versions/A/Sparkle" \

(as that is where the Sparkle Framework lives in my package). Regardless I still get the same error above when I have it like yours or with my modification above. Any thoughts? Thanks.

Revision history for this message
Peter Speck (speck) said :
#5

tornado:

Instead of adding Sparkle to the "Copy Bundle Resources" build phase, you should create a "Copy Files" build phase and set the destination popup to "FrameWorks" (get info for the phase). This makes Sparkle.framework go into a "Frameworks" folder instead of the "Resources" folder.

The "Copy Files" phase must come before the "Run Script" phase from the previous comment.

The "@executable_path" macro expands to the path of the application's (i.e. System Preferences.app) executable and not yours, as the linker regards it as a shared library and not an executable. Therefore, the macro used to point to the sparkle framework must be @loader_path as this is relative to your bundle and not the application bundle.

You can verify which macro is used by running
otool -L path/to/your/Contents/MacOS/file

The "install_name_tool ..." command should have changed it from @executable_path to @loader_path

Revision history for this message
tornado (joe-flexgames) said :
#6

(!) It worked (!) Thank you so much for the clarification!

-Joe

P.S. Since you've written a System Preference with Sparkle integration, do you have any idea about my question about notification (I need to kill a bg process before sparkle relaunches my new system pref after it updates). The thread # is 37318. Again, thank you for the help on this Copy Files issue.

Revision history for this message
tornado (joe-flexgames) said :
#7

I think I spoke too quickly here Peter. I had it working but I've found that when I do NOT have my System Preference already in the ~/Library/System Preferences folder, I get this error when I'm building in Xcode:

Running custom shell script (1 error)
install_name_tool: can't open file: /Users/tornado/Library/PreferencePanes/FlexCal.prefPane/Contents/MacOS/FlexCal (No such file or directory)

Is there a reason that Xcode would look to /Users/tornado/Library/PreferencePanes/

during this phase?

Thanks.

Joe

Revision history for this message
lid (lid) said :
#8

Thanks for the solution Peter! I never knew about install_name_tool...

Revision history for this message
Peter Speck (speck) said :
#9

tornado: it sounds like the "Run Script" phase comes before the "Link Binary" phase. Try dragging it to the end so it's the last phase.
I presume the prefs panel do get installed without futher ado as /Users/tornado/Library/PreferencePanes/FlexCal.prefPane when you build in Xcode?

Revision history for this message
tornado (joe-flexgames) said :
#10

I figured it out. I had the phases in corrector order. It was the following that was making it look to the $INSTALL_PATH /$EXECUTABLE_PATH variable that was making it look to ~/Library/PreferencePanes directory. I switched it to $BUILT_PRODUCTS_DIR/$EXECUTABLE_PATH and all is good.

Take care.

Can you help with this problem?

Provide an answer of your own, or ask Pegolon for more information if necessary.

To post a message you must log in.