Running Linux, 5th Edition - Matthias Kalle Dalheimer [391]
From a programmer's point of view, you don't write makefiles, but rather files called makefile.in. These can contain placeholders that will be replaced with actual values when the user runs the configure program, generating the makefiles that make then runs. In addition, you need to write a file called configure.in that describes your project and what to check for on the target system. The Autoconf tool then generates the configure program from this configure.in file. Writing the configure.in file is unfortunately way too involved to be described here, but the Autoconf package contains documentation to get you started.
Writing the makefile.in files is still a cumbersome and lengthy task, but even this can be mostly automated by using the Automake package. Using this package, you do not write the makefile.in files, but rather the makefile.am files, which have a much simpler syntax and are much less verbose. By running the Automake tool, you convert these makefile.am files to the makefile.in files, which you distribute along with your source code and which are later converted into the makefiles themselves when the package is configured for the user's system. How to write makefile.am files is beyond the scope of this book as well. Again, please check the documentation of the package to get started.
These days, most open source packages use the libtool/Automake/Autoconf combo for generating the makefiles, but this does not mean that this rather complicated and involved method is the only one available. Other makefile-generating tools exist as well, such as the imake tool used to configure the X Window System.[*] Another tool that is not as powerful as the Autoconf suite (even though it still lets you do most things you would want to do when it comes to makefile generation) but extremely easy to use (it can even generate its own description files for you from scratch) is the qmake tool that ships together with the C++ GUI library Qt (downloadable from http://www.trolltech.com).
* * *
[*] X.org is planning to switch to Automake/Autoconf for the next version as well.
Debugging with gdb
Are you one of those programmers who scoff at the very idea of using a debugger to trace through code? Is it your philosophy that if the code is too complex for even the programmer to understand, the programmer deserves no mercy when it comes to bugs? Do you step through your code, mentally, using a magnifying glass and a toothpick? More often than not, are bugs usually caused by a single-character omission, such as using the = operator when you mean +=?
Then perhaps you should meet gdb--the GNU debugger. Whether or not you know it, gdb is your friend. It can locate obscure and difficult-to-find bugs that result in core dumps, memory leaks, and erratic behavior (both for the program and the programmer). Sometimes even the most harmless-looking glitches in your code can cause everything to go haywire, and without the aid of a debugger like gdb, finding these problems can be nearly impossible—especially for programs longer than a few hundred lines. In this section, we introduce you to the most useful features of gdb by way of examples. There's a book on gdb: Debugging with GDB (Free Software Foundation).
gdb is capable of either debugging programs as they run or examining the cause for a program crash with a core dump. Programs debugged at runtime with gdb can either be executed from within gdb itself or can be run separately; that is, gdb can attach itself to an already running process to examine it. We first discuss how to debug programs running within gdb and then move on to attaching to running processes and examining core dumps.
Tracing a Program
Our first example is a program called trymh that detects edges in a grayscale image. trymh takes as input an image file, does some calculations on the data, and spits out another image file. Unfortunately, it crashes whenever it is invoked, as so:
papaya$ trymh < image00.pgm