Section 11.5. Archiving Modules: ar


[Page 408 (continued)]

11.5. Archiving Modules: ar

A medium-sized C project typically uses several hundred object modules. Specifying this many object modules on a command can be tedious and error prone, so I recommend that you learn how to use the GNU archive utility, ar, to organize and group your object modules. An archive utility is sometimes known as a librarian. It allows you to perform the following tasks:

  • creating a special archive format file, ending in a ".a" suffix

  • adding, removing, replacing, and appending any kind of file to an archive

  • obtaining an archive's table of contents

Figure 11-2 is a synopsis of ar.

Figure 11-2. Description of the ar command.

Utility: ar key archiveName { fileName }*

ar allows you to create and manipulate archives. archiveName is the name of the archive file that you wish to access, and it should end with a ".a" suffix. key may be one of the following:

d - deletes a file from an archive

q - appends a file onto the end of an archive, even if it's already present

r - adds a file to an archive if it isn't already there, or replaces the current version if it is

s - builds an index (table of contents) of the library for faster access

t - displays an archive's table of contents to standard output

x - copies a list of files from an archive into the current directory

v - generates verbose output


When a set of object modules is stored in an archive file, it may be accessed from the gcc compiler by simply supplying the name of the archive file as an argument. Any object modules that are needed from the archive file are automatically linked as necessary. This greatly reduces the number of parameters to these utilities when linking large numbers of object modules.

11.5.1. Creating or Adding a File

An archive is automatically created when the first file is added. To add a file to (or replace a file in) a named archive, use the ar utility with the r option (Figure 11-3).


[Page 409]

Figure 11-3. Adding or replacing a file in an archive.

ar r archiveName { fileName }+


This option adds all of the specified files to the archive file archiveName, replacing files if they already exist. If the archive file doesn't exist, it is automatically created. The name of the archive should have a ".a" suffix.

11.5.2. Appending a File

To append a file to a named archive, use the ar utility with the q option (Figure 11-4).

Figure 11-4. Appending a file to an archive.

ar q archiveName { fileName }+


This option appends all of the specified files to the archive file archiveName, regardless of whether they already exist. If the archive file doesn't exist, it is automatically created. This option is handy if you know that the file isn't already present, as it allows ar to avoid searching through the archive.

11.5.3. Obtaining a Table of Contents

To obtain a table of contents of an archive, use the ar utility with the t option (Figure 11-5).

Figure 11-5. Listing the table of contents of an archive.

ar t archiveName


11.5.4. Deleting a File

To delete a list of files from an archive, use the ar utility with the d option (Figure 11-6).

Figure 11-6. Deleting files from an archive.

ar d archiveName {fileName }+


11.5.5. Extracting a File

To copy a list of files from an archive to the current directory, use the ar utility with the x option (Figure 11-7). If you don't specify a list of files, then all of the files in the archive are copied.

Figure 11-7. Extracting a file from an archive.

ar x archiveName { fileName }+



[Page 410]

11.5.6. Maintaining an Archive from the Command Line

Here is an example that illustrates how an archive may be built and manipulated from the command line, using the object modules built earlier in this chapter.

First, I built an archive file called "string.a" to hold all of my string-related object modules. Next, I added each module in turn using the r option. Finally, I demonstrated the various different ar options:

$ gcc -c reverse.c palindrome.c main2.c ...create object files. $ ls *.o                                ...confirm. main2.o     palindrome.o      reverse.o $ ar r string.a reverse.o palindrome.o  ...add to an archive. ar: creating string.a $ ar t string.a       ...obtain a table of contents. reverse.o palindrome.o $ gcc main2.o string.a -o main2     ...link the object modules. $ main2                             ...execute the program. palindrome ("cat") = 0 palindrome ("noon") = 1 $ ar d string.a reverse.o           ...delete a module. $ ar t string.a                     ...confirm deletion. palindrome.o $ ar r string.a reverse.o           ...put it back again. $ ar t string.a                     ...confirm addition. palindrome.o reverse.o $ rm palindrome.o reverse.o         ...delete originals. $ ls *.o                            ...confirm. main2.o $ ar x string.a reverse.o           ...copy them back again. $ ls *.o                            ...confirm. main2.o     reverse.o $ _ 


11.5.7. Indexing Archives

The ar utility does not maintain any particular order in an archive file. This is usually fine, because gcc and its linker are able to extract object modules and resolve external references regardless of order. However, you could have a problem if functions in the archive call each other, depending on the order in which they are found by the linker. If object module A contains a function that calls a function in object module B, then B must appear before A in the archive. Even if you maintained your ordering properly, you could get into a circular organization where one of the modules couldn't find another one and you would wind up with an error about unresolved references to functions that you know you have in your library.

You can help the linker to resolve out-of-order object modules by adding a table of contents to each archive. This also speeds up the linking process, since it doesn't have to search through the archive for each function. On UNIX systems this is often done with the ranlib utility. On Linux, you need only add the s option to your ar command line, like this:


[Page 411]

$ ar rs string.a reverse.o palindrome.o 


11.5.8. Shared Libraries

Static libraries work just fine for many applications. However, as processor speed increases and the prices of disk and memory come down, code has been allowed to become more complex. Programs linked with large archive libraries will result in very large executable files (a small program that creates a single X window can be a megabyte when linked with the required X libraries).

To reduce the size of your generated object code, you can link your program with a shared library instead. A shared (or dynamic) library is associated with a compiled program, but its functions are loaded in dynamically as they are needed rather than all at once at load time. The resulting object code is smaller, because it does not include the object code from the library as it does when linked with a static library.

The one disadvantage of using a shared library is that your object code will have been written for a specific version of the library. If bug fixes are made but no interface changes are made, then your program will benefit from the newer library that works better. However, if calling interface changes are made, problems may (probably will) result when your program links with the newer version of the library at run time. It is therefore important to be aware of changes in supporting libraries when writing an application.

The gcc command honors arguments (that are passed to the linker) to allow you to specify it to build a shared library rather than a static library. These arguments are -shared and -static.




Linux for Programmers and Users
Linux for Programmers and Users
ISBN: 0131857487
EAN: 2147483647
Year: 2007
Pages: 339

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net