For a software developer, the idea of a library is quite simple: It is a file containing a [typically large] number of functions/procedures/subroutines in a special format. At link time, the linker looks in the library [or there may well be more than one, in which case it checks each in turn] to resolve any references to functions not satisfied by the supplied object modules. This means that the programmer just needs to reference commonly used functions and their code is pulled in automatically.
Of course, it is not quite that simple. Also, as with most aspects of embedded programming, libraries present more challenges and options to developers …
When developing software for the desktop, most programmers give little consideration to standard libraries, concentrating only on any special libraries that might be employed for their application. Such libraries are commonly dynamically linked, so they are quite different from anything used in most embedded systems.
The fact that every embedded system is different is often cited [by me anyway] as a reason for much of the complexity with developing embedded software. The use of libraries reflects this. Apart from getting a library that is right for the target device family and the chosen compiler, there may be a wide selection of other variations: chip family member specifics, register relative addressing, PC relative [position independent] code, endianity, size/speed optimization, the list goes on …
A standard C library contains two types of functions:
- Functions called by the generated code where the compiler has determined that so doing is preferable to creating inline instructions.
- Functions explicitly called by the code [like printf()].
Commonly a single library is used to contain both these types of function. However, that is not always the case. For GNU compilers, one library [libgcc] contains the compiler support functions. There are a number of options to choose from for the explicitly called functions:
- GLIBC is very full-featured and designed to be used with Linux, including not only the ISO C functions, but POSIX support and GNU extensions.
- uClibc is also designed to be used with Linux [or uClinux] and contains a subset of GLIBC, so it has a smaller footprint.
- Newlib is smaller still and is primarily aimed at embedded applications with no OS.
An interesting question is: what is the benefit of a smaller library, given that only called functions are extracted from it so final binary image size will not vary? I can think of about three answers:
- A smaller library results in faster link time.
- Less choice of functions might make a programmer more careful in their selection, thus resulting in more optimal [smaller] code.
- A small library may also have smaller [less capable] versions of functions, which will result in a smaller application memory footprint.
Any other ideas or suggestions would be welcome by comment or email.