This is expected behavior.
The version number checks that dyld
performs are limited to ensuring that the compatibility version of the library being loaded is higher than the compatibility version of the library that was used at build time. The current version of the library is something that's programmatically accessible, but isn't used by dyld
when evaluating whether it should load a particular library. You can learn more about these two version numbers by looking at the -compatibility_version
and -current_version
sections of the ld
man page.
You can achieve the effect you're after by making use of the library's install name. You can see this by looking at how libSystem.dylib
is used:
mrowe@angara:~$ ls -lha /usr/lib/libSystem.{,B.}dylib
-rwxr-xr-x 1 root wheel 53K Jul 9 2012 /usr/lib/libSystem.B.dylib
lrwxr-xr-x 1 root wheel 17B Jul 9 2012 /usr/lib/libSystem.dylib -> libSystem.B.dylib
mrowe@angara:~$ otool -L /usr/lib/libSystem.dylib | head -2
/usr/lib/libSystem.dylib:
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 169.3.0)
mrowe@angara:~$
Note how the install name in the second line of otool
output points to the version of the dylib whose name is qualified with the version number (in the case B). If Apple were to introduce a backwards-incompatible revision of libSystem.dylib
they could put it at /usr/lib/libSystem.C.dylib
and update the symlink at libSystem.dylib
to point it. Existing programs would still look for libSystem.B.dylib
since that's the install name that was written in to their LC_LOAD_DYLIB
load command back when they were linked. Any program that was newly linked against libSystem.dylib
would find libSystem.C.dylib
and have its install name written in to their LC_LOAD_DYLIB
load command. Such a program would fail to launch on a system which lacked libSystem.C.dylib
.