Hello, as SONAME changes + symbol versioning seems to be the most viable option, I did some experiments on what end effect it might have and how all this would look like.
Glossary -------- unstable-ABI library - a library which is prone to break BC without SONAME change. Undefined (UNDEF) symbol - a plain symbol reference. It will be resolved to the implementation/definition in the external shared library by dynamic linker. Conclusions ----------- 1) ABI-unstable libraries should get all symbols versioned from the start. That's because undefined unversioned symbols may bind to any symbol of the same name in any library which dynamic linker (recursively) loaded [1]: | In case only the object file with the reference does not use | versioning but the object with the definition does, then the reference | only matches the base definition. [ ...] If there is no symbol definition | with such an version index and there is exactly one version for which this | symbol is defined, then this version is accepted It does not matter if a real symbol in the library is versioned or not. The first same-name real symbol seen by dynamic linker will be bound to the unversioned UNDEF. It means that we basically have no control over this unless we version the symbols. 2) Unlike unversioned (Base) symbols, versioned UNDEF symbols have version *and* originating library information assigned to them. According to [1]: | The last case is if the object with the references uses symbol | versions but the object with the definitions has none. In this case a | matching symbol is accepted unless the object's name matches the one | in the Elfxx_Verneed entry. In the latter case this is a fatal error. However, I determined that this is not the case since middle 1999 [2]. This situation is not a fatal error but merely a warning [3]. However, I'm pretty sure that it's a bug in the dynamic linker which may get fixed one day. Respective assert() is in place [4] but it does not fire in release builds. 3) Versioned symbols cannot be easily "moved" from one library to another down the library dependency tree without breakage (as it was done e.g. with "libkutils4 -> libkcmutils4 libkemoticons4 libkidletime4 libkprintutils4" split). But this should be a non-issue for unstable-ABI libraries. Having in mind the points 1 and 2 above, all symbols in the unstable-ABI libraries should get a unique-per-ABI version. As soon as upstream breaks BC without bumping SOVERSION, we bump SONAME and change a package name. However, initially, we keep original upstream SONAME. This strategy allows to keep some compatibility with the rest of the world as long as upstream does not break BC without bumping SOVERSION so we do not have to bump SONAME ourselves. In particular: a) external binaries (which supposedly have unversioned UNDEF symbols as pushed by upstream, see point 1) will work with unstable-ABI libraries as packaged by Debian; b) binaries with versioned UNDEF symbols (i.e. linked against our unstable- ABI libraries) will work with unstable-ABI libraries as built from upstream sources (kdesrc-build) or packaged by other distros which do not use incompatible symbol versioning. That's because of point 2 and as long as the linker bug is not fixed. So how to handle BIC? --------------------- As said in previous mails, we need to choose a custom string for our SONAMEs (that is either SOVERSION or OUTPUT_NAME suffix, whatever toolchain eats better) and symbol versions. Let it be "abiN" (where N is an integer) for SONAME bumps and ABI_N for symbol versions respectively (with _0 for unchanged SOVERSION). So in 4.6, we add symbol versions ABI_0 to all unstable-ABI libraries which kept BC throughout 4.4 -> 4.6 cycle. Otherwise, if libs broke BC, we rename their packages, bump their SONAMEs by adding "abi1" suffix and set their symbol versions to ABI_1. As 4.6 is going to be a transitional release from unversioned to versioned symbols, we might consider adding "Breaks" against old libs (<< 4:4.6) to all future "abi1" packages. That's to avoid weird crashes if both old unversioned and new versioned BIC libraries end up getting loaded in the same process space. While it's possible, it's also highly unlikely because unstable-ABI libs are not very popular (unlike e.g. libjpeg). So let's not do this "Breaks" stuff at first and see what happens. Implementation details ---------------------- In order to minimize patching, I propose the following scheme. All unstable- ABI library packages would be marked with a custom "X-Custom-ABI: N" (or something like that) debian/control field. Then we would need to implement a cmake script which would parse debian/control, bump SONAME and add appropriate -Wl,--version-script,script-name to the linker command line on- the-fly. This script would be shipped in pkg-kde-tools to be INCLUDEd from the bottom of /CMakeLists.txt of the each source package that needs this capability. That would effectively limit us to one patch per source package while the rest would be conveniently "configured" in debian/control. [1] http://www.akkadia.org/drepper/symbol-versioning [2] http://sourceware.org/git/?p=glibc.git;a=commit;h=9a8fcca0b33c26759134a545ac45251df53418a3 [3] <apppath>: <libpath>: no version information available (required by <apppath>) [4] http://sourceware.org/git/?p=glibc.git;a=blob;f=elf/dl-lookup.c;hb=glibc-2.13#l168 -- Modestas Vainius <mo...@debian.org>
signature.asc
Description: This is a digitally signed message part.
-- http://lists.alioth.debian.org/mailman/listinfo/pkg-kde-talk