Makefile文件详解
一、Makefile 核心语法
- 基本结构
target: dependencies
command
● target:生成的目标(如可执行文件、.o 文件)
● dependencies:依赖文件(如 .c、.h)
● command:执行的命令(必须以 Tab 开头)
2. 变量定义
CC = gcc
CFLAGS = -Wall -g
- 自动变量
- $@ : 当前目标名, main: echo $@ → 输出 main
- $* : 所有依赖文件, main.c a.c b.c: echo $* → 输出 main.c a.c b.c
- $< : 第一个依赖文件, main.c a.c b.c: echo $< → 输出 main.c
- $^ : 所有依赖文件, main.c a.c b.c: echo $^ → 输出 main.c a.c b.c
二、单文件项目示例
# 编译器配置
CC = gcc // 定义编译器,gcc是C语言编译器,不能编译C++,C++用g++
CFLAGS = -Wall -g //定义编译选项
# 目标
all: program
program: main.c
$(CC) $(CFLAGS) $^ -o $@
clean:
rm -f program
使用方式:
make # 编译
./program # 运行
make clean # 清理
三、多文件项目模板(推荐)
假设项目结构:
project/
├── src/
│ ├── main.c
│ ├── utils.c
│ └── math.c
├── include/
│ ├── utils.h
│ └── math.h
└── Makefile
Makefile 内容:
# 配置
CC = gcc
CFLAGS = -Wall -g -Iinclude
SRC_DIR = src
BIN_DIR = bin
# 获取所有.c文件,并替换为.o文件
SRCS = $(wildcard $(SRC_DIR)/*.c)
OBJS = $(patsubst $(SRC_DIR)/%.c, $(BIN_DIR)/%.o, $(SRCS))
TARGET = $(BIN_DIR)/program #最终生成的可执行文件路径:bin/program , TARGET:定义目标可执行文件名称
# 默认目标
all: $(BIN_DIR) $(TARGET) #依赖关系:先创建 bin/ 目录($(BIN_DIR) 目标),再构建可执行文件($(TARGET) 目标),执行 make 或 make all 时会触发此规则
# 链接所有.o文件生成可执行文件
$(TARGET): $(OBJS)
$(CC) $(CFLAGS) $^ -o $@
# 编译每个.c文件到.o文件
$(BIN_DIR)/%.o: $(SRC_DIR)/%.c
$(CC) $(CFLAGS) -c $< -o $@
# 创建bin目录
$(BIN_DIR):
mkdir -p $@
# 清理
clean:
rm -rf $(BIN_DIR)
.PHONY: all clean
●CC: 定义编译器为 gcc(可替换为 clang 等)
●CFLAGS: 编译选项
○-Wall: 启用所有警告
○-g: 生成调试信息(供 GDB 使用)
○-Iinclude: 添加 include/ 目录为头文件搜索路径
●SRC_DIR: 源代码目录(.c 文件存放路径)
●BIN_DIR: 输出目录(存放生成的 .o 和可执行文件)
$(wildcard $(SRC_DIR)/*.c):
●获取 src/ 下所有 .c 文件(如 src/main.c src/utils.c)
$(patsubst ...):
●将 src/XXX.c 替换为 bin/XXX.o
●示例:src/main.c → bin/main.o
最终生成的可执行文件路径:bin/program
all: $(BIN_DIR) $(TARGET)
●依赖关系:
○先创建 bin/ 目录($(BIN_DIR) 目标)
○再构建可执行文件($(TARGET) 目标)
●执行 make 或 make all 时会触发此规则
$(TARGET): $(OBJS)
$(CC) $(CFLAGS) $^ -o $@
●$^: 所有依赖文件(即 $(OBJS) 中的所有 .o 文件)
●$@: 目标文件(即 $(TARGET))
$(BIN_DIR)/%.o: $(SRC_DIR)/%.c
$(CC) $(CFLAGS) -c $< -o $@
●%: 通配符(匹配同名文件)
●$<: 第一个依赖文件(即 .c 文件)
●示例:
○对 src/main.c → 生成 bin/main.o
○实际命令:
gcc -Wall -g -Iinclude -c src/main.c -o bin/main.o