跳转至

GNU Make

为什么使用 GNU Make

当你开始编写 C/C++ 项目时,你可能会遇到这样的情况:

  • 一个项目有多个源文件,每次编译都要手动输入一长串命令
  • 修改了一个文件,重新编译时所有文件都要重新编译,浪费时间
  • 项目结构复杂,编译选项多,手动管理容易出错

GNU Make 是一个构建自动化工具,它通过读取 Makefile 文件来自动执行编译、链接等操作。几乎所有 C/C++ 开源项目都使用 Make(或基于 Make 的构建系统)来管理构建过程。

自动化编译,告别重复劳动

在 Makefile 中定义好编译规则后,只需输入 make 即可自动完成整个项目的编译。

增量编译,只编译修改过的文件

Make 会检测文件的修改时间,只重新编译发生变化的源文件,大幅提升编译效率。

跨平台标准

Make 是 POSIX 标准的一部分,在 Linux、macOS、Windows(通过 MSYS2/MinGW)上都能使用。

安装 GNU Make

Windows

scoop install make

注意:Windows 上建议使用 MSYS2 版本的 Make,与 Unix 工具链兼容性更好。

macOS

macOS 自带 Make(通过 Xcode Command Line Tools):

xcode-select --install

Linux

sudo apt install build-essential

build-essential 包含了 gcc、g++、make 等基础开发工具。

基本使用

最简单的 Makefile

假设你有一个 C 项目:

main.c
utils.c
utils.h

创建 Makefile:

CC = gcc
CFLAGS = -Wall -g

all: main

main: main.c utils.h
    $(CC) $(CFLAGS) -o main main.c utils.c

clean:
    rm -f main

使用方式:

make          # 编译项目
make clean    # 清理编译产物

Makefile 的核心概念

target: dependencies
    command
  • target:要生成的文件
  • dependencies:依赖的文件
  • command:生成 target 需要执行的命令(必须以 Tab 开头)

变量

CC = gcc
CFLAGS = -Wall -g -O2
LDFLAGS = -lm

自动变量

$@    # 当前目标文件名
$<    # 第一个依赖文件名
$^    # 所有依赖文件名

实际项目示例

一个更完整的 Makefile 示例:

CC = gcc
CFLAGS = -Wall -g
LDFLAGS = -lm
SRC = $(wildcard *.c)
OBJ = $(SRC:.c=.o)
TARGET = myprogram

all: $(TARGET)

$(TARGET): $(OBJ)
    $(CC) $(OBJ) -o $(TARGET) $(LDFLAGS)

%.o: %.c
    $(CC) $(CFLAGS) -c $< -o $@

clean:
    rm -f $(OBJ) $(TARGET)

.PHONY: all clean

其他资源