WSU logo


College of Engineering & CS
Wright State University
Dayton, Ohio 45435-0001

CEG 333: Introduction to Unix

Prabhaker Mateti

make


Syntax: make [-f Makefile] rule...

A makefile is a special text file that automates compiling a project. It is composed of rules, which depend on files (targets) to be compiled, commands to be run, and other even rules.

Once a makefile has been written, the make command parses it and runs the necessary commands. By default, make will read from the file in the current directory named Makefile (with a capital "M"), and uses the first rule as its goal. If invoked as make RULENAME..., make instead takes its goal from the given rules. An optional -f option specifies an alternate filename.

make determines whether to execute a rule's commands based on the modification times of its targets. So only those files which have changed will be recompiled.

WARNING: a rule that depends on itself is a circular dependency. If make finds one, it stops with an error, since proceeding would create an infinite loop! This circular dependency may be direct or part of a chain with many links.

The format of a rule is:

      rulename: name(s) of other rules this one depends on...
              [command(s) to run after the dependencies]...
    

Any commands to be run for a rule must be indented with a tab. Not eight spaces, not two tabs, one tab.

Autogenerated Targets

The GNU Make program is smart enough to automatically generate targets for many common tasks. For example, if a target depends on "file.o", but no rule with that name is defined, make will look for "file.c", "file.cpp", or another source code file and attempt to create "file.o". The autogenerated target should usually be used, as it makes the Makefile much simpler.

make can figure out a basic command line on its own. If it is necessary to tell make to different compiler options (e.g., "-g" for programs that will be debugged), the programmer can define special variables in the Makefile:

Variable Use
CXX The name of the C++ compiler.
CXXFLAGS Options for the C++ compiler.

Note: Although our make command can autogenerated targets, some older versions of make can't. Often, the newer GNU Make utility used in the lab is available under the name gmake.

A Simple Example

      all: my_program log
      my_program: program2.o program1.o
              g++ -c -msse -mmmx program1.o program2.o -o my_program
      log:
              date >> log.txt
      program2.o:
              g++ -c -msse -mmmx -o program2.o program2.cpp
    

The first time this is run, make goes through the following steps:

  1. Compile "program1.cpp" to an object file, using the autogenerated rule.
  2. Compile "program2.cpp" to an object file, using some extra optimizations. (These optimizations are for demonstration purposes only and will not be useful in this class.)
  3. Link those object files into an executable named "my_program".
  4. Update the compile log with the current date and time.

On subsequent runs, make examines the output files (my_program, program1.o, etc), and only runs the relevant steps when the files have changed.

A Practical Example

This Makefile is suitable for small, single directory projects. It can be modified to build any of this class's assignments.

      CXXFLAGS = -g -Wall

      OBJFILES = simDisk.o bitVector.o directory.o

      PROJECT = P1

      $(PROJECT): $(OBJFILES)
	$(CXX) $(CXXFLAGS) -o $(PROJECT) $(OBJFILES)

      $(OBJFILES): fs33types.h

      indent:
	indent -kr -i2 -pmt *.cpp *.h

      archive: clean
	( TOPDIR=`basename \`pwd\`` ; cd .. ; tar -czf $$TOPDIR-`date +%G%m%d%H%M`.tgz $$TOPDIR )

      clean:
	rm -fr *.o *~ *.out $(PROJECT) \\#*
    

Things to notice:

Several versions of this example Makefile have been discussed on the newsgroup. You may wish to read over some of the postings for more information on how it works.