Am Wed, 12 Apr 2017 07:42:42 +0000 schrieb Martin Nowak <c...@dawg.eu>:
> On Monday, 10 April 2017 at 16:12:35 UTC, Iain Buclaw wrote: > > Last time someone else looked, it seemed like LDC and DMD make > > use of SOVERSION, but do so in an incorrect manner. > > You know what exactly is the problem? Any suggestion what to use > instead? > > It's currently using libphobos2.so.0.74, where using major > version 0 to mean unstable might be a misapplication of semver > (http://semver.org/#spec-item-4) for SONAME. I still haven't found some definitive documentation about this, but it seems linux shared library working essentially works like this: There's a major and a minor number. There's sometimes a patch version, but there's no conclusive documentation. Reading the ldconfig source code you can have as many version levels as you want [3] (though essentially this is treated like one minor version, it only affects comparing minor versions). But there are different ldconfig implementations (linux, bsd) so I don't know if multi-level minor versions are portable. * Major version reflects ABI level. A new major version can break ABI or add new stuff to ABI. * Minor versions can only extend the ABI of the major version but should not break any ABI. * Micro / Patch version is mostly unused in ldconfig. It only affects comparing minor versions, i.e. when you have libphobos.so.74.0.1 and libphobos.so.74.0.2 ldconfig will link libphobos.so.74=>libphobos.so.74.0.2 Filename format: lib[name].so.[major].[minor][.patch] Soname format: always lib[name].so.[major] It is possible to install and use multiple major versions. Every major version will always use the last installed minor version. (The distribution will manage symlinks for libfoo.[major] to libfoo.[major].[minor] for the largest minor version). Additionally a libfoo.so is installed (for linking / development only, might even be in -dev packages) to point to the latest libfoo.[major] symlink. The libfoo.[major] symlink is used when linking with -lfoo. The dependency encoded in the executable will use the soname though, so it will encode libfoo.[major]. If you install a new major library version, all existing executables will continue to use the major version hardcoded in the executable. If you update a major version to a new minor version, all executables using the major version soname will use the new minor version. This means: * Increase major every time you break ABI * Increase some minor level every time you only extend ABI So DMD should not keep the major version fixed as 0 (every time you update libphobos you break all existing binaries, as you break the ABI of libphobos.so.0). In GDC we use libtool which encodes like this [1][2]: libgphobos.so.[major].0.[release] e.g. libgphobos.74.0.2 This is not 100% safe if a minor release breaks ABI though. BTW: Interestingly even with these complicated rules you can end up in situation where versioning does not work: If you link application APP against libfoo.so on a system with libfoo.so.1.2 the soname will only encode libfoo.so.1. Now ship the library to a system with libfoo.so.1.1 and you may have missing symbols due to extended ABI in libfoo.so.1.2. TLDR: Downgrading libraries is not safe with this versioning approach. [1] https://autotools.io/libtool/version.html [2] https://www.gnu.org/software/libtool/manual/html_node/Libtool-versioning.html ldconfig is responsible for maintaining the symlinks, here's how it determines which version of a library is newer: [3] https://github.com/lattera/glibc/blob/master/elf/ldconfig.c#L939 https://github.com/lattera/glibc/blob/master/elf/dl-cache.c#L138