abimap - Man Page

Generate and update linker version scripts

Synopsis

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

Description

abimap is a tool to generate and update linker scripts which add version information to symbols exported by a shared library.

It is intended to be integrated as part of the build process to check for changes in the set of exported symbols and update the symbol version linker script accordingly.

The complete documentation can be found at https://abimap.readthedocs.io

Options

-h,--help:

Print the available options and subcommands

Subcommands

abimap update

Update an existing map file

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
file

The map file being updated

-o OUT, --out OUT

Output file (defaults to stdout)

-i INPUT, --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 LOGFILE:

Log to this file

-n NAME, --name NAME

The name of the library (e.g. libx)

-v VERSION, --version VERSION

The release version (e.g. 1_0_0 or 1.0.0)

-r RELEASE, --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.

abimap new

Create a new map file

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]
-o OUT, --out OUT

Output file (defaults to stdout)

-i INPUT, --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 LOGFILE

Log to this file

-n NAME, --name NAME

The name of the library (e.g. libx)

-v VERSION, --version VERSION

The release version (e.g. 1_0_0 or 1.0.0)

-r RELEASE, --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.

abimap check

Check the syntax of a map file

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

The map file to be checked

--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 LOGFILE

Log to this file

abimap version

Prints the tool version number

usage:

abimap version [-h]

Notes

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.

References

Author

Anderson Toshiyuki Sasaki <ansasaki@redhat.com>

Info

Sep 23, 2024 0.3.2