• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: location of frameworks at runtime
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: location of frameworks at runtime


  • Subject: Re: location of frameworks at runtime
  • From: Jim Ingham <email@hidden>
  • Date: Sat, 6 Dec 2003 20:41:35 -0800

On Dec 6, 2003, at 5:32 PM, Chris Hanson wrote:

On Dec 6, 2003, at 5:34 AM, Olof Hellman wrote:
If I put the framework inside the application bundle in the Frameworks directory at .../myApp.app/Contents/Frameworks/ the app won't launch -- I get a ' can't open library: /Library/Frameworks/myApp.framework/Versions/A/myApp ' message in the console

This is due to a Mach-O design flaw whereby a framework or other shared/dynamic library has its intended installation path embedded within it and any libraries that link against it. This is unlike a more modern executable format like PEF, which only embeds a library name or identifier, and searches a well-defined set of locations in a well-defined sequence to find a library by name at load time.

This isn't entirely correct. In fact, with one small addition, Mach-O (or really dyld since this has mostly to do with loader conventions and not object file formats) behaves pretty much as you describe "more modern executable formats" to do.


The Mach-O library has a path embedded in it, which serves two purposes. First it specifies one specific install location of the file which is independent of any conventions of the loader. So when other binaries (executable or libraries) link against a given library, they will preferentially load the library from the file given by that path. Second, if the library can't be found in the install location, the path serves to provide the library name (which the loader gets by extracting the filename component of the path), and then the loader searches along a well defined set of locations in a well defined sequence for a library of that name. This search path is, by default:

$(HOME)/Library/Frameworks:/Library/Frameworks:/Network/Library/ Frameworks:/System/Library/Frameworks

but you can override the default path by setting the DYLD_FRAMEWORK_FALLBACK_PATH if you want to, or prepend a set of locations to the search by setting DYLD_FRAMEWORK_PATH (this latter is the more usual way to adjust the search).

So with the ADDITION of the ability to specify one location outside the search path, Mach-O works substantially like the Classic Mac OS Loader (for instance)... It is interesting to note that with the Classic Mac OS loader, you could specify one 'alis' resource which gave an additional place to look for libraries outside the loader's conventions. So you can in fact get the two to be very similar.

The System Essentials guide or the dyld man page describe this behavior in detail if you are interested...

One difference, however, is that the Classic Mac OS loader included the executable directory as one of the elements of the search path, whereas DYLD does not include that or the Framework directory within the executable's bundle in the search path. That is why Olaf's example doesn't work without some intervention. Note that this has nothing to do with Mach-O vrs. any other object format, it just has to do with with details of the search conventions of the loader.

As Chris rightly pointed out, if you want to point to an executable that is not on the standard Framework path (including within the executable bundle), you need to use the additional capabilities of the Mach-O loader, and give "@executable_path..." as the explicit link address.

The reason this works in Xcode without this intervention is that Xcode sets the DYLD_FRAMEWORK_PATH environment variable to point to the build location of frameworks in your project, both when you run your app in Xcode, and run it under the debugger. You can do this yourself when you are test-running your app, for instance by running it from Terminal with the DYLD_FRAMEWORK_PATH environment variable set.

Note also that there was a bug in gdb in the releases before Panther that caused gdb to not find the library if it was specified with "@executable_path" but not actually copied into place. This bug was fixed in Panther, so you shouldn't have to do this copy for your development builds, though of course you will need to for the deployment build...

Hope this helps,

Jim
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
Jim Ingham email@hidden
Developer Tools - gdb
_______________________________________________
xcode-users mailing list | email@hidden
Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/xcode-users
Do not post admin requests to the list. They will be ignored.

References: 
 >location of frameworks at runtime (From: Olof Hellman <email@hidden>)
 >Re: location of frameworks at runtime (From: Chris Hanson <email@hidden>)

  • Prev by Date: Re: Preventing DebugStr() Breaks
  • Next by Date: Errors Using Framework-style Rez Includes
  • Previous by thread: Re: location of frameworks at runtime
  • Next by thread: extensions for dynamic library
  • Index(es):
    • Date
    • Thread