6

SETUP:
OS X 10.8.2
Xcode4.5.2 (4G2008a)
Document-based Cocoa Application with a QuickLook PlugIn


PROBLEM:

I'm trying to add a QuickLook plugin to my Document-based OS X application, but the QL PlugIn will not launch.

My QuickLook PlugIn needs to embed and link to two Frameworks that I've created myself (Called IDEKit and TDAppKit). I've read this SO post about linking Frameworks in QuickLook PlugIns, and followed the instructions there (I set the DYLIB_INSTALL_NAME_BASE of my two Frameworks to @loader_path/../Frameworks).

Here's some relevant information about my QuickLook PlugIn after it is built:

% otool -L /Users/itod/Library/Developer/Xcode/DerivedData/Shapes-bqzarhutlkqukverhbjatfvaextg/Build/Products/Debug/Shapes.app/Contents/Library/QuickLook/ShapesQuickLook.qlgenerator/Contents/MacOS/ShapesQuickLook 
/Users/itod/Library/Developer/Xcode/DerivedData/Shapes-bqzarhutlkqukverhbjatfvaextg/Build/Products/Debug/Shapes.app/Contents/Library/QuickLook/ShapesQuickLook.qlgenerator/Contents/MacOS/ShapesQuickLook:
    /usr/lib/libcrypto.0.9.8.dylib (compatibility version 0.9.8, current version 47.0.0)
    @loader_path/../Frameworks/IDEKit.framework/Versions/A/IDEKit (compatibility version 1.0.0, current version 1.0.0)
    @loader_path/../Frameworks/TDAppKit.framework/Versions/A/TDAppKit (compatibility version 1.0.0, current version 1.0.0)
    /System/Library/Frameworks/QuickLook.framework/Versions/A/QuickLook (compatibility version 1.0.0, current version 555.4.0)
    /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility version 1.0.0, current version 275.0.0)
    /System/Library/Frameworks/Security.framework/Versions/A/Security (compatibility version 1.0.0, current version 55179.0.2)
    /System/Library/Frameworks/QuartzCore.framework/Versions/A/QuartzCore (compatibility version 1.2.0, current version 1.8.0)
    /System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa (compatibility version 1.0.0, current version 19.0.0)
    /System/Library/Frameworks/ApplicationServices.framework/Versions/A/ApplicationServices (compatibility version 1.0.0, current version 45.0.0)
    /System/Library/Frameworks/CoreServices.framework/Versions/A/CoreServices (compatibility version 1.0.0, current version 57.0.0)
    /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 744.1.0)
    /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (compatibility version 300.0.0, current version 945.11.0)
    /usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 169.3.0)
    /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit (compatibility version 45.0.0, current version 1187.33.0)

The linked/embedded Frameworks are in place:

% file /Users/itod/Library/Developer/Xcode/DerivedData/Shapes-bqzarhutlkqukverhbjatfvaextg/Build/Products/Debug/Shapes.app/Contents/Library/QuickLook/ShapesQuickLook.qlgenerator/Contents/MacOS/ShapesQuickLook 
/Users/itod/Library/Developer/Xcode/DerivedData/Shapes-bqzarhutlkqukverhbjatfvaextg/Build/Products/Debug/Shapes.app/Contents/Library/QuickLook/ShapesQuickLook.qlgenerator/Contents/MacOS/ShapesQuickLook: Mach-O universal binary with 2 architectures
/Users/itod/Library/Developer/Xcode/DerivedData/Shapes-bqzarhutlkqukverhbjatfvaextg/Build/Products/Debug/Shapes.app/Contents/Library/QuickLook/ShapesQuickLook.qlgenerator/Contents/MacOS/ShapesQuickLook (for architecture x86_64):    Mach-O 64-bit bundle x86_64
/Users/itod/Library/Developer/Xcode/DerivedData/Shapes-bqzarhutlkqukverhbjatfvaextg/Build/Products/Debug/Shapes.app/Contents/Library/QuickLook/ShapesQuickLook.qlgenerator/Contents/MacOS/ShapesQuickLook (for architecture i386):  Mach-O bundle i386
% file /Users/itod/Library/Developer/Xcode/DerivedData/Shapes-bqzarhutlkqukverhbjatfvaextg/Build/Products/Debug/Shapes.app/Contents/Library/QuickLook/ShapesQuickLook.qlgenerator/Contents/Frameworks/IDEKit.framework/IDEKit 
/Users/itod/Library/Developer/Xcode/DerivedData/Shapes-bqzarhutlkqukverhbjatfvaextg/Build/Products/Debug/Shapes.app/Contents/Library/QuickLook/ShapesQuickLook.qlgenerator/Contents/Frameworks/IDEKit.framework/IDEKit: Mach-O universal binary with 2 architectures
/Users/itod/Library/Developer/Xcode/DerivedData/Shapes-bqzarhutlkqukverhbjatfvaextg/Build/Products/Debug/Shapes.app/Contents/Library/QuickLook/ShapesQuickLook.qlgenerator/Contents/Frameworks/IDEKit.framework/IDEKit (for architecture x86_64):   Mach-O 64-bit dynamically linked shared library x86_64
/Users/itod/Library/Developer/Xcode/DerivedData/Shapes-bqzarhutlkqukverhbjatfvaextg/Build/Products/Debug/Shapes.app/Contents/Library/QuickLook/ShapesQuickLook.qlgenerator/Contents/Frameworks/IDEKit.framework/IDEKit (for architecture i386): Mach-O dynamically linked shared library i386
% file /Users/itod/Library/Developer/Xcode/DerivedData/Shapes-bqzarhutlkqukverhbjatfvaextg/Build/Products/Debug/Shapes.app/Contents/Library/QuickLook/ShapesQuickLook.qlgenerator/Contents/Frameworks/TDAppKit.framework/TDAppKit 
/Users/itod/Library/Developer/Xcode/DerivedData/Shapes-bqzarhutlkqukverhbjatfvaextg/Build/Products/Debug/Shapes.app/Contents/Library/QuickLook/ShapesQuickLook.qlgenerator/Contents/Frameworks/TDAppKit.framework/TDAppKit: Mach-O universal binary with 2 architectures
/Users/itod/Library/Developer/Xcode/DerivedData/Shapes-bqzarhutlkqukverhbjatfvaextg/Build/Products/Debug/Shapes.app/Contents/Library/QuickLook/ShapesQuickLook.qlgenerator/Contents/Frameworks/TDAppKit.framework/TDAppKit (for architecture x86_64):   Mach-O 64-bit dynamically linked shared library x86_64
/Users/itod/Library/Developer/Xcode/DerivedData/Shapes-bqzarhutlkqukverhbjatfvaextg/Build/Products/Debug/Shapes.app/Contents/Library/QuickLook/ShapesQuickLook.qlgenerator/Contents/Frameworks/TDAppKit.framework/TDAppKit (for architecture i386): Mach-O dynamically linked shared library i386

However, when I try to launch my QuickLook PlugIn using qlmanage and a test document, I get the following error:

dyld: DYLD_ environment variables being ignored because main executable (/System/Library/Frameworks/QuickLook.framework/Versions/A/Resources/quicklookd.app/Contents/MacOS/qlmanage) is code signed with entitlements
Testing Quick Look preview with files:
    /Users/itod/Desktop/test.shapes
[ERROR] Can't load plug-in at file://localhost/Users/itod/Library/Developer/Xcode/DerivedData/Shapes-bqzarhutlkqukverhbjatfvaextg/Build/Products/Debug/Shapes.app/Contents/Library/QuickLook/ShapesQuickLook.qlgenerator/: The bundle “ShapesQuickLook” couldn’t be loaded because it is damaged or missing necessary resources.

Note the:

The bundle “ShapesQuickLook” couldn’t be loaded because it is damaged or missing necessary resources.

I'm not certain that this issue is caused by a problem with embedded Frameworks (but I think it probably is).

What might I be missing? How can I get my QuickLook PlugIn to launch?

Community
  • 1
  • 1
Todd Ditchendorf
  • 11,217
  • 14
  • 69
  • 123

1 Answers1

5

OP here. I found the solution in this blog post about Dylibs, Install Names, and rpaths.

Specifically, the advice under the @rpath section worked for me.

So in my embedded frameworks, I set the DYLIB_INSTALL_NAME_BASE to be @rpath/.

Then I have an App and a QL PlugIn which each embed the frameworks:

In my Application target's build settings, I added the following Other Linker Flags: -rpath @executable_path/../Frameworks/.

And in my QuickLook Plugin target's build settings I added the following Other Linker Flags: -rpath @loader_path/../Frameworks/.

That solved the issue. Now the app and the QL PlugIn work correctly.

Todd Ditchendorf
  • 11,217
  • 14
  • 69
  • 123
  • the problem is that the executable name that one normally users really means the executable of the process and for your QL plugin that'd be quicklookd -- can't you se the loader path in both cases? – Daij-Djan Mar 03 '13 at 11:04
  • 1
    Yes, I understand the issue of the executable being different when my app is running vs when my QL plugin is running. But changing to `@loader_path` alone did not fix the issue. I'm not entirely sure why, but I have a theory. Basically: Not only does the Plugin link to both of these frameworks, but one of these frameworks is also linking to the other framework, further complicating matters. Using `@rpath` seems to allow them all to find each other. – Todd Ditchendorf Mar 03 '13 at 17:47
  • Awesome - same issue here, same steps worked for us as well!! – Jay May 02 '17 at 07:33
  • Additional great information to be found in http://www.dribin.org/dave/blog/archives/2009/11/15/rpath/ – Jay May 02 '17 at 07:43