Getting started with Embedded Linux: Part Four

We are continuing our series on how to get started with Embedded Linux if you have experience with embedded systems, but no Linux experience. You can find the first article here, second article here.
and the third here.

Linux has a large number of libraries that can be used for application development, and many of these libraries can be used with embedded systems. You may need to use your package manager to install the library and the related development package, which contains the headers. Some libraries are available in both static and dynamic versions. The static libraries are linked with your program while dynamic libraries are separate, loaded as needed when your program is executed.

Whenever I write any but the simplest application, my go-to reference for many years has been Advanced Programming in the UNIX Environment by W. Richard Stevens. This reference, originally published in 1992 before Linux was developed, has been updated by Stephen A. Rago, with a third edition published this year. Linux adopted most of the APIs and interfaces of Unix, although the implementations may be different. Another reference is The Linux Programming Interface by Michael Kerrisk. At over 900 and 1,500 pages respectively, neither is going to end up as bedside reading, but if you need to know the nitty-gritty details of file or process manipulation, signals, threads, inter- or intra-process or network communication and synchronization, and much more, these are great places to start. There are also significant online resources as well as help forums like Stack Overflow.

There is an extensive Open Source infrastructure supporting Linux, both in desktop and embedded environments. The GNU project of the Free Software Foundation maintains a large number of widely used utility programs and libraries. You can download these packages from http://gnu.mirrors.pair.com/gnu, which should automatically connect you to a mirror near you. SourceForge has source for over 300,000 projects, many very substantial. Freecode also has thousands of open-source applications. The last destination on my short list is GitHub, which provides hosting for the code repositories of thousands of projects.

Most libraries or programs are built using the GNU make utility, along with bash scripts or support utilities like automake and autoconf. At its simplest, make checks which files need to be compiled and manages (using a Makefile written by the developer) the order in which these compilations are performed. Makefiles can be quite complex, with the Makefile invoking make to build subdirectories or invoking itself recursively. Automake is designed to generate Makefiles, identifying dependencies and invoking libtool, a utility to create shared libraries. Autoconf allows libraries or programs to be compiled for different targets and operating systems or with different options. All of these are beyond the scope of this overview, but O'Reilley has excellent books about make and autotools.

The standard sequence to build most of the standard libraries or program for your Linux system is to download the sources, usually in the form of a tar file, possibly compressed with gzip, bzip2, or xz. If I'd like to build my own copy of diff, I would first download the diffutils package from a GNU mirror. Usually I'd use a browser to save the package, but I could also use the wget utility:

$ cd /tmp
$ wget ftp://ftp.gnu.org/gnu/diffutils/diffutils-3.3.tar.xz

Untar the file and cd to the resulting directory:

$ tar xfv diffutils-3.3.tar.xz
$ cd diffutils-3.3

(If the package has a .gz or .tgz suffix, you will need to add the "z" option after "xfv". If it has the .bz suffix, add the "j" option.)

Many packages have a README file. You should read this before you build. While most packages use a configure script generated by autoconf, not all do. The README will tell you how to build the package.

Building most packages, like the diffutils, is simple: you enter the following commands:

$ ./configure
$ make
$ make install

The first command invokes configure that will analyze your system and create a Makefile to build your library or program tailored for your system. The second command invokes make, which will compile and link the library or program in work directory. The third command will install the library or program. Naturally, on occasion there will be errors in each of these steps. Configure may tell you that you need to install other packages, or perhaps the headers for installed libraries. The make step may stop with compile errors. The final step may try to install the library or program in a protected system directory. If this is the case, you can either run this last step as root, or prefixing this with the sudo command to temporarily assume root privileges. Alternately, you can specify the --prefix option to configure and point to an unprotected directory:

$ ./configure --prefix=~/mydiff

When you run "make install", the program and any other files will be installed in the directory mentioned in the prefix option, in this case, mydiff in my home directory.

With some caveats which we will discuss in the future, this means that libraries and programs which you build on your native x86 Linux environment can also be built for other processors such as ARM, PowerPC, or MIPS, or for other configurations of Linux, using the many of the same tools and techniques.

Our next installment will talk about the Linux kernel, how it is configured, and how to build it.Michael Eager is principal consultant at Eager Consulting in Palo Alto, Calif. He has over four decades experience developing compilers, debuggers, and simulators for a wide range of processor architectures used in embedded systems. His current and former clients include major semiconductor companies and systems developers. Michael has been a member of the ISO C++ Standard Committee and ABI Committees for several processor architectures. He is chair of the Debugging Standards Committee for DWARF, a widely used debug data format. He is active in the open-source and Linux communities.