Mac OS X and the Dylib Workaround

Comes time, comes a Mac related post. On the Mac, application bundles are used to hide all the files of a program. If you ask me, I’d say it’s paternalism, but as I’m a programmer it’s better not to ask me. Anyway, there is the Info.plist file inside of the application bundle that can be used to set a few variables as well as the executable for the application.

Games, in general, use a lot of third-party libraries for a lot of different things. Some are linked statically whereas others are linked dynamically. So when you are shipping a game, you have to pack all the dynamic libraries into the release, because they do not exist on the gamers’ machines. The game itself must be able to find and load these libraries at startup. That is why there is an environment variable called DYLD_LIBRARY_PATH that points to the directory/directories where the dylibs are located. It is possible to set application specific enviroment variables in the Info.plist file by adding a dictionary item called LSEnvironment to which the variables are added to as children.

Oh great, you think once you’ve discovered that option, but now comes the rather tricky part. If you want to put the libraries somewhere inside your application bundle, the first thought is to set the DYLD_LIBRARY_PATH to a relative path, like ../Frameworks or ../Resources

That does not work. If you are launching the application through Finder, the working directory you get is neither the application bundle directory nor the directory of your executable inside the application bundle, but simply /

Really strange, and I don’t know of any reason why they implemented it that way. So if you set the absolute path to your dylibs, it works, but if you try to set a relative one, it does not work out of the box. So I was thinking of a work around and wrote a small shell script to get the correct working directory, set the dylib path and then launch the application.

[code]
#!/bin/sh

working_dir=”${0%/*}”
echo “working directory: $working_dir”
export DYLD_LIBRARY_PATH=”${DYLD_LIBRARY_PATH}”:$working_dir/../Resources
executable=${working_dir}/your_executable_name
echo “executable: $executable”
“$executable”
[/code]

Note that I’m launching the application using the quoted “$executable” to avoid problems with spaces in the launch path.