一、Makefile自动推导理解
在Makefile中,自动推导是通过一些内置规则(implicit rules)来实现的。这些内置规则定义了一些常见的编译和链接操作,用于根据文件的扩展名自动推导生成目标文件和可执行文件。
当make命令执行时,它会查找Makefile中的目标和依赖关系,并根据这些规则来自动推导生成相关的目标文件。
例如,如果你有一个名为 program
的目标,并在Makefile中没有明确给出如何生成它,但存在一个名为 program.c
或 program.cpp
的源文件,那么make命令会自动根据内置规则来推导生成 program
目标。
自动推导的过程通常遵循以下规则:
-
根据目标文件名确定源文件的名称:如果目标是
target.ext
,那么Makefile会查找同名的源文件,比如target.c
或target.cpp
。 -
根据源文件生成目标文件:根据上一步中找到的源文件名确定要生成的目标文件名,比如将
.c
或.cpp
替换为.o
,得到target.o
。然后使用默认的编译规则来编译源文件生成目标文件。 -
自动推导依赖关系:根据源文件中的
#include
预处理指令或其他依赖关系,自动推导出源文件的依赖关系,并在编译时处理这些依赖关系。 -
自动链接可执行文件:如果存在
main
目标,但在Makefile中没有明确给出如何生成它,make命令会自动将所有生成的目标文件链接到一起,生成可执行文件。
通过这种自动推导的方式,Makefile可以根据源文件的扩展名和内置规则进行智能地推导生成目标文件和可执行文件,简化了Makefile的编写过程。但同时也可以手动定义规则来覆盖或修改默认的推导行为,以满足更复杂的需求。
二、Makefile中自动推导生成目标文件的规则
1、没有使用自动推导的makefile
现在有main.c
a.c
b.c
a.h
b.h
五个文件,以下是不使用自动推导的makefile完整示例:
CC = gcc
CFLAGS = -c
TARGET = program
OBJS = main.o a.o b.oall: $(TARGET)$(TARGET): $(OBJS)$(CC) -o $(TARGET) $(OBJS)main.o: main.c a.h b.h$(CC) $(CFLAGS) main.c -o main.oa.o: a.c a.h$(CC) $(CFLAGS) a.c -o a.ob.o: b.c b.h$(CC) $(CFLAGS) b.c -o b.oclean:rm -f $(TARGET) $(OBJS)
以下是构建的文件及其内容:
main.c:
<