MysteryMoose
MysteryMoose

Reputation: 2363

GCC: Specifying a Minimum Shared Library Version

Background

I inherited and maintain a Linux shared library that is very closely coupled with specific hardware; let's call it libfoo.so.0.0.0. This library has been around for some time and "just worked". This library has now become a dependency for several higher-layer applications.

Now, unfortunately, new hardware designs have forced me to create symbols with wider types, thereby resulting in libfoo.so.0.1.0. There have been only additions; no deletions or other API changes. The original, narrow versions of the updated symbols still exist in their original form.

Additionally, I have an application (say, myapp) that depends on libfoo. It was originally written to support the 0.0.0 version of the library but has now been reworked to support the new 0.1.0 APIs.

For backwards compatibility reasons, I would like to be able to build myapp for either the old or new library via a compile flag. The kernel that a given build of myapp will be loaded on will always have exactly one version of the library, known at compile time.

The Question

It is very likely that libfoo will be updated again in the future.

  1. When building myapp, is it possible to specify a minimum version of libfoo to link against based on a build flag?

  2. I know it is possible to specify the library name directly on the build CLI. Will this cause myapp to require exactly that version or will later versions of the lib with the same major revision still be able to link against it (ex. libfoo.so.0.2.0)? I am really hoping to not have to update every dependent app's build each time a new minor version is released.

  3. Is there a more intelligent way of accomplishing this in an application-agnostic way?

References

How do you link to a specific version of a shared library in GCC

Upvotes: 3

Views: 1811

Answers (1)

Employed Russian
Employed Russian

Reputation: 213506

You are describing external library versioning, where the app is built against libfoo.so.0, libfoo.so.1, etc. Documentation here.

Using external library versioning requires that exactly the same version of libfoo.so.x be present at runtime.

This is generally not the right technique on Linux, which, through the magic of symbol versioning, allows a single libfoo.so.Y to provide multiple incompatible definitions of the same symbol, and thus allows a single library serve both the old and the new applications simultaneously.

In addition, if you are simply always adding new symbols, and are not modifying existing symbols in incompatible way, then there is no reason to increment the external version. Keep libfoo.so at version 0, provide a int foo_version_X_Y; global variable in it (as well as all previous versions: foo_version_1_0, foo_version_1_1, etc.), and have an application binary read the variable that it requres. If an application requires a new symbol foo_version_1_2 and is run with an old library that only provides foo_version_1_1, then the application will fail to start with an obvious error.

Upvotes: 3

Related Questions