<span>Makefile</span>
is a tool used for automating the build and management of projects, widely used in C/C++ projects but also applicable to other languages and tasks. It describes how to generate target files (such as executables, library files, etc.) from source code by defining rules.
1. Getting Started: Basic Concepts and Simple Examples
1.1 What is Makefile?
-
<span>Makefile</span>
is a text file that contains a set of rules describing how to build a project. -
Each rule defines the target file, dependency files, and the commands to generate the target file. -
<span>make</span>
is a tool used to parse the<span>Makefile</span>
and execute build commands.
1.2 Basic Syntax
The basic format of a rule is as follows:
target_file: dependency_file
command
-
target_file: The file that needs to be generated (such as an executable file, object file, etc.). -
dependency_file: The files required to generate the target file (such as source code, header files, etc.). -
command: The specific operations to generate the target file (such as compilation, linking, etc.).
1.3 Simple Example
Assume there is a C project containing the following files:
-
<span>main.c</span>
: The main program file. -
<span>utils.c</span>
: The utility functions file. -
<span>utils.h</span>
: The utility functions header file.
Write a simple <span>Makefile</span>
:
# Define the compiler and target file
CC = gcc
TARGET = my_program
OBJS = main.o utils.o
# Default target
all: $(TARGET)
# Generate executable file
$(TARGET): $(OBJS)
$(CC) $(OBJS) -o $(TARGET)
# Compile .c files to .o files
main.o: main.c utils.h
$(CC) -c main.c -o main.o
utils.o: utils.c utils.h
$(CC) -c utils.c -o utils.o
# Clean up generated files
clean:
rm -f $(OBJS) $(TARGET)
1.4 Using Makefile
-
Build the project: make
-
Clean up generated files: make clean
2. Advanced: Variables and Pattern Rules
2.1 Variables
Variables can simplify the writing and maintenance of a <span>Makefile</span>
. For example:
CC = gcc
CFLAGS = -Wall -O2
TARGET = my_program
OBJS = main.o utils.o
-
<span>CC</span>
: The compiler. -
<span>CFLAGS</span>
: Compilation options. -
<span>TARGET</span>
: The final executable file generated. -
<span>OBJS</span>
: All object files.
2.2 Pattern Rules
Pattern rules can simplify the definition of repetitive rules. For example:
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
-
<span>%.o</span>
: Matches all<span>.o</span>
files. -
<span>%.c</span>
: Matches the corresponding<span>.c</span>
files. -
<span>$<span></span></span>
: Represents the first dependency file (i.e., the<span>.c</span>
file). -
<span>$@</span>
: Represents the target file (i.e., the<span>.o</span>
file).
2.3 Improved Makefile
CC = gcc
CFLAGS = -Wall -O2
TARGET = my_program
OBJS = main.o utils.o
all: $(TARGET)
$(TARGET): $(OBJS)
$(CC) $(OBJS) -o $(TARGET)
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
clean:
rm -f $(OBJS) $(TARGET)
3. Mastery: Multi-Directory Projects and Cross Compiling
3.1 Multi-Directory Projects
For multi-directory projects, you can place the source code, object files, and executables in different directories. For example:
project/
├── src/
│ ├── main.c
│ └── utils.c
├── include/
│ └── utils.h
├── build/
└── Makefile
3.2 Improved Makefile
CC = gcc
CFLAGS = -Wall -Iinclude
TARGET = build/my_program
SRCS = $(wildcard src/*.c)
OBJS = $(patsubst src/%.c,build/%.o,$(SRCS))
all: $(TARGET)
$(TARGET): $(OBJS)
$(CC) $(OBJS) -o $(TARGET)
build/%.o: src/%.c
$(CC) $(CFLAGS) -c $< -o $@
clean:
rm -f $(OBJS) $(TARGET)
3.3 Cross Compiling
Cross compiling means generating executables for another platform on one platform. For example, generating executables for ARM platform on x86 platform.
3.4 Cross Compiling Example
CC = arm-linux-gnueabi-gcc
CFLAGS = -Wall -Iinclude
TARGET = build/my_program
SRCS = $(wildcard src/*.c)
OBJS = $(patsubst src/%.c,build/%.o,$(SRCS))
all: $(TARGET)
$(TARGET): $(OBJS)
$(CC) $(OBJS) -o $(TARGET)
build/%.o: src/%.c
$(CC) $(CFLAGS) -c $< -o $@
clean:
rm -f $(OBJS) $(TARGET)