To all port maintainers: libtool
tijl at FreeBSD.org
Wed May 7 22:24:30 UTC 2014
I've been asked to write something about USES=libtool to clarify a few
things about what it does and why.
First: what is libtool?
Libtool is a build script that acts as a wrapper around a compiler. You
can compile code or link a library (or executable) with libtool and it will
invoke the right compiler, linker and other commands for you. It supports
multiple languages, compilers and platforms and simplifies writing
makefiles when used in combination with automake. Many ports use it.
The problems with libtool on FreeBSD.
Libraries created with libtool have three version numbers X.Y.Z. How they
are calculated is not straightforward but that's not important right now.
The important thing is that the major version number X is the only one
that really matters. An executable that links to libA will ask for
libA.so.X and doesn't care about Y and Z. Only when the major version
number of a library changes does everything that link to it need to be
recompiled. On FreeBSD however libtool uses X+Y as major version number
which means that changes in Y also require rebuilding all ports that
depend on the library.
A second problem is that libtool flattens the dependency tree. When you
link an executable or library with libA while libA in turn links to libB
then libtool will make the executable or library also link with libB.
This means that when the major version number of libB changes, the
executable or library will also have to be rebuilt. Some libraries get
propagated into hundreds and even thousands of ports this way while only
a few actually use them directly.
These two problems make major version number changes too frequent and too
painful, not only for users who build their own ports, but also for
package users, because too many packages need to be rebuilt, mirrored and
downloaded every week than strictly necessary.
A third problem is with ports that have USE_AUTOTOOLS=libtool in their
Makefile. Normally the libtool script is generated by the configure
script so it uses the compiler, linker and other tools that you configure
a port with. Ports with USE_AUTOTOOLS=libtool however use
/use/local/bin/libtool. This is the libtool script generated by the
configure script of devel/libtool. This mechanism was meant for ports
that ship with a version of libtool that doesn't work properly, but the
problem is that such ports aren't necessarily built with the same tools as
devel/libtool. An upcoming feature that allows cross-building ports and
that will be used to provide ARM packages is currently blocked by this
because these ports don't use the right cross compiler and linker.
All ports that use libtool need to have USES=libtool added to their
Makefile and USE_AUTOTOOLS=libtool removed. USES=libtool will patch the
port to address the problems above along with a few smaller problems with
older versions of libtool that some ports still ship with. USES=libtool
also replaces USE_GNOME=ltverhack so that should be removed as well. In
fact, all libtool related hacks and patches that a port contains can
probably be removed (typically patches or post-patch commands for files
like ltconfig, ltmain.sh and configure).
The easiest way to know if a port uses libtool is to build it first. You
can then search the work directory for a file named "libtool":
# cd some/port
# find work -name libtool
Another giveaway is the installation of files with .la extension.
USES=libtool modifiers :keepla and :oldver.
One of the ways libtool propagates links is through .la libraries. These
are ordinary text files that contain some meta-data about a library,
including a record of all dependencies. These files are normally not
needed and USES=libtool removes them from the staging area. For the rare
cases where a port does need these files USES=libtool:keepla can be used.
In this case .la files are kept but the dependency record is cleared so
dependencies won't be propagated to other ports.
Another important reason to keep .la files is that in this transition
period other ports may still contain references to them in the dependency
record of their .la files. These ports first need to have some form of
USES=libtool added to their Makefile such that these references are
removed. So, as long as there are dependent ports that install .la files
but do not have some form of USES=libtool, a port must use
Finally, because the major version number goes from X+Y to X, if Y is
non-zero, the library version will go backwards. This is not a problem
in the sense of API compatibility (because of the way libtool versioning
works everything between X and X+Y is backwards compatible and a new
release that isn't backwards compatible will see its major version number
jump to newX=oldX+oldY+1), but it may be a problem if due to link
propagation many ports depend on the library and they all need to get a
PORTREVISION bump. To avoid this, USES=libtool:oldver can be used. A
port will then continue to use the old X+Y version scheme but it will
no longer propagate its own dependencies to other ports. Once enough
ports use some form of USES=libtool the number of dependent ports will
drop to a point that removing :oldver becomes possible. Note that
USES=libtool:oldver is a transitional measure and support for it will
eventually be removed.
More information about the freebsd-ports