-->
Previous Table of Contents Next


To create a target in the Makefile, begin with a new line and name the target—what you want to build—then place a colon (:) and a tab, and then list the files the target depends on. Starting on the next line, begin with a tab, then place the UNIX command used to build the target. You can have multiple commands, each of which should go on its own line, and every command line must start with a tab.

In the abstract, the Makefile rules look like the following:

what_to_build: what_it_depends_on
command1_to_build_it
command2_to_build_it
command3_to_build_it
lastcommand_to_build_it

In the abstract, this looks confusing. Here’s a more concrete example, using the chap10 program we provided earlier.

The target we want to build is the chap10 program. The chap10 program (the target) depends on the object module chap10.o. Once we have the object module chap10.o, then the command line to create the chap10 program is:


     chap10:     chap10.o

     cc -o chap10 chap10.o

This make rule states that if chap10.o has a more recent date, then execute the cc command to build the chap10 program from the object module chap10.o.

This is just part of the task; we still have to compile chap10.c to create the object module chap10.o. That is, the file chap10.o, is said to depend on the file chap10.c. You build chap10.o from chap10.c. To do this, we use another make rule.

This time, the object module chap10.o depends on the text file chap10.c. The command to build the object module is:


     chap10.o:     chap10.c

     cc -c chap10.c

With this make rule, if you edit chap10.c, you’ll make the file chap10.c have a more recent date/time than the object module chap10.o. This causes make to trigger the cc command to compile chap10.c into chap10.o.

You’ve discovered the secret to make’s rules. Everything depends on the date/time of the files, a very simple—but clever—idea. The idea is that if the text of the program .c file is modified, you better rebuild the program with cc. Because most users are impatient, if the .c file hasn’t been changed, there’s simply no reason (at least in our example) to rebuild the program with cc.

A Make Example

To try make, enter the following text into a file named Makefile:


     #

     # Test Makefile

     #

     # The program chap10 depends on chap10.o.

     chap10:     chap10.o

          cc -o chap10 chap10.o



     # The object module chap10.o depends on chap10.c.

     chap10.o:     chap10.c

          cc -c chap10.c

This Makefile should be in the same directory as your sample C program file, chap10.c. To use make, we need to tell it what to make, that is, what target we want to build. In our case, we want make to build the program chap10. The following command will build this program:


     $ make chap10

             cc -c chap10.c

             cc -o chap10 chap10.o

We should now have the chap10 program ready to run. If we try make again, it—being very lazy—tells us there’s no new work to do:


     $ make chap10

     chap10 is up to date.

Why? Because the chap10 program was built, and nothing has changed. Now, edit the chap10.c file again or use the touch command to bump up the date/time associated with the file:


     $ touch chap10.c

When you call make again, it knows it now needs to rebuild the chap10 program, because presumably the chap10.c file has changed since the last time chap10.c was compiled with cc. Because touch only updates the date/time associated with the file and doesn’t change the internals of the file in any way, we’ve just fooled make. make doesn’t bother checking if a file is different; it merely checks the time the file was last written to, blindly assuming that no one would ever write to a file without modifying its contents. Normally, though, you don’t want to fool make; use its simple rules to make your life easier.

Make supports a number of useful command-line parameters, as shown in Table 10.4.

Table 10.4 Make Command-Line Parameters
Parameter Meaning

-f makefile Uses the named file instead of Makefile for the rules
-n Runs in no-execute mode—only prints the commands, doesn’t execute them
-s Runs in silent mode; doesn’t print any commands make executes


Previous Table of Contents Next