当前位置: 首页 > article >正文

【Linux】基础开发工具(下)

文章目录

  • 一、自动化构建工具
    • 1. 什么是 make 和 Makefile?
    • 2. 如何自动化构建可执行程序?
    • 3. Makefile 的核心思想
    • 4. 如何清理可执行文件?
    • 5. make 的工作原理
      • 5.1 make 的执行顺序
      • 5.2 为什么 make 要检查文件是否更新?
        • 5.2.1 避免重复编译,节省时间
        • 5.2.2 时间戳检查机制
      • 5.3 `.PHONY`伪目标
      • 补充知识:make 依赖关系推导
      • 补充知识:分阶段编译
    • 6. Makefile 扩展语法
      • 6.1 定义变量
      • 6.2 多个源文件
      • 6.3 多个.o文件
      • 6.4 测试是否可行
      • 6.5 `$^` 和 `$@`
      • 6.6 `%`通配符与`<`
      • 6.7 测试一下
      • 6.8 清理文件
      • 6.9 自定义输出信息
      • 6.10 Makefile 扩展语法汇总

一、自动化构建工具

平时用 gcc / g++ 编译代码时,每次都要手动输入编译命令。尤其是当项目包含多个源文件时,重复输入命令不仅繁琐,还容易出错。有没有办法自动化完成编译过程,一键生成可执行文件呢?
答案是:make 与 makefile

1. 什么是 make 和 Makefile?

make 是一个自动化构建工具,而 Makefile 是配合 make 使用的配置文件,它们的组合可以帮你解决手动重复输入编译命令的问题。
简单说:make是一条指令,makefile是一个文件。

2. 如何自动化构建可执行程序?

简单认识一下 make 和 makefile 如何自动化构建可执行程序。
第一步:在源代码同级目录下,创建一个文件名为:makefile / Makefile 的文件。(首字母大小写均可)
在这里插入图片描述
第二步:在文件内部写上一些语句用来构建可执行程序

目标可执行程序文件名:依赖的文件名 //依赖关系gcc xxx -o xxx       //依赖方法
//第二行要紧跟着以tab键开头

冒号右面又叫依赖文件列表,依赖文件可能有多个。
在这里插入图片描述

在这里插入图片描述
第三步:执行make命令,即可自动形成可执行程序
在这里插入图片描述

3. Makefile 的核心思想

根据依赖关系和依赖方法形成目标文件。
在这里插入图片描述
例如:小明想和小明爸爸要生活费,并且小明只能用学校公用电话。

场景一:
小明给爸爸打电话说:爸,我是你儿子。(表明依赖关系)
如果此时小明不再说话,此时小明爸爸会一脸蒙圈,回复:干啥?
小明继续说:给我打钱!(表明依赖方法)
此时小明爸爸明白了小明的意思:转账2000元。

场景二:
小明给小李爸爸打电话说:我是小明,给我打钱!
此时小李的爸爸依然会一脸蒙圈,回复:???打错了吧?(依赖关系不匹配)

场景三:
小明想追求心仪的女同学小美,直接跟小美表白。(直接表明依赖方法)
小美说:你是谁呀,我都不认识你,算了吧。(没有先产生依赖关系)

场景四:
小明想追求心仪的女同学小花,这次有经验了,先给小花讲解数学题,又经常约小花一起共进晚餐(先产生依赖关系)
在某次一起共进晚餐时,和小花表白。(再表明依赖方法)
小花说:我也喜欢你!

所以,成事需要依赖方法和依赖关系同时存在、匹配,且往往需先建立依赖关系,再执行方法。
Makefile 核心逻辑:
依赖关系 = “我和对方的关系” = “目标和依赖文件的关系”
依赖方法 = “怎么让对方行动” = “怎么用命令处理文件”
顺序原则 = “先混熟,再提需求” = “先处理依赖项,再生成目标”

4. 如何清理可执行文件?

先打开Makefile,添加新配置,如图:

.PHONY:clean
clean:rm -f ok

在这里插入图片描述
当想要删除可执行文件时,执行make clean就会自动进行rm
在这里插入图片描述

5. make 的工作原理

5.1 make 的执行顺序

make 会自顶向下扫描makefile文件,默认形成第一个目标文件
如果想指定形成目标文件,语法:make 目标文件
我们将 clean 和 ok 调换一下顺序
在这里插入图片描述
可以发现,再次执行make指令,就默认执行rm了,只有执行make ok才执行gcc指令
在这里插入图片描述

5.2 为什么 make 要检查文件是否更新?

make 工具通过检查文件更新状态,仅重新编译必要的文件,从而大幅提高编译效率。

5.2.1 避免重复编译,节省时间

假设一个项目包含 100 个源文件,其中只有 1 个文件被修改:
不检查更新时:每次执行 make 都需重新编译全部 100 个文件,耗时可能长达数十分钟。
检查更新时:make 仅编译被修改的文件及其依赖项,其他文件直接复用之前的编译结果(如 .o 目标文件),节省大量时间。

5.2.2 时间戳检查机制

make 会比较 依赖文件(如 .c、.h)和 目标文件(如 .o) 的修改时间戳。
若依赖文件的时间戳比目标文件新(即依赖文件被修改过),则认为目标文件 “过时”,需要重新编译。
若所有依赖文件未更新,则跳过编译目标文件。

简单说:通过对比源文件(依赖文件)和可执行程序(目标文件)的修改时间(Modify time)
在这里插入图片描述
在这里插入图片描述
总结:make 检查文件更新的核心目的是实现增量编译—— 仅更新过时的文件,在保证编译结果正确性的前提下最大化提升效率。这一机制通过 Makefile 定义的依赖关系和文件时间戳对比实现,是现代软件开发中构建工具的基础设计思想。

5.3 .PHONY伪目标

在 Makefile 中,伪目标(Phony Target) 的依赖方法总是会被执行
伪目标是一种特殊的目标,它不代表一个实际的文件,而是作为执行一组命令的标识。通过.PHONY声明:
在这里插入图片描述
为什么伪目标的依赖方法总是执行?

  1. make 的默认行为
    对于普通目标,make 会:
    检查目标文件是否存在。
    比较目标文件与依赖文件的修改时间。
    仅当目标不存在或依赖更新时,才执行命令。

  2. 伪目标打破时间戳检查
    伪目标没有对应的文件,因此 make 无法检查其时间戳。当你执行 make clean 时:
    make 发现 clean 是伪目标,直接执行对应的命令,不检查任何条件。
    即使当前目录存在名为 clean 的文件,.PHONY 声明会让 make 忽略它。

简单说:凡是被.PHONY修饰的伪目标,忽略对比修改时间,总是能被执行。

由于clean.PHONY修饰:
在这里插入图片描述
ok目标文件前加上.PHONY,可以发现,和上面的clean一样,可以一直被执行。
在这里插入图片描述
在这里插入图片描述

补充知识:make 依赖关系推导

make 会进行依赖关系的推导,直到依赖文件是存在的
在这里插入图片描述
类似将依赖方法不断入栈,推导完毕出栈执行方法。
在这里插入图片描述

补充知识:分阶段编译

一般在编译时,我们通常不会直接把文件从 .c 直接到可执行文件,而是先从 .c 到 .o 再到可执行。
为什么要分阶段编译?

  1. 效率更高:只修改一个源文件时,只需重新编译对应的 .o 文件,无需重新编译整个项目。
  2. 模块化开发:不同模块可以独立编译,最后链接在一起,便于团队协作。
  3. 复用性:可以将常用功能编译为静态库或动态库,供多个项目复用。

6. Makefile 扩展语法

讲解这部分知识,是为了能让我们的Makefile文件变的更加通用,假设未来有变更,直接修改变量即可。

6.1 定义变量

下面讲解一下如何将Makefile文件写的更加通用
首先定义一批变量

BIN=ok
SRC=test.c
OBJ=test.o
CC=gcc
RM=rm -f

将所有可以被变量替换的指令替换,用这种形式:$(变量)
在这里插入图片描述 在这里插入图片描述
可以发现可以正常使用make
在这里插入图片描述

6.2 多个源文件

当我们想把非常多的源文件编译形成一个可执行文件时,该怎么办呢?
第一种方法:SRC=$(shell ls *.c),在Makefile中可以通过这种方法使用shell指令
在这里插入图片描述

第二种方法:SRC=$(wildcard *.c),Makefile中的内部语法
在这里插入图片描述

6.3 多个.o文件

把所有的源文件的.c后缀替换为.o,形成OBJ
OBJ=$(SRC:.c=.o)
此时,OBJ就等于所有的同名.o文件了
在这里插入图片描述

6.4 测试是否可行

测试多个源文件是否正确
在这里插入图片描述
make回显问题:
make默认会对指令进行回显,如果不想回显,在不想回显的指令前加上@符号
在这里插入图片描述
测试多个目标文件是否正确
在这里插入图片描述
加了@符号之后就不会再多回显一次了。
正常显示,一段.c文件,一段.o文件。并且确实都是源文件的同名.o文件。
在这里插入图片描述

6.5 $^$@

此时 SRC 和 OBJ 不再是单一文件,他们表示的都是多个文件
依然可以是用之前的方法:

$(BIN):$(OBJ)gcc $(OBJ) -o $(BIN)

更优方法:

$(BIN):$(OBJ)gcc $^ -o $@

如图,$^表示所有的OBJ文件,$@表示BIN文件
在这里插入图片描述

6.6 %通配符与<

%.o:%.c$(CC) -c $<

在这里插入图片描述

在这里插入图片描述

6.7 测试一下

在这里插入图片描述

6.8 清理文件

在这里插入图片描述

在这里插入图片描述

6.9 自定义输出信息

BIN=ok    
SRC=$(wildcard *.c)    
OBJ=$(SRC:.c=.o)    
CC=gcc    
RM=rm -f    $(BIN):$(OBJ)    @$(CC) $^ -o $@    @echo "链接 $^ 成 $@"
%.o:%.c    @$(CC) -c $<    @echo "编译 $< 成 $@".PHONY:clean    
clean:    $(RM) $(OBJ) $(BIN).PHONY:test
test:                        @echo $(SRC)                            @echo $(OBJ)  

这样就直观很多了:
在这里插入图片描述

6.10 Makefile 扩展语法汇总

BIN=proc.exe # 定义变量
CC=gcc
#SRC=$(shell ls *.c) # 采⽤shell命令⾏⽅式,获取当前所有.c⽂件名
SRC=$(wildcard *.c) # 或者使⽤ wildcard 函数,获取当前所有.c⽂件名
OBJ=$(SRC:.c=.o) # 将SRC的所有同名.c 替换 成为.o 形成⽬标⽂件列表
LFLAGS=-o # 链接选项
FLAGS=-c # 编译选项
RM=rm -f # 引⼊命令$(BIN):$(OBJ)@$(CC) $(LFLAGS) $@ $^ # $@:代表⽬标⽂件名。 $^: 代表依赖⽂件列表@echo "linking ... $^ to $@"%.o:%.c # %.c 展开当前⽬录下所有的.c。 %.o: 同时展开同名.o@$(CC) $(FLAGS) $< # %<: 对展开的依赖.c⽂件,⼀个⼀个的交给gcc。@echo "compling ... $< to $@" # @:不回显命令.PHONY:clean
clean:$(RM) $(OBJ) $(BIN) # $(RM): 替换,⽤变量内容替换它.PHONY:test # 测试$符号的作用
test:@echo $(SRC)@echo $(OBJ)
http://www.lryc.cn/news/2387663.html

相关文章:

  • Python爬虫实战:研究Portia框架相关技术
  • chrome打不开axure设计的软件产品原型问题解决办法
  • 达梦数据库-学习-23-获取执行计划的N种方法
  • 【数据结构】树形结构--二叉树
  • Baklib构建企业CMS高效协作与安全管控体系
  • 深入理解 JDK、JRE 和 JVM 的区别
  • LSTM 与 TimesNet的时序分析对比解析
  • 图论学习笔记 4 - 仙人掌图
  • 语音识别算法的性能要求一般是多少
  • 百度ocr的简单封装
  • 华为高斯数据库(GaussDB)深度解析:国产分布式数据库的旗舰之作
  • LWIP 中,lwip_shutdown 和 lwip_close 区别
  • xml双引号可以不转义
  • 互联网大厂Java面试:从Spring到微服务的挑战
  • 兰亭妙微 | 图标设计公司 | UI设计案例复盘
  • OpenCV视觉图片调整:从基础到实战的技术指南
  • C#日期和时间:DateTime转字符串全面指南
  • 手机收不到WiFi,手动输入WiFi名称进行连接不不行,可能是WiFi频道设置不对
  • 批量文件重命名工具
  • ATPrompt方法:属性嵌入的文本提示学习
  • 14.「实用」扣子(coze)教程 | Excel文档自动批量AI文档生成实战,中级开篇
  • 对于geoserver发布数据后的开发应用
  • 液体散货装卸管理人员备考指南
  • 基于Qlearning强化学习的二阶弹簧动力学模型PID控制matlab性能仿真
  • 【监控】Spring Boot 应用监控
  • 「MATLAB」计算校验和 Checksum
  • 【AS32X601驱动系列教程】SMU_系统时钟详解
  • 09 接口自动化-用例管理框架pytest之allure报告定制以及数据驱动
  • React笔记-Ant Design X样本间对接智谱AI
  • 网络安全-等级保护(等保) 3-2 GB/T 28449-2019《信息安全技术 网络安全等级保护测评过程指南》-2018-12-28发布【现行】