The Linker

The linker is a program that takes the object files (.o) produced by the compiler, including object files stored in libraries and turns them into programs (or DLLs). It does this by combining the object files and linking (or resolving) the names (or symbols) used in one object but not defined to symbols (i.e. pieces of code or data) defining those names in other objects. This is why it is called linking.

In the GNU compiler suite the linker is called ld. However you should not run ld directly except under very special circumstances. Instead you should use the front end, gcc, which was mentioned in the section on the compiler. To link a program you can type in a command like this:

gcc -o foobar.exe foo.o bar.o

That command produces a program called foobar.exe as output (from the -o foobar.exe argument) by combining the object files foo.o and bar.o. For any object file included directly on the linker command line (like foo.o and bar.o in that example) the linker simply includes all the symbols (functions and data) from the object file in the program. It also checks for the entry point (e.g. the function main in a console-based C program) and includes the position of that function in the program header so that when the program is run it will start at that function.

Linking With Libraries

To link with a library you can do two things. You can include the library on the linker command line directly, like this:

gcc -o foobar.exe foo.o bar.o libstuff.a

In addition to linking the object files foo.o and bar.o this will add the objects in the library libstuff.a that contain functions and data used by the first two objects (or, in turn, the objects linked in to provide those functions and/or data) to the program.  You can also do this with the -l option (l for library).

gcc -o foobar.exe foo.o bar.o -lstuff

The -l option doesn't require that you know exactly where the library is, as long as it is one of a standard set of directories (the library path). Notice that you don't put a space between the name of the library and the -l option. Also, you don't use the full file name of the library but instead only the part after lib and before .a. The linker looks for the library called libstuff.a in some standard places and checks all the objects in the library for symbols which are used by foo.o or bar.o but which aren't defined by either of them. If it finds an object which supplies a needed symbol it includes that object in the executable (but not the whole library). Of course, it also checks objects included from libraries in this way for undefined symbols and trys to resolve them as well, which may lead to more objects being included from libraries until all the symbols are resolved.

One thing that is important to remember about linking with gcc is that it checks libraries in the order they appear, and it will only resolve references to symbols in libraries earlier on the command line if the object containing the symbol definition was already included for some other reason. Thus if foo.o uses a function in libstuff.a the following command line will fail:

gcc -o foobar.exe -lstuff foo.o bar.o

Also if the library libmorestuff.a uses functions in libstuff.a which are not used by foo.o or bar.o then the following may fail:

gcc -o foobar.exe foo.o bar.o -lstuff -lmorestuff

Finally, if a symbol is defined in two different libraries gcc will use the first one it finds and ignore the second one unless the second one is included in an object file which gets included for some other reason. Say the library libstuff.a defines a function called StuffIt and libmorestuff.a also defines a function called StuffIt in the same object file as a function called StuffSomeMore. If foo.o contained a call to StuffIt the function used will be the one in libstuff.a. However, if foo.o contained a call to both StuffIt and StuffSomeMore, or if bar.o contained a call to StuffSomeMore then the above example would result in an "duplicate symbol" error.

Telling gcc Where to Find Libraries

gcc will search in some default locations for libraries. It will also search all the directories listed in the environment variable LIBRARY_PATH. So, for example, including the following statement in the autoexec.bat file for Windows 98 will allow a Mingw32 version of gcc to find libstuff.a in the directory C:\mylibs or in the directory C:\usr\local\lib (note, you can use either slashes or backslashes as path separators, and you can leave off the drive letters if you always compile on the same drive as the directories listed in the path).

SET LIBRARY_PATH=C:\mylibs;C:\usr\local\lib

One of the directories not searched by default is the current directory. To include the current directory, or any other directory in the search use the -L option. The following command line would search in the current directory (indicated by the special name '.') and in the directory \usr\local\lib on the same drive for the library libstuff.a.

gcc -o foobar.exe foo.o bar.o -L. -L/usr/local/lib -lstuff

Like the -l option you don't include a space between the -L and the directory name. You can use slashes or backslashes with the Mingw32 version of gcc, but I prefer to use slashes. Remember to include the -L option before the -l option so that the library path is set before gcc tries to search for the library.