The process of writing a Makefile is as follows:
- Define variables: Define variables such as compiler and compilation options.
- Define target file: Define the target file name.
- Define source files: Define all source files.
- Define rules: Define the rules for compiling each source file into an object file.
- Define pseudo-target: Defines a pseudo-target that cleans up object files and other intermediate files.
The following is an example Makefile, assuming that each directory has a .c
source file ending in that needs to be compiled into a corresponding .o
file:
CC = gcc
CFLAGS = -Wall -Wextra -Werror
SRCDIR = src
OBJDIR = obj
TARGET = myapp
SOURCES := $(wildcard $(SRCDIR)/**/*.c)
OBJECTS := $(patsubst $(SRCDIR)/%.c, $(OBJDIR)/%.o, $(SOURCES))
$(TARGET): $(OBJECTS)
$(CC) $(CFLAGS) $^ -o $@
$(OBJDIR)/%.o: $(SRCDIR)/%.c
$(CC) $(CFLAGS) -c $< -o $@
.PHONY: clean
clean:
rm -rf $(OBJDIR)/*.o $(TARGET)
CC
Defines the compiler used, gcc is used here.CFLAGS
Compilation options are defined, and some warning options are enabled here.SRCDIR
Defines the directory where the source files are located.OBJDIR
Defines the directory where the intermediate and object files are located.TARGET
Defines the final generated executable file name.SOURCES
is a list of all source files, using wildcards to recursively find source files in subdirectories.**
OBJECTS
is a list of all object files, using the patsubst function to replace the source file path with the object file path.$(TARGET): $(OBJECTS)
Indicates that the target file depends on all intermediate files, and$ make myapp
the final executable file can be generated by entering on the command line.$(OBJDIR)/%.o: $(SRCDIR)/%.c
Indicates a rule, compiles all files in a directory into corresponding files, and stores them in the directory.$(SRCDIR)
.c
.o
$(OBJDIR)
.PHONY: clean
Indicates that clean is a pseudo-target, not a real file, and$ make clean
all intermediate and target files can be deleted by typing in the command line.