libtool
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: libtool versioning and ABI


From: Charles Wilson
Subject: Re: libtool versioning and ABI
Date: Tue, 11 Aug 2009 20:41:32 -0400
User-agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.8.1.22) Gecko/20090605 Thunderbird/2.0.0.22 Mnenhy/0.7.6.666

Michel Briand wrote:

>> libavutil49-0.4.9-3.pre1.8994.2plf2008.0
>>                                      ABI=49, pkgver=0.4.9
>>
> 
> Please give me the way to learn those ABI number you cite.

libavutil49-0.4.9-<stuff>
         ^^
is usually used by the distribution (Red Hat? Debian?) to indicate that
this package (.rpm? .deb?) contains the shared runtime library of
libavutil with SOVERSION 49. That is, it probably contains a "real" file
named

libavutil.so.49.x.y

and closely related items, such as the runtime symlink needed by ld.so
for on-demand loading:

libavutil.so.49 -> libavutil.so.49.x.y

It usually does NOT contain the *linktime* symlink needed by ld when
compiling clients with -lavutil:

libavutil.so -> libavutil.so.49.x.y

because that's in the libavutil-devel-0.4.9-<stuff> package.

The libavutil49-0.4.9-<stuff> package may also contain a postinstall
script to run ldconfig appropriately.  The point is, what you've been
calling the "major version" (here, 49) is the ABI number, properly
speaking, or in libtool terms, the *interface* major version [*], not
the *package* major version. (that's "0" from "0.4.9" above).

[*] but even that's cheating, because we usually don't like to talk
about "major/minor/patch" with regards to API/ABI.  We prefer these
compatibility indications current, revision, age because it's a more
appropriate vocabulary.  'age' tells you how many of the previous ABI's
before current, that 'current' is compatible with.  'revision' tells you
how many internal code modifications have occured on the implementation
of the 'current' ABI, but which have had zero impact on the public ABI
itself.  Therefore, in this context, ABI "major" version is just "the
earliest ABI instance prior to 'current' with which 'current' is
backwards-compatible."  That is,
  7:3:2  --> "major" is 5, and
    curr = 7 is compatible with 5
           6 is compatible with 5
           5 is compatible with 5
  so the SONAME for all three -version-infos would be libfoo.so.5.
and that's why libtool "major" interface numbers skip.  If we follow the
rules with an ABI change, the next -version-info would be
  8:0:0
whose "major" is 8 --> libfoo.so.8

because interfaces #7 and #6 were backwards-compatible with #5, so we
skip them.

"minor" and "patch" don't *explicitly* tell you any of these things.
and "major" only tells you about ABI compatibility if the project
managers are very careful.

> I've looked into many OSS and found in Makefile.am only 2 cases :
> 
> - version-info 1:0:0 (the guys there didn't want to bother with
>   libtool versioning apparently... ;))
> 
> - version-info with the X.Y.Z version "back crafted" to make
>   the soname version read the same as X.Y.Z

You're not looking in the right places. <g>

Sure, there are a lot of misconfigured projects out there. But almost
all of the GNU projects Do It Right.  Hunt around here:

http://ftp.gnu.org/pub/gnu/

> Practice usually prevails in software.

And when you have the opportunity at the beginning of a project, to do
detailed upfront design, so that "in practice" you don't end up "in the
ditch", is better.

It's real easy to write a quick and dirty makefile that builds 'project
bar' on linux.  then, you start hacking around with various make rules
to ensure that it builds on BSD. Then Darwin.  Then, God help you, you
try to hack around your custom makefile to get it to work on win32 (and
I'm just talking build system, not actual code porting here).

And then you try to retrofit it with VPATH so that out-of-sourcedir
builds work.

The you try to fix the Makefile to support cross-builds.

OR

leverage decades of work from the automake team, and write a Makefile.am
once, up front, even when all you care about is linux, that looks like:

bin_PROGRAMS = bar
bar_SOURCES = bar.c helper.c
man_MANS = bar.1

and it basically works unchanged when you decide to worry about other
platforms.  Now, if you're really smart and experienced, you could
hand-code a Makefile that does all these things up front, the right way,
so that it works later on BSD and win32 and with VPATH and crossbuilds.
 But it is HARD.  Three lines of Makefile.am is EASY. And the payoff is
huge.

Similarly, if you're really smart and work hard, you could hand-craft
rules to build your shared library, and even special case for the
wild-and-wacky cygwin/mingw DLL issues.  Or, you could just use libtool.

Ditto, you could think really hard about how to ensure proper ABI
numbering and compatibility, and explicitly tie those values to your
package version numbers (thus linking the two).  Or, you could rely on
the effort for supporting shared library builds on 129 different $hosts
that has been expended over 15 or more years by people smarter than both
of us put together. (Fer instance, did you know it is *illegal* to have
a SOVERSION of zero on IRIX? libfoo.so.0 won't work. libtool knows this,
and computes ABI major as 'current - age + 1' for that platform.  So,
how would you package libfoo-0.1.1.tar.gz on IRIX, if your Makefile
explicitly ties the SONAME to the package major version of 0?).

Up to you.

--
Chuck





reply via email to

[Prev in Thread] Current Thread [Next in Thread]