Software Development Tools in Linux


Software Development Tools in Linux

As expected, as a UNIX look-alike, Linux includes these traditional UNIX software-development tools:

  • A text editor, such as vi or emacs, for editing the source code (described in Chapter 11)

  • A C compiler for compiling and linking programs written in C-the programming language of choice for writing UNIX applications (although nowadays, many programmers are turning to C++). Linux includes the GNU C and C++ compilers. Originally, the GNU C Compiler was known as GCC. The acronym GCC now stands for GNU Compiler Collection (see description in http://gcc .gnu.org/).

  • The GNU make utility for automating the software build process-the process of combining object modules into an executable or a library

  • A debugger for debugging programs. Linux includes the GNU debugger gdb.

  • A version-control system to keep track of various revisions of a source file. Linux comes with RCS (Revision Control System) and CVS (Concurrent Versions System). Nowadays, most open-source projects use CVS as the version-control system.

These tools are installed automatically if you select the Development Tools package group when you install Red Hat Linux from this book's companion CD-ROMs, following the steps outlined in Chapter 2. The next few sections briefly describe how to use these tools to write applications for Linux.

Using info for Help on GNU Tools

You may have noticed that most of the Linux software-development tools are from the Free Software Foundation's GNU project. The online documentation for all these tools comes as info files. The info program is GNU's hypertext help system.

To see info in action, type info at the shell prompt, or type Esc-x followed by info in GNU Emacs. Typically, I access info from GNU Emacs; doing so enables me to use online help while editing a program. However, you can always type info in a separate terminal window. Figure 23-1 shows the terminal window after I type info at the shell prompt.

Click To expand
Figure 23-1: The Terminal Window after Typing info at the Shell Prompt.

In info, the online help text is organized in nodes; each node represents information on a specific topic. The first line shows the header for that node.

Figure 23-1 shows the initial info screen, with a directory of topics. This directory is an info file: /usr/share/info/dir, a text file that contains embedded special characters. The following are a few lines from the /usr/share/info/dir file that correspond to the screen shown in Figure 23-1:

$Id: dir,v 1.2 1996/09/24 18:43:01 karl Exp $
This is the file .../info/dir, which contains the topmost node of the
Info hierarchy.  The first time you invoke Info you start off
looking at that node, which is (dir)Top.
^_   (This is the Ctrl+_ character)
File: dir       Node: Top       This is the top of the INFO tree

  This (the Directory node) gives a menu of major topics.
  Typing "q" exits, "?" lists all Info commands, "d" returns here,
  "h" gives a primer for first-timers,
  "mEmacs<Return>" visits the Emacs topic, etc.

  In Emacs, you can click mouse button 2 on a menu item or cross reference
  to select it.

* Menu:

Texinfo documentation system
* Standalone info program: (info-stnd).    Standalone Info-reading program.
* Texinfo: (texinfo).           The GNU documentation format.
* install-info: (texinfo)Invoking install-info. Update info/dir entries.
* makeinfo: (texinfo)makeinfo Preferred.        Translate Texinfo source.
(...Lines deleted...)

A comparison of this listing with the screen shown in Figure 23-1 shows that info displays only the lines that follow the Ctrl+_ character. In your system, the /usr/share/info directory contains this info file, as well as others, with the text for each topic. Usually, these info files are stored in compressed format. You really don't have to know these details to use the info files.

Insider Insight 

You have to use several single-letter commands to navigate info files. The best way to learn the commands is to type h from the initial info directory, shown in Figure 23-1. Type d after reading the help screens to return to the initial directory of topics.

From the directory screen of Figure 23-1, type m, followed by the name of a menu item (shown with an asterisk prefix). For example, to view the online help for GCC, type m; then type gcc, and press Enter. The info system, in turn, displays the top-level menu of items for GCC, as shown in Figure 23-2.

Click To expand
Figure 23-2: The Info Window, Showing the Top-Level Help on GCC.

You can explore further by typing m, followed by one of the menu items shown in Figure 23-2.

While you're at it, you may want to type m, then copy; then press Enter in the screen shown in Figure 23-2. That action displays the GNU General Public License (GPL), shown in Figure 23-3.

Click To expand
Figure 23-3: The Info Window, Showing the First Page of the GNU General Public License (GPL).

GPL covers Linux and the gcc compiler. GPL requires distribution of the source code (that's why all Linux distributions come with source code). In the 'Implications of GNU Licenses' section, you learn that you can still use GNU tools to develop commercial applications and to distribute applications in binary form (without source code), as long as they link with selected GNU libraries only.

At any time in info, you can type d to return to the info topic directory shown in Figure 23-1. From that screen, you can view help on other GNU tools, such as make and the GNU debugger.

To quit info, type q. If you access info from the Emacs editor, press Ctrl+X, followed by Ctrl+C, to quit the Emacs editor.

Running the GNU C and C++ Compilers

The most important software-development tool in Linux is GCC, which is the GNU C and C++ compiler. In fact, GCC can compile three languages: C, C++, and Objective-C (a language that adds object-oriented extensions to C). You use the same gcc command to compile and link both C and C++ source files. The GCC compiler supports ANSI standard C, making it easy to port any ANSI C program to Linux. In addition, if you've ever used a C compiler on other UNIX systems, you are right at home with GCC.

Running GCC

Use the gcc command to run GCC. By default, when you use the gcc command on a source file, GCC preprocesses, compiles, and links the executable. However, you can use GCC options to stop this process at an intermediate stage. For example, you might invoke gcc by using the -c option to compile a source file and to generate an object file, but not to perform the link step.

Using GCC to compile and link a few C source files is very simple. Suppose you want to compile and link a simple program made up of two source files. The following listing shows the file area.c (the main program that computes the area of a circle whose radius is specified through the command line):

#include <stdio.h>
#include <stdlib.h>

/* Function prototype */
double area_of_circle(double r);

int main(int argc, char **argv)
{
  if(argc < 2)
  {
    printf("Usage: %s radius\n", argv[0]);
    exit(1);
  }
  else
  {
    double radius = atof(argv[1]);
    double area = area_of_circle(radius);
    printf("Area of circle with radius %f = %f\n",
        radius, area);
  }
  return 0;
}

The following listing shows the file circle.c, which provides a function that computes the area of a circle.

#include <math.h>

#define SQUARE(x) ((x)*(x))

double area_of_circle(double r)
{
  return 4.0 * M_PI * SQUARE(r);
}

For such a simple program, of course, I can place everything in a single file, but this contrived example lets me show you how to handle multiple files.

To compile these two programs and to create an executable file named area, you might use this command:

gcc -o area area.c circle.c

This invocation of GCC uses the -o option to specify the name of the executable file. (If you do not specify the name of an output file, GCC creates a file named a.out.)

If there are too many source files to compile and link, compile the files individually, and generate object files (that have the .o extension). That way, when you change a source file, you need to compile only that file and to link all the object files. The following example shows how to separate the compile and link steps for the example program:

gcc -c area.c
gcc -c circle.c
gcc -o area area.o circle.o

The first two invocations of gcc with the -c option compile the source files. The third invocation links the object files into an executable named area.

In case you are curious, here's how you run the sample program (to compute the area of a circle with a radius of 1):

./area 1
Area of circle with radius 1.000000 = 12.566371
Insider Insight 

Incidentally, you have to add the ./ prefix to the program's name (area) only if the current directory is not in the PATH environment variable. There is no harm in adding the prefix, even if your PATH contains the current directory.

Compiling C++ programs

GNU CC is a combined C and C++ compiler, so the gcc command also can compile C++ source files. GCC uses the file extension to determine whether a file is C or C++. C files have a lowercase .c extension, whereas C++ files end with .C or .cpp.

Although the gcc command can compile a C++ file, that command does not automatically link with various class libraries that C++ programs typically require. That's why it's easier to compile and link a C++ program by using the g++ command, which invokes gcc with appropriate options.

Suppose you want to compile the following simple C++ program stored in a file named hello.C (it's customary to use an uppercase C extension for C++ source files):

#include <iostream>

int main()
{
  using namespace std;
  cout << "Hello from Red Hat Linux!" << endl;
}

To compile and link this program into an executable program named hello, use this command:

g++ -o hello hello.C

This command creates the hello executable, which you can run as follows:

./hello
Hello from Red Hat Linux!

As you see in the following section, a host of GCC options controls various aspects of compiling C++ programs.

Exploring GCC Options

Following is the basic syntax of the gcc command:

gcc options filenames

Each option starts with a hyphen (-) and usually has a long name, such as -funsigned-char or -finline-functions. Many commonly used options are short, however, such as -c, to compile only, and -g, to generate debugging information, (needed to debug the program by using the GNU debugger).

You can view a summary of all GCC options by using info. Type info at the shell prompt, and press m, followed by gcc. Then follow the menu items: Invoking GCC>Option Summary. Usually, you do not have to specify GCC options explicitly; the default settings are fine for most applications. Table 23-1 lists some of the GCC options you might use.

Table 23-1: Commonly Used GCC Options

Option

Meaning

-ansi

Support ANSI standard C syntax only. (This option disables some GNU C-specific features, such as the asm and typeof keywords.)

-c

Compile and generate object file only

-DMACRO

Define the macro with the string '1' as its value

-DMACRO=DEFN

Define the macro as DEFN where DEFN is some text

-E

Run only the C preprocessor

-fallow-single-precision

Perform all math operations in single precision

-fpack-struct

Pack all structure members without any padding

-fpcc-struct-return

Return all struct and union values in memory, rather than in registers. (Returning values this way is less efficient, but is compatible with other compilers.)

-fPIC

Generate position-independent code (PIC) suitable for use in a shared library

-freg-struct-return

When possible, return struct and union values in registers

-g

Generate debugging information. (The GNU debugger can use this information.)

-IDIRECTORY

Search the specified directory for files you include by using the #include preprocessor directive

-LDIRECTORY

Search the specified directory for libraries

-lLIBRARY

Search the specified library when linking

-mcpu=cputype

Optimize code for a specific processor (cputype can take many different values-some common ones are i386, i486, i586, i686, pentium2, pentium3, and pentium4).

-o FILE

Generate the specified output file (used to designate the name of an executable file)

-O0

Do not optimize

-O or -O1

Optimize the generated code

-O2

Optimize even more

-O3

Perform optimizations beyond those done for -O2

-pedantic

Generate errors if any non-ANSI standard extensions are used

-pg

Add extra code to the program so that, when run, it generates information the gprof program can use to display timing details for various parts of the program

-shared

Generate a shared object file (typically used to create a shared library)

-UMACRO

Undefine the specified macro (MACRO)

-v

Display the version number of GCC

-w

Don't generate any warning messages

-Wl,OPTION

Pass the OPTION string (containing multiple comma-separated options) to the linker. To create a shared library named libXXX.so.1, for example, use the following flag: -Wl,-soname,libXXX.so.1

Using the GNU make Utility

When an application is made up of more than a few source files, compiling and linking the files by manually typing the gcc command is inconvenient. Also, you do not want to compile every file whenever you change something in a single source file. The GNU make utility is helpful in this situation because make can compile only those files that really must be compiled.

The make utility works by reading and interpreting a makefile: a text file you have to prepare according to a specified syntax. The makefile describes which files constitute a program and explains how to compile and link the files to build the program. Whenever you change one or more files, make determines which files should be recompiled and issues the appropriate commands for compiling those files and rebuilding the program.

The make utility is, in fact, specified in Section 6.2 of the POSIX.2 standard (IEEE Standard 1003.2-1992) for shells and tools. GNU make conforms to the POSIX.2 standard.

Learning makefile Names

By default, GNU make looks for a makefile that has one of the following names, in the order shown:

  • GNUmakefile

  • makefile

  • Makefile

In UNIX systems, using Makefile as the name of the makefile is customary because it appears near the beginning of directory listings where the uppercase names appear before the lowercase names.

When you download software from the Internet, you usually find a Makefile, together with the source files. To build the software, you have only to type make at the shell prompt; make takes care of all the steps necessary to build the software.

If your makefile does not have a standard name, such as Makefile, you have to use the -f option to specify the makefile's name. If your makefile is called webprog.mak, for example, you have to run make using the following command line:

make -f webprog.mak

GNU make also accepts several other command-line options, which are summarized in the 'How to Run make' section of this chapter.

Understanding the makefile

For a program that consists of several source and header files, the makefile specifies the following:

  • The items make will create-usually the object files and the executable. The term target is used for an item to be created.

  • The files or other actions required to create the target.

  • Which commands should be executed to create each target.

Suppose you have a C++ source file named form.C that contains the following preprocessor directive:

#include "form.h"  // Include header file

The object file form.o clearly depends on the source file form.C and the header file form.h. In addition to these dependencies, you must specify how make should convert the form.C file to the object file form.o. Suppose you want make to run g++ (because the source file is in C++) with these options:

  • -c (compile only)

  • -g (generate debugging information)

  • -O2 (optimize some)

In the makefile, you can express this with the following rule:

# This a comment in the makefile
# The following lines indicate how form.o depends
# form.C and form.h and how to create form.o.

form.o: form.C form.h
        g++ -c -g -O2 form.C

In this example, the first noncomment line shows form.o as the target and form.C and form.h as the dependent files.

Insider Insight 

The line following the dependency indicates how to build the target from its dependents. This line must start with a Tab; otherwise make will not work.

Using Variables (or Macros)

In addition to the basic service of building targets from dependents, GNU make includes many nice features that make it easy for you to express the dependencies and rules for building a target from its dependents. If you need to compile a large number of C++ files by using GCC with the same options, for example, typing the options for each file is tedious. You can avoid this task by defining a variable or macro in make as follows:

# Define macros for name of compiler
CXX= g++

# Define a macro for the GCC flags
CXXFLAGS= -O2 -g -mcpu=i686

# A rule for building an object file
form.o: form.C form.h
        $(CXX) -c $(CXXFLAGS) form.C

In this example, CXX and CXXFLAGS are make variables. GNU make prefers to call them variables, but most UNIX make utilities call them macros.

To use a variable anywhere in the makefile, start with a dollar sign ($) followed by the variable within parentheses. GNU make replaces all occurrences of a variable with its definition; thus, it replaces all occurrences of $(CXXFLAGS) with the string -O2 -g -mcpu=i686.

GNU make has several predefined variables that have special meanings. Table 23-2 lists these variables. In addition to the variables listed in Table 23-2, GNU make considers all environment variables predefined.

Table 23-2: Some Predefined Variables in GNU make

Variable

Meaning

$%

Member name for targets that are archives. If the target is libDisp.a(image.o), for example, $% is image.o, and $@ is libDisp.a.

$*

Name of the target file without the extension

$+

Names of all dependent files with duplicate dependencies, listed in their order of occurrence

$<

The name of the first dependent file

$?

Names of all dependent files (with spaces between the names) that are newer than the target

$@

Complete name of the target

$^

Names of all dependent files, with spaces between the names. Duplicates are removed from the dependent filenames.

AR

Name of the archive-maintaining program (Default value: ar)

ARFLAGS

Flags for the archive-maintaining program (Default value: rv)

AS

Name of the assembler program that converts the assembly language to object code (Default value: as)

ASFLAGS

Flags for the assembler

CC

Name of the C compiler. (Default value: cc)

CFLAGS

Flags to be passed to the C compiler

CO

Name of the program that extracts a file from RCS (Default value: co)

COFLAGS

Flags for the RCS co program

CPP

Name of the C preprocessor (Default value: $(CC) -E)

CPPFLAGS

Flags for the C preprocessor.

CXX

Name of the C++ compiler (Default value: g++)

CXXFLAGS

Flags to be passed to the C++ compiler

FC

Name of the FORTRAN compiler (Default value: f77)

FFLAGS

Flags for the FORTRAN compiler

GET

Name of the program to extract a file from SCCS (Default value: get)

GFLAGS

Flags for the SCCS get program

LDFLAGS

Flags for the compiler when it is supposed to invoke the linker ld

LEX

Name of the program to convert Lex grammar to C program (Default value: lex)

LFLAGS

Flags for Lex

MAKEINFO

Name of the program that converts Texinfo source files to info files (Default value: makeinfo)

RM

Name of the command to delete a file (Default value: rm -f)

TEX

Name of the program to generate TeX DVI files from TeX source files (Default value: tex)

TEXI2DVI

Name of the program to generate TeX DVI files from the Texinfo source (Default value: texi2dvi)

YACC

Name of the program to convert YACC grammars to C programs (Default value: yacc -r)

YFLAGS

Flags for yacc

Taking Stock of Implicit Rules

GNU make also includes built-in, or implicit, rules that define how to create specific types of targets from various dependencies. An example of an implicit rule is the command that make should execute to generate an object file from a C source file.

GNU make supports two types of implicit rules:

  • Suffix rules -Suffix rules define implicit rules for make. A suffix rule defines how to convert a file that has one extension to a file that has another extension. Each suffix rule is defined with the target showing a pair of suffixes (file extensions). The suffix rule for converting a .c (C source) file to a .o (object) file, for example, might be written as follows:

    .c.o:
    $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<

    This rule uses the predefined variables CC, CFLAGS and CPPFLAGS. For filenames, the rule uses the variables $@ (the complete name of the target) and $< (the name of the first dependent file).

  • Pattern rules-These rules are more versatile because you can specify more complex dependency rules by using pattern rules. A pattern rule looks just like a regular rule, except that a single percent sign (%) appears in the target's name. The dependencies also use % to indicate how the dependency names relate to the target's name. The following pattern rule specifies how to convert any file X.c to a file X.o:

    %.o: %.c
    $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<

GNU make has a large set of implicit rules, defined as both suffix and pattern rules. To see a list of all known variables and rules, run make by using the following command:

make -p -f/dev/null

The output includes the names of variables, as well as implicit rules.

Writing a Sample makefile

You can write a makefile easily if you use GNU make's predefined variables and its built-in rules. Consider, for example, a makefile that creates the executable xdraw from three C source files (xdraw.c, xviewobj.c, and shapes.c) and two header files (xdraw.h and

shapes.h). Assume that each source file includes one of the header files. Given these facts, here is what a sample makefile might look like:

#########################################################
# Sample makefile
# Comments start with '#'
#
#########################################################

# Use standard variables to define compile and link flags

CFLAGS= -g -O2
# Define the target "all"
all: xdraw

OBJS=xdraw.o xviewobj.o shapes.o

xdraw: $(OBJS)

# Object files
xdraw.o: Makefile xdraw.c xdraw.h

xviewobj.o: Makefile xviewobj.c xdraw.h

shapes.o: Makefile shapes.c shapes.h

This makefile relies on GNU make's implicit rules. The conversion of .c files to .o files uses the built-in rule. Defining the variable CFLAGS passes the flags to the C compiler.

If you have a directory that contains the appropriate source files and header files, you can try the makefile. Here's what happens when I try the sample makefile:

make
cc -g -O2  -c xdraw.c -o xdraw.o
cc -g -O2  -c xviewobj.c -o xviewobj.o
cc -g -O2  -c shapes.c -o shapes.o
cc  xdraw.o xviewobj.o shapes.o  -o xdraw

As the output of make shows, make uses the cc command (which happens to be a symbolic link to GCC in your Red Hat Linux system) with appropriate options to compile the source files and, finally, to link the objects to create the xdraw executable.

Running make

Typically, you run make with a single command in the command line; that is, you run make by typing make. When run this way, GNU make looks for a file named GNUmakefile, makefile, or Makefile-in that order. If make finds one of these makefiles, it builds the first target specified in that makefile. However, if make does not find an appropriate makefile, it displays the following error message and exits:

make: *** No targets.  Stop.

If your makefile happens to have a different name from the default names, you have to use the -f option to specify the makefile. The syntax of this make option is the following:

make -f filename

where filename is the name of the makefile.

Even when you have a makefile with a default name such as Makefile, you may want to build a specific target out of several targets defined in the makefile. In that case, you have to run make by using this syntax:

make target

If the makefile contains the target named clean, you can build that target with this command:

make clean

Another special syntax overrides the value of a make variable. For example, GNU make uses the CFLAGS variable to hold the flags used when compiling C files. You can override the value of this variable when you invoke make. Here is an example of how you can define CFLAGS to be the option -g -O2:

make CFLAGS="-g -O2"

In addition to these options, GNU make accepts several other command-line options. Table 23-3 lists the GNU make options.

Table 23-3: Options for GNU make

Option

Meaning

-b

Ignore but accept for compatibility with other versions of make

-C DIR

Change to the specified directory before reading the makefile

-d

Print debugging information

-e

Allow environment variables to override definitions of similarly named variables in the makefile

-f FILE

Read FILE as the makefile

-h

Display the list of make options

-i

Ignore all errors in commands executed when building a target

-I DIR

Search specified directory for included makefiles (the capability to include a file in a makefile is unique to GNU make)

-j NUM

Specify the number of commands that make can run simultaneously

-k

Continue to build unrelated targets, even if an error occurs when building one of the targets

-l LOAD

Don't start a new job if load average is at least LOAD (a floating-point number)

-m

Ignore but accept for compatibility with other versions of make

-n

Print the commands to be executed, but do not execute them

-o FILE

Do not rebuild the file named FILE, even if it is older than its dependents

-p

Display the make database of variables and implicit rules

-q

Do not run anything, but return zero if all targets are up to date; return 1 if anything needs updating and 2 if an error occurs

-r

Get rid of all built-in rules

-R

Get rid of all built-in variables and rules

-s

Work silently (without displaying the commands as they are executed)

-t

Change the timestamp of the files

-v

Display the version number of make and a copyright notice

-w

Display the name of the working directory before and after processing the makefile

-W FILE

Assume that the specified file has been modified (used with -n to see what happens if you modify that file)