👆Click the blue text "Linux Armory" at the top, then select "Set as Star" at the top right
Makefile is a tool used for building and managing projects, especially suitable for C/C++ projects. It defines the dependencies between various files in the project and specifies how to compile and link these files. Below is a simple example of a Makefile, along with a detailed explanation of its key parts:
1. Makefile Example
# Makefile Example
# Compiler
CC = gcc
# Compilation options
CFLAGS = -Wall -g
# Target file
TARGET = myprogram
# Source files
SRCS = main.c func1.c func2.c
# Intermediate files
OBJS = $(SRCS:.c=.o)
# Default target
all: $(TARGET)
# Target file generation rule
$(TARGET): $(OBJS)
$(CC) $(CFLAGS) -o $@ $^
# Intermediate file generation rule
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
# Clean rule
clean:
rm -f $(TARGET) $(OBJS)
2. Makefile Explanation
-
CC
: Variable for the compiler, usinggcc
here. -
CFLAGS
: Variable for compilation options, setting-Wall
(show all warnings) and-g
(generate debug information). -
TARGET
: Variable for the target file, defining the name of the final executable file. -
SRCS
: Variable for source files, listing all source files here. -
OBJS
: Variable for intermediate files, replacing the suffix of source files from.c
to.o
. -
all
: Default target, this will be built when executing themake
command. -
$(TARGET)
: Generation rule for the target file, telling Make how to generate the final executable file. -
$(OBJS)
: Generation rule for intermediate files, telling Make how to generate intermediate target files. -
%.o: %.c
: Generic rule, telling Make how to compile.c
files into corresponding.o
files. -
clean
: Clean rule, executingmake clean
will delete the generated executable and intermediate target files.
3. Using Makefile
In the project directory, execute the following commands:
-
Build the project:
make
ormake all
. -
Clean the project:
make clean
.
4. Notes
-
Whitespace Issue: Makefile uses the Tab key instead of spaces to indent rules.
-
File Dependencies: The core of Makefile is the dependencies between files, ensuring that each target depends on the correct files.
-
Variable References: Use
$@
to represent the target,$^
to represent all dependent files, and$<code> to represent the first dependent file.
-
Wildcards: Use
%
wildcard to represent a class of files, for example,%.o: %.c
.
Makefile is a very powerful tool that can be used to manage complex project structures. The above example is a simple entry-level Makefile, while actual projects may contain more configurations and rules.
5. Makefile Rules
Makefile typically contains rules that describe how to generate one or more target files. The basic format of each rule is as follows:
target: dependencies
command
-
target
: The name of the target file, which can be an executable file, an intermediate file, or a label. -
dependencies
: A list of files that the target file depends on, which are needed to generate the target file. -
command
: The command to generate the target file, describing how to generate the target file from the dependent files.
Here is a simple example:
main: main.o utils.o
gcc -o main main.o utils.o
main.o: main.c
gcc -c main.c
utils.o: utils.c
gcc -c utils.c
In this example, main
is the target file, which depends on main.o
and utils.o
. The command to generate main
file is gcc -o main main.o utils.o
. Similarly, main.o
depends on main.c
, and utils.o
depends on utils.c
.
6. Automatic Variables
Makefile has some special variables called automatic variables, which are used in the commands of rules to represent specific information. Some commonly used automatic variables are:
-
$@
: Represents the name of the target file. -
$<code>:
Represents the name of the first dependent file in the rule. -
$^
: Represents the names of all dependent files in the rule, separated by spaces.
Here is an example of using automatic variables:
main: main.o utils.o
gcc -o $@ $^
This rule is equivalent to the previous rule, using automatic variables to represent the target file and all dependent files.
7. Generic Rules
If there are multiple similar target files, generic rules can be used. Generic rules use the wildcard %
to match part of the file name.
%.o: %.c
gcc -c $<
This rule indicates that for any .o
file, it depends on the corresponding .c
file, and the generation rule is gcc -c $<code>.
8. Variables
Variables can be defined in Makefile to store strings, file names, compilation options, and other information. The format for defining variables is as follows:
VAR_NAME = value
Example of using variables:
CC = gcc
CFLAGS = -Wall -O2
main: main.o utils.o
$(CC) -o $@ $^ $(CFLAGS)
In this example, CC
and CFLAGS
are both variables, storing the compiler and compilation options, respectively. When used in the command of the rule, $(CC)
and $(CFLAGS)
replace specific values.
9. Include Directive
Makefile can include other Makefiles using the include
directive. This can split the Makefile into multiple modules for better maintainability.
include common.mk
main: main.o utils.o
$(CC) -o $@ $^ $(CFLAGS)
10. PHONY Targets
Sometimes, we need to define some targets that do not produce actual files, such as cleaning temporary files or executing specific tasks. To tell Make that these targets are not file names, we can use .PHONY
targets.
.PHONY: clean
clean:
rm -f *.o main
In this example, clean
is a PHONY target used to delete temporary files.
When building a software project, the make
tool can automate the compilation process, ensuring that only files that have changed are recompiled. make
uses a file named Makefile, which contains a series of rules and instructions describing the dependencies between files and how to generate target files. Below is a simple structure and basic elements of a Makefile:
11. Basic Structure
Makefile consists of a series of rules and variables. Each rule describes how to generate one or more target files. The basic structure is as follows:
# Comments start with '#'
# Variable definitions
CC = gcc
CFLAGS = -Wall
# The first rule is the default rule
all: target1 target2
# Rule: Target files depend on files
# [tab] Instructions (commands to generate target files)
target1: dependency1 dependency2
$(CC) $(CFLAGS) -o target1 dependency1 dependency2
target2: dependency3 dependency4
$(CC) $(CFLAGS) -o target2 dependency3 dependency4
12. Variables
In Makefile, variables can be used to store and reference values. In the above example, CC
and CFLAGS
are variables that store the compiler and compilation options, respectively.
13. Rules
Rules consist of the following parts:
-
Target: Describes the name of the generated file. Multiple targets can be specified, separated by spaces. -
Dependencies: Describes the list of files that the target file depends on. If the content of the dependent files changes, the target file will be regenerated. -
Commands: Describes the commands to generate the target file. Commands must be preceded by a tab character ( \t
).
14. Default Rules
The first rule is usually the default rule, which is executed by default when the make
command is run. In the above example, the default rule is all: target1 target2
.
15. Wildcards
Makefile supports wildcards to match file lists. Common wildcards include *
(matches any character) and %
(matches any sequence of characters).
# Match all files ending with .c
sources = $(wildcard *.c)
16. Automatically Generate Dependencies
Using the -M
option allows the compiler to automatically generate dependencies. This is helpful for tracking dependencies between header files.
# Automatically generate dependencies
%.d: %.c
$(CC) -M $< > $@
17. Include Directive
Using the include
directive allows other Makefile files to be included in the current Makefile.
# Include other Makefile files
include other.mk
18. Example
Below is a simple Makefile example for a C language project:
CC = gcc
CFLAGS = -Wall
LDFLAGS =
SRCDIR = src
OBJDIR = obj
BINDIR = bin
SOURCES = $(wildcard $(SRCDIR)/*.c)
OBJECTS = $(patsubst $(SRCDIR)/%.c,$(OBJDIR)/%.o,$(SOURCES))
EXECUTABLE = $(BINDIR)/my_program
all: $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) -o $@ $^
$(OBJDIR)/%.o: $(SRCDIR)/%.c
$(CC) $(CFLAGS) -c -o $@ $<
clean:
rm -rf $(OBJDIR)/*.o $(EXECUTABLE)
This Makefile describes a simple project structure, where source files are located in the src
directory, target files in the obj
directory, and executable files in the bin
directory. This Makefile includes all
(default target), clean
(clean target), and other rules.
19. Functions
Makefile supports some built-in functions for handling strings, paths, etc. Common functions include $(wildcard)
, $(patsubst)
, $(foreach)
, etc.
# Get a list of all .c files
C_FILES = $(wildcard src/*.c)
# Replace .c files with .o files
O_FILES = $(patsubst src/%.c, obj/%.o, $(C_FILES))
# Use foreach to iterate
SOURCES = file1.c file2.c file3.c
OBJECTS = $(foreach src, $(SOURCES), obj/$(src:.c=.o))
20. Conditional Statements
Conditional statements can be used in Makefile to execute different commands based on different conditions.
# Conditional statements
ifeq ($(DEBUG),1)
CFLAGS += -g
else
CFLAGS += -O2
endif
21. Recursive Calls
Makefile can build sub-targets through recursive calls.
# Recursive calls
subtarget:
$(MAKE) -C subdir
22. Example
Below is a Makefile example that includes multiple source files, header files, and library files:
CC = gcc
CFLAGS = -Wall
LDFLAGS =
SRCDIR = src
INCDIR = include
OBJDIR = obj
BINDIR = bin
LIBDIR = lib
SOURCES = $(wildcard $(SRCDIR)/*.c)
HEADERS = $(wildcard $(INCDIR)/*.h)
OBJECTS = $(patsubst $(SRCDIR)/%.c,$(OBJDIR)/%.o,$(SOURCES))
EXECUTABLE = $(BINDIR)/my_program
LIBRARY = $(LIBDIR)/libmylibrary.a
all: $(EXECUTABLE) $(LIBRARY)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) -o $@ $^
$(LIBRARY): $(OBJECTS)
ar rcs $@ $^
$(OBJDIR)/%.o: $(SRCDIR)/%.c $(HEADERS)
$(CC) $(CFLAGS) -I$(INCDIR) -c -o $@ $<
clean:
rm -rf $(OBJDIR)/*.o $(EXECUTABLE) $(LIBRARY)
This Makefile describes a project containing multiple source files, including default target all
, clean target clean
, and two generation targets: one executable and one static library. Note that the variables and rules in this Makefile can be adjusted according to the project’s structure and needs.
23. Installation Rules
Makefile can include installation rules for installing executable files, library files, etc., to specified locations. Below is a simple installation rule example:
INSTALL_DIR = /usr/local/bin
install: $(EXECUTABLE)
cp $(EXECUTABLE) $(INSTALL_DIR)
uninstall:
rm -f $(INSTALL_DIR)/$(notdir $(EXECUTABLE))
In this example, the install
rule copies the executable file to the specified directory ($(INSTALL_DIR)
). The uninstall
rule deletes the installed executable file.
↓↓Recommended Articles↓↓
👉 Detailed Methods for Creating Library Files in Linux
👉 Summary of the Most Common Command Usages in Linux (Selection)
👉 Step-by-Step Guide to Writing Linux Thread Pools
👉 Summary of Common Methods in Linux Shell Programming
👉 Essence of C++ Basic Knowledge
↓↓Recommended Collections↓↓
👉 Collection of C Language Introductory Tutorials
👉 Collection of Common Software Tools
👉 Collection of Linux Knowledge
👉 Collection of Linux Libraries Explained
For learning and communication, pleaseaddAssistant WeChatto join high-quality learning groups
👇Learn from others to improve yourself👇
Please click→【Technical Learning Group】
❝
FollowLinux Armory, reply in the chat interface with「1024」to get all Linux materials and code.
❞
Make progress every day, support the author, remember to like and share!
Support the author, please extend your hand to prosperity
Share, collect👇👇👇👇👇Like, view
Support quality content with action!