/* Copyright (c) 2007 Eric B. Weddington
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of the copyright holders nor the names of
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE. */
/* $Id: library.dox,v 1.3 2007/12/20 14:17:56 joerg_wunsch Exp $ */
/**
\page library How to Build a Library
\section library_intro Introduction
So you keep reusing the same functions that you created over and over? Tired of
cut and paste going from one project to the next? Would you like to reduce your
maintenance overhead? Then you're ready to create your own library! Code reuse
is a very laudable goal. With some upfront investment, you can save time and
energy on future projects by having ready-to-go libraries. This chapter
describes some background information, design considerations, and practical
knowledge that you will need to create and use your own libraries.
\section library_linker How the Linker Works
The compiler compiles a single high-level language file (C language, for
example) into a single object module file. The linker (ld) can only work with
object modules to link them together. Object modules are the smallest unit
that the linker works with.
Typically, on the linker command line, you will specify a set of object modules
(that has been previously compiled) and then a list of libraries, including
the Standard C Library. The linker takes the set of object modules that you
specify on the command line and links them together. Afterwards there will
probably be a set of "undefined references". A reference is essentially a
function call. An undefined reference is a function call, with no defined
function to match the call.
The linker will then go through the libraries, in order, to match the undefined
references with function definitions that are found in the libraries. If it
finds the function that matches the call, the linker will then link in the
object module in which the function is located. This part is important: the
linker links in THE ENTIRE OBJECT MODULE in which the function is located.
Remember, the linker knows nothing about the functions internal to an object
module, other than symbol names (such as function names). The smallest unit the
linker works with is object modules.
When there are no more undefined references, the linker has linked everything
and is done and outputs the final application.
\section library_design How to Design a Library
How the linker behaves is very important in designing a library. Ideally, you
want to design a library where only the functions that are called are the
only functions to be linked into the final application. This helps keep the
code size to a minimum. In order to do this, with the way the linker works, is
to only write one function per code module. This will compile to one function
per object module. This is usually a very different way of doing things than
writing an application!
There are always exceptions to the rule. There are generally two cases where
you would want to have more than one function per object module.
The first is when you have very complementary functions that it doesn't make
much sense to split them up. For example, malloc() and free(). If someone is
going to use malloc(), they will very likely be using free() (or at least should
be using free()). In this case, it makes more sense to aggregate those two
functions in the same object module.
The second case is when you want to have an Interrupt Service Routine (ISR) in
your library that you want to link in. The problem in this case is that the
linker looks for unresolved references and tries to resolve them with code
in libraries. A reference is the same as a function call. But with ISRs, there
is no function call to initiate the ISR. The ISR is placed in the Interrupt
Vector Table (IVT), hence no call, no reference, and no linking in of the ISR.
In order to do this, you have to trick the linker in a way. Aggregate the ISR,
with another function in the same object module, but have the other function
be something that is required for the user to call in order to use the ISR, like
perhaps an initialization function for the subsystem, or perhaps a function
that enables the ISR in the first place.
\section library_creating Creating a Library
The librarian program is called \c ar (for "archiver") and is found in the GNU
Binutils project. This program will have been built for the AVR target and will
therefore be named \c avr-ar.
The job of the librarian program is simple: aggregate a list of object modules
into a single library (archive) and create an index for the linker to use. The
name that you create for the library filename must follow a specific pattern:
libname.a. The name part is the unique part of the filename that you create.
It makes it easier if the name part relates to what the library is about. This
name part must be prefixed by "lib", and it must have a file extension of .a,
for "archive". The reason for the special form of the filename is for how the
library gets used by the toolchain, as we will see later on.
\note The filename is case-sensitive. Use a lowercase "lib" prefix, and a
lowercase ".a" as the file extension.
The command line is fairly simple:
\code
avr-as rcs
\endcode
The \c r command switch tells the program to insert the object modules into
the archive with replacement. The \c c command line switch tells the program
to create the archive. And the \c s command line switch tells the program
to write an object-file index into the archive, or update an existing one. This
last switch is very important as it helps the linker to find what it needs to
do its job.
\note The command line switches are case sensitive! There are uppercase switches
that have completely different actions.
\note MFile and the WinAVR distribution contain a Makefile Template that
includes the necessary command lines to build a library. You will have to
manually modify the template to switch it over to build a library instead of
an application.
See the GNU Binutils manual for more information on the \c ar program.
\section library_using Using a Library
To use a library, use the \c -l switch on your linker command line. The string
immediately following the \c -l is the unique part of the library filename that
the linker will link in. For example, if you use:
\code
-lm
\endcode
this will expand to the library filename:
\code
libm.a
\endcode
which happens to be the math library included in avr-libc.
If you use this on your linker command line:
\code
-lprintf_flt
\endcode
then the linker will look for a library called:
\code
libprintf_flt.a
\endcode
This is why naming your library is so important when you create it!
The linker will search libraries in the order that they appear on the command
line. Whichever function is found first that matches the undefined reference, it
will be linked in.
There are also command line switches that tell GCC which directory to look in (\c -L)
for the libraries that are specified to be linke in with \c -l.
See the GNU Binutils manual for more information on the GNU linker (ld) program.
*/