Calamares 3.3 series ABI compatibility
Feb 28, 2024
A long-standing wish of mine is to reach some kind of ABI stability in the Calamares core. Over the lifetime of the 3.2 series, methods were added and removed, namespaces shuffled around, and data members littered all over. This has a major downside for (third-party) C++ modules that need to be recompiled for each Calamares release. The 3.3 series aims to improve the situation.
ABI Compatibility
For background on C++ ABI Compatibility, the KDE Community Wiki provides a good overview.
Calamares modules, or plugins, are loaded into the Calamares executable. The modules can use services provided by the executable (e.g. Global Storage). Conversely, Calamares itself calls into the plugins to create the UI for the module and run jobs. This means that plugins and Calamares must agree on names, types, sizes and layout of data.
Calamares 3.2 series did not track o promise ABI compatibility at all. Any third-party modules needed to be recompiled for each release.
Calamares 3.3 series tries, a little.
ABI Checking
libabigail is a suite of tools for dealing with “ABI-relevant artifacts”. It does all the heavy lifting that Calamares needs.
In the Calamares repository, the script ci/abicheck.sh
builds Calamares
libraries twice: once for a reference version, and once for the current
version. Then it compares the two with libabigail tools. This produces
a report of ABI-relevant changes. The idea is that the report should be
empty, meaning the two versions are ABI-compatible and modules compiled
against the reference version will still work with the current version.
The script defines a specific git hash as the reference version. It corresponds (when I started writing this, but take note of the concluding paragraph) to release 3.3.0.
Right now the report is gigantic. There is a big ABI difference between 3.3.0 and the latest 3.3.4 release. There are no ABI compatibility guarantees – in fact I think it is guaranteed to break.
ABI Intentions
One of the reasons for the ABI changes is the visibility of
symbols (methods, namespaces and data members) in the libraries.
Calamares in the 3.1 series used a collection of macros
in the header DllMacro.h
to mark things as “public ABI”.
In the 3.2 series, this mechanism was not used consistently
at all, and 3.3 started with a mess: everything was public,
and only some things marked-as-such.
Note that all this ABI drift happened under my watch, so it is entirely my fault.
- In Calamares release 3.3.2, symbol-visibility in libcalamares
was set to hidden-by-default with explicit use of the
DLLEXPORT
macro to mark things as part of the public ABI. - In Calamares release 3.3.3, the same was done with libcalamaresui
and the macro
UIDLLEXPORT
. - In Calamares release 3.3.4, some loose ends for the previous two releases and the exposed ABI were tied up.
In principle this means that 3.3.4 “should” be the stable ABI we have always wanted.
Conclusions
I’m waiting for fallout from real third-party plugins. The calamares-extensions repository is one that acts as an example of plugins (and branding and other things) and it builds, but who knows what other people use.
Based on the assumption that 3.3.4 is stable, I will be changing the reference release for ABI-checking to that, and then introducing an ABI-compatibility check into the release scripts so that barring unpleasant surprises, we can guarantee forward-compatibility of the libraries to third-party consumers.