Operating system is MacOS X, specifically 10.5 (Leopard) on a PowerPC G4, but I have the same problem on an x86 running 10.6.
I am writing an application which dynamically loads a DLL. The DLL (let's call it foo.dylib
) is part of another application, located elsewhere on the harddisk; my application finds foo.dylib
programmatically (exact emplacement may change, possibly the user designates the DLL path through a GUI from the running application itself). For instance, assume that my application is located in directory /Application/MyApp.app/Contents/MacOS
, and foo.dylib
happens to be in /Application/OtherApp.app/Contents/MacOS
. DLL loading uses dlopen()
.
Now, it turns out that foo.dylib
itself needs a bunch of other DLL, which are in the same directory, but about which I do not know anything beforehand. Each such extra DLL is registered in foo.dylib
with a path such as @executable_path/bar.dylib
. The semantics of @executable_path
are that it should be replaced by the directory in which the current process executable was found. This works great for OtherApp, not for me: when I open foo.dylib
, it tries to load bar.dylib
, and it looks for it in /Application/MyApp.app/Contents/MacOS/bar.dylib
, which is not the right directory.
A workaround is to set the DYLD_FALLBACK_LIBRARY_PATH
environment variable to /Application/OtherApp.app/Contents/MacOS
, but this must be done before launching my application (that environment variable is read only once by the dynamic linker; changing its value programmatically with setenv()
or putenv()
has no effect). This is not compatible with the dynamic discovery of the location of the foo.dylib
file.
Is there a programmatic way to override the effect of @executable_path
?
dlopen
-ing the dependencies before the main library does not work: from the point of view of dyld,@executable_path/bar.dylib
and/Application/OtherApp.app/Contents/MacOS/bar.dylib
are not the same file (there is no concept of "SONAME" here; the path under which the DLL was searched serves as DLL name), so dyld refuses to use the manually loadedbar.dylib
(I have tried). – Persephone