Use Makefile in C++

This article will demonstrate multiple methods of how to use Makefile in C++.

Use Makefile to Compile a Multi-file Program Easily in C++

Makefile is the name of the file that describes the relationship between program source files and headers to be compiled. This file is used by the make utility which is invoked on the command-line, and it acts as a mini build system for the code project. Note though, make is not limited to the programming language and even to the program compilation, as it can be utilized in scenarios where files need to be updated based on modifications made in relative files. The relations are represented by the set of rules that describe the specific actions. The following snippet shows the structure of a typical rule. A target is commonly a name for the executable or object files. prerequisites are usually input files that are needed to output the target file. A recipe is an action conducted by the make, and they are indented with the tab on each new line. Mind that make scans the file named makefile or Makefile if it exists in the current working directory.

target: prerequisites
<TAB> recipe

The rules are the main part of the Makefile as they are the only necessary part. The following example demonstrates the simple Makefile structure that builds the executable file named program. Now, the program has the prerequisites - main.o and library1.o, which are object files outputted from the rules below. Both of them have their respective recipes that compile certain prerequisites to get the given output. Note that, g++ command is the GNU C++ compiler that executes as a part of the recipe and can be constructed with the usual command-line arguments.

program : main.o library1.o
    g++ -o program main.o library1.o
main.o : main.cpp header1.h
    g++ -c main.cpp
library1.o : library1.cpp library1.h
    g++ -c library1.cpp

Another feature of Makefile is variables that behave similarly to the C++ preprocessor macro expressions. Namely, we can define name aliases for strings that appear in the file multiple times and place the variable names. E.g., the next snippet shows the OBJ variable defined at the beginning of the file, and it includes program prerequisites which repeat in the first rule. Note, though, variables are the most efficient when far longer strings are substituted.

OBJ = main.o library1.o

program : $(OBJ)
    g++ -o program $(OBJ)
main.o : main.cpp header1.h
    g++ -c main.cpp
library1.o : library1.cpp library1.h
    g++ -c library1.cpp

Additionally, we can define other variables that may represent compiler or linker flags, usually used in multiple locations in the Makefile. Thus, when the project is big, and the Makefile gets bigger, it is easier to modify the single line than change every instance of the given parameter.

OBJ = main.o library1.o
CC = g++
LFLAGS = -lm

program : $(OBJ)
    $(CC) -o $(LFLAGS) program $(OBJ)
main.o : main.cpp header1.h
    $(CC) -c main.cpp
library1.o : library1.cpp library1.h
    $(CC) -c library1.cpp
Contribute
DelftStack is a collective effort contributed by software geeks like you. If you like the article and would like to contribute to DelftStack by writing paid articles, you can check the write for us page.