Can anyone explain why dynamic libraries on macOS have an id, and it's always a path? I can change this id
via install_name_tool
but why is this even necessary?
I don't recall this on Linux. Why did Apple decide to not pass the path of the loaded path during initialization?
$ otool -L /path/to/lib/libgobject-2.0.0.dylib
/path/to/lib:
@loader_path/libgobject-2.0.0.dylib <--- ??? (compatibility ...)
.. other dependencies
CodePudding user response:
Because "standard paths" just aren't enough for macOS.
On Linux, libraries are identified by $(basename $path)
and everything is thrown in /usr/lib
or some other standard path. If two libraries collide, that's your problem. If you don't have root permissions, that's your problem. If you wanna test some stuff, you can at least set LD_LIBRARY_PATH
, but for distribution that's really not great.
Now consider macOS (and by extension, iOS) where /usr/lib is on a readonly volume and applications very often ship third-party frameworks inside their .app bundle, and expect them to work regardless of path on disk, and without requiring root to install.
Shared libraries on macOS have an ID that is a path, because that path tells the runtime linker where to find the library on disk.
Now you might ask why doesn't it just embed the compile-time path of the library? For one, because entire app bundles might get moved around, and for another, because cross-compilation is a thing.
In essence, this gives the same capability as LD_LIBRARY_PATH
, except with the granularity of single binaries, and in a way that can be distributed.