Update on more geekery...
Oct. 24th, 2007 10:11 pmReferencing previous geeky post on porting Linux app to MacOS X...
So it turns out that the solution was much simpler than I originally thought - a few dead ends later, (there's a ton of crap in the MacOS X linker system for supporting legacy stuff - and the legacy and current mechanisms aren't very well pointed out in the documentation, the bastards) it finally gelled, at least for our case.
When building the lowest-most dynamic library, pass the linker -install_path @executable_path/relative/path/to/library - this sets up the library to be 'portable', as long as the relative path between it and the executable is maintained. This isn't as weird as it seems - MacOS X uses bundles for those .app applications you see, and internally, there's a fixed relation between the binary and the libraries. (It also makes sense for most CLI tools, but I don't feel like enumerating the possibilities.)
Do the same for dylibs that rely on the first one, but also pass them -Wl,-executable_path,/where/you/expect/to/build/the/bin/for/now so that the static linker has a value for @executable_path that it can use to reference into the lower dylibs. You can move the binary and libraries later all you want, as long as you keep the relative path between them, but this just gives it *something* to work with during this point.
When building the binary, give it -undefined dynamic_lookup, so that symbols that aren't immediately statically linkable will be deferred to runtime.
See? Geeky.
So it turns out that the solution was much simpler than I originally thought - a few dead ends later, (there's a ton of crap in the MacOS X linker system for supporting legacy stuff - and the legacy and current mechanisms aren't very well pointed out in the documentation, the bastards) it finally gelled, at least for our case.
When building the lowest-most dynamic library, pass the linker -install_path @executable_path/relative/path/to/library - this sets up the library to be 'portable', as long as the relative path between it and the executable is maintained. This isn't as weird as it seems - MacOS X uses bundles for those .app applications you see, and internally, there's a fixed relation between the binary and the libraries. (It also makes sense for most CLI tools, but I don't feel like enumerating the possibilities.)
Do the same for dylibs that rely on the first one, but also pass them -Wl,-executable_path,/where/you/expect/to/build/the/bin/for/now so that the static linker has a value for @executable_path that it can use to reference into the lower dylibs. You can move the binary and libraries later all you want, as long as you keep the relative path between them, but this just gives it *something* to work with during this point.
When building the binary, give it -undefined dynamic_lookup, so that symbols that aren't immediately statically linkable will be deferred to runtime.
See? Geeky.