I've seen it said that at static link-time (ie, the linking stage that occurs after compilation, rather than at run-time), both the name and the version of any linked external libraries may be encoded in the resulting binary. I think I can see the logic for fixing the name of the external library, since many unrelated libraries seem to use the same header file names.
How/why the version of the library is fixed is less clear to me. As far as I can see, all the linker can assert at static-link-time, is that the version of the library that is provided is valid for the underlying code (ie, that the function signatures, struct definitions etc of the linked library correctly match the declarations in the header file). By the logic of semantic versioning, you might then say that any version of the library with the same major version number would also be valid (and be able to draw no conclusions about either higher or lower major version numbers). My questions would be:
- Have I understood this correctly?
- If so, does the linker fix the major version number and refuse to dynamically link to a library of a different major version number? This would seem to come with some downsides.
- If not, how does the linker set version restrictions for dynamic linking?
Thanks in advance for any help here.
CodePudding user response:
Assuming your question is about Linux.
Each shared library declares it's version via special attribute in .dynamic segment:
$ readelf -d /lib/x86_64-linux-gnu/libgobject-2.0.so.0
Dynamic section at offset 0x5d760 contains 29 entries:
Tag Type Name/Value
...
0x000000000000000e (SONAME) Library soname: [libgobject-2.0.so.0]
This version gets updated by library developers (or distro maintainers) when incompatible changes are done to library (e.g. changes in function signatures, function definitions, etc.).
When you link your application, this version is embedded into executable by the linker:
$ readelf -d /bin/gnome-logs
Dynamic section at offset 0x2e288 contains 35 entries:
Tag Type Name/Value
...
0x0000000000000001 (NEEDED) Shared library: [libgobject-2.0.so.0]
When application is loaded, the dynamic linker will only allow versions of libgobject.so with exact same version to be loaded.