2011年1月1日星期六

强烈推荐的(strongly recommended)...

点击播放按钮即可播放(仅限于Firefox,不兼容IE):


Name
Artist
Album
Play!
Delicate
Damien Rice
O
Play!
Amie
Damien Rice
O
Play!

使用BlogThisSong!,在你的博客上放置一个带歌词显示功能的音乐播放器!

2007年2月11日星期日

[转载]使用ar来生成静态库

1. Introduction

A library is really nothing more than a collection of object files. When the collection of object files provides related behavior to solve a given problem, the objects can be integrated into a library to simplify their access for application developers.

Static libraries are created using the ar or archive, utility. Once the application developer compiles and then links with the library, the needed elements of the library are integrated into the resulting executable image. From the perspective of the application, the external library is no longer relevant because it’s been combined with the application image.

2. Building using ar

Let’s now get back to the subject of libraries, and rather than build the entire source together, we’ll build a library for our random number functions. This is achieved using the ar utility (archive). Below, we’ll demonstrate the building of our static library along with the construction of the final image.

$ gcc -c -Wall initapi.c $ gcc -c -Wall randapi.c $ ar -cru libmyrand.a initapi.o randapi.o

Next, we use the ar command to build our library (libmyrand.a). The cru options are a standard set of options for creating or adding to an archive. The c option specifies to create the static library (unless it already exists, in which case the option is ignored). The r option tells ar to replace existing objects in the static library (if they already exist). Finally, the u option is a safety option to specify that objects are replaced in the archive only if the objects to be inserted are newer than existing objects in the archive (of the same name).



We now have a new file called libmyrand.a, which is our static library containing two objects: initapi.o and randapi.o. Let’s now look at how we can build our application using this static library. Consider the following:

$ gcc test.c -L. -lmyrand -o test
$ ./test
getRand() Average 4
getSRand() Average 0.499892
$

Here we use gcc to first compile the file test.c and then link the test.o object with libmyrand.a to produce the test image file. The -L. option tells gcc that libraries can be found in the current subdirectory (. represents the directory). Note that we could also provide a specific subdirectory for the library, such as -L/usr/mylibs. The -l option identifies the library to use. Note that myrand isn’t the name of our library, but instead libmyrand.a. When the -l option is used, it automatically surrounds the name specified with lib and .a. Therefore, if the user had specified -ltest, gcc would look for a library called libtest.a.

Now that we see how to create a library and use it to build a simple application, let’s return to the ar utility to see what other uses it has. We can inspect a static library to see what’s contained within it by using the -t option:

$ ar -t libmyrand.a
initapi.o
randapi.o
$

If desired, we can also remove objects from a static library. This is done using the -d option, such as:

$ ar -d libmyrand.a initapi.o
$ ar -t libmyrand.a
randapi.o
$

It’s important to note that ar won’t actually show a failure for a delete. To see an error message if the delete fails, add a -v option as shown below:

$ ar -d libmyrand.a initapi.o
$ ar -dv libmyrand.a initapi.o
No member named ‘initapi.o’
$

In the first case, we try to delete the object initapi.o, but no error message is generated (even though it doesn’t exist in the static library). In the second case, we add the verbose option and the corresponding error message results.

Rather than remove the object from the static library, we can extract it using the -x option.

$ ar -xv libmyrand.a initapi.o
x - initapi.o
$ ls
initapi.o libmyrand.a
$ ar -t libmyrand.a
randapi.o
initapi.o
$

The extract option is coupled with verbose (-v) so that we can see what ar is doing. The ar utility responds with the file being extracted (x - initapi.o), which we can see after doing a ls in the subdirectory. Note here that we also list the contents of the static library after extraction, and our initapi.o object is still present. The extract option doesn’t actually remove the object, it only copies it externally to the archive. The delete (-d) option must be used to remove it outright from the static library.

The ar utility option list is shown in Table 1.

Table 1: Important Options for the ar Utility

Option

Name

Example

-d

Delete

ar -d <archive> <objects>

-r

Replace

ar -r <archive> <objects>

-t

Table list

ar -t <archive>

-x

Extract

ar -x <archive> <objects>

-v

Verbose

ar -v

-c

Create

ar -c <archive>

-ru

Update object

ar -ru <archive> <objects>


ranlib

The ranlib utility is one of the most important utilities when creating static libraries. This utility creates an index of the contents of the library and stores it in the library file itself. When this index is present in the library, the linking stage of building an image can be sped up considerably. Therefore, the ranlib utility should be performed whenever a new static library is created. An example of using ranlib is shown here:

$ ranlib libmyrand.a
$

Note that the same thing can be performed using the ar command with the -s option, as:

$ ar -s libmyrand.a