Tuesday, July 25, 2006

XCode - copying Dynamic Libraries into Applications

I'm working on a Mac OS X application which uses a dynamic library (dylib) I'm building. I'd been having a problem where the application would launch perfectly if I launched it from the XCode, but it would never launch from the Finder.

I had the dylib in a Copy Phase copying the .dylib file into the './Contents/MacOS' directory in the application package.

I was trying all sorts of things, including copying the built dynamic library into '/usr/local/lib' which worked, but then I realised that the library was not within the application package so it would not be transportable.

So ultimately I wanted the dynamic library (dylib) copied into the application package, resulting in a completely transportable application.

I then figured out why it wasn't working. It has all to do with the search paths that 'dyld' uses when the application is launched. When XCode launched the application, it launches it from the common build directory (which I had manually set), and consequently the dynamic library (dylib) was in the current directory. dyld found it easily.

When my application was launched from the Finder, the working directory was set to something else... i don't know what.. but it's different, and 'dyld' couldn't find my dynamic library (dylib). I could prove this by opening a Terminal window, and launching the application from different working directories. When i 'cd' to the build directory where the .dylib is built, it works, but from any other directory, it fails.

Then i discovered, an interesting article http://developer.apple.com/releasenotes/DeveloperTools/dyld.html and the little gem "@executable_path/". So here's the solution:

Go to the XCode project for the dynamic library (dylib) and set the "Installation Directory" to "@executable_path/". Then rebuild it. In the main application XCode project, make a "Copy Files" build phase which copies the dynamic library (dylib) into the "Executables" directory. Now regardless of what the current directory is, 'dyld' will always find the dylib because it looks in the same directory as the application's executable file.

I hope this saves someone a little bit of time. It bugged me for hours.

1 comment:

Andreas said...

Thanks a lot! Was a great help!