First | Next | Previous | Last | Glossary | About

# Using the GNU archiver ar

- Introduction
- An example
- The command line
- Tutorial 1
- ar and libraries
- Read GNU ar description
- Tutorial 2

## Introduction

You have probably used programs like gunzip, pkzip, tar and others. In the case of gunzip and pkzip the programs gather groups of files and compress them into a single large file. The program tar does a similar job but without compression. There is a distant cousin of tar called ar, it too is an archiver but it has a particular application for programmers who need to maintain libraries for their programs.

Return to top of page

## An example

    ar ru cprogs.a *.cc

The first example shows a use of ar which you probably normally wouldn't bother with. I do it though to show you that although ar is normally thought of as a software development tool it can be used for all kinds of archiving.

In this example I have archived all the cc source files in the current directory. The command line uses an operation r - replace and a modifier u - update. The name of the archive is specified cprogs.a and a list of files to be archived follows. If the archive doesn't exist it will be created.

You could use r operation by itself, just replace. This is fine with a new archive but could be a problem for an existing archive. Just using r will replace a member already in the archive. It's not impossible that you might accidentally replace an archive member with an older version. If the archive exists then it is a good idea to use the u modifier which modifies the replace operation so that a member is only replaced if it is a newer version.

    ar t cprogs.a
    fn1.cc
    fn2.cc
    fdll.cc
    getr.cc
    tr1.cc
    tr2.cc

    ar tv cprogs.a
    rw-rw-rw- 0/0   46 Mar 03 09:31 2000 fn1.cc
    rw-rw-rw- 0/0   49 Mar 02 19:14 2000 fn2.cc
    rw-rw-rw- 0/0  360 Mar 02 21:00 2000 fdll.cc
    rw-rw-rw- 0/0  182 Mar 02 19:14 2000 getr.cc
    rw-rw-rw- 0/0  661 Mar 02 20:15 2000 tr1.cc
    rw-rw-rw- 0/0  491 Mar 02 21:02 2000 tr2.cc

    ar tv cprogs.a
    rw-rw-r-- 503/503 2584 Oct 14 20:01 1999 file1.cc
    rw-rw-r-- 503/503 2782 Oct 14 20:22 1999 file2.cc

To view the contents of the archive you can use the t - tabulate contents operation.

You can use a modifier v - verbose to get a detailed table of the archive contents.

The first tv example shows the output from a DOS/Win98 session, the second is from a Linux session. You can see they are slightly different and reflect the different file systems.

As the GNU man page says:

> The original files' contents, mode (permissions), timestamp, owner, and group are preserved in the archive, and may be reconstituted on extraction.

Here are two more examples, one using the q - quick operation, the other uses the d - delete operation.

    ar q cprogs.a fn1.cc

    ar tv cprogs.a
    rw-rw-rw- 0/0  46 Mar 03 09:31 2000 fn1.cc
    rw-rw-rw- 0/0  49 Mar 02 19:14 2000 fn2.cc
    rw-rw-rw- 0/0 360 Mar 02 21:00 2000 fdll.cc
    rw-rw-rw- 0/0 182 Mar 02 19:14 2000 getr.cc
    rw-rw-rw- 0/0 661 Mar 02 20:15 2000 tr1.cc
    rw-rw-rw- 0/0 491 Mar 02 21:02 2000 tr2.cc
    rw-rw-rw- 0/0  46 Mar 03 09:41 2000 fn1.cc
    ar d cprogs.a fn1.cc

    ar tv cprogs.a
    rw-rw-rw- 0/0  49 Mar 02 19:14 2000 fn2.cc
    rw-rw-rw- 0/0 360 Mar 02 21:00 2000 fdll.cc
    rw-rw-rw- 0/0 182 Mar 02 19:14 2000 getr.cc
    rw-rw-rw- 0/0 661 Mar 02 20:15 2000 tr1.cc
    rw-rw-rw- 0/0 491 Mar 02 21:02 2000 tr2.cc
    rw-rw-rw- 0/0  46 Mar 03 09:41 2000 fn1.cc

Return to top of page

## The command line options

    AR.EXE [-]{dmpqrstx}[abcilosSuvV] [member-name] archive-file file...
    AR.EXE -M [mri-script]
     commands:
      d            - delete file(s) from the archive
      m[ab]        - move file(s) in the archive
      p            - print file(s) found in the archive
      q[f]         - quick append file(s) to the archive
      r[ab][f][u]  - replace existing or insert new file(s) into the
                     archive
      t            - display contents of archive
      x[o]         - extract file(s) from the archive
     command specific modifiers:
      [a]          - put file(s) after [member-name]
      [b]          - put file(s) before [member-name] (same as [i])
      [f]          - truncate inserted file names
      [o]          - preserve original dates
      [u]          - only replace files that are newer than current archive
                     contents
     generic modifiers:
      [c]          - do not warn if the library had to be created
      [s]          - create an archive index (cf. ranlib)
      [S]          - do not build a symbol table
      [v]          - be verbose
      [V]          - display the version number
    AR.EXE: supported targets: pe-i386 pei-i386 srec symbolsrec
            tekhex binary ihex

Return to top of page

## Tutorial 1

Exercise 1.1

Create a temporary directory and copy some cc files to it. Change to the directory and create an archive of all the source files. List the archive to see that everything is there.

Exercise 1.2

Use the q operation as in ar q archive.a file.cc to add a second copy of a file to the archive. List the archive you should have to two identical members. If you now use the d operation which one will be deleted?

Exercise 1.3

Try using the a and b modifiers to set the location of members you add to the archive.

Return to top of page

## ar and libraries

I mentioned earlier that programmers use ar to create and maintain libraries for their programs. Anything can be archived but probably the most common thing is to create libraries of functions which can then be used by any program that has access to the library.

We'll work through an example which shows all the steps in creating and using a library.

    #define RAD (180.0/3.14159265359)
    double getr(double x)
    { return (x / RAD); }
    int fn1(int x, int y)
    { return  x * y; }
    int fn2(int x, int y)
    { return  x + y; }

Imagine we have three source files. We compile each of these to an object file:

- g++ -c fn1.cc
- g++ -c fn2.cc
- g++ -c getr.cc

We now have three object files fn1.o, fn2.o and getr.o.

    ar ru libfunc.a fnc1.o fnc2.o getr.o

We create the library using ar and we are ready to use it but first we need to create an interface, ie a header file.

    #ifndef FUNCLIB_H
    #define FUNCLIB_H

    int fn1(int, int);
    int fn2(int, int);
    double getr(double);

    #endif

The interface or header file is required for any source file which might want to use the library. The interface contains the declarations for whatever is in the library, any program using functions from the library will need these declarations because the function objects won't be available until link time.

    #include <iostream>
    #include "funclib.h"

    int main()
    { int i;
      double r;

      i = fn1(22,22);
      r = 45;
      cout << r << " degrees is "
           << getr(45)
           << " radians." << endl;
      cout << i << endl;
      cout << fn2(22,23) << endl;
    }

The simplest way is to directly link the library with a program which needs to use the functions:

    g++ -o tr tr1.cc libfunc.a

Here you can see a simple program which uses each of the functions. The compiler compiles tr1.cc to get an object file tr1.o then this is linked with the library to create the executable file tr1.

Note that tr1.cc uses the interface funclib.h.

    g++ -o tr tr1.cc -L. -lfunc

Linking this way is quite legitimate but probably not done very often. The usual way is to use a library argument in the command line:

    g++ -o tr tr1.cc -L. -lfunc

The -L argument is followed by a . (dot). This directs the compiler to look in the current directory for libraries, in effect -L adds the path which follows to the library search path.

    g++ -o tr3 tr1.cc -L../units -lfunc

We can put any path after -L but make sure there are no spaces between the switch and the directory.

If you have the right permissions you can copy your library to a standard library directory and then use:

    g++ -o tr2 tr1.cc -lfunc

This would be necessary if the library was to be used by many different programmers.

Return to top of page

## Tutorial 2

Exercise 2.1

Copy the example source files and build and test the library libfunc.a.

Exercise 2.2

Create the following functions and add them to the library:

- a function to convert yards to metres,
- a function to convert metres to yards,
- a function to convert nautical miles to yards,
- a function which returns a random integer in the range 1 to 1000.

Exercise 2.3

Give a copy of the archive file and the interface file to someone else and get them to use each of the functions in a program. The user of your library is not to know how you implemented the functions.

Exercise 2.4

Create a Makefile which builds the library and make it.

Return to top of page

First | Next | Previous | Last | Glossary | About

Copyright © 1999 - 2001 David Beech