makefile规则
admin2025-10-08 21:50:26【世界杯比赛视频】
makefile是make进行处理的依据,它包括了目标体、依赖文件及其之间的命令语句。
它定义了一系列的规则来指定如何从源文件生成目标文件。以下是 Makefile 的基本规则:
一、基本结构
Makefile 由一系列规则组成,每条规则通常包含以下三个部分:
目标(target):通常是一个文件,可以是可执行文件、目标文件或其他文件。
依赖(prerequisites):生成目标所需要的文件或其他目标。
命令(commands):用于生成目标的一系列命令。
例如:
target: prerequisites
commands
二、目标和依赖
目标可以是单个文件或多个文件的列表。例如:
myprogram: main.o func1.o func2.o
gcc -o myprogram main.o func1.o func2.o
在这个例子中,myprogram 是目标,main.o、func1.o 和 func2.o 是依赖。
依赖可以是文件、其他目标或两者的组合。如果依赖中的任何一个文件比目标更新,Makefile 将会执行相应的命令来更新目标。
三、命令
命令必须以制表符(Tab)开头,而不是空格。这是 Makefile 的语法要求。
命令可以是任何 shell 命令,用于生成目标。例如:
main.o: main.c
gcc -c main.c
在这个例子中,命令 gcc -c main.c 用于从 main.c 源文件生成 main.o 目标文件。
可以在一条规则中包含多个命令,每个命令都必须以制表符开头。例如:
myprogram: main.o func1.o func2.o
gcc -o myprogram main.o func1.o func2.o
strip myprogram
在这个例子中,首先使用 gcc 命令生成可执行文件 myprogram,然后使用 strip 命令去除可执行文件中的调试信息。
四、变量
Makefile 支持变量,可以使用变量来简化规则和提高可维护性。变量可以在 Makefile 中定义,并在规则中使用。
定义变量:
CC = gcc
CFLAGS = -Wall -O2
在这个例子中,定义了两个变量 CC 和 CFLAGS。
使用变量:
myprogram: main.o func1.o func2.o
$(CC) -o myprogram main.o func1.o func2.o $(CFLAGS)
在这个例子中,使用变量 CC 和 CFLAGS 来指定编译器和编译选项。
五、通配符和模式规则
通配符:Makefile 支持通配符,可以使用通配符来匹配一组文件。例如:
SRCS = *.c
OBJS = $(SRCS:.c=.o)
在这个例子中,使用通配符 *.c 来匹配所有的 .c 文件,并将其存储在变量 SRCS 中。然后,使用变量替换功能将 .c 替换为 .o,生成目标文件列表 OBJS。
模式规则:模式规则是一种通用的规则,可以用于生成具有相同模式的目标文件。例如:
%.o: %.c
$(CC) -c $(CFLAGS) $< -o $@
在这个例子中,模式规则 %.o: %.c 表示任何 .o 文件都依赖于同名的 .c 文件。命令 $(CC) -c $(CFLAGS) $< -o $@ 表示使用变量 CC 和 CFLAGS 来编译 .c 文件,并生成 .o 文件。其中,$< 表示第一个依赖文件,$@ 表示目标文件。
六、伪目标
伪目标不是真正的文件,而是一个标签,用于执行一系列命令。例如:
clean:
rm -f *.o myprogram
在这个例子中,clean 是一个伪目标,用于执行清理操作,删除所有的 .o 文件和可执行文件 myprogram。
要执行伪目标,可以使用以下命令:
make clean
在 Makefile 中,变量是一种非常有用的特性,可以帮助提高 Makefile 的可读性、可维护性和灵活性。以下是关于 Makefile 变量的详细介绍:
一、变量的定义
直接赋值:
可以使用“=”或“:=”进行直接赋值。例如:
VAR = value:在执行时展开变量,可能会根据后续的赋值发生变化。
VAR := value:立即展开变量,在定义时就确定其值,后续不会改变。
追加赋值:
使用“+=”可以在变量原有值的基础上进行追加。例如:
VAR += value:如果 VAR 之前已经有值,新的值会被追加到后面。
二、变量的使用
在规则中使用变量:
可以通过 $(VAR) 的方式来引用变量。例如:
CC = gcc
myprogram: main.o func1.o func2.o
$(CC) -o myprogram main.o func1.o func2.o
在这个例子中,变量 CC 被用来指定编译器。
在命令中使用变量:
同样可以在命令中使用变量,例如:
DIR = src
compile:
$(CC) -c $(DIR)/main.c
这里变量 DIR 和 CC 在命令中被引用,用于指定编译的源文件路径和编译器。
三、预定义变量
Makefile 中有一些预定义变量,它们具有特定的含义和用途:
$@:表示目标文件。
$<:表示第一个依赖文件。
$^:表示所有依赖文件。
$?:表示比目标文件更新的依赖文件列表。
例如:
myprogram: main.o func1.o func2.o
gcc -o $@ $^
在这个例子中,$@ 代表目标文件 myprogram,$^ 代表所有依赖文件 main.o、func1.o 和 func2.o。
四、自动变量
自动变量是在特定上下文中自动设置的变量,通常与模式规则一起使用。
%:表示匹配的文件名部分。例如,在模式规则“%.o: %.c”中,% 可以匹配源文件和目标文件的相同部分。
$*:表示去掉后缀的文件名部分。例如,如果有文件“main.c”,在模式规则中 $* 将表示“main”。
五、环境变量
Makefile 可以使用环境变量。环境变量可以在 Makefile 中直接引用,也可以通过在 Makefile 中重新赋值来覆盖。
例如,如果在环境中设置了 CFLAGS 变量,可以在 Makefile 中这样使用:
myprogram: main.o func1.o func2.o
gcc -o $@ $^ $(CFLAGS)
如果想要覆盖环境变量,可以在 Makefile 中重新定义它,例如:
CFLAGS := -Wall -O2
通过合理使用变量,可以使 Makefile 更加简洁、灵活和易于维护,适应不同的项目需求和编译环境。