### 11.1 Creating a library with the GNU archiver ¶

The GNU archiver `ar` combines a collection of object files into a single archive file, also known as a library. An archive file is simply a convenient way of distributing a large number of related object files together (as described earlier in Linking with external libraries).

To demonstrate the use of the GNU archiver we will create a small library `libhello.a` containing two functions `hello` and `bye`.

The first object file will be generated from the source code for the `hello` function, in the file `hello_fn.c` seen earlier:

    #include <stdio.h>
    #include "hello.h"

    void
    hello (const char * name)
    {
      printf ("Hello, %s!\n", name);
    }

The second object file will be generated from the source file `bye_fn.c`, which contains the new function `bye`:

    #include <stdio.h>
    #include "hello.h"

    void
    bye (void)
    {
      printf ("Goodbye!\n");
    }

Both functions use the header file `hello.h`, now with a prototype for the function `bye()`:

    void hello (const char * name);
    void bye (void);

The source code can be compiled to the object files `hello_fn.o` and `bye_fn.o` using the commands:

    $ gcc -Wall -c hello_fn.c
    $ gcc -Wall -c bye_fn.c

These object files can be combined into a static library using the following command line:

    $ ar cr libhello.a hello_fn.o bye_fn.o

The option `cr` stands for “create and replace”.39 If the library does not exist, it is first created. If the library already exists, any original files in it with the same names are replaced by the new files specified on the command line. The first argument `libhello.a` is the name of the library. The remaining arguments are the names of the object files to be copied into the library.

The archiver `ar` also provides a “table of contents” option `t` to list the object files in an existing library:

    $ ar t libhello.a
    hello_fn.o
    bye_fn.o

Note that when a library is distributed, the header files for the public functions and variables it provides should also be made available, so that the end-user can include them and obtain the correct prototypes.

We can now write a program using the functions in the newly created library:

    #include "hello.h"

    int
    main (void)
    {
      hello ("everyone");
      bye ();
      return 0;
    }

This file can be compiled with the following command line, as described in Linking with external libraries, assuming the library `libhello.a` is stored in the current directory:

    $ gcc -Wall main.c libhello.a -o hello

The main program is linked against the object files found in the library file `libhello.a` to produce the final executable.

The short-cut library linking option `-l` can also be used to link the program, without needing to specify the full filename of the library explicitly:

    $ gcc -Wall -L. main.c -lhello -o hello

The option `-L.` is needed to add the current directory to the library search path. The resulting executable can be run as usual:

    $ ./hello
    Hello, everyone!
    Goodbye!

It displays the output from both the `hello` and `bye` functions defined in the library.

#### Footnotes

##### (39)

Note that `ar` does not require a prefix ‘`-`’ for its options.