|
10.4 Linking a Library
Libraries often rely on code in other libraries. Traditionally the way
to deal with this is to know what the dependencies are and, when
linking an executable, be careful to list all of the dependencies on the
link line in the correct order. If you have ever built an X Window
application using a widget library, you will already be familiar with
this notion.
Even though you only use the functions in the widget library directly, a
typical link command would need to be:
| $ gcc -o Xtest -I/usr/X11R6/include Xtest.c -L/usr/X11R6/lib \
-lXm -lXp -lXaw -lXmu -lX11 -lnsl -lsocket
|
With modern architectures, this problem has been solved by allowing
libraries to be linked into other libraries, but this feature is not yet
particularly portable. If you are trying to write a portable project,
it is not safe to rely on native support for inter-library dependencies,
especially if you want to have dependencies between static and shared
archives. Some of the features discussed in this section were not fully
implemented before Libtool 1.4, so you should make sure that you are
using this version or newer if you need these features.
If you want to try the examples in this section to see what
libtool does on your machine, you will first need to modify
the source of `hello.c' to introduce a dependency on `trim.c':
| #include <stdio.h>
extern char *trim ();
extern void free ();
void
hello (char *who)
{
char *trimmed = trim (who);
printf ("Hello, %s!\n", trimmed);
free (trimmed);
}
|
You might also want to modify the `main.c' file to exercise the new
`trim' functionality to prove that the newly linked executable is
working:
| void hello ();
int
main (int argc, char *argv[])
{
hello ("\tWorld \r\n");
exit (0);
}
|
Suppose I want to make two libraries, `libtrim' and
`libhello'. `libhello' uses the `trim' function in
`libtrim' but the code in `main' uses only the `hello'
function in `libhello'. Traditionally, the two libraries are built
like this:
| $ rm hello *.a *.la *.o *.lo
$ gcc -c trim.c
$ ls
hello.c main.c trim.c trim.o
$ ar cru libtrim.a trim.o
$ ranlib libtrim.a
$ gcc -c hello.c
$ ls
hello.c hello.o libtrim.a main.c trim.c trim.o
$ ar cru libhello.a hello.o
$ ranlib libhello.a
$ ls
hello.c libhello.a main.c trim.o
hello.o libtrim.a trim.c
|
Notice that there is no way to specify that `libhello.a' won't work
unless it is also linked with `libtrim.a'. Because of this I need
to list both libraries when I link the application. What's more, I need
to list them in the correct order:
| $ gcc -o hello main.c libtrim.a libhello.a
/usr/bin/ld: Unsatisfied symbols:
trim (code)
collect2: ld returned 1 exit status
$ gcc -o hello main.c libhello.a libtrim.a
$ ls
hello hello.o libtrim.a trim.c
hello.c libhello.a main.c trim.o
$ ./hello
Hello, World!
|
|