- Table of Contents
- Copyright
- About the Lead Authors
- About the Contributing Authors
- Acknowledgments
- Tell Us What You Think!
- Introduction
- I. Red Hat Linux Installation and User Services
- Chapter 1. Introduction to Red Hat Linux
- Chapter 2. Installation of Your Red Hat System
- Chapter 3. LILO and Other Boot Managers
- Chapter 4. Configuring the X Window System, Version 11
- Chapter 5. Window Managers
- Chapter 6. Connecting to the Internet
- Chapter 7. IRC, ICQ, and Chat Clients
- Chapter 8. Using Multimedia and Graphics Clients
- II. Configuring Services
- Chapter 9. System Startup and Shutdown
- Chapter 10. SMTP and Protocols
- Chapter 11. FTP
- Chapter 12. Apache Server
- Chapter 13. Internet News
- Chapter 14. Domain Name Service and Dynamic Host Configuration Protocol
- Chapter 15. NIS: Network Information Service
- Chapter 16. NFS: Network Filesystem
- Chapter 17. Samba
- III. System Administration and Management
- Chapter 18. Linux Filesystems, Disks, and Other Devices
- Chapter 19. Printing with Linux
- Chapter 20. TCP/IP Network Management
- Chapter 21. Linux System Administration
- Chapter 22. Backup and Restore
- Chapter 23. System Security
- IV. Red Hat Development and Productivity
- Chapter 24. Linux C/C++ Programming Tools
- Chapter 25. Shell Scripting
- Chapter 26. Automating Tasks
- Chapter 27. Configuring and Building Kernels
- Chapter 28. Emulators, Tools, and Window Clients
- V. Appendixes
- A. The Linux Documentation Project
- B. Top Linux Commands and Utilities
- C. The GNU General Public License
- D. Red Hat Linux RPM Package Listings
Project Management Tools
This section introduces some of the programming and project management tools included with Red Hat Linux. You will find tools on this book's CD-ROMs that you can use to help automate your software development projects. If you have some previous UNIX experience, you will be familiar with most of these programs because they are traditional complements to a programmer's suite of software.
If you have programming experience on other software platforms, you will find that these programs are easy to learn. However, mastery will come with experience!
Building Programs with make
The make command is only one of several programming automation utilities included with Red Hat Linux. You will find others, such as pmake (a parallel make), imake (a dependency-drive Makefile generator, usually for building X11 applications), automake, and one of the newer tools, autoconf (which builds shell scripts used to configure program source code packages). Check the man pages for more information.
The make command's roots stem from an early version of System V UNIX. The version included with Red Hat Linux is part of the GNU utilities distribution. Make is used to automatically handle the building and install of a program, which can be as simple as
# make install
The magic of make is that it will automatically update and build applications. You create this magic through a default file named Makefile. However, if you use make's -f option, you can specify any Makefile, such as MyMakeFile, like this:
# make -f MyMakeFile
A Makefile is a text file that can contain instructions about which options to pass on to the compiler preprocessor, the compiler, and the linker. The Makefile can also specify which source code files need to be compiled (and the compiler command line) for a particular code module, and which code modules are needed to build the program—a mechanism called dependency checking.
Using make can also aid in the portability of your program through the use of macros. This allows users of other operating systems to easily configure a program build by specifying local values, such as the names and locations, or pathnames of any required software tools. In the following example, macros define the name of the compiler (CC), the installer program (INS), where the program should be installed (INSDIR), where the linker should look for required libraries (LIBDIR), the names of required libraries (LIBS), a source code file (SRC), the intermediate object code file (OBS), and the name of the final program (PROG):
# a sample makefile for a skeleton program
CC= gcc
INS= install
INSDIR = /usr/local/bin
LIBDIR= -L/usr/X11R6/lib
LIBS= -lXm -lSM -lICE -lXt -lX11
SRC= skel.c
OBJS= skel.o
PROG= skel
skel: ${ OBJS}
${ CC} -o ${ PROG} ${ SRC} ${ LIBDIR} ${ LIBS}
install: ${ PROG}
${ INS} -g root -o root ${ PROG} ${ INSDIR}
Using this approach, you can build the program with
# make
To build a specified component of your Makefile, use a target definition on the command line. To build just the program, use make with the skel target like this:
# make skel
If you make any changes to any element of a target object, such as a source code file, make will rebuild the target. To build and install the program in one step (using the example), specify the install target like this:
# make install
Larger software projects may have any number of traditional targets in the Makefile, such as
- test—To run specific tests on the final software.
- man—To process an include troff document with the -man macros.
- clean—To delete any remaining object files.
- archive—To clean up, archive, and compress the entire source code tree.
- bugreport—To automatically collect and then mail build or error logs.
The beauty of the make command is in its flexibility. You can use make with a simple Makefile, or write complex Makefiles containing numerous macros, rules, or commands that work in a single directory or traverse your filesystem recursively to build programs, update your system, and even function as a document management system. The make command will work with nearly any program, including text processing systems such as TeX!
Building Large Applications
C programs can be broken into any number of files, as long as no single function spans more than one file. To compile this program, you compile each source file into an intermediate object before you link all the objects into a single executable. The -c flag tells the compiler to stop at this stage. During the link stage, all the object files should be listed on the command line. Object files are identified by the .o suffix.
Making Libraries with ar
If several different programs use the same functions, they can be combined into a single library archive. The ar command is used to build a library. When this library is included on the compile line, the archive is searched to resolve any external symbols. Listing 24.1 shows an example of building and using a library.
Example 24.1. Building a Large Application
$ gcc -c sine.c $ gcc -c cosine.c $ gcc -c tangent.c $ ar c libtrig.a sine.o cosine.o tangent.o $ gcc -c mainprog.c $ gcc -o mainprog mainprog.o libtrig.a
gcc is the command used to invoke the GNU C Compiler. The GNU C/C++ Compiler Command-Line Switches section will explain what -c and -o mean.
Large applications can require hundreds of source code files. Compiling and linking these applications can be a complex and error-prone task of its own. The make utility, described previously, is a tool that helps developers organize the process of building the executable form of complex applications from many source files.
Managing Software Projects with RCS and CVS
Although make can be used to manage a software project, larger software projects requiring document management, source code controls, security, and tracking usually use the Revision Control System (RCS) or the Concurrent Versions System (CVS). You will find both of these source code version control utilities on your Red Hat Linux CD-ROMs.
The RCS and CVS systems are used to track changes to multiple versions of files, and they can be used to backtrack or branch off versions of documents inside the scope of a project. The systems are also used to prevent or resolve conflicting entries or (sometimes simultaneously) changes to source code files by numerous developers.
Although RCS and CVS aim to provide similar features, the main difference between the two systems is that RCS uses a locking and unlocking scheme for access, whereas CVS provides a modification and merging approach to working on older, current, or new versions of software. Whereas RCS uses different programs to check in or out of a revision under a directory, CVS uses a number of administrative files in a software repository of source code modules to merge and resolve change conflicts.
RCS uses at least eight separate programs, including the following:
- ci—Checks in revisions.
- co—Checks out revisions.
- ident—Keyword utility for source files.
- rcs—Changes file attributes.
- rcsclean—Cleans up working files.
- rcsdiff—Revision comparison utility.
- rcsmerge—Merges revisions.
- rlog—Logging and information utility.
Source code control with CVS requires the use of at least six command options on the cvs command line. Some of these commands require additional fields, such as the names of files:
- checkout—Checks out revisions.
- update—Updates your sources with changes by other developers.
- add—Adds new files in cvs records.
- import—Adds new sources into the repository.
- remove—Eliminates files from the repository.
- commit—Publishes changes to other repository developers.
RCS and CVS may be used for more than software development projects. These tools may also be used for document preparation and workgroup editing of documents, and will work with any text files. Both systems use registration and control files to accomplish revision management. Both systems also offer the opportunity to revisit any step or branch in a revision history, and to restore previous versions of a project. This mechanism is extremely important in cross-platform development or for software maintenance.
Tracking information is usually contained in separate control files, and each document within a project may contain information automatically updated with each change to a project using a process called keyword substitution. CVS can use keywords similar to RCS, which are usually included inside C comment strings (/* */) near the top of a document. A sample of the available keywords includes
- $Author$—Username of person performing last check-in.
- $Date$—Date and time of last check-in.
- $Header$—Inserts the pathname of the document's RCS file, revision number, date and time, author, and state.
- $Id$—Same as $Header$, but without full pathname.
- $Name$—A symbolic name (see the co man page).
- $Revision$—The assigned revision number (such as 1.1).
- $Source$—RCS file's full pathname.
- $State$—The state of the document, such as Exp for experimental, Rel for released, or Stab for stable.
These keywords may also be used to insert version information into compiled programs by using character strings in program source code. For example, given an extremely short C program named foo.c:
/* $Header$ */
#include <stdio.h>
static char rsrcid{ } = "$Header$";
main() {
printf("Hello, Linus!\n");
}
The resulting $Header$ keyword may expand (in an RCS document) to
$Header: /home/bball/sw/RCS/foo.c,v 1.1 1999/04/20 15:01:07 root Exp Root $
Getting started with RCS is as simple as creating a project directory and an RCS directory under the project directory, and then creating or copying initial source files in the project directory. You then use the ci command to check in documents. Getting started with CVS requires you to initialize a repository by first setting the $CVSROOT environment variable with the full pathname of the repository and then using the init command option with the cvs command, like this:
# cvs init
You will find documentation for RCS and CVS in various man pages, under the /usr/doc directories for each of them, and in GNU info documents.
Many organizations use CVS and RCS to manage the source for their projects. There are also commercial code-management (version control) tools that include fancy interfaces, homogenous platform support, and greater flexibility. But those tools require dedicated administrators and significant licensing costs—major disadvantages when compared to RCS or CVS.
Debugging Tools
Debugging is a science and an art unto itself. Sometimes, the simplest tool—the code listing—is best. At other times, however, you need to use other tools. Three of these tools are lint, gprof, and gdb. Other available tools include escape, cxref, and cb. Many UNIX commands have debugging uses.
lint is a traditional UNIX command that examines source code for possible problems, but it is not included with Red Hat Linux. The code might meet the standards for C and compile cleanly, but it might not execute correctly. lint checks type mismatches and incorrect argument counts on function calls. lint also uses the C preprocessor, so you can use command-like options similar to those you would use for gcc. The GNU C compiler supports extensive warnings (through the –Wall and –pedantic options) that might eliminate the need for a separate lint command.
The gprof command is used to study how a program is spending its time. If a program is compiled and linked with -p as a flag, a mon.out file is created when it executes, with data on how often each function is called and how much time is spent in each function. gprof parses and displays this data. An analysis of the output generated by gprof helps you determine where performance bottlenecks occur. Whereas using an optimizing compiler can speed up your program, taking the time to use gprof's analysis and revising bottleneck functions will significantly improve program performance.
The third tool is gdb—a symbolic debugger. When a program is compiled with -g, the symbol tables are retained and a symbolic debugger can be used to track program bugs. The basic technique is to invoke gdb after a core dump and get a stack trace. This indicates the source line where the core dump occurred and the functions that were called to reach that line. Often, this is enough to identify the problem. It is not the limit of gdb, though.
gdb also provides an environment for debugging programs interactively. Invoking gdb with a program enables you to set breakpoints, examine variable values, and monitor variables. If you suspect a problem near a line of code, you can set a breakpoint at that line and run the program. When the line is reached, execution is interrupted. You can check variable values, examine the stack trace, and observe the program's environment. You can single-step through the program, checking values. You can resume execution at any point. By using breakpoints, you can discover many of the bugs in your code that you have missed.
There is an X Window version of gdb called xxgdb.
cpp is another tool that can be used to debug programs. It performs macro replacements, includes headers, and parses the code. The output is the actual module to be compiled. Normally, though, cpp is never executed by the programmer directly. Instead, it is invoked through gcc with either an -E or -P option. -E sends the output directly to the terminal; -P makes a file with an .i suffix.
GNU C/C++ Compiler Command-Line Switches | Next Section

Account Sign In
View your cart