Top Up Prev Next Bottom Contents Index Search

D.1 Introduction


Shared libraries are a facility that can provide many benefits to software but have a slight cost of additional complications. In this appendix we discuss the pros and cons of shared libraries. For further information about shared libraries, you should consult the programmer's documentation that comes with your operating system, such as the Unix ld manual page.

D.1.1 Static Libraries

A static library file is a file that consists of an archive of object files (.o files) collected into one file by the ar program. Static libraries usually end with .a (i.e., libg++.a). At link time, static libraries are searched for each global function or variable symbol. If the symbol is found then the code for that symbol is copied into the binary. In addition, any other symbols that were in the original .o file for the symbol in question are also copied into the binary. In this way, if we need a symbol that is dependent on other functions in the .o file in which it is defined, at link time we get the dependent functions. There are several important details about linking, such as the order of libraries, that should be discussed in your system documentation.

D.1.2 Shared Libraries

Most modern operating systems have shared libraries that can be linked in at runtime. SunOS4.x, Solaris2.x and HPUX all have shared libraries.

Shared libraries allow multiple programs to share a library on disk, rather than copying code into a binary, resulting in smaller binaries. Also shared libraries allow a binary to access all of the symbols in a shared library at runtime, even if a symbol was not needed at link time.

A shared library consists of an archive of object files (.o files) collected into one file by either the compiler or the linker. Usually, to create a shared library, the .o files must be compiled into Position Independent Code (PIC) by the compiler. The compiler usually has a special option to produce PIC code, under gcc/g++, the -fPIC option produces PIC code. Shared libraries have suffixes that are architecture dependent: under SunOS4.1 and Solaris, shared libraries end with .so (i.e., libg++.so); under HPUX, shared libraries end with .sl (i.e., libg++.sl).

In addition, shared libraries can also have versioning information included in the name. Shared library versioning is architecture dependent, but a versioned shared library name might look like libg++.so.2.7.1. Note that the version of a shared library can be encoded in the shared library in the SONAME feature of that library. Usually, the SONAME of a library is the same as the filename (i.e., the SONAME of /users/ptolemy/gnu/sol2/lib/libg++.so.2.7.1 would be libg++.so.2.7.1). Interestingly, if you rename a shared library without changing the SONAME and then link against the renamed shared library, then at runtime the binary may report that it cannot find the proper library.

The constraint with shared libraries is that the binary be able to find the shared libraries at run time. Exactly how this is done is architecture dependent, but in general the runtime linker looks for special environment variable that contains pathnames for directories to be searched. Under SunOS4.1.x and Solaris2.x, this environment variable is named LD_LIBRARY_PATH. Under HPUX, the variable is named SHLIB_PATH. A binary can also have a list of pathnames to be searched encoded inside it. Usually this is called the RPATH. In general, asking the user to set the LD_LIBRARY_PATH or SHLIB_PATH is frowned upon. It is better if the binary has the proper RPATH set at link time.

D.1.3 Differences between static and shared libraries: Unresolved symbols

A library consists of .o files archived together. A .o file inside a library might contain symbols (functions, variables etc.) that are not used by your program.

At link time, a static library can have unresolved symbols in it, as long as you don't need the unresolved symbols, and you don't need any symbol that is in a .o file that contains an unresolved symbol. However, with shared libraries, you must resolve all the symbols at link time, even if you don't necessarily use the unresolved symbol.

As an example, say you have a program that uses a symbol from the pigi library ($PTOLEMY/lib.$PTARCH/libpigi.*), but does not use Octtools which is used by other files that make up the pigi library

If you are linking with a static library, you can have some unresolved symbols in the static library, as long as you don't reference the unresolved symbols. So, in our example, you could just link with the static libpigi.a.

If you are linking with a shared libpigi, you must resolve all the unresolved symbols. So, if you need a symbol from the libpigi library, then you must also include references to the Octtools libraries that pigilib uses, even though you are not using Octtools. So you would have to link in liboct.so and libport.so and the other Octtools libraries.

One positive benefit of this is that all the symbols in pigilib are available at run time, which makes incremental linking much easier, especially if we have a shared g++ library.

D.1.4 Differences between static and shared libraries: Pulling in stars

If you are using static libraries, then for a symbol to be present in the binary, you must explicitly reference that symbol at link time. When building Ptolemy with static libraries, each star directory contains a xxxstars.c file (where xxx is the domain name, an example file is $PTOLEMY/src/domains/sdf/stars/sdfstars.c) which gets compiled into xxxstars.o. At link time, the xxxstars.o file is included in the link command and the linker searches libxxxstars.a for the symbols defined in xxxstars.o, and pulls in the rest of the star definition.

If you are using shared libraries, then all the symbols in the libxxxstars file are present at runtime, so you need not include the xxxstars.o file at link time.



Top Up Prev Next Bottom Contents Index Search

Copyright © 1990-1997, University of California. All rights reserved.