Google

Back: Linking an Executable
Forward: Inter-library Dependencies
 
FastBack: Executing Uninstalled Binaries
Up: Introducing GNU Libtool
FastForward: Executing Uninstalled Binaries
Top: Autoconf, Automake, and Libtool
Contents: Table of Contents
Index: Index
About: About this document

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!


This document was generated by Gary V. Vaughan on May, 24 2001 using texi2html