23.7 The Makefile for Multiple Files

I l @ ve RuBoard

The utility make is designed to aid the programmer in compiling and linking programs. Before make , the programmer had to type compile commands explicitly each time there was a change in the program:

 g++ -Wall -g -ohello hello.cpp 

In this chapter we use the commands for the GNU g++ compiler. The C++ compiler on your system may have a different name and a slightly different syntax.

As programs grow, the number of commands needed to create them grows. Typing in a series of 10 or 20 commands is tiresome and error-prone , so programmers started writing shell scripts (or, in MS-DOS, .BAT files ). Then all the programmer had to type was do-it and the computer would compile everything. This was overkill, however, because all the files were recompiled regardless of need.

As the number of files in a project grew, this recompiling became a significant problem. Changing one small file, starting the compilation, and then having to wait until the next day while the computer executed several hundred compile commands was frustrating ” especially when only one compile was really needed.

The program make was created to do intelligent compiles . Its purpose is to first decide what commands need to be executed and then execute them.

The file Makefile (upper/lowercase is important in Unix) contains the rules used by make to decide how to build the program. The Makefile contains the following sections:

  • Comments

  • Macros

  • Explicit rules

  • Default rules

Any line beginning with a # is a comment.

A macro has the format:

name = data

Name is any valid identifier. Data is the text that will be substituted whenever make sees $( name ).

Here's an example:

 #  # Very simple Makefile  #  MACRO = Doing All  all:          echo $(MACRO) 

Explicit rules tell make what commands are needed to create the program. These rules can take several forms. The most common is:

target : source [ source2 ] [ source3 ]
command
[ command ]
[ command ]
. . .

Target is the name of a file to create. It is "made," or created, out of the source file source . If the target is created out of several files, they are all listed.

The command used to create the target is listed on the next line. Sometimes it takes more than one command to create the target. Commands are listed one per line. Each is indented by a tab.

For example, the rule:

 hello: hello.cpp         g++ -Wall -g -o hello hello.cpp 

tells make to create the file hello from the file hello.cpp using the command:

 g++ -Wall -g -o hello hello.cpp 

make will create hello only if necessary. The files used in the creation of hello, arranged in chronological order (by modification time), are shown in Table 23-2.

Table 23-2. File modification times

Unix

MS-DOS/Windows

Modification time

hello.cpp

HELLO.CPP

Oldest

hello.o

HELLO.OBJ

Old

hello

HELLO.EXE

Newest

If the programmer changes the source file hello.cpp , the file's modification time will be out of date with respect to the other files. make will sense this and re-create the other files.

Another form of the explicit rule is:

source :
command
[ command ]

In this case, the commands are executed each time make is run, unconditionally.

If the commands are omitted from an explicit rule, make uses a set of built-in rules to determine what command to execute.

For example, the rule:

 hist.o: ia.h hist.cpp 

tells make to create hist.o from hist.cpp and ia.h , using the standard rule for making <file>.o from <file>.cpp . This rule is:

g++ $(CFLAGS) -c file .cpp

( make predefines the macro $(CFLAGS) .)

We are going to create a main program hist.cpp that calls the module ia.cpp . Both files include the header ia.h , so they depend on it. The Unix Makefile that creates the program hist from hist.cpp and ia.cpp is listed in Example 23-5.

Example 23-5. ia/makefile.unx
 # # Makefile for many Unix compilers using the # "standard" command name CC # CC=CC CFLAGS=-g SRC=ia.cpp hist.cc OBJ=ia.o  hist.o all: hist          hist: $(OBJ)         $(CC) $(CFLAGS) -o hist $(OBJ) hist.o: ia.h hist.cpp         $(CC) $(CFLAGS) -c hist.cpp ia.o: ia.h ia.cpp         $(CC) $(CFLAGS) -c ia.cpp clean:         rm hist io.o hist.o 

The macro SRC is a list of all the C++ files. OBJ is a list of all the object (. o) files. The lines:

 hist: $(OBJ)          g++ $(CFLAGS) -o hist $(OBJ) 

tell make to create hist from the object files. If any of the object files are out of date, make will re-create them.

The line:

 hist.o:ia.h 

tells make to create hist.o from ia.h and hist.cpp ( hist.cpp is implied ). Because no command is specified, the default is used.

Example 23-6 shows the Makefile for MS-DOS/Windows, using Borland-C++.

Example 23-6. ia/makefile.bcc
 # # Makefile for Borland's Borland-C++ compiler # CC=bcc32 # # Flags  #       -N  -- Check for stack overflow #       -v  -- Enable debugging #       -w  -- Turn on all warnings #       -tWC -- Console application # CFLAGS=-N -v -w -tWC SRC=ia.cpp hist.cpp OBJ=ia.obj hist.obj all: hist.exe          hist.exe: $(OBJ)         $(CC) $(CFLAGS) -ehist $(OBJ) hist.obj: ia.h hist.cpp         $(CC) $(CFLAGS) -c hist.cpp ia.obj: ia.h ia.cpp         $(CC) $(CFLAGS) -c ia.cpp clean:         erase hist.exe io.obj hist.obj 

There is one big drawback with make . It only checks to see whether the files have changed, not the rules. If you have compiled your entire program with CFLAGS = -g for debugging and need to produce the production version ( CFLAGS = -O ), make will not recompile.

The Unix command touch changes the modification date of a file. (It doesn't change the file; it just makes the operating system think it did.) If you touch a source file such as hello.cpp and then run make , the program will be re-created. This is useful if you have changed the compile-time flags and want to force a recompilation.

Make provides a rich set of commands for creating programs. Only a few have been discussed here. [1]

[1] If you are going to create programs that require more than 10 or 20 source files, it is suggested you read the book Managing Projects with make (O'Reilly & Associates, Inc.).

I l @ ve RuBoard


Practical C++ Programming
Practical C Programming, 3rd Edition
ISBN: 1565923065
EAN: 2147483647
Year: 2003
Pages: 364

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net