Skip to main content

Documentation Status GitHub Actions CI Status Coverage Status Coverage Status

abimap

A helper for library maintainers to use symbol versioning

Why use symbol versioning?

The main reason is to be able to keep the library [ABI] stable.

If a library is intended to be used for a long time, it will need updates for eventual bug fixes and/or improvement. This can lead to changes in the [API] and, in the worst case, changes to the [ABI].

Using symbol versioning, it is possible to make compatible changes and keep the applications working without recompiling. If incompatible changes were made (breaking the [ABI]), symbol versioning allows both incompatible versions to live in the same system without conflict. And even more uncommon situations, like an application to be linked to different (incompatible) versions of the same library.

For more information, I strongly recommend reading:

  • [HOW_TO] How to write shared libraries, by Ulrich Drepper

How to add symbol versioning to my library?

Adding version information to the symbols is easy. Keeping the [ABI] stable, unfortunately, is not. This project intends to help in the first part.

To add version information to symbols of a library, one can use version scripts (in Linux). Version scripts are files used by linkers to map symbols to a given version. It contains the symbols exported by the library grouped by the releases where they were introduced. For example:

LIB_EXAMPLE_1_0_0
  {
    global:
      symbol;
      another_symbol;
    local:
      *;
  };

In this example, the release LIB_EXAMPLE_1_0_0 introduces the symbols symbol and another_symbol. The * wildcard in local catches all other symbols, meaning only symbol and another_symbol are globally exported as part of the library [API].

If a compatible change is made, it would introduce a new release, like:

LIB_EXAMPLE_1_0_0
{
    global:
        symbol;
        another_symbol;
    local:
        *;
};

LIB_EXAMPLE_1_1_0
{
    global:
        new_symbol;
} LIB_EXAMPLE_1_0_0;

The new release LIB_EXAMPLE_1_1_0 introduces the symbol new_symbol. The * wildcard should be only in one version, usually in the oldest version. The } LIB_EXAMPLE_1_0_0; part in the end of the new release means the new release depends on the old release.

Suppose a new incompatible version LIB_EXAMPLE_2_0_0 released after LIB_EXAMPLE_1_1_0. Its map would look like:

LIB_EXAMPLE_2_0_0
{
    global:
        a_newer_symbol;
        another_symbol;
        new_symbol;
    local:
        *;
};

The symbol symbol was removed (and that is why it was incompatible). And a new symbol was introduced, a_newer_symbol.

Note that all global symbols in all releases were merged in a unique new release.

Installation:

At the command line:

pip install abimap

Usage:

This project delivers a script, abimap. This is my first project in python, so feel free to point out ways to improve it.

The sub-commands update and new expect a list of symbols given in stdin. The list of symbols are words separated by non-alphanumeric characters (matches with the regular expression [a-zA-Z0-9_]+). For example:

symbol, another, one_more

and:

symbol
another
one_more

are valid inputs.

The last sub-command, check, expects only the path to the map file to be checked.

tl;dr

$ abimap update lib_example.map < symbols_list

or (setting an output):

$ abimap update lib_example.map -o new.map < symbols_list

or:

$ cat symbols_list | abimap update lib_example.map -o new.map

or (to create a new map):

$ cat symbols_list | abimap new -r lib_example_1_0_0 -o new.map

or (to check the content of a existing map):

$ abimap check my.map

or (to check the current version):

$ abimap version

Long version

Running abimap -h will give:

usage: abimap [-h] {update,new,check,version} ...

Helper tools for linker version script maintenance

options:
  -h, --help            show this help message and exit

Subcommands:
  {update,new,check,version}
                        These subcommands have their own set of options
    update              Update the map file
    new                 Create a new map file
    check               Check the map file
    version             Print version

Call a subcommand passing '-h' to see its specific options

Call a subcommand passing ‘-h’ to see its specific options There are four subcommands, update, new, check, and version

Running abimap update -h will give:

usage: abimap update [-h] [-o OUT] [-i INPUT] [-d] [--verbosity {quiet,error,warning,info,debug} | --quiet | --debug] [-l LOGFILE] [-n NAME] [-v VERSION] [-r RELEASE] [--no_guess]
                     [--allow-abi-break] [-f] [-a | --remove]
                     file

positional arguments:
  file                  The map file being updated

options:
  -h, --help            show this help message and exit
  -o, --out OUT         Output file (defaults to stdout)
  -i, --in INPUT        Read from this file instead of stdio
  -d, --dry             Do everything, but do not modify the files
  --verbosity {quiet,error,warning,info,debug}
                        Set the program verbosity
  --quiet               Makes the program quiet
  --debug               Makes the program print debug info
  -l, --logfile LOGFILE
                        Log to this file
  -n, --name NAME       The name of the library (e.g. libx)
  -v, --version VERSION
                        The release version (e.g. 1_0_0 or 1.0.0)
  -r, --release RELEASE
                        The full name of the release to be used (e.g. LIBX_1_0_0)
  --no_guess            Disable next release name guessing
  --allow-abi-break     Allow removing symbols, and to break ABI
  -f, --final           Mark the modified release as final, preventing later changes.
  -a, --add             Adds the symbols to the map file.
  --remove              Remove the symbols from the map file. This breaks the ABI.

A list of symbols is expected as the input. If a file is provided with '-i', the symbols are read from the given file. Otherwise the symbols are read from stdin.

Running abimap new -h will give:

usage: abimap new [-h] [-o OUT] [-i INPUT] [-d] [--verbosity {quiet,error,warning,info,debug} | --quiet | --debug] [-l LOGFILE] [-n NAME] [-v VERSION] [-r RELEASE] [--no_guess] [-f]

options:
  -h, --help            show this help message and exit
  -o, --out OUT         Output file (defaults to stdout)
  -i, --in INPUT        Read from this file instead of stdio
  -d, --dry             Do everything, but do not modify the files
  --verbosity {quiet,error,warning,info,debug}
                        Set the program verbosity
  --quiet               Makes the program quiet
  --debug               Makes the program print debug info
  -l, --logfile LOGFILE
                        Log to this file
  -n, --name NAME       The name of the library (e.g. libx)
  -v, --version VERSION
                        The release version (e.g. 1_0_0 or 1.0.0)
  -r, --release RELEASE
                        The full name of the release to be used (e.g. LIBX_1_0_0)
  --no_guess            Disable next release name guessing
  -f, --final           Mark the new release as final, preventing later changes.

A list of symbols is expected as the input. If a file is provided with '-i', the symbols are read from the given file. Otherwise the symbols are read from stdin.

Running abimap check -h will give:

usage: abimap check [-h] [--verbosity {quiet,error,warning,info,debug} | --quiet | --debug] [-l LOGFILE] file

positional arguments:
  file                  The map file to be checked

options:
  -h, --help            show this help message and exit
  --verbosity {quiet,error,warning,info,debug}
                        Set the program verbosity
  --quiet               Makes the program quiet
  --debug               Makes the program print debug info
  -l, --logfile LOGFILE
                        Log to this file

Running abimap version -h will give:

usage: abimap version [-h]

options:
  -h, --help  show this help message and exit

Import as a library:

To use abimap in a project as a library:

from abimap import symver

Documentation:

Check in Read the docs

References:

Release files for abimap 0.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for abimap 0.4.0
File Size Uploaded
abimap-0.4.0.tar.gz 59.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for abimap 0.4.0
File Interpreter ABI Platform
abimap-0.4.0-py2.py3-none-any.whl Python 3, Python 2 none any Details

Total release size: 79.5 kB

Release files / abimap-0.4.0.tar.gz

Download URL abimap-0.4.0.tar.gz
Size 59.7 kB
Tags Source
SHA-256 checksum
How to use checksums
883caf8e42ad1daecae058a294b769df48b3234df81084b6f7cc80b4bcef5c3b
BLAKE2b-256 checksum
How to use checksums
98cd57044525e84c7fbe202e9792c582597603ab609df935efceb96005ec57d3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.5

Release files / abimap-0.4.0-py2.py3-none-any.whl

Download URL abimap-0.4.0-py2.py3-none-any.whl
Size 19.7 kB
Tags Python 2 Python 3
SHA-256 checksum
How to use checksums
68b69346d581e9260c52cf7d594d434fd97ad4c6b5aa12ea3ac96fb7ee9e38dd
BLAKE2b-256 checksum
How to use checksums
321622636e78edd8be1219803ce2efb5ea377fe74c2f0941d0188e4b1b372a62
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.5

Release history Release notifications | RSS feed

This release

0.4.0 This release

2 release files

0.3.2

2 release files

0.3.1

1 release file

0.3.0

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page