文章

Makefile

前言

很多时候,配环境和编译代码非常麻烦,Makefile提供了一种自动化的编译方式,能够解放程序员的双手,一句make就能走天下

什么是Makefile

Makefile 是一种编程语言,主要用于自动化编译和程序构建。它是由 GNU Make 工具解析的,这个工具可以解析 Makefile 文件中的指令,然后执行相应的命令来构建程序。Makefile 文件通常包含一系列的规则,这些规则定义了如何从源代码和其他依赖项生成目标文件。

Makefile常见使用场景

Makefile 最常见的使用场景是在 C 或 C++ 项目中自动化编译和链接过程。它可以用来描述源文件之间的依赖关系,然后自动执行编译命令。此外,Makefile 也可以用于其他类型的项目,例如自动化测试、部署、打包等任务。

Makefile编写规则

Makefile 的编写规则主要包括目标、依赖和命令三部分。以下是一个简单的例子:

1
2
target: dependencies
    commands
  • target 是需要生成的文件或者是需要执行的任务
  • dependencies 是生成目标所需要的文件或者其他目标。
  • commands 是生成目标所需要执行的命令,每个命令需要独占一行,并且前面必须有一个 Tab 字符。

例如,以下的 Makefile 规则描述了如何从 main.c 和 hello.c 两个源文件生成 hello 程序:

1
2
hello: main.c hello.c
    gcc -o hello main.c hello.c

再比如

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# Variables
CXX = g++
CXXFLAGS = -Wall -std=c++11
SRC_DIR = src
OBJ_DIR = obj
BIN_DIR = bin
SRCS = $(wildcard $(SRC_DIR)/*.cpp)
OBJS = $(SRCS:$(SRC_DIR)/%.cpp=$(OBJ_DIR)/%.o)
DEPS = $(OBJS:.o=.d)
TARGET = $(BIN_DIR)/program

# Rules
all: $(TARGET)

-include $(DEPS)

$(TARGET): $(OBJS)
    $(CXX) $(CXXFLAGS) $^ -o $@

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
    $(CXX) $(CXXFLAGS) -MMD -c $< -o $@

clean:
    rm -f $(OBJS) $(DEPS) $(TARGET)

.PHONY: all clean

这个 Makefile 定义了四个变量:CXX 是编译器,CXXFLAGS 是编译选项,SRC_DIR 是源文件目录,OBJ_DIR 是目标文件目录。SRCSOBJS 是源文件和目标文件的列表,DEPS 是依赖文件的列表,TARGET 是最终生成的程序。

这个 Makefile 定义了四个规则:all 规则生成最终的程序,-include $(DEPS) 包含了所有的依赖文件,$(TARGET) 规则链接所有的目标文件生成程序,$(OBJ_DIR)/%.o 规则编译源文件生成目标文件,clean 规则删除所有生成的文件。

这个 Makefile 使用了 -MMD 选项自动生成依赖文件,这样当头文件被修改时,相关的源文件会被重新编译。它也使用了 .PHONY 伪目标,这样即使目录中存在名为 allclean 的文件,对应的规则也会被执行。

本文由作者按照 CC BY 4.0 进行授权