目录
前言
1. 基本概念
2. Makefile 的基本结构
3. Makefile 中的变量
4. 伪目标(Phony Targets)
5. Makefile 的规则
6. 自动变量
7. 条件判断
8. 函数
9. Makefile 示例
Makefile 是用于管理项目构建过程的文件,通常用于C/C++等编译型语言项目中。它通过定义规则来描述如何从源文件生成目标文件,自动化编译和链接步骤,避免手动重复输入复杂的编译命令。下面是关于 Makefile 的详细介绍,包括语法、规则、变量、函数、条件语句等。
Makefile 的基本结构如下:
target: dependencies
command
例子:
main.o: main.c
gcc -c main.c -o main.o
上述 Makefile 规则表示:如果 main.c
文件发生变化,gcc -c main.c -o main.o
命令将被执行,以生成 main.o
文件。
Makefile 支持变量,用于简化和重用代码。变量定义后,可以通过 $(VARIABLE_NAME)
的形式引用。
变量定义:
CC = gcc
CFLAGS = -Wall -g
main.o: main.c
$(CC) $(CFLAGS) -c main.c -o main.o
在这个例子中,CC
变量定义了使用的编译器,CFLAGS
变量定义了编译选项。通过使用变量,修改编译器或编译选项变得更加容易。
伪目标并不对应实际文件,而是一些执行特定操作的命令。常见的伪目标包括 clean
和 all
。伪目标通常用于构建和清理任务。
例子:
.PHONY: clean
clean:
rm -f *.o my_program
.PHONY
用于声明 clean
为伪目标,避免与目录下的文件名冲突。clean
目标用于删除所有 .o
文件和最终生成的可执行文件 my_program
。Makefile 支持复杂的规则,包括自动推导规则、隐含规则等。
隐含规则:
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
%
是通配符,表示任意文件名。$<
是第一个依赖文件,$@
是目标文件。.c
文件,自动生成相应的 .o
文件。Makefile 提供了一些自动变量,在规则中可以使用这些变量简化命令。
$@
:表示规则中的目标文件名。$<
:表示第一个依赖文件名。$^
:表示所有依赖文件名,去除重复。$?
:表示比目标文件更新的依赖文件名。例子:
main: main.o utils.o
$(CC) -o $@ $^
这里的 $@
表示生成的目标 main
,$^
表示 main.o utils.o
。
Makefile 支持条件判断,可以根据条件来选择性地执行某些规则。
条件语句:
ifeq ($(OS),Windows_NT)
RM = del
else
RM = rm -f
endif
clean:
$(RM) *.o my_program
ifeq
和 endif
用于条件判断。Makefile 提供了多种函数来处理字符串、文件路径等,常用的函数包括 subst
、patsubst
、wildcard
、shell
等。
常见函数:
subst
:替换字符串中的子串。
$(subst old,new,text)
将 text
中的 old
替换为 new
。
patsubst
:模式替换。
$(patsubst %.c,%.o,file.c file2.c)
将 .c
后缀替换为 .o
。
wildcard
:匹配文件名。
SOURCES = $(wildcard *.c)
匹配当前目录下的所有 .c
文件。
shell
:执行 shell 命令并返回结果。
CURRENT_DIR = $(shell pwd)
获取当前目录路径。
一个完整的 Makefile 示例如下:
CC = gcc
CFLAGS = -Wall -g
TARGET = my_program
OBJECTS = main.o utils.o
$(TARGET): $(OBJECTS)
$(CC) $(CFLAGS) -o $@ $^
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
.PHONY: clean
clean:
rm -f $(OBJECTS) $(TARGET)
解释:
CC
和 CFLAGS
定义了编译器和编译选项。TARGET
是最终生成的可执行文件。OBJECTS
是所有的目标文件。my_program
。.c
文件编译为 .o
文件。clean
伪目标用于清理构建生成的文件。