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 &Library;
instead of &Program;:
Library('foo', ['f1.c', 'f2.c', 'f3.c'])
&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
cc -c -o f1.o f1.c
cc -c -o f2.o f2.c
cc -c -o f3.o f3.c
ar r libfoo.a f1.o f2.o f3.o
ranlib libfoo.a
On a Windows system,
a build of the above example would look like:
C:\>scons -Q
cl /nologo /c f1.c /Fof1.obj
cl /nologo /c f2.c /Fof2.obj
cl /nologo /c f3.c /Fof3.obj
lib /nologo /OUT:foo.lib f1.obj f2.obj f3.obj
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.
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 &LIBS; construction variable,
and by specifying the directory in which
the library will be found in the
&LIBPATH; construction variable:
Library('foo', ['f1.c', 'f2.c', 'f3.c'])
Program('prog.c', LIBS='foo', LIBPATH='.')
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
cc -c -o f1.o f1.c
cc -c -o f2.o f2.c
cc -c -o f3.o f3.c
ar r libfoo.a f1.o f2.o f3.o
ranlib libfoo.a
cc -c -o prog.o prog.c
cc -o prog prog.o -L. -lfoo
On a Windows system,
a build of the above example would look like:
C:\>scons -Q
cl /nologo /c f1.c /Fof1.obj
cl /nologo /c f2.c /Fof2.obj
cl /nologo /c f3.c /Fof3.obj
lib /nologo /OUT:foo.lib f1.obj f2.obj f3.obj
cl /nologo /c prog.c /Foprog.obj
link /nologo /OUT:prog.exe /LIBPATH:. foo.lib prog.obj
As usual, notice that &SCons; has taken care
of constructing the correct command lines
to link with the specified library on each system.
Finding Libraries: the &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
&LIBPATH; construction variable.
&LIBPATH; consists of a list of
directory names, like so:
Program('prog.c', LIBS = 'm',
LIBPATH = ['/usr/lib', '/usr/local/lib'])
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'
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
cc -c -o prog.o prog.c
cc -o prog prog.o -L/usr/lib -L/usr/local/lib -lm
On a Windows system,
a build of the above example would look like:
C:\>scons -Q
cl /nologo /c prog.c /Foprog.obj
link /nologo /OUT:prog.exe /LIBPATH:\usr\lib /LIBPATH:\usr\local\lib m.lib prog.obj
Note again that &SCons; has taken care of
the system-specific details of creating
the right command-line options.