ℹ️大家好,我是练小杰,今天周二了,距离除夕只有6天了,新的一年就快到了😆
本文是有关Linux C/C++编程的make和Makefile实现自动编译相关知识点,后续会不断添加相关内容 ~~
回顾:【Emacs编辑器、GCC编译器以及GDB调试器】
更多Linux 相关内容请点击👉【Linux专栏】
文章目录
- make工具
- 优点
- 基本语法
- make 的工作原理
- Makefile基础
- 配置文件基本结构
- 配置文件说明
- Makefile文件依赖关系链
- Makefile的编译机制
- Makefile的高级特性
- 模式规则
- 隐式规则
- 伪目标
- 使用通配符
- 文件包含
- make的工作方式
- `Autotools`自动产生Makefile
- Autotools工作原理
- `configure`产生的Makefile文件
- Autotools工具
- Autotools应用示例
make工具
make
是一个根据依赖关系自动执行命令的工具。它主要用于编译源代码,但也可以用于其他需要根据文件变化自动执行任务的场景。
make
通过Makefile
文件维护源程序,实现自动编译。
优点
- 可自动化:减少手动编译的繁琐步骤。
- 高效率:只重新编译发生变化的部分,节省时间。
- 可维护性:通过
Makefile
集中管理构建过程,便于维护和理解。
基本语法
make [选项] [目标名]
- 主要选项
-f
:描述文件,指定make
编译所依据的描述文件(Makefile
)
-n
:只显示生成指定目标的所有执行命令,但并不实际执行。
-p
:输出Makefile文件中所有宏定义和目标文件描述。
-d
:使用Debug(调试)模式。
-c
:指定目录,在读取Makefile
之前改变到指定的目录。
make 的工作原理
- 首先解析 Makefile:make 读取 Makefile,构建依赖关系图。
- 然后确定目标:如果没有指定目标,make 默认执行第一个目标(通常是 all)。
- 再检查依赖:对于每个目标,
make
检查其依赖是否需要更新。- 最后执行命令:如果依赖有更新或目标不存在,
make
执行相应的命令生成目标。
Makefile基础
Makefile
是make
的配置文件,定义了目标和依赖关系。
Makefile
文件通过若干条规则来定义文件依赖关系。每条规则包括目标(target
)、条件(prerequisites
)和命令(command
)三大要素。
配置文件基本结构
如下,是一个简单的Makefile
示例
# 定义编译器
CC = gcc
# 定义编译选项
CFLAGS = -Wall -g
# 定义目标可执行文件
TARGET = myprogram
# 定义源文件
SRCS = main.c utils.c
# 生成目标文件列表
OBJS = $(SRCS:.c=.o)
# 默认目标
all: $(TARGET)
# 链接目标文件生成可执行文件
$(TARGET): $(OBJS)
$(CC) $(CFLAGS) -o $(TARGET) $(OBJS)
# 编译 .c 文件生成 .o 文件
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
# 清理生成的文件
clean:
rm -f $(OBJS) $(TARGET)
配置文件说明
-
目标(
Target
):要生成的文件或要执行的操作。例如,all 和 clean 都是目标。 -
依赖(Prerequisites):生成目标所需的文件或目标。例如,
$(TARGET)
依赖于$(OBJS)
-
命令(
Commands
):生成目标所需执行的命令。例如,$(CC) $(CFLAGS) -o $(TARGET) $(OBJS)
-
变量(
Variables
):用于存储可复用的字符串。例如,CC
存储编译器,CFLAGS
存储编译选项。 -
自动变量
$@
:指明当前目标 。比如,在%.o: %.c
规则中,$@
代表.o
文件。
$<
:指第一个依赖。比如,在%.o: %.c
规则中,$<
代表.c
文件。
$^
:指所有依赖。
Makefile文件依赖关系链
- 这里我们通过一个Makefile示例来分析
#第1部分
textedit : main.o input.o output.o command.o files.o tools.o
cc -o textedit main.o input.o output.o command.o /
files.o utils.o
#第2部分
main.o : main.c def.h
cc -c main.c
input.o : input.c def.h command.h
cc -c input.c
output.o : output.c def.h buffer.h
cc -c output.c
command.o : command.c def.h command.h
cc -c command.c
files.o : files.c def.h buffer.h command.h
cc -c files.c
utils.o : tools.c def.h
cc -c tools.c
#第3部分
clean :
rm textedit main.o input.o output.o
rm command.o files.o tools.o
- 下面由一张图了解上述文件的依赖关系
Makefile的编译机制
-
如果该项目没有编译过,也就是没有生成过目标,那么就根据所给的条件来生成目标,所有源文件都要编译并进行连接。
-
如果该项目已经编译过,生成有目标,一旦条件发生变化,则需要重新生成目标。
-
若项目的某些源文件被修改,只编译被修改的源文件,并连接生成目标程序。
-
如果项目的某些头文件改变,则需要编译引用了这些头文件的源文件,并连接生成目标程序。
-
make
通过比较目标和条件中的文件的修改日期来识别文件是否被修改。如果条件中的文件的日期要比目标中的文件的日期要新,或者目标不存在,那么make就会执行后续定义的命令。
Makefile的高级特性
Makefile
示例修改
#第1部分
objects = main.o input.o output.o command.o files.o utils.o
#第2部分
textedit : $(objects)
cc -o edit $(objects)
#第3部分
main.o : defs.h
input.o : defs.h command.h
command.o : defs.h command.h
output.o : defs.h buffer.h
insert.o : defs.h buffer.h
tools.o : defs.h
#第4部分
.PHONY : clean
clean :
rm edit $(objects)
模式规则
模式规则使用
%
通配符,可以匹配多个文件。
- 表示所有
.o
文件都依赖于对应的.c
文件
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
隐式规则
- make 内置了一些隐式规则,可以使用命令
make -p
查看所有内置的隐式规则
比如:
从.c
文件生成.o
文件的规则。
从.o
文件链接生成可执行文件的规则。
伪目标
伪目标并不是一个文件,只是一个标签
使用通配符
make支持通配符:“
*
”、“?
”和“[...]
”,用于代替一系列的文件。
文件包含
在一个Makefile文件中可以引用另一个Makefile文件。
make的工作方式
(1)读入所有的
Makefile
文件。
(2)读入被include
语句嵌入的其他Makefile
文件。
(3)初始化这些文件中的变量。
(4)推导隐式规则,并分析所有规则。
(5)为所有的目标文件创建依赖关系链。
(6)根据依赖关系,决定哪些目标需要重新生成。
(7)执行生成目标的命令。
Autotools
自动产生Makefile
Autotools工作原理
- 一个
Autotools
项目至少需要一个名为configure
的配置脚本和一个名为Makefile.in
的Makefile模板。 - 实际上并不需要
Autotools
来建立Autotools包,configure是在最基本的Shell
(sh)上运行的Shell脚本,它检查用户系统获取每个特征,通过模板写出Makefile
文件。 configure
在每个目录中创建所有文件,并且在命令行接受几个选项用于在不同的目录中安装文件。
configure
产生的Makefile文件
由
configure
产生的Makefile文件很标准,它们定义由GNU
标准所需的所有标准目标,常用的目标如下所示。
make
或make all
:创建程序make install
:安装程序make distclean
:删除由configure
产生的所有文件
Autotools工具
-
Autoconf
:用于生成configure
脚本,检测系统特性和依赖关系。 -
Automake
:用于根据Makefile.am
文件生成Makefile.in
文件。 -
Libtool
:用于简化共享库的管理和编译。 -
Autotools 的辅助工具:
Autoheader
:用于生成config.h.in
AutoMake
: 用于处理Makefile.am
中的条件语句。
Autotools应用示例
- 步骤如下
(1)准备源代码。
(2)切换到项目工作目录,执行命令autoscan
命令扫描工作目录生成configure.scan
文件。
(3)将文件configure.scan
重命名为configure.ac
,然后再编辑修改这个配置文件。
(4)项目目录下执行aclocal
命令,扫描configure.ac
文件生成aclocal.m4
文件。
(5)项目目录下执行autoconf
命令生成configure
文件。
(6)项目目录下执行autoheader
命令生成config.h.in
文件。
(7)项目目录下创建一个Makefile.am
文件,供automake
工具根据configure.in
中的参数将Makefile.am
转换成Makefile.in
文件。
(8)在项目目录下执行automake
命令生成Makefile.in
文件。通常要使用选项--add-missing
让automake自动添加一些必需的脚本文件。
(9)在项目目录下执行./congigure
命令,基于Makefile.in生成最终的Makefile文件。该命令将一些配置参数添加到Makefile文件中。
(10)在项目目录下执行make
命令,基于Makefile文件编译源代码文件并生成可执行文件。
(11)在项目目录下执行make install
命令将编译后的软件包安装到系统中。
(12)如果要对外发布,可以在项目目录下执行make dist
命令将程序和相关的文档打包为一个压缩文档。
晚上好,今天Linux的相关内容到这里就结束了😆
如果想了解更多,点击主页【练小杰的CSDN】
⚠️若博客里的内容有问题,欢迎指正,我会及时修改!!!
明天再见啦,各位🧍♂️大佬们~~