Reputation: 2363
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.
When building myapp
, is it possible to specify a minimum version of libfoo
to link against based on a build flag?
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.
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
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