[gnutls-devel] symbol and library versioning

Andreas Metzler ametzler at bebt.de
Thu Aug 10 14:21:29 CEST 2017


On 2017-08-10 Nikos Mavrogiannopoulos <n.mavrogiannopoulos at gmail.com> wrote:
>  With mind in the upcoming 3.6.0 release I tried to codify/clarify the
> library and symbol versioning rules that are considered best practice
> today.

> The output is at:
> https://gitlab.com/gnutls/gnutls/blob/master/CONTRIBUTING.md#symbol-and-library-versioning

> My take-away from it, is that the complexity of libtool rules is
> unnecessary and in fact all that is being used from it is the major
> soname version (thus the minor and patch versions set via libtool are
> being used by no software).

Hello,

yes and no. ;-) Afaiui libtool versioning is an abstraction level. On e.g.
Linux the only important result is that a soname bump happens when
necessary. On other more exotic platforms libtool might (need to) do
something different.

> The versioning that matters is via the linker script, which is then
> used by packaging software like rpm (I guess possibly dpkg as well),
> to detect proper dependencies.

rpm and dpkg work differently here.
rpm looks at the library at build time and scans it for versioned symbol
definitions. If the library exports GNUTLS_3_4_0 and GNUTLS_3_4_1 the
resulting library package provides
libgnutls.so.30
libgnutls.so.30 (GNUTLS_3_4_0)
libgnutls.so.30 (GNUTLS_3_4_1)

And a package linking against gnutls which uses foo at GNUTLS_3_4_1 will
get a dependency against "libgnutls.so.30 (GNUTLS_3_4_1)".

Debian works a little bit differently. There is no benefit for dpkg
based systems in using the fine grained symbol version approach.  The
gnutls development package comes with a list of exported symbols[1] and
the respective version that a using package needs to depend on:
 gnutls_idna_reverse_map at GNUTLS_3_4 3.5.9
 gnutls_init at GNUTLS_3_4 3.5.6
 gnutls_key_generate at GNUTLS_3_4 3.5.0
If a binary uses both gnutls_key_generate and gnutls_init it will depend
on gnutls >= 3.5.6 (the maximum of 3.5.6 and 3.5.0).
There is usually a manual review process involved in updating this list
of symbols. This is evident by the gnutls_init() dependency info.
gnutls_init was introduced ages ago, however the GNUTLS_NO_TICKETS
argument was only added in 3.5.6.

> Did I miss something in that? Are there are best practices I missed,
> or any issues in the rules I set above?

| Symbol versioning as provided by libgnutls.map have several advantages.
|   1 they allow for symbol clashing between different gnutls library
|     versions being in the same address space.
|   2 they allow installers to detect the library version used for an
|     application utilizing a specific symbol
|   3 the allow introducing multiple versions of a symbol a la libc,
|     keeping the semantics of old functions while introducing new.

1 is what GnuTLS symbol-versioning in released versions (all symbols
versioned with a unified sonamed-specific label) currently accomplishes.
2 seems to be what you are aiming for, enhancing RedHat's package
dependencies.
3 Is this a goal you are envisioning of following? If not it would clear
things up to clearly state that GnuTLS is not (currently) using symbol
versioning for this purpose. (On a sidenote: Is there anybody except
glibc doing this?)

I think there is typo in the following text, the numbers seem to be off.
s/GNUTLS_3_6_2/GNUTLS_3_6_3/
| As such for every symbol introduced on a particular version, we create
| an entry in libgnutls.map based on the version and containing the new
| symbols. For example, if in version 3.6.3 we introduce symbol
| gnutls_xyz, the entry would be:
| 
| GNUTLS_3_6_2 { global: gnutls_xyz; } GNUTLS_3_6_1;
| 
| where GNUTLS_3_6_1 is the last version that symbols were introduced, and
| indicates a dependency of 3.6.2 to symbols of 3.6.1.



This has not been a problem with the old approach. 
| Backporting new symbols to an old version which is soname compatible is
| not allowed (can cause quite some problems).
[...]

cu Andreas


[1] There is also an older, less fine grained way, where the development
ackage simply specifies "any binary build against and linking with this
version of the library gets a dependency >= x.y.z). If new symols are
introduced the depinfo is bumped and the generated dependency becomes
stricer even if the new symbol is not used.
-- 
`What a good friend you are to him, Dr. Maturin. His other friends are
so grateful to you.'
`I sew his ears on from time to time, sure'



More information about the Gnutls-devel mailing list