Make and Makefiles#
make is a commonly used Linux utility to perform a series of commands for a particular target. Typically,
developers use make to compile and link a program from its source files, especially in C/C++ programming.
The configuration/commands are included in a file typically called Makefile.
Makefile Advantages#
Using a Makefile offers several advantages:
Automation: Makefiles automate the compilation and linking process, saving you from manually retyping lengthy compilation commands.
Dependency Tracking: Makefiles can track dependencies between source files and object files, ensuring that only the necessary files are recompiled when changes are made.
Customization: Makefiles allow you to define custom build rules, targets, and variables, providing flexibility in the build process.
Portability: Makefiles work consistently across different platforms and development environments.
Makefile Syntax#
A Makefile consists of a set of rules that define how to create target files from their dependencies. Each rule has the following structure:
target: dependencies
commands
target: The file or action to be created or performed.
dependencies: The files that the target depends on.
commands: The commands to be executed to create the target. These commands must be indented with a tab character, not spaces.
C++ Makefile Example#
Let’s create a simple Makefile to compile a C++ program consisting of two source files: main.cpp and utils.cpp.
# Compiler
CXX = g++
# Compiler flags
CXXFLAGS = -pedantic -std=c++17 -Wall -Wextra -Werror -ggdb3
# Target executable
TARGET = myprogram
# Source files
SOURCES = main.cpp utils.cpp
# Object files
OBJECTS = $(SOURCES:.cpp=.o)
# Default target
all: $(TARGET)
# Rule to create the target executable
$(TARGET): $(OBJECTS)
$(CXX) $(CXXFLAGS) $(OBJECTS) -o $(TARGET)
# Rule to create object files
%.o: %.cpp
$(CXX) $(CXXFLAGS) -c $< -o $@
# Clean target
clean:
rm -f $(TARGET) $(OBJECTS)
Here’s what each part of the Makefile does:
CXX = g++defines the C++ compiler to use (in this case, g++).CXXFLAGS = -pedantic -std=c++17 -Wall -Wextra -Werror -ggdb3sets the compiler flags for warnings and C++17 standard.TARGET = myprogramdefines the name of the target executable.SOURCES = main.cpp utils.cpplists the source files.OBJECTS = $(SOURCES:.cpp=.o)creates a list of object files by replacing the .cpp extension with .o for each source file.all: $(TARGET)defines the default target all that depends on the target executable.$(TARGET): $(OBJECTS)defines the rule for creating the target executable from the object files.%.o: %.cppis a pattern rule that defines how to create object files from source files.clean:defines the clean target that removes the target executable and object files.
Using the Makefile#
To build the program using the Makefile, navigate to the directory containing the Makefile and source files, and run the make command:
$ make
This will compile the source files and link them into the target executable myprogram. If any of the source files change, running make again will only recompile the modified files and recreate the executable.
To clean the build artifacts (remove the target executable and object files), run:
$ make clean