Re: -rpath unrecognised by linker
Re: -rpath unrecognised by linker
- Subject: Re: -rpath unrecognised by linker
- From: "Peter O'Gorman" <email@hidden>
- Date: Sun, 12 Nov 2006 00:55:10 +0900
On Nov 11, 2006, at 9:56 PM, Jonas Maebe wrote:
On 11 Nov 2006, at 13:44, Alan Fry wrote:
The result of this is the binaries in '/usr/local/netpbm/bin' look
for the 'dylib' at the top level instead of '/usr/local/netpbm'.
man install_name_tool
On Mac OS X, a library's location isn't stored in the binary (so no
-rpath), but in the library itself. And although this has been
discussed at large in the past, I still don't understand the use of
that (I do understand the use of not storing the library's location
in the binary, but I do not understand why it is useful to limit a
library to working only when it's installed in a particular location).
rpath support is documented as a missing feature in the tiger dyld
release note, however I'll outline current behavior:
Let's make a library - libfoo.dylib:
$ touch foo.c
$ cc -o libfoo.dylib -dynamiclib -install_name /opt/foo/libfoo.dylib
foo.c
For those familiar with some other systems -install_name is similar
to the -soname flag, so we have just created a library with an
absolute soname. This can be checked with otool:
$ otool -XD libfoo.dylib
/opt/foo/libfoo.dylib
Now saying that the install location is not stored in the binary is
not true, the absolute soname is indeed stored in the binary. This
allows you to do some odd stuff, like for example have your
application load multiple libraries with the same basename, but
different absolute paths. So one app could load, and use /usr/lib/
libfoo.dylib and /opt/lib/libfoo.dylib simultaneously, which can, on
occasion, be useful.
For example, with two level namespaces, you could load library
libfoo.dylib, which needs /opt/baz/libbaz.dylib, and libbar.dylib
which needs /opt/baz2/libbaz.dylib, and you would get both
incompatible baz libraries loaded, with libfoo using the symbols
from /opt/baz/libbaz and libbar usiing the symbols from /opt/baz2/
libbaz.
Anyway to get back to the boring example:
If we link a binary:
$ echo "int main(){;}" > main.c
$ cc -o main main.c ./libfoo.dylib
$ otool -L main
main:
/opt/foo/libfoo.dylib (compatibility version 0.0.0, current
version 0.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0,
current version 88.1.7)
Now, you see the absolute path in there. if we try to execute the
binary:
$ ./main
dyld: Library not loaded: /opt/foo/libfoo.dylib
Referenced from: /Users/peter/./main
Reason: image not found
Trace/BPT trap
Because, well, it is not there.
We can make the library relative to the application using
install_name_tool:
$ install_name_tool -change /opt/foo/libfoo.dylib @executable_path/
libfoo.dylib main
$ ./main
And we see that it works, woohoo!
We could also use @loader_path here if we had a shared library that
wanted to load another library at a location relative to itself.
So all is well, however add -rpath support becomes complicated. How
do you deal with libraries with the same basename that currently have
every instance loaded, if listed in the load commands? What about
stuff like DYLD_ env vars? There are many things that need careful
consideration before adding the -rpath feature, I'm sure that they
are getting that consideration.
Peter
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden