Chapter 5. Managing More Code with Make

The GNU make utility, commonly abbreviated make, is a tool for controlling the generation of executables from source files. make automatically determines which parts of a complex program have changed and need to be recompiled. make uses configuration files called Makefiles to control the way programs are built.

5.1. GNU make and Makefile overview

To create a usable form (usually executable files) from the source files of a particular project, perform several necessary steps. Record the actions and their sequence to be able to repeat them later.

Red Hat Enterprise Linux contains GNU make, a build system designed for this purpose.

Prerequisites

  • Understanding the concepts of compiling and linking

GNU make

GNU make reads Makefiles which contain the instructions describing the build process. A Makefile contains multiple rules that describe a way to satisfy a certain condition (target) with a specific action (recipe). Rules can hierarchically depend on another rule.

Running make without any options makes it look for a Makefile in the current directory and attempt to reach the default target. The actual Makefile file name can be one of Makefile, makefile, and GNUmakefile. The default target is determined from the Makefile contents.

Makefile details

Makefiles use a relatively simple syntax for defining variables and rules, which consists of a target and a recipe. The target specifies what is the output if a rule is executed. The lines with recipes must start with the TAB character.

Typically, a Makefile contains rules for compiling source files, a rule for linking the resulting object files, and a target that serves as the entry point at the top of the hierarchy.

Consider the following Makefile for building a C program which consists of a single file, hello.c.

all: hello

hello: hello.o
        gcc hello.o -o hello

hello.o: hello.c
        gcc -c hello.c -o hello.o

This specifies that to reach the target all, file hello is required. To get hello, one needs hello.o (linked by gcc), which in turn is created from hello.c (compiled by gcc).

The target all is the default target because it is the first target that does not start with a period (.). Running make without any arguments is then identical to running make all, when the current directory contains this Makefile.

Typical makefile

A more typical Makefile uses variables for generalization of the steps and adds a target "clean" - remove everything but the source files.

CC=gcc
CFLAGS=-c -Wall
SOURCE=hello.c
OBJ=$(SOURCE:.c=.o)
EXE=hello

all: $(SOURCE) $(EXE)

$(EXE): $(OBJ)
        $(CC) $(OBJ) -o $@

%.o: %.c
        $(CC) $(CFLAGS) $< -o $@

clean:
        rm -rf $(OBJ) $(EXE)

Adding more source files to such Makefile requires only adding them to the line where the SOURCE variable is defined.

Additional resources

5.2. Example: Building a C program using a Makefile

Build a sample C program using a Makefile by following the steps in the following example.

Prerequisites

  • You must understand the concepts of Makefiles and make.

Procedure

  1. Create a directory hellomake and change to this directory:

    $ mkdir hellomake
    $ cd hellomake
  2. Create a file hello.c with the following contents:

    #include <stdio.h>
    
    int main(int argc, char *argv[]) {
      printf("Hello, World!\n");
      return 0;
    }
  3. Create a file Makefile with the following contents:

    CC=gcc
    CFLAGS=-c -Wall
    SOURCE=hello.c
    OBJ=$(SOURCE:.c=.o)
    EXE=hello
    
    all: $(SOURCE) $(EXE)
    
    $(EXE): $(OBJ)
            $(CC) $(OBJ) -o $@
    
    %.o: %.c
            $(CC) $(CFLAGS) $< -o $@
    
    clean:
            rm -rf $(OBJ) $(EXE)
    Caution

    The Makefile recipe lines must start with the tab character! When copying the text above from the documentation, the cut-and-paste process may paste spaces instead of tabs. If this happens, correct the issue manually.

  4. Run make:

    $ make
    gcc -c -Wall hello.c -o hello.o
    gcc hello.o -o hello

    This creates an executable file hello.

  5. Run the executable file hello:

    $ ./hello
    Hello, World!
  6. Run the Makefile target clean to remove the created files:

    $ make clean
    rm -rf hello.o hello

5.3. Documentation resources for make

For more information about make, see the resources listed below.

Installed documentation

  • Use the man and info tools to view manual pages and information pages installed on your system:

    $ man make
    $ info make

Online documentation