The D ecosystem in Debian with free-as-in-freedom DMD

Johannes Pfau via Digitalmars-d digitalmars-d at puremagic.com
Wed Apr 12 01:28:14 PDT 2017


Am Wed, 12 Apr 2017 07:42:42 +0000
schrieb Martin Nowak <code at 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


More information about the Digitalmars-d mailing list