[OpenAFS-devel] Libtool

Simon Wilkinson simonxwilkinson@gmail.com
Wed, 12 Sep 2012 16:48:48 +0100


As those of you who've been watching gerrit will have noticed, we're now =
using libtool to manage some of our libraries on Unix. Whilst I've been =
discussing doing this for a number of years, I thought it might make =
sense to describe the motivation, and the current state of the libtool =
work. Sorry for not getting this sent out before the changes hit the =
tree.

The OpenAFS tree is complex, because code is built in many different =
configurations as part of the build process. For most library objects, =
these configurations are:
 *) LWP
 *) pthreaded
 *) pthreaded and position indepedent (PIC),=20
 *) kernel
 *) ukernel
 *) ukernel PIC

Generally, it isn't safe to link objects that are built in one way with =
objects that are built in another, as the different compiler options can =
change the API. In particular, mixing LWP and pthreaded objects within =
the same binary can cause very unpredictable results. Historically, all =
of the pthreaded library code has been collected in libafsauthent and =
libafsrpc. However, the pthreaded ubik servers build their own copies of =
a lot of various libraries, as well as linking against libafsauthent. =
Lots of other bits of the code have precarious combinations of LWP and =
pthread objects

So, we have a tangled mess of libraries, none of which work particularly =
well with each other, and the situation where individual objects can be =
built as many as 15 times, and adding a new object to the tree can =
involve changing lots and lots of Makefiles.

In addition, because our only libraries with map files are libafsauthent =
and libafsrpc, we have no way of enforcing boundaries between individual =
modules. As nothing in the tree actually uses the shared versions of =
libafsauthent and libafsrpc, there's no real testing for the =
completeness of those map files, either.

I've been talking for a while about fixing this, and over that time it =
has become clear that libtool is the least-worst option. So, I started =
taking a look at using libtool to create a cleaner set of libraries. YFS =
have kindly funded that work, and contributed it to OpenAFS

The idea is that each directory that builds a library builds three =
versions of each library object - a LWP one, a pthreaded one, and a PIC =
one. The 'old' library name (libcmd.a for example) remains the LWP =
library. liboafs_<library> is then built as the pthreaded variant. =
libtool takes care of managing the PICness of these objects. libtool =
aware programs can just use libtool to link against the .la file, but it =
is also possible to link against the static or shared versions directly. =
Each directory has its own symbol list, which clearly lists all of the =
functions and variables from that module which are available to other =
sections of the code.

libafsrpc and libafsauthent are still available for out-of-tree users, =
but these are built using the objects already built by libtool, rather =
than building the tree yet again. All of the directories which used to =
build their own copies of library objects have been modified to use the =
ones that libtool has built, so the number of times we build things is =
much less.

Now that this is done, other work should be possible. We should be able =
to use the libtool archives, rather than the various *_pic.a objects =
which have appeared in the tree over the last few years. It should be =
possible to gradually move ukernel towards using user space libraries =
for its functionality, rather than building half of the tree itself.

And, most importantly, we're one step closer to knowing what our public =
interface looks like. It is now possible to take the contents of the =
symbol files, and rearrange header files so our interface is clearly =
stated.

My hope is that from now on, we'll use the liboafs_* libraries for all =
new code. Doing so is straightforwards - there are a lot of examples in =
the tree.

Any questions, feel free to ask.

Cheers,

Simon.