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

news2025/7/17 20:03:20

文章目录

  • 一、自动化构建工具
    • 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.coloradmin.cn/o/2387663.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

chrome打不开axure设计的软件产品原型问题解决办法

1、打开原型文件夹&#xff0c;进入到其中的如下目录中&#xff1a;resources->chrome->axure-chrome-extension.crx&#xff0c;找到 Axure RP Extension for Chrome插件。 2、axure-chrome-extension.crx文件修改扩展名.rar&#xff0c;并解压到文件夹 axure-chrome-ex…

【数据结构】树形结构--二叉树

【数据结构】树形结构--二叉树 一.知识补充1.什么是树2.树的常见概念 二.二叉树&#xff08;Binary Tree&#xff09;1.二叉树的定义2.二叉树的分类3.二叉树的性质 三.二叉树的实现1.二叉树的存储2.二叉树的遍历①.先序遍历②.中序遍历③.后序遍历④.层序遍历 一.知识补充 1.什…

Baklib构建企业CMS高效协作与安全管控体系

企业CMS高效协作体系构建 基于智能工作流引擎的设计逻辑&#xff0c;现代企业内容管理系统通过预设多节点审核路径与自动化任务分配机制&#xff0c;有效串联市场、技术、法务等跨部门协作链路。系统支持多人同时编辑与版本追溯功能&#xff0c;结合细粒度权限管控模块&#x…

深入理解 JDK、JRE 和 JVM 的区别

在 Java 中&#xff0c;JDK、JRE 和 JVM 是非常重要的概念&#xff0c;它们各自扮演着不同的角色&#xff0c;却又紧密相连。今天&#xff0c;就让我们来详细探讨一下它们之间的区别。 一、JVM JVM 即 Java 虚拟机&#xff0c;它是整个 Java 技术体系的核心。JVM 提供了 Java…

LSTM 与 TimesNet的时序分析对比解析

前言 Hi&#xff0c;我是GISerLiu&#x1f642;, 这篇文章是参加2025年5月Datawhale学习赛的打卡文章&#xff01;&#x1f4a1; 本文将深入探讨在自定义时序数据集上进行下游分类任务的两种主流分析方法。一种是传统的“先插补后分析”策略&#xff0c;另一种是采用先进的端到…

图论学习笔记 4 - 仙人掌图

先扔张图&#xff1a; 为了提前了解我们采用的方法&#xff0c;请先阅读《图论学习笔记 3》。 仙人掌图的定义&#xff1a;一个连通图&#xff0c;且每条边只出现在至多一个环中。 这个图就是仙人掌图。 这个图也是仙人掌图。 而这个图就不是仙人掌图了。 很容易发现&#xf…

华为高斯数据库(GaussDB)深度解析:国产分布式数据库的旗舰之作

高斯数据库介绍 一、高斯数据库概述 GaussDB是华为自主研发的新一代分布式关系型数据库&#xff0c;专为企业核心系统设计。它支持HTAP&#xff08;混合事务与分析处理&#xff09;&#xff0c;兼具强大的事务处理与数据分析能力&#xff0c;是国产数据库替代的重要选择。 产…

LWIP 中,lwip_shutdown 和 lwip_close 区别

实际开发中&#xff0c;建议对 TCP 连接按以下顺序操作以确保可靠性&#xff1a; lwip_shutdown(newfd, SHUT_RDWR); // 关闭双向通信 lwip_close(newfd); // 释放资源

xml双引号可以不转义

最近在开发soap方面的协议&#xff0c;soap这玩意&#xff0c;就避免不了XML&#xff0c;这里我用到了pguixml库。 输入了这个XML后&#xff0c;发现<和>都被转义&#xff0c;但是""没有被转义&#xff0c;很是奇怪啊。毕竟去网上随便一搜转义字符&#xff0c…

兰亭妙微 | 图标设计公司 | UI设计案例复盘

在「33」「312」新高考模式下&#xff0c;选科决策成为高中生和家长的「头等大事」。兰亭妙微公司受委托优化高考选科决策平台个人诊断报告界面&#xff0c;核心挑战是&#xff1a;如何将复杂的测评数据&#xff08;如学习能力倾向、学科报考机会、职业兴趣等&#xff09;转化为…

OpenCV视觉图片调整:从基础到实战的技术指南

引言:数字图像处理的现代意义与OpenCV深度应用 在人工智能与计算机视觉蓬勃发展的今天,图像处理技术已成为多个高科技领域的核心支撑。根据市场研究机构Grand View Research的数据,全球计算机视觉市场规模预计将从2022年的125亿美元增长到2030年的253亿美元,年复合增长率达…

手机收不到WiFi,手动输入WiFi名称进行连接不不行,可能是WiFi频道设置不对

以下是电脑上分享WiFi后&#xff0c;部分手机可以看到并且能连接&#xff0c;部分手机不行&#xff0c;原因是&#xff1a;频道设置为5GHz&#xff0c;修改成&#xff0c;任何可用频率&#xff0c;则可

批量文件重命名工具

分享一个自己使用 python 开发的小软件&#xff0c;批量文件重命名工具&#xff0c;主要功能有批量中文转拼音&#xff0c;简繁体转换&#xff0c;大小写转换&#xff0c;替换文件名&#xff0c;删除指定字符&#xff0c;批量添加编号&#xff0c;添加前缀/后缀。同时还有文件时…

ATPrompt方法:属性嵌入的文本提示学习

ATPrompt方法:属性嵌入的文本提示学习 让视觉-语言模型更好地对齐图像和文本(包括未知类别)。 一、问题场景:传统方法的局限 假设你有一个模型,能识别图像中的物体并关联到文本标签(如“狗”“猫”)。 传统方法: 用“软提示”(可学习的文本标签)和“硬类别标记”…

14.「实用」扣子(coze)教程 | Excel文档自动批量AI文档生成实战,中级开篇

随着AI编程工具及其能力的不断发展&#xff0c;编程将变得越来越简单。 在这个大趋势下&#xff0c;大师兄判断未来的编程将真正成为像office工具一样的办公必备技能。每个人通过 &#xff08;专业知识/资源编程&#xff09;将自己变成一个复合型的人才&#xff0c;大大提高生…

对于geoserver发布数据后的开发应用

对于geoserver发布数据后的开发应用 文章目录 对于geoserver发布数据后的开发应用[TOC](文章目录) 前言一、geosever管理地理数据的后端实用方法后端进行登录geoserver并且发布一个矢量数据前置的domain数据准备后端内容 总结 前言 首先&#xff0c;本篇文章仅进行技术分享&am…

基于Qlearning强化学习的二阶弹簧动力学模型PID控制matlab性能仿真

目录 1.算法仿真效果 2.算法涉及理论知识概要 2.1 传统PID控制器 2.2 Q-Learning强化学习原理 2.3 Q-Learning与PID控制器的融合架构 3.MATLAB核心程序 4.完整算法代码文件获得 1.算法仿真效果 matlab2024B仿真结果如下&#xff08;完整代码运行后无水印&#xff09;&a…

【AS32X601驱动系列教程】SMU_系统时钟详解

在现代嵌入式系统中&#xff0c;时钟与复位管理是确保系统稳定运行的关键。我们的SMU&#xff08;系统管理单元&#xff09;模块专注于此核心任务&#xff0c;通过精准的时钟配置和复位控制&#xff0c;为整个系统提供可靠的时序保障。 SMU模块的主要功能是完成时钟和复位的管…

09 接口自动化-用例管理框架pytest之allure报告定制以及数据驱动

文章目录 一、企业级的Allure报告的定制左边的定制&#xff1a;右边的定制&#xff1a;1.用例的严重程度/优先级2.用例描述3.测试用例连接的定制4.测试用例步骤的定制5.附件的定制 二、企业中真实的定制有哪些&#xff1f;三、allure报告如何在本地访问四、allure中的数据驱动装…

React笔记-Ant Design X样本间对接智谱AI

目标 后端对接是智谱AI。 过程 先把Ant Design X样本间搭建好&#xff0c;通过此篇博文获得智谱AI的URL等 智谱AI开放平台 看下此篇博文的“使用API接入” 通义千问 - Ant Design X 将样本间代码的&#xff1a; const [agent] useXAgent({request: async ({ message }, { …