On Mon, 20 Mar 2023 at 12:45, Francesco Pretto <cez...@gmail.com> wrote: > If there are two numbers, one specifying the ABI didn't > break, and the second with the additions, eg. 1.10, still any program > linking to a 2-number SO version 1.11 will refuse to load with 1.10, > even if it didn't use anything new introduced in 1.11, correct?
I answered myself and the answer is: it depends on the SONAME attribute of the library being linked. That is: when you link a .so library, the end result binary may be linked to a completely different library than expected, or a missing one if SONAME misconfigured. I verified it myself empirically but it is also documented in this guide[1], which it may also be the document that zyx referred to: "The linker then reads the soname from the library file and records it into the application executable file. Finally, the linker creates the application so that it declares dependency on the library using the soname, not name or file name." The document also mentions what it may be a convention or "golden rule": "A library foo version X.Y is ABI-compatible with other versions with the same value of X in the version number. Minor changes preserving compatibility increase the number Y. Major changes that break compatibility increase the number X. [...] The Y component of the version number is not limited to just a single number." The fact is that the Y, or Y.Z component is not really reflected in the actual SONAME, see few examples in my system: $ readelf -d libjpeg.so.8.2.2 | grep SONAME 0x000000000000000e (SONAME) Library soname: [libjpeg.so.8] $ readelf -d libfreetype.so.6.18.1 | grep SONAME 0x000000000000000e (SONAME) Library soname: [libfreetype.so.6] $ readelf -d libavformat.so.58.76.100 | grep SONAME 0x000000000000000e (SONAME) Library soname: [libavformat.so.58] So linking these libraries will only bind to the ABI-breaking versioning (eg. libjpeg.so.8, not libjpeg.so.8.2.2), and the reference to the full versioning is erased in the linked binary (I verified it empirically with the command "strings"). I agree with Mattia here: having a SO version with the Y or Y.Z components seems to be cargo cult from (most) older projects, and the Y or Y.Z components for these projects are not be enforced by the SONAME mechanism, nor they are required. In fact a few notable examples that has actual libraries without Y.Z components at all exists: $ readelf -d libssl.so.3 | grep SONAME 0x000000000000000e (SONAME) Library soname: [libssl.so.3] # There are no libssl.so.3.Y nor libssl.so.3.Y.Z $ readelf -d libresolv.so.2 | grep SONAME 0x000000000000000e (SONAME) Library soname: [libresolv.so.2] # There are no libresolv.so.3.Y nor libresolv.so.3.Y.Z I think it's a sign of maturity questioning practices of the past and decide to do differently if it has some rationale. I still suggest to move to a single number SO versioning because: - It's one less burden to take care of when the non-breaking part of the versioning (which would be not checked anyway) should be updated; - I noticed CMake doesn't seems to support the full libtool machinery as pointed by Mattia, as setting SOVERSION[2] in the form X.Y will really end to set a SONAME like "libpodofo.so.X.Y", and not "libpodofo.so.X", which is what we actually want. I also suggest: - To arbitrarily start with SOVERSION "10" because it makes more clear that there were other incompatible ABIs before; - To preserve the libpodofo.so -> libpodofo.so.10 symlink (that is created by default with CMake) because it doesn't hurt and someone may want link pointing directly to libpodofo.so. If you want to comment further please do it quickly because the 0.10 release is imminent. Regards, Francesco [1] https://access.redhat.com/documentation/it-it/red_hat_enterprise_linux/7/html/developer_guide/creating-libraries-gcc#the_soname_mechanism [2] https://cmake.org/cmake/help/latest/prop_tgt/SOVERSION.html _______________________________________________ Podofo-users mailing list Podofo-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/podofo-users