一、一个Makefile的内容
假设我们有一个简单的Makefile用于编译C程序。下面是一个示例:
# 变量定义
CC = gcc
CFLAGS = -Wall -g
# 显式规则
main: main.o func.o
$(CC) $(CFLAGS) -o main main.o func.o
# 隐式规则
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
# 指令
clean:
rm -f main *.o
# 注释
# 这是一个简单的Makefile,用于编译C程序
在上述示例中,我们可以看到以下五种内容:
- 变量定义:定义了
CC
和CFLAGS
两个变量,分别表示编译器和编译选项。 - 显式规则:定义了一个显式规则,指定了如何生成
main
目标文件。它依赖于main.o
和func.o
这两个先决条件。当执行make main
命令时,会执行相应的命令将目标文件生成或更新。 - 隐式规则:定义了一个隐式规则,描述了如何根据
.c
文件生成对应的.o
目标文件。例如,当执行make main.o
命令时,会自动根据main.c
文件生成main.o
文件。 - 指令:定义了一个名为
clean
的指令,用于清理生成的目标文件和中间文件。当执行make clean
命令时,会执行相应的命令删除main
文件和所有.o
文件。 - 注释:通过使用
#
字符开头的行来添加注释,可以提供对Makefile的解释和说明。在示例中,我们添加了一条注释来说明这是一个简单的Makefile用于编译C程序。
以上就是示例中包含的五种内容:变量定义、显式规则、隐式规则、指令和注释。它们在Makefile中起到不同的作用,用来控制程序的编译和构建过程。
二、五种内容的详细介绍
Makefiles包含五种内容:显式规则、隐式规则、变量定义、指令和注释。规则、变量和指令详细描述:
- 显式规则:指定何时以及如何重新生成一个或多个文件,被称为目标(targets)。它列出了目标所依赖的其他文件,称为目标的先决条件(prerequisites),并且可能提供了用于创建或更新目标的命令。
- 隐式规则:根据文件名指定何时以及如何重新生成一类文件。它描述了目标如何依赖于与目标类似的文件,并提供了用于创建或更新此类目标的命令。
- 变量定义:是指为变量指定一个文本字符串值的行,稍后可以将其替换到文本中。简单的Makefile示例展示了一个变量定义,将objects定义为所有对象文件的列表。
- 指令:是指让make在读取Makefile时执行一些特殊操作的指令。例如,读取另一个Makefile、根据变量的值决定是否使用或忽略Makefile的某个部分、从包含多行的原始字符串定义一个变量等。
- 注释:在Makefile中以‘#’开始的行是注释,它及其后面的内容会被忽略。但是,如果在注释中使用反斜杠转义的非转义反斜杠,则可以跨多行继续注释。只包含注释的行(可能有空格)被视为空行,会被忽略。如果要使用字面上的#字符,需要用反斜杠进行转义(例如,#)。注释可以出现在Makefile的任何行中,尽管在某些情况下会受到特殊处理。
在变量引用或函数调用中不能使用注释:在变量引用或函数调用中,#字符将按照字面意义对待(而不是作为注释的起始),所以需要注意。
在一个命令中的注释会被传递给shell,就像其他命令文本一样。shell决定如何解释它:是否将其作为注释取决于shell本身。
在define指令内部,注释在变量定义过程中不被忽略,而是保留在变量值中。当扩展变量时,根据上下文来决定将其视为make注释还是命令文本。