Make (and Makefiles)

Overview

make is a powerful tool that helps you organize and issue collections of shell commands. It is commonly used to:

  • Determine which parts of a program need to be compiled, and issue shell commands to compile these programs. While C/C++ is the most commonly compiled language, make can be used to compile any language that uses a command-line interface for compiling.
  • More broadly, make can be used for any task where files are created or modified via shell commands and need to be updated when other files change.
  • Even more broadly, make is often used as a shorthand for issuing multiple shell commands in a single statement.

Installation

From a Linux terminal, run:

sudo apt install make
Wondering what this does?
  • sudo - This command elevates the privileges of the next command to superuser level, allowing you to install make system-wide.
  • apt - This command runs the command-line interface of the APT (advanced package tool), which handles the installation of make.
  • install - This is an apt-specific command that installs the packages named as inputs.
  • make - The name of the package to install.

Lecture Video

On May 5, 2021, we had a Make Tutorial by Prof Goeders. The video is embedded below:

Timestamps

0:00 Introduction to Make
1:01 Creating a recipe
2:54 Running makefiles and recipes
4:09 Common uses of Make
5:15 Using Make to create other files
8:20 A simple C program
9:28 Compiling C with Make
10:25 Adding dependencies
12:35 make clean
12:53 Importance of recipe names
15:01 Adding variables
16:40 Chaining recipes
24:47 Importance of recipe order
25:17 Comments on suppressing output
25:50 Comments on calling other makefiles
26:28 Built-in variables
30:06 Simplifying through pattern matching
32:01 Demonstration of verbose option
34:35 Making your makefiles more generic and reusable
40:54 Creating overridable variables
43:55 Creating a default, catch-all rule

Example

The lecture video presents a simple C program that implements an interactive calculator and then discusses how to use make to compile it. The lecture walks through how a Makefile works, starting with a very simple example and building up to a more complex generic makefile.

The files used in the lecture video can be found here: https://github.com/byu-cpe/ComputingBootCamp/tree/main/make

The lectures starts by creating a very simple Makefile, which is copied from makefiles/mk1. It then walks through the steps of modifying this Makefile to the one in makefiles/mk2, then makefiles/mk3, and so on.

The various stages of makefile development shown in the lecture are (time stamps in parentheses):

  • mk1 (10:13): The simplest makefile where we discuss makefile “recipes” (targets). Build and clean only.

ACTIVITY

What is the target of the first rule?

  • compute.c
  • gcc
  • -o
  • calc
  • mk2 (15:01): Variables
  • mk3 (16:36): We split up the compilation/linker steps, and introduce chained dependencies. We do a bunch of demos of deleting files and rebuilding targets. The linux ‘touch’ command is very helpful here.
  • mk4 (26:28): We introduce Makefile automatic variables ($@ and $<)

ACTIVITY

Match the automatic variable with its value

  • $<
  • $?
  • $^
  • $@
  • The name of the first prerequisite
  • The names of all the prerequisites that are newer than the target
  • The names of all the prerequisites
  • The target of the rule

See https://www.gnu.org/software/make/manual/html_node/Automatic-Variables.html for help

  • mk5 (30:06): Pattern matching
  • mk6 (34:35): Makefile functions, and making the makefile more generic.

ACTIVITY

Which of the following is a Makefile function that takes the .cpp files in a variable called CPP, changes the endings to .h, and saves them in a variable called HEADERS?

  • HEADERS=$(wildcard *.h)
  • CPP=$(wildcard *.cpp)
  • HEADERS=$(CPP:.cpp=.h)
  • CPP=$(HEADERS:.h=.cpp)

Conclusion

make is a powerful tool for collecting the shell commands used for compilation into a single file. With a bit of knowledge, you can make Makefiles that are generic enough to be reused again and again. It simplifies compilation by reducing it to a single, memorable command, and it allows you to automate the repetitive parts of the compilation process.

Activities

  • Check if a project you’re working on uses a Makefile to compile. Open up the Makefile, and try to understand what it is doing. A lot of C/C++ projects will use Makefiles automatically generated by CMake, so they may be a bit hard to understand, but definitely take a look!

  • Write a short C program of your own, and write a Makefile to compile it.

  • Checkout the Makefiles Dr. Goeders used, and experiment with changing things and seeing what happens.

Certify Your Skills

Make Badge

For those who believe they have mastered Make and Makefiles, we present the Make badge! This badge can be viewed in its entirety on Badgr.com here: Make Badge. The Make badge can be used to prove your Makefile knowledge to potential employers, educational institutions, or anyone else! To earn it, you’ll have to complete the Make test and use your knowledge to write Makefiles for varying situations. Attempt the Make test and earn the Make badge with the button below!

EARN THE MAKE BADGE

Good luck to those who attempt the test, and if you pass, congratulations! You are now certified in Make and Makefiles by the BYU Computing Boot Camp.

Additional Resources