Programming with GNU Software
Authors: Mike Loukides and Andy Orem
Publisher: O'Reilly & Associates, 1997
Price: $39.95; includes CD-ROM
Reviewer: Randyl Britten
Linux is built on twin pillars. The one we usually associate with Linux is the kernel developed by Linus Torvalds. And the other, the one we often take for granted, is the set of GNU tools that make up the portable software development system from the Free Software Foundation (FSF). Programming with GNU Software is a brief but thoroughly useful introduction to these tools and how to use them. The tools covered are Emacs, the C and C++ compilers gcc and g++, the gdb debugger, the make utility, the RCS revision control system and gprof, a utility for profiling and timing your programs. The CD-ROM contains the sources for these tools and compiled binaries for several popular Unix systems such as SunOS and Solaris for SPARC, HP-UX for HP9000, AIX for the RS/6000, Irix for Indigo, and DEC Unix for the Alpha.
The book and CD-ROM combination is not specifically intended for Linux users, but this is an important book for anyone who develops software for Unix or Linux. This book was described as “forthcoming” in an O'Reilly catalog over a year ago and I have been eagerly awaiting it since then. If you have a recent distribution of Linux, you probably already have most or all of the tools discussed here. Even so, nearly everything in the book, and many of the sources on the CD-ROM, can be useful to Linux beginners and experts alike. A significant additional benefit is the discussion of cross-compilation and cross-development for a wide variety of platforms. If you are interested in portable software or porting applications, embedded systems, or just a good introduction to the GNU tools, this book is a good place to start.
The libraries on the CD-ROM are not the FSF versions governed by the LGPL (a General Public License for libraries). The libraries are rewritten versions from Cygnus Support, a company that ports and supports free software for commercial use, particularly in embedded systems. Using the Cygnus libraries avoids the more impractical restrictions of the LGPL for commercial embedded systems, and Cygnus requires only that you acknowledge use of their software. If you invent the world's greatest latte maker/bagel warmer, for example, and use the FSF libraries in the controller, you either have to make the source code available or provide a way for your customers to upgrade the libraries in case of a new release. If you have any questions about the legal issues, you should contact Cygnus Support. Check out their web site at http://www.cygnus.com/.
After an introduction and discussion of free software philosophy in Chapter 1, Chapter 2 offers a brief introduction to the use of Unix and its traditional tools for software development. Then Chapter 3 gets into the heart of GNU software with Emacs. If you have been intimidated by the sheer mass of Emacs, you should find this chapter an easy way to get started.
The coverage in this book is not simply introductory, but also has depth where it counts. Even though I've used versions of Emacs for years I learned several new tricks in this chapter. For example, I like to use the original Kernighan & Ritchie indentation style in my C programs, and indent by four spaces with each press of the TAB key. Using an example in the book, I was able to add a customization to my default initialization file, .emacsrc, in my home directory. Now, whenever I edit a file that ends in .c, .cpp or .h, Emacs will automatically be in C-mode, and will indent my programs properly when I press the TAB key at the beginning of a line. Most of its features and all of its customizations are written in Emacs Lisp. Emacs itself is mostly an interpreter for this language and its many extensions. Also covered is how to run the compiler from within Emacs, so you can continue editing while compilation proceeds in the background.
The GNU software tools are integrated and work together in a variety of ways, and Emacs is at the heart of it. Here are some additional incentives for learning and using Emacs I've gleaned from the book:
bash—the default Linux shell—uses Emacs commands for basic command line and history editing.
info—the command often more helpful than man pages—is an Emacs-like hypertext application that uses a special set of commands for basic navigation plus many familiar Emacs commands.
gdb—a shell in its own right—uses Emacs commands for basic command line and history editing.
Because of the interoperability between Emacs, bash, gcc, GNU make, RCS and gdb, learning to use Emacs just makes good sense.
Chapter 4 begins with an overview of the compilation process, including the preprocessor, translator/optimizer, assembler and linker, plus many other tools (such as the libraries) that take part in the software development process. There are many compiler options, optimization levels and intermediate file formats you can use. Like the rest of the book, this chapter does not attempt to be a comprehensive reference. Instead, it does a good job of discussing the most frequently used commands and options, and adds tips that even power users will appreciate. The chapter ends with an introduction to cross-compilers, and the requirements for building your own libraries in a cross-development environment. A table is included that outlines the large number of host and target systems supported by the Cygnus libraries, and the output formats such as a.out, COFF and ELF, that can be generated.
Chapter 5 continues with more details about using the C and C++ libraries, and what is needed to support the system interface to Unix- or Posix-like systems. So if you are interested in porting Linux to the latest 64-bit PDA or the new WebTV your aunt just bought on sale, this is the place to learn what it takes. Keep in mind that these two chapters are not about the C or C++ languages or how to write programs. Many other books are more useful as learning aids (see the Resources sidebar). Chapter 5 ends with a brief discussion of the library licensing issues.
The GNU debugging tool, gdb, is an interactive shell with its own commands, history (previously executed commands) and editor (Emacs-like, of course). The basic idea is that you can control and examine the internal working of an executing process, and interact with its source code and variables. The coverage of gdb is extensive here, and I have not seen gdb covered with a good tutorial in any other reference. This coverage alone could be worth the price of the book.
The make utility is used to build programs from multiple sources and compiles only files in need of updating, based on the date stamps and dependencies for each file. It is fairly easy to write simple dependencies so that if an include file is changed, for example, only the files that use it are recompiled; automating these steps saves time when building a new executable program. The make utility has been around a long time and has become very sophisticated, and the GNU make is one of the most comprehensive. The coverage in Chapter 7 is brief, but is an excellent tutorial introduction that covers both basic and advanced features. For more in-depth coverage, see the O'Reilly book on make.
The RCS revision control system is a tool to manage the versions of a program as it evolves over time. GNU make is aware of RCS, and can automatically use the current revisions. Again, the coverage is brief but presents sufficient basics for you to start using them; further details are available in other works from O'Reilly and FSF.
There are two tools for timing and profiling your programs: time and gprof. The time command is built into the bash shell and is similar to the timex command in other shells. It simply gives the elapsed execution time of a program as a whole, broken down by user and system, with a few additional system details. The gprof tool is a report generator that can provide detailed information on where your program is spending its time. The gprof utility can give either a one-dimensional profile or a two-dimensional accounting that follows the call graph of your program. The call graph starts with the main() function and has an execution breakdown for every function called that includes both the time spent and the number of times the function is called. It even handles recursive programs. Learning to use gprof is the best way to improve the performance of your programs. Coverage of this important tool has not been easily available elsewhere and is another reason why this book is a valuable resource.
What is particularly good about this book is the combination of an excellent tutorial style that makes it easy for you to get started, and depth that cuts to the important topics in each subject. Even if you are already experienced with C/C++ programming using Unix tools, you will find many useful tips. With only about 250 pages, this is brief coverage, and the one thing I might wish for is a more complete reference. For that we will have to turn elsewhere, such as the info pages and the references listed below. I'm sure this book will be a valuable reference for me for some time. The authors, Mike Loukides and Andy Orem, are senior technical editors with O'Reilly and have done an excellent job that rises well above the average for software documentation.