Search code examples
objective-ccocoaframeworksdynamic-linkingquicklook

Linking Frameworks into QuickLook plugins


I am trying to write a QuickLook generator. For this, I need to link against a framework I created. However, as soon as I link against said framework, qlmanage refuses to load my plugin by telling me:

[ERROR] Can't load plug-in at /path/to/my-ql.qlgenerator: The bundle “my-ql” couldn’t be loaded because it is damaged or missing necessary resources.

I have read all the relevant tutorials on Linking, Frameworks and QuickLook but found no answer.

Things I have found out/ruled out so far

  • Architecture: when including the Framework as 32-bit binary, the entire linking process faults, so this does not seem to be the problem.
  • I have verified that the Framework gets copied into the plugin’s bundle under Contents/Frameworks.
  • The framework’s install path is set to @executable_path/../Frameworks

Also, when using the framework in another application, everything goes well. The only possible explanation I can fathom is as follows: When executing qlmanage, the @executable_path actually points to that binary and so my framework is never found. If this is the case, how must I set the install path to still allow a location relative to the plugin? I don’t want to install my framework globally.

EDIT

otool -L on the built QuickLook Plugin yields the following:

/System/Library/Frameworks/QuickLook.framework/Versions/A/QuickLook (compatibility version 1.0.0, current version 327.4.0)
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/ApplicationServices (compatibility version 1.0.0, current version 38.0.0)
/System/Library/Frameworks/CoreServices.framework/Versions/A/CoreServices (compatibility version 1.0.0, current version 44.0.0)
/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 550.29.0)
/System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa (compatibility version 1.0.0, current version 15.0.0)
@executable_path/../Frameworks/PESHandler.framework/Versions/A/PESHandler (compatibility version 1.0.0, current version 1.0.0) <== *this is my framework*
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.0)
/usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 227.0.0)

otool -D on my framework yields this:

@executable_path/../Frameworks/PESHandler.framework/Versions/A/PESHandler

The Framework does not require garbage collection.


Solution

  • @executable_path resolves against the main executable image for the process. That would be the quicklook daemon, not your plug-in. You should use @loader_path instead.

    Here's a blog post covering this.