O'Reilly NetworkO'Reilly.com
Search To FeaturesTo MeerkatFAQsForumsAll ArticlesFree Newsletter
Linux DevCenter Tech Jobs | Linux FAQs | Forum | Articles
 O'Reilly's Emerging Technology Conference: May 13-16, 2002

O'Reilly Network: Linux DevCenter

 Articles


Interviews

Living Linux

Linux in the
  Enterprise


Linux Network
  Administration


Security Alerts

The Linux
  Professional


Tutorials



 Topics


Devices

Email

Game Development

LDAP

PDA

Administration

Browsers

Certification

Community

Database

Desktop

Device Drivers

Firewalls

Getting Started

Kernel

Multimedia

Networking

Programming

Security

Tools

Utilities

X Window System


Print this article

Introduction to Make

by Jennifer Vesperman
01/31/2002

Make originated as a system for building compiled code. It is now used as a system for making changes across many files and directories. It is useful whenever a change in one file requires changes or actions elsewhere.

Make is useful for system administrators as well as developers. This article primarily discusses Make as a compilation tool, but it can be effective for program installation or system configuration changes.

Running Make

Make requires a configuration file. Once this file is constructed for your project, you usually type make to build the changed files.

The usual name for this file is Makefile; the capitalization lists the makefile with README and other special files.

When run with no arguments, GNU Make looks for the configuration files named GNUmakefile, Makefile, and makefile in the current working directory. If using other names, call Make with make -f filename.

The makefile in this example displays make complete and does nothing else. By default, Make lists the commands it runs. To have it run quietly, call Make with make -s.

$ls
makefile    renamed_makefile

$make
echo make complete
make complete

$make -f renamed_makefile
echo make complete
make complete

$make -s
make complete

Simple Makefiles

The examples in this article are written for C, and produce the sample target file. Make can produce any target file, use any shell commands, and work from any source files. Make works best with languages where the compiler does not itself try to resolve dependencies.

Experienced users of Make will see redundant lines in the example makefile. Make already knows how to compile some types of files, and the rules for those files can be left out. (These are called implicit rules.) For clarity, the examples show these rules.

# Linking object files
sample: main.o example.o
		cc -o sample main.o example.o
		echo sample: make complete

# Compiling source files
main.o: main.c main.h
		cc -c main.c
example.o: example.c defs.h
		cc -c example.c

A Make rule is composed of:

target: prerequisites
	commands

A target is considered "up to date" if it exists and is newer than its prerequisites.

Make works backwards, starting with the target of the first rule in the file. In our example, that's sample. Make checks the prerequisites for sample -- main.o and example.o -- to see if they have rules. If they do, it recursively checks their rules.

Make walks down the recursion chain until it finds a target that has no prerequisites, or whose prerequisites have no rules. Once it hits one of those, it walks back up its recursion chain and runs commands as necessary. It creates a recursion chain for every prerequisite it encounters that has a rule.

Once all of the prerequisite rules have been run, it eventually returns to sample's rule. If the file doesn't exist, or is older than its prerequisites now are (after their rules have been recursively tested), it runs the commands to generate sample.

In the example makefile, Make:

  1. Runs the first rule it sees -- sample.
  2. Checks to see whether sample's prerequisites have rules. They do.
  3. Runs the rule for the first prerequisite -- main.o.
  4. Checks to see whether main.o's prerequisites have rules. They don't.
  5. Checks whether main.o is up to date. If not, it runs the commands for main.o.
  6. Runs the rule for the second prerequisite -- example.o.
  7. Checks to see whether example.o's prerequisites have rules. They don't.
  8. Checks whether or not example.o is up to date. If not, it runs the commands for example.o.
  9. Returns to sample's rule
  10. Checks whether or not sample is up to date. If not, it runs the commands to update it.

Make can run the prerequisites in any order. The important part of this sequence is that it runs recursively backwards from the first target (or the target named in the command parameters), and tests only the rules that it encounters in the prerequisites chain.

Make aborts compilation if it receives an error. This is usually useful behavior -- it lets you correct compiler-detected problems during a compile-and-test cycle. The option -i tells Make to ignore errors.

2

Pages: 1, 2



Sponsored by:

Click here!

O'Reilly Bioinformatics Technology Conference

What is the promise of P2P?

Contact UsMedia KitPrivacy PolicyPress NewsJobs @ O'Reilly Network
Copyright © 2000-2002 O'Reilly & Associates, Inc. All Rights Reserved.
All trademarks and registered trademarks appearing on the O'Reilly Network are the property of their respective owners.
For problems or assistance with this site, email help@oreillynet.com

Have you seen Meerkat?