# Building and Linking with Libraries

It's often useful to organize large software projects by collecting parts of the software into one or more libraries. &SCons; makes it easy to create libraries and to use them in the programs.

## Building Libraries

You build your own libraries by specifying &b-link-Library; instead of &b-link-Program;:

Library('foo', ['f1.c', 'f2.c', 'f3.c'])
void f1() { printf("f1.c\n"); }
void f2() { printf("f2.c\n"); }
void f3() { printf("f3.c\n"); }

&SCons; uses the appropriate library prefix and suffix for your system. So on POSIX or Linux systems, the above example would build as follows (although &ranlib; may not be called on all systems):

scons -Q

On a Windows system, a build of the above example would look like:

scons -Q

The rules for the target name of the library are similar to those for programs: if you don't explicitly specify a target library name, &SCons; will deduce one from the name of the first source file specified, and &SCons; will add an appropriate file prefix and suffix if you leave them off.

### Building Libraries From Source Code or Object Files

The previous example shows building a library from a list of source files. You can, however, also give the &b-link-Library; call object files, and it will correctly realize they are object files. In fact, you can arbitrarily mix source code files and object files in the source list:

Library('foo', ['f1.c', 'f2.o', 'f3.c', 'f4.o'])
void f1() { printf("f1.c\n"); }
object file
void f3() { printf("f3.c\n"); }
object file

And SCons realizes that only the source code files must be compiled into object files before creating the final library:

scons -Q

Of course, in this example, the object files must already exist for the build to succeed. See , below, for information about how you can build object files explicitly and include the built files in a library.

### Building Static Libraries Explicitly: the &b-StaticLibrary; Builder

The &b-link-Library; function builds a traditional static library. If you want to be explicit about the type of library being built, you can use the synonym &b-link-StaticLibrary; function instead of &b-Library;:

StaticLibrary('foo', ['f1.c', 'f2.c', 'f3.c'])

There is no functional difference between the &b-link-StaticLibrary; and &b-Library; functions.

### Building Shared (DLL) Libraries: the &b-SharedLibrary; Builder

If you want to build a shared library (on POSIX systems) or a DLL file (on Windows systems), you use the &b-link-SharedLibrary; function:

SharedLibrary('foo', ['f1.c', 'f2.c', 'f3.c'])
void f1() { printf("f1.c\n"); }
void f2() { printf("f2.c\n"); }
void f3() { printf("f3.c\n"); }

The output on POSIX:

scons -Q

And the output on Windows:

scons -Q

Notice again that &SCons; takes care of building the output file correctly, adding the `-shared` option for a POSIX compilation, and the `/dll` option on Windows.

## Linking with Libraries

Usually, you build a library because you want to link it with one or more programs. You link libraries with a program by specifying the libraries in the &cv-link-LIBS; construction variable, and by specifying the directory in which the library will be found in the &cv-link-LIBPATH; construction variable:

Library('foo', ['f1.c', 'f2.c', 'f3.c']) Program('prog.c', LIBS=['foo', 'bar'], LIBPATH='.')
int main() { printf("Hello, world!\n"); }
int main() { printf("Hello, world!\n"); }
int main() { printf("Hello, world!\n"); }
int main() { printf("Hello, world!\n"); }

Notice, of course, that you don't need to specify a library prefix (like `lib`) or suffix (like `.a` or `.lib`). &SCons; uses the correct prefix or suffix for the current system.

On a POSIX or Linux system, a build of the above example would look like:

scons -Q

On a Windows system, a build of the above example would look like:

scons -Q

As usual, notice that &SCons; has taken care of constructing the correct command lines to link with the specified library on each system.

Note also that, if you only have a single library to link with, you can specify the library name in single string, instead of a Python list, so that:

Program('prog.c', LIBS='foo', LIBPATH='.')

is equivalent to:

Program('prog.c', LIBS=['foo'], LIBPATH='.')

This is similar to the way that &SCons; handles either a string or a list to specify a single source file.

## Finding Libraries: the &cv-LIBPATH; Construction Variable

By default, the linker will only look in certain system-defined directories for libraries. &SCons; knows how to look for libraries in directories that you specify with the &cv-link-LIBPATH; construction variable. &cv-LIBPATH; consists of a list of directory names, like so:

Program('prog.c', LIBS = 'm', LIBPATH = ['/usr/lib', '/usr/local/lib'])
int main() { printf("prog.c\n"); }

Using a Python list is preferred because it's portable across systems. Alternatively, you could put all of the directory names in a single string, separated by the system-specific path separator character: a colon on POSIX systems:

LIBPATH = '/usr/lib:/usr/local/lib'

or a semi-colon on Windows systems:

LIBPATH = 'C:\\lib;D:\\lib'

(Note that Python requires that the backslash separators in a Windows path name be escaped within strings.)

When the linker is executed, &SCons; will create appropriate flags so that the linker will look for libraries in the same directories as &SCons;. So on a POSIX or Linux system, a build of the above example would look like:

scons -Q

On a Windows system, a build of the above example would look like:

scons -Q

Note again that &SCons; has taken care of the system-specific details of creating the right command-line options.