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 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
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