Introduction to C: A Simple Makefile

Video Walkthrough

A Simple Example

main: main.c
        cc -Wall -Werror -std=c11 -o main main.c

Caution: The above code will not work if it is copied and pasted into a Makefile. This is because the eight-space indent must appear in the file as a Tab character. Be sure your editor does not convert tabs to spaces when saving a Makefile.

Rules

A Makefile is a text file that provides a set of rules that the make program can understand. A complete rule consists of a target, its prerequisites, and a recipe. A rule appears in this format:

<target(s)>: <prerequisitie(s)>
        <recipe>

In addition to rules, a Makefile can also define variables, comments, and directives. See the manual for more details.

Targets

A target defined in a Makefile generally defines a specific file to be built.

A target is called phony if it declares a set of commands to be run that do not result in a file being created. (A common example is a clean target, which typically removes any and all files that make might create when any other recipe executes.)

In this example, main is the target.

Prerequisites

The prerequisites list the files that must exist before the target can be created.

In this example, main.c is the prerequisite.

It's important for Make to know which files are prerequisites to build which targets, so that Make can incrementally build your software efficiently. For example, if your Makefile specifies several hundred .c files which must be built, it's useful if make avoids building files that have not changed.

Recipes

A recipe is intended to be interpreted by the shell (often /bin/sh by default). In other words, when writing a recipe in a Makefile, you would use the same commands you would use at a command prompt.

The make program knows that it is processing a recipe (as opposed to part of the Makefile itself) because the line it's written on begins with a Tab character. When editing a Makefile, be careful that your editor is not set to convert tabs to spaces (or spaces to tabs).

In this example, cc -Wall -Werror -std=c11 -o main main.c is the recipe.

Using a simple Makefile can save time and effort by making incremental builds efficient, while simultaneously standardizing and documenting the commands used to build your software,

Conclusion

That's all you need to create your first Makefile! With that, now we won't need to remember which arguments to pass to cc to get our program to build.

This simple Makefile illustrates a basic recipe, but won't scale well as the project grows. In future lessons, we'll look at how to change this to accommodate your growing project. In the next lesson, we'll jump back into C code and learn how to read a line of text from the console.