|
RpathSaver
Demonstration of using @rpath in a framework's install path.
BackgroundI wrote a couple of blog entires at http://setdoggedly.blogspot.com about my troubles with frameworks. My problem seems unusual but it might be familiar to plugin writers. I found that I couldn't link to a private framework from both a plugin and from one of the plugin's frameworks. However, in !MacOS X 10.5 (Leopard), new features have been added to ld, the linker used at compile time, and dyld, the dynamic linker used at run time, to add arbitrary freedom in specifying the installed path of dynamically linked libraries. @rpathThe solution is elegant. Instead of requiring a framework or dylib to have an install location relative to @loader_path, the path of the code requiring the framework to be loaded, or @executable_path, the path of the main executable, they can now have an install location relative to @rpath, the "run path" specified in the code requiring the framework to be loaded. This is explained pretty well in the Release Notes. The process of using @rpath requires two steps.
And that's it. It's pretty easy and almost limitless in flexibility. ExampleEverything is simpler with an example. Here's the scenario: I want to write a screen saver plugin called RpathSaver.saver that uses a framework called LevelTwo.framework. The plugin and the framework require loading a second framework called LevelOne.framework. I can't use an install path relative to the @executable_path, since that would require installing the screen saver plugin is in a known location (i.e. /System/Library/Screen Savers/. Bad form. I can't use an install path relative to the @loader_path since both the plugin and the framework are loaders of LevelOne.framework. It seems I have three bad options.
But in Mac OS X 10.5, I can use the @rpath in the install path, and everything sorts itself out. Here's the solution:
I'm enclosing the sample code below. It is the screen saver code that I discuss above. It simply displays some text from LevelOne.framework and LevelTwo.framework, which in turn uses LevelOne.framework to generate its own text. I hope you find it useful. |
RpathSaver.saver