[bind10-dev] Libtool problem

Stephen Morris stephen at isc.org
Thu May 12 13:27:17 UTC 2011


I've been fighting with libtool in working on ticket 542 and have
reached a bit of an impasse.  Although the fix is simple and quick (and
is what I have checked into the repository), there is an underlying
problem that I don't understand.  I've encountered it before, so if
anyone has a solution, I'd be interested to know what it is.

Regards

Stephen


Introduction
============
If we build a shared library A which is linked against shared library B,
then build a program P that links against A, when we run P we expect
both A and B to be loaded. In other words, the requirement for B is
hidden from P; when linking P we only need to specify A in the link
command line, we should not have to specify B as well.

However, this is precisely the problem that was encountered recently
when building BIND 10 during work on ticket 542.  After a lot of messing
around and adding what appeared to be additional dependencies to the
makefiles, the situation was reached where the problem occurred at only
one place in the build.  This is described below.


The Problem
===========
After removing all non-repository files (with "git clean -fdx"), then
running autoreconf and configure, a "make check" was executed.  This
failed with the error:

/home/stephen/bind10/tests/tools/badpacket/tests/.libs/lt-run_unittests:
   error while loading shared libraries: libutil.so.0: cannot open
   shared object file: No such file or directory

In the above it can be seen that the failure occurred when running the
unit tests for tests/tools/badpacket and was due to being unable to find
the BIND 10 utilities library.  "lt-run_unittests" is the actual image
being run, and from the name (and location) it can be seen that this has
been created using libtool.

ldd showed the shared library dependencies of lt-run_unittests as:

libutil_unittests.so.0 => /home/stephen/bind10/src/lib/util/
    unittests/.libs/libutil_unittests.so.0 (0x00d02000)
libutil.so.0 => not found
libexceptions.so.0 => not found
libutil.so.0 => /home/stephen/bind10/src/lib/util/.libs/
    libutil.so.0 (0x00b3a000)
libutil_io.so.0 => /home/stephen/bind10/src/lib/util/io/.libs/
    libutil_io.so.0 (0x00163000)
libexceptions.so.0 => /home/stephen/bind10/src/lib/exceptions/.libs/
    libexceptions.so.0 (0x00267000)

(Long lines have been wrapped and references to system libraries removed.)

Of note is that there are two entries for libutil: one points to the
library and one (the first) is marked "not found".  The same is true for
libexceptions (the shared library for BIND 10 exceptions).

The dependency for libutil was added to the Makefile.am and a relink
forced forced by deleting run_unittests and executing "make check".
This produced the error:

/home/stephen/bind10/tests/tools/badpacket/tests/.libs/lt-run_unittests:
   error while loading shared libraries: libexceptions.so.0:
   cannot open shared object file: No such file or directory

The ldd output was similar to the output given above except that the
"not found" entry for libutil had disappeared.  (Also, the various
addresses associated with each library had changed.) When libexceptions
was added to the Makefile.am and the program re-linked and run, all
worked. (This ended up as the version of Makefile.am checked into git.)

Library Dependencies
====================
The fact that there were two entries in the image for libutil and
libexceptions suggests that something has gone wrong.  Also, there
should be no need to include them in the link process: the Makefile
links in the libutil_unittests library which itself is linked to these.

In the diagram below, the symbol "A ---> B" indicates a link dependency:
in other words, in the Makefile.am building library A, there is a line
of the form:

libA_LIBADD += $(top_builddir)/<path>/libB.la

(The exception is the top-level program, where the dependency is
enforced by a line with the LDADD symbol.)

run_unittests ---> util_unittests -+-> util ---> exceptions
                                   |
                                   +-> util_io
                                   |
                                   +-> exceptions


Running ldd on libtuil_unittests gave:

libutil.so.0 => /home/stephen/bind10/src/lib/util/.libs/
    libutil.so.0 (0x00d5b000)
libutil_io.so.0 => /home/stephen/bind10/src/lib/util/io/.libs/
    libutil_io.so.0 (0x00e6e000)
libexceptions.so.0 => /home/stephen/bind10/src/lib/exceptions/.libs/
    libexceptions.so.0 (0x001cb000)

... and running it on libutil.so gives:

libexceptions.so.0 => /home/stephen/bind10/src/lib/exceptions/.libs/
    libexceptions.so.0 (0x009c5000)

All appears normal: ldd shows the dependencies expected from the
dependency diagram.


Current State
=============
The unanswered question is why the link of the test program appears to
introduce two dependencies on BIND 10 libraries, one pointing to the
correct library and one to "not found".  I've tried playing around with
the order of libraries on the command line but to no avail.  I suspect
it is some issue concerning search paths, but nothing I've done seems to
have an effect.

Rather than spend any more time on the issue, the quick way out -
specify the libraries explicitly in the Makefile.am - has been taken.
But if anyone has a clue as to what is happening, I'd be interested to know.



More information about the bind10-dev mailing list