Makefile 是一个在软件开发中用于自动化编译和构建过程的文件。它定义了编译项目的规则,包括哪些文件需要编译、如何编译它们以及它们之间的依赖关系。通过使用 Makefile,开发者可以简化编译过程,确保所有组件按照正确的顺序和方式进行编译,同时减少重复性工作。
基本概念
- 目标(Target):Makefile 中定义的要生成的文件或执行的操作。目标可以是可执行文件、对象文件(.o)、库文件或任何其他类型的文件。
- 依赖(Dependencies):生成目标文件所需的其他文件。如果依赖文件发生了变化,那么目标文件就需要重新生成。
- 命令(Commands):用于生成目标文件的命令,这些命令会在目标文件或其依赖文件发生变化时被执行。
基本结构
Makefile 的基本结构包含一系列的规则(rules),每条规则定义了如何生成一个或多个目标文件。规则的基本格式如下:
target: dependencies
command
...
[other commands]
target
:规则的目标文件名,可以是单个文件名或多个文件名,通过空格分隔。dependencies
:生成目标文件所依赖的文件列表,如果目标文件不存在或依赖文件比目标文件新,则执行下面的命令。command
:生成目标文件需要执行的命令,这些命令以 Tab 键开始,而不是空格。
常用命令
make
:在包含Makefile
的目录下执行make
命令,会按照Makefile
中定义的规则生成第一个目标(默认目标),通常是可执行文件。make target
:指定要生成的目标文件,只生成该目标及其依赖。make clean
:通常,Makefile
中会定义一个clean
目标,用于删除编译过程中生成的所有文件(如 .o 文件、可执行文件等),以便重新编译。
示例
假设有一个简单的 C 程序,包含两个源文件 main.c
和 hello.c
,以及一个头文件 hello.h
。下面是 Makefile 内容举例:
# 定义编译器
CC=gcc
# 定义编译选项
CFLAGS=-I.
# 定义可执行文件名
TARGET=hello
# 定义源文件
SRCS=$(wildcard *.c)
# 定义对象文件
OBJS=$(SRCS:.c=.o)
# 默认目标
all: $(TARGET)
# 链接对象文件生成可执行文件
$(TARGET): $(OBJS)
$(CC) -o $@ $^ $(CFLAGS)
# 编译 C 源文件生成对象文件
%.o: %.c
$(CC) -c -o $@ $< $(CFLAGS)
# 清理编译生成的文件
clean:
rm -f $(OBJS) $(TARGET)
.PHONY: clean all
在这个 Makefile
中:
- 使用
wildcard
函数自动找到所有的 .c 文件。 - 使用变量来简化命令和依赖的书写。
- 定义了
all
目标作为默认目标,它依赖于可执行文件hello
。 - 定义了如何编译 .c 文件生成 .o 文件(对象文件)。
- 定义了如何链接对象文件生成可执行文件。
- 定义了
clean
目标用于清理编译生成的文件。 - 使用
.PHONY
声明clean
和all
为伪目标,防止它们与同名文件冲突。